diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile deleted file mode 100644 index b85a6aee0e9a44..00000000000000 --- a/package/kernel/qca-nss-dp/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-dp -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://github.com/openwrt/qca-nss-dp.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2026-03-13 -PKG_SOURCE_VERSION:=6a5c4716ca258d67202fc7964c9294dfefa3ccfa -PKG_MIRROR_HASH:=5f9a9a44f91842492d8c9038670379011b90e68fda7af291b2bdd81889a9ea1a - -PKG_BUILD_PARALLEL:=1 -PKG_FLAGS:=nonshared - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/qca-nss-dp - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Devices - DEPENDS:=@TARGET_qualcommax +kmod-qca-ssdk - TITLE:=Qualcom NSS dataplane ethernet driver - FILES:=$(PKG_BUILD_DIR)/qca-nss-dp.ko - AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp,1) -endef - -define KernelPackage/qca-nss-dp/Description - NSS dataplane ethernet driver for Qualcom SoCs. -endef - -define Build/InstallDev - mkdir -p $(1)/usr/include/qca-nss-dp - $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-dp/ -endef - -EXTRA_CFLAGS+= \ - -I$(STAGING_DIR)/usr/include/qca-ssdk - -NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal -define Build/Configure - $(CP) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_SUBTARGET)/nss_$(CONFIG_TARGET_SUBTARGET).h \ - $(PKG_BUILD_DIR)/exports/nss_dp_arch.h -endef - -define Build/Compile - +$(KERNEL_MAKE) $(PKG_JOBS) \ - -C "$(LINUX_DIR)" \ - M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(CONFIG_TARGET_SUBTARGET)" \ - modules -endef - -$(eval $(call KernelPackage,qca-nss-dp)) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile deleted file mode 100644 index c82fab7ef0b5da..00000000000000 --- a/package/kernel/qca-ssdk/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-ssdk -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://github.com/openwrt/qca-ssdk.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2026-06-04 -PKG_SOURCE_VERSION:=bb4f3f0b947ebfce51c78a8d39f57c7c758521c9 -PKG_MIRROR_HASH:=da990d2956db471071568fd6c7c9193b075f9a1e87e5ae5ac8729cc4dba9dc24 - -PKG_FLAGS:=nonshared -PKG_BUILD_PARALLEL:=1 -PKG_BUILD_FLAGS:=no-lto - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/qca-ssdk - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Devices - TITLE:=Qualcom SSDK switch driver - DEPENDS:=@(TARGET_qualcommax) - FILES:=$(PKG_BUILD_DIR)/qca-ssdk.ko - AUTOLOAD:=$(call AutoLoad,30,qca-ssdk) -endef - -define KernelPackage/qca-ssdk/Description - Driver for Qualcomm Atheros switches. -endef - -GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') - -LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' PRJ_PATH=$(PKG_BUILD_DIR) MODULE_TYPE=KSLIB modules - -EXTRA_CFLAGS:= \ - -fno-stack-protector \ - -Wno-missing-prototypes \ - -Wno-missing-declarations \ - -I$(STAGING_DIR)/usr/include - -MAKE_FLAGS+= \ - TARGET_NAME=$(CONFIG_TARGET_NAME) \ - TOOL_PATH=$(firstword $(TOOLCHAIN_BIN_DIRS)) \ - SYS_PATH=$(LINUX_DIR) \ - TOOLPREFIX=$(TARGET_CROSS) \ - KVER=$(LINUX_VERSION) \ - ARCH=$(LINUX_KARCH) \ - TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ - GCC_VERSION=$(GCC_VERSION) \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - SoC=$(CONFIG_TARGET_SUBTARGET) \ - SHELL="$(BASH)" \ - PTP_FEATURE=disable SWCONFIG_FEATURE=disable \ - ISISC_ENABLE=disable MHT_ENABLE=disable \ - IN_QCA803X_PHY=FALSE IN_QCA808X_PHY=FALSE \ - IN_MALIBU_PHY=FALSE IN_MP_PHY=FALSE \ - $(LNX_CONFIG_OPTS) - -ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") - MAKE_FLAGS+= CHIP_TYPE=HPPE -endif - -ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") - MAKE_FLAGS+= CHIP_TYPE=CPPE \ - IN_AQUANTIA_PHY=TRUE -endif - -ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq50xx") - MAKE_FLAGS+= CHIP_TYPE=MP -endif - -define Build/Compile - +$(MAKE) $(PKG_JOBS) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/ref - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/fal - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/sal - $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/init - $(CP) -rf $(PKG_BUILD_DIR)/include/api/sw_ioctl.h $(1)/usr/include/qca-ssdk/api - if [ -f $(PKG_BUILD_DIR)/include/ref/ref_vsi.h ]; then \ - $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_vsi.h $(1)/usr/include/qca-ssdk/ref/; \ - fi - if [ -f $(PKG_BUILD_DIR)/include/ref/ref_fdb.h ]; then \ - $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_fdb.h $(1)/usr/include/qca-ssdk/ref/; \ - fi - if [ -f $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h ]; then \ - $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h $(1)/usr/include/qca-ssdk/ref/; \ - fi - if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_init.h ]; then \ - $(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_init.h $(1)/usr/include/qca-ssdk/init/; \ - fi - if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_netlink.h ]; then \ - $(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_netlink.h $(1)/usr/include/qca-ssdk/init/; \ - fi - $(CP) -rf $(PKG_BUILD_DIR)/include/fal $(1)/usr/include/qca-ssdk - $(CP) -rf $(PKG_BUILD_DIR)/include/common/*.h $(1)/usr/include/qca-ssdk - $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/linux/*.h $(1)/usr/include/qca-ssdk - $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/*.h $(1)/usr/include/qca-ssdk - -endef - -$(eval $(call KernelPackage,qca-ssdk)) diff --git a/target/linux/generic/pending-6.12/770-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch b/target/linux/generic/pending-6.12/770-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch index da608c6c21ef66..676e23c0019450 100644 --- a/target/linux/generic/pending-6.12/770-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch +++ b/target/linux/generic/pending-6.12/770-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch @@ -56,7 +56,7 @@ Signed-off-by: Christian Marangi menu "PCS device drivers" +config FWNODE_PCS -+ bool "PCS Firmware Node" ++ tristate + depends on (ACPI || OF) + depends on PHYLINK + help diff --git a/target/linux/generic/pending-6.18/737-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch b/target/linux/generic/pending-6.18/737-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch index da608c6c21ef66..676e23c0019450 100644 --- a/target/linux/generic/pending-6.18/737-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch +++ b/target/linux/generic/pending-6.18/737-04-net-pcs-implement-Firmware-node-support-for-PCS-driv.patch @@ -56,7 +56,7 @@ Signed-off-by: Christian Marangi menu "PCS device drivers" +config FWNODE_PCS -+ bool "PCS Firmware Node" ++ tristate + depends on (ACPI || OF) + depends on PHYLINK + help diff --git a/target/linux/qualcommax/Makefile b/target/linux/qualcommax/Makefile index f08a9c83701a1f..1ef9ac337966b0 100644 --- a/target/linux/qualcommax/Makefile +++ b/target/linux/qualcommax/Makefile @@ -14,7 +14,7 @@ include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES += \ kmod-usb3 kmod-usb-dwc3 kmod-usb-dwc3-qcom \ kmod-leds-gpio kmod-gpio-button-hotplug \ - kmod-qca-nss-dp kmod-ath11k-ahb \ + kmod-ath11k-ahb \ wpad-basic-mbedtls uboot-envtools \ e2fsprogs kmod-fs-ext4 losetup diff --git a/target/linux/qualcommax/config-6.12 b/target/linux/qualcommax/config-6.12 index 43f4e25744e504..ed50f8fce408c0 100644 --- a/target/linux/qualcommax/config-6.12 +++ b/target/linux/qualcommax/config-6.12 @@ -153,6 +153,7 @@ CONFIG_FS_IOMAP=y CONFIG_FUNCTION_ALIGNMENT=4 CONFIG_FUNCTION_ALIGNMENT_4B=y CONFIG_FWNODE_MDIO=y +CONFIG_FWNODE_PCS=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y @@ -191,6 +192,7 @@ CONFIG_GPIOLIB_IRQCHIP=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_WATCHDOG=y # CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set +CONFIG_GRO_CELLS=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -281,6 +283,9 @@ 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_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_TAG_OOB=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y CONFIG_NET_INGRESS=y @@ -327,10 +332,12 @@ CONFIG_PCIE_QCOM_COMMON=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_MSI=y +CONFIG_PCS_QCA_UNIPHY=y CONFIG_PER_VMA_LOCK=y CONFIG_PGTABLE_LEVELS=3 CONFIG_PHYLIB=y CONFIG_PHYLIB_LEDS=y +CONFIG_PHYLINK=y CONFIG_PHYS_ADDR_T_64BIT=y # CONFIG_PHY_QCOM_APQ8064_SATA is not set # CONFIG_PHY_QCOM_EDP is not set @@ -402,6 +409,7 @@ CONFIG_QCA807X_PHY=y CONFIG_QCA808X_PHY=y # CONFIG_QCM_DISPCC_2290 is not set # CONFIG_QCM_GCC_2290 is not set +# CONFIG_QCOM_80211AX_PPE is not set # CONFIG_QCOM_A53PLL is not set # CONFIG_QCOM_AOSS_QMP is not set CONFIG_QCOM_APCS_IPC=y @@ -414,6 +422,7 @@ CONFIG_QCOM_BAM_DMA=y # CONFIG_QCOM_CPR is not set # CONFIG_QCOM_CPUCP_MBOX is not set # CONFIG_QCOM_EBI2 is not set +# CONFIG_QCOM_EDMA is not set # CONFIG_QCOM_FASTRPC is not set # CONFIG_QCOM_GENI_SE is not set # CONFIG_QCOM_GSBI is not set @@ -533,6 +542,7 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y +CONFIG_SKB_EXTENSIONS=y CONFIG_SMP=y # CONFIG_SM_CAMCC_4450 is not set # CONFIG_SM_CAMCC_6350 is not set diff --git a/target/linux/qualcommax/dts/ipq5018-ax6000.dts b/target/linux/qualcommax/dts/ipq5018-ax6000.dts index df967bd414be65..1d7d352b5bce5b 100644 --- a/target/linux/qualcommax/dts/ipq5018-ax6000.dts +++ b/target/linux/qualcommax/dts/ipq5018-ax6000.dts @@ -12,7 +12,7 @@ compatible = "xiaomi,ax6000", "qcom,ipq5018"; aliases { - label-mac-device = &dp1; + label-mac-device = &gmac0; led-boot = &led_system_blue; led-failsafe = &led_system_yellow; led-running = &led_system_blue; @@ -225,11 +225,11 @@ #address-cells = <1>; #size-cells = <1>; - mac_addr_dp1: macaddr@0 { + mac_addr_gmac0: macaddr@0 { reg = <0x0 0x6>; }; - mac_addr_dp2: macaddr@6 { + mac_addr_gmac1: macaddr@6 { reg = <0x6 0x6>; }; @@ -292,45 +292,31 @@ * ================================================================= */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy --- MDI --- QCA8337 Switch - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - phy_dac = <0x10 0x10>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8081 - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - phy_address = <8>; - port_mac_sel = "QGMAC_PORT"; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; - nvmem-cells = <&mac_addr_dp1 0>; + nvmem-cells = <&mac_addr_gmac0 0>; nvmem-cell-names = "mac-address"; }; -// MAC1 ---SGMII---> QCA8081 -&dp2 { +// MAC1 --- SGMII+ ---> QCA8081 +&gmac1 { status = "okay"; - label = "wan"; phy-handle = <&qca8081>; - nvmem-cells = <&mac_addr_dp2 0>; + phy-mode = "2500base-x"; + + label = "wan"; + + nvmem-cells = <&mac_addr_gmac1 0>; nvmem-cell-names = "mac-address"; }; @@ -455,7 +441,7 @@ reg = <4>; phy-handle = <&qca8337_3>; phy-mode = "gmii"; - ethernet = <&dp1>; + ethernet = <&gmac0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq5018-ax830.dts b/target/linux/qualcommax/dts/ipq5018-ax830.dts index 4772b51050a9e3..6729f756c2f16a 100644 --- a/target/linux/qualcommax/dts/ipq5018-ax830.dts +++ b/target/linux/qualcommax/dts/ipq5018-ax830.dts @@ -75,45 +75,32 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8081 - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; label = "lan"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; - phy-mode = "sgmii"; }; -// MAC1 ---SGMII---> QCA8081 -&dp2 { +// MAC1 --- SGMII+ ---> QCA8081 +&gmac1 { status = "okay"; - label = "wan"; phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + + label = "wan"; + nvmem-cells = <&hw_mac_addr 1>; nvmem-cell-names = "mac-address"; }; diff --git a/target/linux/qualcommax/dts/ipq5018-ax850.dts b/target/linux/qualcommax/dts/ipq5018-ax850.dts index 02dacde426eafc..35d327918b828d 100644 --- a/target/linux/qualcommax/dts/ipq5018-ax850.dts +++ b/target/linux/qualcommax/dts/ipq5018-ax850.dts @@ -74,45 +74,32 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8081 - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; label = "lan"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; - phy-mode = "sgmii"; }; // MAC1 ---SGMII---> QCA8081 -&dp2 { +&gmac1 { status = "okay"; - label = "wan"; phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + + label = "wan"; + nvmem-cells = <&hw_mac_addr 1>; nvmem-cell-names = "mac-address"; }; diff --git a/target/linux/qualcommax/dts/ipq5018-gl-b3000.dts b/target/linux/qualcommax/dts/ipq5018-gl-b3000.dts index d0cd077491cfe6..15c4c818c1c8b2 100644 --- a/target/linux/qualcommax/dts/ipq5018-gl-b3000.dts +++ b/target/linux/qualcommax/dts/ipq5018-gl-b3000.dts @@ -13,8 +13,8 @@ compatible = "glinet,gl-b3000", "qcom,ipq5018"; aliases { - ethernet1 = &dp2; - label-mac-device = &dp2; + ethernet1 = &gmac1; + label-mac-device = &gmac1; led-boot = &led_system_blue; led-failsafe = &led_status_white; led-running = &led_status_white; @@ -58,31 +58,20 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy -> QCA8337 Phy2 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - // MAC1 ---SGMII---> QCA8337 SerDes - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC1 ---SGMII---> QCA8337 SerDes -&dp2 { +&gmac1 { status = "okay"; - nvmem-cells = <&macaddr_dp2 0>; + + phy-mode = "sgmii"; + + nvmem-cells = <&macaddr_gmac1 0>; nvmem-cell-names = "mac-address"; fixed-link { @@ -131,7 +120,7 @@ reg = <0>; label = "cpu"; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { @@ -153,7 +142,7 @@ label = "lan1"; phy-handle = <&qca8337_1>; - nvmem-cells = <&macaddr_dp2 2>; + nvmem-cells = <&macaddr_gmac1 2>; nvmem-cell-names = "mac-address"; }; @@ -163,7 +152,7 @@ label = "lan2"; phy-handle = <&qca8337_2>; - nvmem-cells = <&macaddr_dp2 2>; + nvmem-cells = <&macaddr_gmac1 2>; nvmem-cell-names = "mac-address"; }; }; @@ -228,7 +217,7 @@ #address-cells = <1>; #size-cells = <1>; - macaddr_dp2: macaddr@0 { + macaddr_gmac1: macaddr@0 { compatible = "mac-base"; #nvmem-cell-cells = <1>; reg = <0x6 0x6>; diff --git a/target/linux/qualcommax/dts/ipq5018-mr3000d-ci.dts b/target/linux/qualcommax/dts/ipq5018-mr3000d-ci.dts index a03f9de657c7a2..07c2b406b82557 100644 --- a/target/linux/qualcommax/dts/ipq5018-mr3000d-ci.dts +++ b/target/linux/qualcommax/dts/ipq5018-mr3000d-ci.dts @@ -15,7 +15,7 @@ compatible = "cmcc,mr3000d-ci", "qcom,ipq5018"; aliases { - label-mac-device = <&dp1>; + label-mac-device = <&gmac1>; led-boot = &led_status_red; led-failsafe = &led_status_green; @@ -178,31 +178,15 @@ * =============================================================== */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy -> QCA8337 Phy4 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 ---SGMII---> QCA8337 SerDes - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; nvmem-cell-names = "mac-address"; @@ -210,9 +194,11 @@ }; // MAC1 -> SGMII -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cell-names = "mac-address"; nvmem-cells = <&macaddr_art_6 (0)>; @@ -304,7 +290,7 @@ port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-mr5500.dts b/target/linux/qualcommax/dts/ipq5018-mr5500.dts index f9ee89d62e7836..413a2a7de44842 100644 --- a/target/linux/qualcommax/dts/ipq5018-mr5500.dts +++ b/target/linux/qualcommax/dts/ipq5018-mr5500.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" #include "ipq5018-mx-base.dtsi" / { @@ -48,32 +49,19 @@ * =============================================================== */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 ---SGMII---> QCA8337 SerDes - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC1 ---SGMII---> QCA8337 SerDes -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; @@ -238,7 +226,7 @@ reg = <6>; label = "cpu"; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-mx-base.dtsi b/target/linux/qualcommax/dts/ipq5018-mx-base.dtsi index 49560a82db9ad8..9f4a824643d672 100644 --- a/target/linux/qualcommax/dts/ipq5018-mx-base.dtsi +++ b/target/linux/qualcommax/dts/ipq5018-mx-base.dtsi @@ -1,5 +1,4 @@ #include "ipq5018.dtsi" -#include "ipq5018-ess.dtsi" #include #include diff --git a/target/linux/qualcommax/dts/ipq5018-mx2000.dts b/target/linux/qualcommax/dts/ipq5018-mx2000.dts index 9d5fae468f6f8a..d36a94b3225ce7 100644 --- a/target/linux/qualcommax/dts/ipq5018-mx2000.dts +++ b/target/linux/qualcommax/dts/ipq5018-mx2000.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" #include "ipq5018-mx-base.dtsi" #include "ipq5018-qcn6122.dtsi" @@ -29,32 +30,19 @@ * =============================================================== */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy -> QCA8337 Phy4 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 ---SGMII---> QCA8337 SerDes - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC1 ---SGMII---> QCA8337 SerDes -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; @@ -139,7 +127,7 @@ reg = <6>; label = "cpu"; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-mx5500.dts b/target/linux/qualcommax/dts/ipq5018-mx5500.dts index 954a787af7230d..d1c05c445a5541 100644 --- a/target/linux/qualcommax/dts/ipq5018-mx5500.dts +++ b/target/linux/qualcommax/dts/ipq5018-mx5500.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" #include "ipq5018-mx-base.dtsi" / { @@ -13,7 +14,7 @@ }; aliases { - label-mac-device = &dp2; + label-mac-device = &gmac1; }; }; @@ -32,32 +33,19 @@ * =============================================================== */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy -> QCA8337 Phy4 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 ---SGMII---> QCA8337 SerDes - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC1 ---SGMII---> QCA8337 SerDes -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; @@ -142,7 +130,7 @@ reg = <6>; label = "cpu"; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-mx6200.dts b/target/linux/qualcommax/dts/ipq5018-mx6200.dts index 8bd128152058e3..2d968849a17422 100644 --- a/target/linux/qualcommax/dts/ipq5018-mx6200.dts +++ b/target/linux/qualcommax/dts/ipq5018-mx6200.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" #include "ipq5018-mx-base.dtsi" #include "ipq5018-qcn6122.dtsi" @@ -32,45 +33,31 @@ * ================================================================= */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy -> MDI --> RJ45 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 ---SGMII---> MaxLinear PHY -> RJ45 - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - phy_address = <15>; - port_mac_sel = "QGMAC_PORT"; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -// MAC0 ---MDI---> IPQ5018 GE PHY -&dp1 { +&gmac0 { status = "okay"; label = "lan"; - phy-handle = <&ge_phy>; + nvmem-cells = <&hw_mac_addr 1>; nvmem-cell-names = "mac-address"; }; -// MAC1 ---SGMII---> MXL Phy -&dp2 { +// MAC1 ---SGMII---> QCA8337 SerDes +&gmac1 { status = "okay"; - label = "wan"; phy-handle = <&gpy115c>; + phy-mode = "sgmii"; + + label = "wan"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; @@ -89,7 +76,7 @@ // Maxlinear Ethernet GPY115C gpy115c: ethernet-phy@f { compatible = "ethernet-phy-id67c9.df10"; - reg = <15>; + reg = <0xf>; }; }; diff --git a/target/linux/qualcommax/dts/ipq5018-pz-l8.dts b/target/linux/qualcommax/dts/ipq5018-pz-l8.dts index 5b4e3b5ba7ba8a..f6b486322d54b4 100644 --- a/target/linux/qualcommax/dts/ipq5018-pz-l8.dts +++ b/target/linux/qualcommax/dts/ipq5018-pz-l8.dts @@ -20,7 +20,7 @@ led-failsafe = &led_lan; led-running = &led_wan; led-upgrade = &led_lan; - label-mac-device = <&dp1>; + label-mac-device = <&gmac0>; }; chosen { @@ -136,31 +136,15 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy --- MDI --- QCA8337 Phy4(Port5) - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8337 SerDes(Port6) - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; nvmem-cells = <&hw_mac_addr 0>; @@ -168,9 +152,11 @@ }; // MAC1 -> SGMII -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&hw_mac_addr 1>; nvmem-cell-names = "mac-address"; @@ -235,7 +221,7 @@ port@0 { reg = <0>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { @@ -272,7 +258,7 @@ reg = <5>; phy-handle = <&qca8337_4>; phy-mode = "gmii"; - ethernet = <&dp1>; + ethernet = <&gmac0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq5018-redmi-ax5400.dts b/target/linux/qualcommax/dts/ipq5018-redmi-ax5400.dts index 65bef4376a7505..cc9c700beaea5f 100644 --- a/target/linux/qualcommax/dts/ipq5018-redmi-ax5400.dts +++ b/target/linux/qualcommax/dts/ipq5018-redmi-ax5400.dts @@ -12,7 +12,7 @@ compatible = "xiaomi,redmi-ax5400", "qcom,ipq5018"; aliases { - label-mac-device = &dp1; + label-mac-device = &gmac0; led-boot = &led_system_blue; led-failsafe = &led_system_yellow; led-running = &led_system_blue; @@ -222,11 +222,11 @@ #address-cells = <1>; #size-cells = <1>; - mac_addr_dp2: macaddr@0 { + mac_addr_gmac1: macaddr@0 { reg = <0x0 0x6>; }; - mac_addr_dp1: macaddr@6 { + mac_addr_gmac0: macaddr@6 { reg = <0x6 0x6>; }; }; @@ -281,42 +281,28 @@ * ================================================================= */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy --- MDI --- QCA8337 PHY4 - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - phy_dac = <0x10 0x10>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8337 MAC6 - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; // MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; - nvmem-cells = <&mac_addr_dp1 0>; + nvmem-cells = <&mac_addr_gmac0 0>; nvmem-cell-names = "mac-address"; }; // MAC1 ---SGMII---> QCA8337 -&dp2 { +&gmac1 { status = "okay"; - nvmem-cells = <&mac_addr_dp2 0>; + phy-mode = "sgmii"; + + nvmem-cells = <&mac_addr_gmac1 0>; nvmem-cell-names = "mac-address"; fixed-link { @@ -380,7 +366,7 @@ label = "wan"; phy-handle = <&qca8337_0>; - nvmem-cells = <&mac_addr_dp1 0>; + nvmem-cells = <&mac_addr_gmac0 0>; nvmem-cell-names = "mac-address"; }; @@ -406,13 +392,13 @@ reg = <5>; phy-handle = <&qca8337_4>; phy-mode = "gmii"; - ethernet = <&dp1>; + ethernet = <&gmac0>; }; port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-scr50axe.dts b/target/linux/qualcommax/dts/ipq5018-scr50axe.dts index e00a571d36b093..ecd724ffc97e3b 100644 --- a/target/linux/qualcommax/dts/ipq5018-scr50axe.dts +++ b/target/linux/qualcommax/dts/ipq5018-scr50axe.dts @@ -15,7 +15,7 @@ compatible ="zyxel,scr50axe", "qcom,ipq5018"; aliases { - label-mac-device = &dp2; + label-mac-device = &gmac1; led-boot = &led_power_blue; led-failsafe = &led_power_red; led-upgrade = &led_power_green; @@ -134,36 +134,27 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - qcom,port_phyinfo { - - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -&dp1 { +&gmac0 { status = "okay"; label = "wan"; + nvmem-cells = <&macaddr_appsblenv_ethaddr 0>; nvmem-cell-names = "mac-address"; }; -&dp2 { +&gmac1 { status = "okay"; + + phy-mode = "sgmii"; + nvmem-cells = <&macaddr_appsblenv_ethaddr (-4)>; nvmem-cell-names = "mac-address"; @@ -236,7 +227,7 @@ port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-spnmx56.dts b/target/linux/qualcommax/dts/ipq5018-spnmx56.dts index 2cc71e4a2e92de..1215f09521a8cf 100644 --- a/target/linux/qualcommax/dts/ipq5018-spnmx56.dts +++ b/target/linux/qualcommax/dts/ipq5018-spnmx56.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" #include "ipq5018-mx-base.dtsi" / { @@ -31,44 +32,29 @@ * ================================================================= */ -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - // MAC0 -> GE Phy --- MDI --- QCA8337 Switch - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - phy_dac = <0x10 0x10>; - }; - - // MAC1 -> Uniphy --- SGMII --- QCA8081 - port@2 { - port_id = <2>; - mdiobus = <&mdio1>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -// MAC0 -> GE Phy -&dp1 { +&gmac0 { status = "okay"; nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; -// MAC1 ---SGMII---> QCA8081 -&dp2 { +// MAC1 ---SGMII---> QCA8337 SerDes +&gmac1 { status = "okay"; - label = "wan"; phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + + label = "wan"; + nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; @@ -155,7 +141,7 @@ reg = <5>; phy-handle = <&qca8337_4>; phy-mode = "gmii"; - ethernet = <&dp1>; + ethernet = <&gmac0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq5018-wn-dax3000gr.dts b/target/linux/qualcommax/dts/ipq5018-wn-dax3000gr.dts index b5b473679bcc8e..a2d9143595eedd 100644 --- a/target/linux/qualcommax/dts/ipq5018-wn-dax3000gr.dts +++ b/target/linux/qualcommax/dts/ipq5018-wn-dax3000gr.dts @@ -19,7 +19,7 @@ led-boot = &led_status_green; led-failsafe = &led_status_red; led-upgrade = &led_status_green; - label-mac-device = <&dp1>; + label-mac-device = <&gmac0>; }; chosen { @@ -186,37 +186,27 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -&dp1 { +&gmac0 { status = "okay"; label = "wan"; + nvmem-cells = <&macaddr_appsblenv_ethaddr 2>; nvmem-cell-names = "mac-address"; }; -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&macaddr_appsblenv_ethaddr 0>; nvmem-cell-names = "mac-address"; @@ -290,7 +280,7 @@ port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-wrc-x3000gs2.dts b/target/linux/qualcommax/dts/ipq5018-wrc-x3000gs2.dts index 5f5095d9dff684..742164b4974b28 100644 --- a/target/linux/qualcommax/dts/ipq5018-wrc-x3000gs2.dts +++ b/target/linux/qualcommax/dts/ipq5018-wrc-x3000gs2.dts @@ -20,7 +20,7 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - label-mac-device = <&dp1>; + label-mac-device = <&gmac0>; }; chosen { @@ -180,37 +180,27 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -&dp1 { +&gmac0 { status = "okay"; label = "wan"; + nvmem-cells = <&macaddr_appsblenv_ethaddr 3>; nvmem-cell-names = "mac-address"; }; -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; + nvmem-cells = <&macaddr_appsblenv_ethaddr 0>; nvmem-cell-names = "mac-address"; @@ -284,7 +274,7 @@ port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq5018-wrc-x3000gst2.dts b/target/linux/qualcommax/dts/ipq5018-wrc-x3000gst2.dts index 14b0d7a704c379..e9d7f9536760ff 100644 --- a/target/linux/qualcommax/dts/ipq5018-wrc-x3000gst2.dts +++ b/target/linux/qualcommax/dts/ipq5018-wrc-x3000gst2.dts @@ -20,7 +20,7 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - label-mac-device = <&dp1>; + label-mac-device = <&gmac0>; }; chosen { @@ -180,27 +180,14 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - switch_mac_mode = ; - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - mdiobus = <&mdio0>; - phy_address = <7>; - }; - - port@2 { - port_id = <2>; - forced-speed = <1000>; - forced-duplex = <1>; - }; - }; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; }; -&dp1 { +&gmac0 { status = "okay"; label = "wan"; @@ -208,9 +195,10 @@ nvmem-cell-names = "mac-address"; }; -&dp2 { +&gmac1 { status = "okay"; + phy-mode = "sgmii"; nvmem-cells = <&macaddr_appsblenv_ethaddr 0>; nvmem-cell-names = "mac-address"; @@ -284,7 +272,7 @@ port@6 { reg = <6>; phy-mode = "sgmii"; - ethernet = <&dp2>; + ethernet = <&gmac1>; qca,sgmii-enable-pll; fixed-link { diff --git a/target/linux/qualcommax/dts/ipq6000-360v6.dts b/target/linux/qualcommax/dts/ipq6000-360v6.dts index 07aabe045a6906..46e3d5a8b8fd5d 100644 --- a/target/linux/qualcommax/dts/ipq6000-360v6.dts +++ b/target/linux/qualcommax/dts/ipq6000-360v6.dts @@ -156,29 +156,58 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { port@1 { - port_id = <1>; - phy_address = <0>; + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; }; + port@2 { - port_id = <2>; - phy_address = <1>; + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; + port@3 { - port_id = <3>; - phy_address = <2>; + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; + port@4 { - port_id = <4>; - phy_address = <3>; + reg = <4>; + label = "wan"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; }; }; @@ -187,30 +216,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq6000-ap120c-ax.dts b/target/linux/qualcommax/dts/ipq6000-ap120c-ax.dts index 3cc14d77a23600..df558b414c995b 100644 --- a/target/linux/qualcommax/dts/ipq6000-ap120c-ax.dts +++ b/target/linux/qualcommax/dts/ipq6000-ap120c-ax.dts @@ -349,23 +349,46 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_wan_bmp = ; + ports { + #address-cells = <1>; + #size-cells = <0>; - switch_mac_mode = ; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { port@4 { - port_id = <4>; - phy_address = <3>; + reg = <4>; + label = "lan"; + phy-handle = <&qca8072_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; port@5 { - port_id = <5>; - phy_address = <4>; + reg = <5>; + label = "wan"; + phy-handle = <&qca8072_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_wan>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -374,24 +397,6 @@ status = "okay"; }; -&dp4 { - status = "okay"; - - phy-handle = <&qca8072_3>; - label = "lan"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - - phy-handle = <&qca8072_4>; - label = "wan"; - nvmem-cells = <&macaddr_wan>; - nvmem-cell-names = "mac-address"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq6000-gl-ax1800.dts b/target/linux/qualcommax/dts/ipq6000-gl-ax1800.dts index bd3f0c3c643161..747dacfd2f6910 100644 --- a/target/linux/qualcommax/dts/ipq6000-gl-ax1800.dts +++ b/target/linux/qualcommax/dts/ipq6000-gl-ax1800.dts @@ -9,7 +9,7 @@ compatible = "glinet,gl-ax1800", "qcom,ipq6018"; aliases { - label-mac-device = &dp1; + label-mac-device = &swport1; }; }; @@ -21,49 +21,20 @@ }; }; -&switch { - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; - switch_wan_bmp = ; -}; - -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "wan"; - nvmem-cells = <&macaddr_wan>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "lan1"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan2"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; -&dp4 { +&swport4 { status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan3"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; -&dp5 { +&swport5 { status = "okay"; - phy-handle = <&qca8075_4>; - label = "lan4"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; &wifi { diff --git a/target/linux/qualcommax/dts/ipq6000-gl-axt1800.dts b/target/linux/qualcommax/dts/ipq6000-gl-axt1800.dts index 5db3c8e1edf907..432794a8c3135f 100644 --- a/target/linux/qualcommax/dts/ipq6000-gl-axt1800.dts +++ b/target/linux/qualcommax/dts/ipq6000-gl-axt1800.dts @@ -9,7 +9,7 @@ compatible = "glinet,gl-axt1800", "qcom,ipq6018"; aliases { - label-mac-device = &dp1; + label-mac-device = &swport1; }; vcc_sd: regulator-vcc-sd { @@ -136,33 +136,20 @@ status = "okay"; }; -&switch { - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3)>; - switch_wan_bmp = ; +&swport2 { + label = "lan2"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "wan"; - nvmem-cells = <&macaddr_wan>; - nvmem-cell-names = "mac-address"; +&swport3 { + label = "lan1"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "lan2"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan1"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; }; &wifi { diff --git a/target/linux/qualcommax/dts/ipq6000-glinet.dtsi b/target/linux/qualcommax/dts/ipq6000-glinet.dtsi index 5c862f39785029..e1563222b2ddf1 100644 --- a/target/linux/qualcommax/dts/ipq6000-glinet.dtsi +++ b/target/linux/qualcommax/dts/ipq6000-glinet.dtsi @@ -276,31 +276,76 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + swport1: port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_wan>; + nvmem-cell-names = "mac-address"; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport2: port@2 { + reg = <2>; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport3: port@3 { + reg = <3>; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport4: port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; + status = "disabled"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport5: port@5 { + reg = <5>; + label = "lan4"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; + status = "disabled"; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq6000-link.dtsi b/target/linux/qualcommax/dts/ipq6000-link.dtsi index c3b7621ec7df3c..9a5d16c852851f 100644 --- a/target/linux/qualcommax/dts/ipq6000-link.dtsi +++ b/target/linux/qualcommax/dts/ipq6000-link.dtsi @@ -118,6 +118,107 @@ qcom,ath11k-calibration-variant = "Link-NN6000"; }; +&mdio { + status = "okay"; + + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>; + + ethernet-phy-package@0 { + compatible = "qcom,qca8075-package"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; + + qca8075_4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; + }; +}; + +&uniphy0 { + status = "okay"; +}; + +&switch { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport1: port@1 { + reg = <1>; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + status = "disabled"; + }; + + swport2: port@2 { + reg = <2>; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + }; + + swport3: port@3 { + reg = <3>; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + }; + + swport4: port@4 { + reg = <4>; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport5: port@5 { + reg = <5>; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + status = "disabled"; + }; + }; +}; + &edma { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq6000-mr7350.dts b/target/linux/qualcommax/dts/ipq6000-mr7350.dts index f9b2171bd55b1a..9c595cf7dc3d31 100644 --- a/target/linux/qualcommax/dts/ipq6000-mr7350.dts +++ b/target/linux/qualcommax/dts/ipq6000-mr7350.dts @@ -347,33 +347,76 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { port@1 { - port_id = <1>; - phy_address = <0>; + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; + port@2 { - port_id = <2>; - phy_address = <1>; + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; + port@3 { - port_id = <3>; - phy_address = <2>; + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; + port@4 { - port_id = <4>; - phy_address = <3>; + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; + port@5 { - port_id = <5>; - phy_address = <4>; + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -382,46 +425,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq6000-nn6000-v1.dts b/target/linux/qualcommax/dts/ipq6000-nn6000-v1.dts index 641e5f0a31626d..7d62d3f99395b2 100644 --- a/target/linux/qualcommax/dts/ipq6000-nn6000-v1.dts +++ b/target/linux/qualcommax/dts/ipq6000-nn6000-v1.dts @@ -9,81 +9,20 @@ compatible = "link,nn6000-v1", "qcom,ipq6018"; aliases { - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; }; }; -&mdio { - status = "okay"; - - pinctrl-0 = <&mdio_pins>; - pinctrl-names = "default"; - reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>; - - ethernet-phy-package@0 { - compatible = "qcom,qca8075-package"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; - - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; - - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - }; - }; -}; - -&switch { - status = "okay"; - - switch_lan_bmp = <(ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; - - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; - }; - - port@3 { - port_id = <3>; - phy_address = <2>; - }; - - port@4 { - port_id = <4>; - phy_address = <3>; - }; - }; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "wan"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan1"; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; +&swport4 { label = "lan2"; }; diff --git a/target/linux/qualcommax/dts/ipq6000-nn6000-v2.dts b/target/linux/qualcommax/dts/ipq6000-nn6000-v2.dts index 3ed2614094525e..300871e85b44dc 100644 --- a/target/linux/qualcommax/dts/ipq6000-nn6000-v2.dts +++ b/target/linux/qualcommax/dts/ipq6000-nn6000-v2.dts @@ -9,115 +9,31 @@ compatible = "link,nn6000-v2", "qcom,ipq6018"; aliases { - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5; + ethernet0 = &swport1; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + ethernet4 = &swport5; }; }; -&mdio { - status = "okay"; - - pinctrl-0 = <&mdio_pins>; - pinctrl-names = "default"; - reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>; - - ethernet-phy-package@0 { - compatible = "qcom,qca8075-package"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - qca8075_0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; - - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; - - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; - - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - }; - - qca8075_4: ethernet-phy@4 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <4>; - }; - }; -}; - -&switch { - status = "okay"; - - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; - switch_wan_bmp = ; - switch_mac_mode = ; - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; - }; - - port@2 { - port_id = <2>; - phy_address = <1>; - }; - - port@3 { - port_id = <3>; - phy_address = <2>; - }; - - port@4 { - port_id = <4>; - phy_address = <3>; - }; - - port@5 { - port_id = <5>; - phy_address = <4>; - }; - }; -}; - -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; +&swport1 { label = "lan1"; + status = "okay"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "wan"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan2"; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; +&swport4 { label = "lan3"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; +&swport5 { label = "lan4"; }; diff --git a/target/linux/qualcommax/dts/ipq6000-re-ss-01.dts b/target/linux/qualcommax/dts/ipq6000-re-ss-01.dts index a71574cc4f50c2..49a25010b37659 100644 --- a/target/linux/qualcommax/dts/ipq6000-re-ss-01.dts +++ b/target/linux/qualcommax/dts/ipq6000-re-ss-01.dts @@ -14,13 +14,13 @@ compatible = "jdcloud,re-ss-01", "qcom,ipq6018"; aliases { - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + ethernet4 = &swport5; serial0 = &blsp1_uart3; - label-mac-device = &dp2; + label-mac-device = &swport2; led-boot = &led_status_red; led-failsafe = &led_status_red; led-running = &led_status_green; @@ -162,29 +162,58 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + }; + + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport4: port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; @@ -193,30 +222,6 @@ status = "okay"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan1"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan2"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan3"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq6010-mango-dvk.dts b/target/linux/qualcommax/dts/ipq6010-mango-dvk.dts index 60769457ed4558..f58f4a169f6d32 100644 --- a/target/linux/qualcommax/dts/ipq6010-mango-dvk.dts +++ b/target/linux/qualcommax/dts/ipq6010-mango-dvk.dts @@ -200,34 +200,6 @@ }; }; -&dp3 { - status = "okay"; - - phy-handle = <&qca8072_1>; - nvmem-cells = <&macaddr_eth1>; - nvmem-cell-names = "mac-address"; - label = "lan2"; -}; - -&dp4 { - status = "okay"; - - phy-handle = <&qca8072_0>; - nvmem-cells = <&macaddr_eth0>; - nvmem-cell-names = "mac-address"; - label = "lan1"; -}; - -&dp5 { - status = "okay"; - - phy-mode = "sgmii"; - phy-handle = <&qca8081>; - nvmem-cells = <&macaddr_eth2>; - nvmem-cell-names = "mac-address"; - label = "wan"; -}; - &edma { status = "okay"; }; @@ -277,28 +249,60 @@ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy1 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode1 = ; - port3_pcs_channel = <4>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { port@3 { - port_id = <3>; - phy_address = <4>; + reg = <3>; + label = "lan2"; + phy-handle = <&qca8072_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_eth1>; + nvmem-cell-names = "mac-address"; }; + port@4 { - port_id = <4>; - phy_address = <3>; + reg = <4>; + label = "lan1"; + phy-handle = <&qca8072_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_eth0>; + nvmem-cell-names = "mac-address"; }; + port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + reg = <5>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&macaddr_eth2>; + nvmem-cell-names = "mac-address"; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq6010-re-cs-02.dts b/target/linux/qualcommax/dts/ipq6010-re-cs-02.dts index 6a7e3eff3df1ea..8594ea7bf0013a 100644 --- a/target/linux/qualcommax/dts/ipq6010-re-cs-02.dts +++ b/target/linux/qualcommax/dts/ipq6010-re-cs-02.dts @@ -9,13 +9,13 @@ compatible = "jdcloud,re-cs-02", "qcom,ipq6018"; aliases { - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5; + ethernet0 = &swport1; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + ethernet4 = &swport5; - label-mac-device = &dp1; + label-mac-device = &swport1; serial0 = &blsp1_uart3; serial1 = &blsp1_uart6; }; @@ -97,35 +97,66 @@ }; }; +&uniphy1 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode1 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <24>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <25>; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; }; - port@3 { - port_id = <3>; - phy_address = <26>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <27>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@5 { - port_id = <5>; - phy_address = <12>; - port_mac_sel = "QGMAC_PORT"; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; }; }; }; @@ -134,37 +165,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; -}; - -&dp5 { - status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq6010-re-cs-07.dts b/target/linux/qualcommax/dts/ipq6010-re-cs-07.dts index 650e2c55f35404..1ee45622167f3c 100644 --- a/target/linux/qualcommax/dts/ipq6010-re-cs-07.dts +++ b/target/linux/qualcommax/dts/ipq6010-re-cs-07.dts @@ -9,12 +9,12 @@ compatible = "jdcloud,re-cs-07", "qcom,ipq6018"; aliases { - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; + ethernet0 = &swport1; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; - label-mac-device = &dp2; + label-mac-device = &swport2; serial0 = &blsp1_uart3; }; @@ -45,26 +45,51 @@ &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <24>; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <25>; + + swport1: port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; }; - port@3 { - port_id = <3>; - phy_address = <26>; + + swport2: port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <27>; + + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + }; + + swport4: port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; }; }; @@ -72,27 +97,3 @@ &edma { status = "okay"; }; - -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "wan"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan1"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan2"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan3"; -}; diff --git a/target/linux/qualcommax/dts/ipq6010-re-cs.dtsi b/target/linux/qualcommax/dts/ipq6010-re-cs.dtsi index 7ff432613a5286..bd971145c8c753 100644 --- a/target/linux/qualcommax/dts/ipq6010-re-cs.dtsi +++ b/target/linux/qualcommax/dts/ipq6010-re-cs.dtsi @@ -137,3 +137,7 @@ }; }; }; + +&uniphy0 { + status = "okay"; +}; diff --git a/target/linux/qualcommax/dts/ipq6010-wax214.dts b/target/linux/qualcommax/dts/ipq6010-wax214.dts index 90a4828c17bd75..5df12f4ed66bcc 100644 --- a/target/linux/qualcommax/dts/ipq6010-wax214.dts +++ b/target/linux/qualcommax/dts/ipq6010-wax214.dts @@ -15,8 +15,8 @@ aliases { serial0 = &blsp1_uart3; - ethernet0 = &dp3; - label-mac-device = &dp3; + ethernet0 = &swport3; + label-mac-device = &swport3; led-boot = &pwr; led-failsafe = &pwr; led-running = &pwr; @@ -95,13 +95,6 @@ }; }; -&dp3 { - status = "okay"; - - phy-handle = <&qca8072_4>; - label = "lan"; -}; - &edma { status = "okay"; }; @@ -129,17 +122,34 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode = ; - port3_pcs_channel = <4>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@3 { - port_id = <3>; - phy_address = <4>; + swport3: port@3 { + reg = <3>; + label = "lan"; + phy-handle = <&qca8072_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq6010-wax610-base.dtsi b/target/linux/qualcommax/dts/ipq6010-wax610-base.dtsi index e51ed90629f948..2db7294a4bac08 100644 --- a/target/linux/qualcommax/dts/ipq6010-wax610-base.dtsi +++ b/target/linux/qualcommax/dts/ipq6010-wax610-base.dtsi @@ -8,8 +8,8 @@ / { aliases { serial0 = &blsp1_uart3; - ethernet0 = &dp5; - label-mac-device = &dp5; + ethernet0 = &swport5; + label-mac-device = &swport5; led-boot = &led_system_blue; led-failsafe = &led_system_orange; @@ -111,17 +111,34 @@ status = "okay"; }; +&uniphy1 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode1 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&qca8081_24>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; }; }; }; @@ -156,12 +173,6 @@ }; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8081_24>; - label = "lan"; -}; - &blsp1_uart3 { pinctrl-0 = <&serial_3_pins>; pinctrl-names = "default"; diff --git a/target/linux/qualcommax/dts/ipq6010-xe3-4.dts b/target/linux/qualcommax/dts/ipq6010-xe3-4.dts index f0094a7d8f0302..7f795e1e5d55ca 100644 --- a/target/linux/qualcommax/dts/ipq6010-xe3-4.dts +++ b/target/linux/qualcommax/dts/ipq6010-xe3-4.dts @@ -15,9 +15,9 @@ aliases { serial0 = &blsp1_uart3; - ethernet0 = &dp5; - ethernet1 = &dp4; - label-mac-device = &dp5; + ethernet0 = &swport5; + ethernet1 = &swport4; + label-mac-device = &swport5; led-boot = &led_status_amber; led-failsafe = &led_status_amber; @@ -183,23 +183,50 @@ status = "okay"; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy1 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT4 | ESS_PORT5)>; - switch_mac_mode = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8072>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cell-names = "mac-address"; + nvmem-cells = <ð1addr 0>; }; - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + swport5: port@5 { + reg = <5>; + label = "lan1"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cell-names = "mac-address"; + nvmem-cells = <ðaddr 0>; }; }; }; @@ -235,25 +262,6 @@ }; }; -&dp4 { - status = "okay"; - - phy-handle = <&qca8072>; - nvmem-cell-names = "mac-address"; - nvmem-cells = <ð1addr 0>; - label = "lan2"; -}; - -&dp5 { - status = "okay"; - - phy-mode = "sgmii"; - phy-handle = <&qca8081>; - nvmem-cell-names = "mac-address"; - nvmem-cells = <ðaddr 0>; - label = "lan1"; -}; - &blsp1_spi1 { pinctrl-0 = <&spi_0_pins>; pinctrl-names = "default"; diff --git a/target/linux/qualcommax/dts/ipq6018-eap620-hd-v3.dts b/target/linux/qualcommax/dts/ipq6018-eap620-hd-v3.dts index fd7b9c54a73a0f..b2352b203558d1 100644 --- a/target/linux/qualcommax/dts/ipq6018-eap620-hd-v3.dts +++ b/target/linux/qualcommax/dts/ipq6018-eap620-hd-v3.dts @@ -40,8 +40,8 @@ gpio-reserved-ranges = <20 1>; }; -&switch { - switch_mac_mode1 = ; +&swport5 { + phy-handle = <&rtl8211f_4>; }; &wifi { diff --git a/target/linux/qualcommax/dts/ipq6018-fap650.dts b/target/linux/qualcommax/dts/ipq6018-fap650.dts index c7f7f699929ee2..2405d6b18dfb5e 100644 --- a/target/linux/qualcommax/dts/ipq6018-fap650.dts +++ b/target/linux/qualcommax/dts/ipq6018-fap650.dts @@ -15,12 +15,12 @@ compatible = "yuncore,fap650", "qcom,ipq6018"; aliases { - ethernet0 = &dp5; - ethernet1 = &dp4; - ethernet2 = &dp3; - ethernet3 = &dp2; - ethernet4 = &dp1; - label-mac-device = &dp5; + ethernet0 = &swport5; + ethernet1 = &swport4; + ethernet2 = &swport3; + ethernet3 = &swport2; + ethernet4 = &swport1; + label-mac-device = &swport5; serial0 = &blsp1_uart3; led-boot = &led_system; led-failsafe = &led_system; @@ -133,36 +133,66 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1|ESS_PORT2|ESS_PORT3|ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; }; - port@2 { - port_id = <2>; - phy_address = <1>; + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; - port@5 { - port_id = <5>; - phy_address = <4>; + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; @@ -179,37 +209,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - phy-mode = "psgmii"; - label = "wan"; -}; - &qpic_bam { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq6018-mr7500.dts b/target/linux/qualcommax/dts/ipq6018-mr7500.dts index a01299f42a4877..bb58959c9f3581 100644 --- a/target/linux/qualcommax/dts/ipq6018-mr7500.dts +++ b/target/linux/qualcommax/dts/ipq6018-mr7500.dts @@ -23,7 +23,7 @@ led-failsafe = &led_system_red; led-upgrade = &led_system_green; - label-mac-device = &dp5_syn; + label-mac-device = &swport5; }; chosen { @@ -347,84 +347,84 @@ }; }; -&dp1 { +&edma { status = "okay"; - label = "lan1"; - phy-handle = <&qca8075_0>; - phy-mode = "qsgmii"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; }; -&dp2 { +&uniphy0 { status = "okay"; - label = "lan2"; - phy-handle = <&qca8075_1>; - phy-mode = "qsgmii"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; }; -&dp3 { +&uniphy1 { status = "okay"; - label = "lan3"; - phy-handle = <&qca8075_2>; - phy-mode = "qsgmii"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; }; -&dp4 { +&switch { status = "okay"; - label = "lan4"; - phy-handle = <&qca8075_3>; - phy-mode = "qsgmii"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; -&dp5_syn { - status = "okay"; - label = "wan"; - phy-handle = <&aqr114c>; - phy-mode = "usxgmii"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; + ports { + #address-cells = <1>; + #size-cells = <0>; -&edma { - status = "okay"; -}; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; -&switch { - status = "okay"; - switch_lan_bmp = <( ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4 )>; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode1 = ; - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <8>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; + }; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&aqr114c>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq6018-rbs350.dts b/target/linux/qualcommax/dts/ipq6018-rbs350.dts index 3b3090cdc22135..4c199450faf3ae 100644 --- a/target/linux/qualcommax/dts/ipq6018-rbs350.dts +++ b/target/linux/qualcommax/dts/ipq6018-rbs350.dts @@ -9,10 +9,10 @@ compatible = "netgear,rbs350", "qcom,ipq6018"; }; -&dp2 { +&swport2 { status = "disabled"; }; -&dp3 { +&swport3 { status = "disabled"; }; diff --git a/target/linux/qualcommax/dts/ipq6018-rbx350.dtsi b/target/linux/qualcommax/dts/ipq6018-rbx350.dtsi index 2b111736186308..dd6a7b7543fa54 100644 --- a/target/linux/qualcommax/dts/ipq6018-rbx350.dtsi +++ b/target/linux/qualcommax/dts/ipq6018-rbx350.dtsi @@ -11,7 +11,7 @@ led-failsafe = &led_status_red; led-upgrade = &led_status_blue; serial0 = &blsp1_uart3; - label-mac-device = &dp5; + label-mac-device = &swport5; }; @@ -84,37 +84,66 @@ status = "okay"; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + swport2: port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&phy1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_boarddata 3>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&phy2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_boarddata 2>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&phy3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_boarddata 1>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + swport5: port@5 { + reg = <5>; + label = "lan1"; + phy-handle = <&phy4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_boarddata 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -181,38 +210,6 @@ }; }; -&dp2 { - status = "okay"; - phy-handle = <&phy1>; - label = "wan"; - nvmem-cells = <&macaddr_boarddata 3>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&phy2>; - label = "lan3"; - nvmem-cells = <&macaddr_boarddata 2>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&phy3>; - label = "lan2"; - nvmem-cells = <&macaddr_boarddata 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&phy4>; - label = "lan1"; - nvmem-cells = <&macaddr_boarddata 0>; - nvmem-cell-names = "mac-address"; -}; - &blsp1_uart3 { pinctrl-0 = <&serial_3_pins>; pinctrl-names = "default"; diff --git a/target/linux/qualcommax/dts/ipq6018-tplink-eap6xx-outdoor.dtsi b/target/linux/qualcommax/dts/ipq6018-tplink-eap6xx-outdoor.dtsi index 9ab252ef378d89..6373ae007658fa 100644 --- a/target/linux/qualcommax/dts/ipq6018-tplink-eap6xx-outdoor.dtsi +++ b/target/linux/qualcommax/dts/ipq6018-tplink-eap6xx-outdoor.dtsi @@ -94,13 +94,6 @@ }; }; -&dp5 { - phy-handle = <&rtl8211f_4>; - phy-mode = "sgmii"; - label = "lan"; - status = "okay"; -}; - &edma { status = "okay"; }; @@ -120,15 +113,34 @@ }; }; +&uniphy1 { + status = "okay"; +}; + &switch { - switch_lan_bmp = ; - switch_mac_mode1 = ; status = "okay"; - qcom,port_phyinfo { - port@4 { - port_id = <5>; - phy_address = <4>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&rtl8211f_4>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy1 0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq8070-cax1800.dts b/target/linux/qualcommax/dts/ipq8070-cax1800.dts index 728820e6bb4cea..532a01132e1707 100644 --- a/target/linux/qualcommax/dts/ipq8070-cax1800.dts +++ b/target/linux/qualcommax/dts/ipq8070-cax1800.dts @@ -20,8 +20,8 @@ led-running = &led_system_green; led-upgrade = &led_system_red; /* Aliases as required by u-boot to patch MAC addresses */ - ethernet0 = &dp5; - label-mac-device = &dp5; + ethernet0 = &swport5; + label-mac-device = &swport5; }; chosen { @@ -274,16 +274,34 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; /* lan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <4>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; @@ -292,12 +310,6 @@ status = "okay"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "lan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8070-nwa110ax.dts b/target/linux/qualcommax/dts/ipq8070-nwa110ax.dts index c9358a031d84d9..2dfc2a263b4e6a 100644 --- a/target/linux/qualcommax/dts/ipq8070-nwa110ax.dts +++ b/target/linux/qualcommax/dts/ipq8070-nwa110ax.dts @@ -12,17 +12,12 @@ compatible = "zyxel,nwa110ax", "qcom,ipq8074"; aliases { - ethernet0 = &dp1; - label-mac-device = &dp1; + ethernet0 = &swport1; + label-mac-device = &swport1; }; }; -&switch { - switch_lan_bmp = ; - switch_mac_mode = ; -}; - -&dp1 { +&swport1 { label = "uplink"; nvmem-cell-names = "mac-address"; nvmem-cells = <&label_mac 0>; diff --git a/target/linux/qualcommax/dts/ipq8070-rm2-6.dts b/target/linux/qualcommax/dts/ipq8070-rm2-6.dts index 5d3123f75ea3ff..203f2074a44f94 100644 --- a/target/linux/qualcommax/dts/ipq8070-rm2-6.dts +++ b/target/linux/qualcommax/dts/ipq8070-rm2-6.dts @@ -24,10 +24,10 @@ * Aliases as required by u-boot * to patch MAC addresses */ - ethernet0 = &dp4; - ethernet1 = &dp2; - ethernet2 = &dp5; - label-mac-device = &dp4; + ethernet0 = &swport4; + ethernet1 = &swport2; + ethernet2 = &swport5; + label-mac-device = &swport4; }; chosen { @@ -253,25 +253,54 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + /* + * Directly connect to the Hi5630 + * PLC (Power Line Communication) + */ + swport2: port@2 { + reg = <2>; + label = "plc"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + }; + + swport4: port@4 { + reg = <4>; + label = "lan"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; @@ -280,28 +309,6 @@ status = "okay"; }; -/* - * Directly connect to the Hi5630 - * PLC (Power Line Communication) - */ -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "plc"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8071-ap8220.dts b/target/linux/qualcommax/dts/ipq8071-ap8220.dts index 7e70cfc61892a6..e2802f0cfb1b22 100644 --- a/target/linux/qualcommax/dts/ipq8071-ap8220.dts +++ b/target/linux/qualcommax/dts/ipq8071-ap8220.dts @@ -289,24 +289,46 @@ }; }; +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_wan_bmp = ; - switch_mac_mode1 = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081_24>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + }; + + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -315,19 +337,6 @@ status = "okay"; }; -&dp5 { - status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081_24>; - label = "wan"; -}; - -&dp6 { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "lan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8071-ax3600.dtsi b/target/linux/qualcommax/dts/ipq8071-ax3600.dtsi index c3c41ae2c1663c..8439e88c796d41 100644 --- a/target/linux/qualcommax/dts/ipq8071-ax3600.dtsi +++ b/target/linux/qualcommax/dts/ipq8071-ax3600.dtsi @@ -14,7 +14,7 @@ led-failsafe = &led_system_yellow; led-running = &led_system_blue; led-upgrade = &led_system_yellow; - label-mac-device = &dp2; + label-mac-device = &swport2; }; chosen { @@ -242,29 +242,66 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_dp2>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_dp3>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_dp4>; + nvmem-cell-names = "mac-address"; + }; + + swport5: port@5 { + reg = <5>; + label = "lan3"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_dp5>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -273,38 +310,6 @@ status = "okay"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "wan"; - nvmem-cells = <&macaddr_dp2>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan1"; - nvmem-cells = <&macaddr_dp3>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan2"; - nvmem-cells = <&macaddr_dp4>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "lan3"; - nvmem-cells = <&macaddr_dp5>; - nvmem-cell-names = "mac-address"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8071-eap102.dts b/target/linux/qualcommax/dts/ipq8071-eap102.dts index 41b6dd066cc489..31b226cc0faf4a 100644 --- a/target/linux/qualcommax/dts/ipq8071-eap102.dts +++ b/target/linux/qualcommax/dts/ipq8071-eap102.dts @@ -22,9 +22,9 @@ led-running = &led_system_green; led-upgrade = &led_system_green; /* Aliases as required by u-boot to patch MAC addresses */ - ethernet0 = &dp6; - ethernet1 = &dp5; - label-mac-device = &dp5; + ethernet0 = &swport6; + ethernet1 = &swport5; + label-mac-device = &swport5; }; chosen { @@ -342,24 +342,46 @@ }; }; +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&qca8081_24>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -368,19 +390,6 @@ status = "okay"; }; -&dp5 { - status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081_24>; - label = "lan"; -}; - -&dp6 { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8071-mf269.dts b/target/linux/qualcommax/dts/ipq8071-mf269.dts index da72f6bf7195a4..a382c73e65f130 100644 --- a/target/linux/qualcommax/dts/ipq8071-mf269.dts +++ b/target/linux/qualcommax/dts/ipq8071-mf269.dts @@ -19,7 +19,7 @@ led-failsafe = &led_power; led-running = &led_power; led-upgrade = &led_power; - label-mac-device = &dp6_syn; + label-mac-device = &swport6; }; chosen { @@ -401,24 +401,50 @@ }; }; +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&qca8081_24>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_mac_0 1>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_mac_0 0>; }; }; }; @@ -427,22 +453,6 @@ status = "okay"; }; -&dp5_syn { - status = "okay"; - phy-handle = <&qca8081_24>; - label = "lan"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_mac_0 1>; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "wan"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_mac_0 0>; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8071-nwa210ax.dts b/target/linux/qualcommax/dts/ipq8071-nwa210ax.dts index 91a4027b40b3f6..388f304ba2a957 100644 --- a/target/linux/qualcommax/dts/ipq8071-nwa210ax.dts +++ b/target/linux/qualcommax/dts/ipq8071-nwa210ax.dts @@ -13,9 +13,9 @@ compatible = "zyxel,nwa210ax", "qcom,ipq8074"; aliases { - ethernet0 = &dp5; - ethernet1 = &dp1; - label-mac-device = &dp5; + ethernet0 = &swport5; + ethernet1 = &swport1; + label-mac-device = &swport5; }; leds { @@ -46,20 +46,28 @@ }; }; -&switch { - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT5)>; - switch_mac_mode = ; - switch_mac_mode1 = ; +&uniphy1 { + status = "okay"; }; -&phyinfo { - port@5 { - port_id = <5>; - phy_address = <16>; - port_mac_sel = "QGMAC_PORT"; +&swports { + swport5: port@5 { + reg = <5>; + label = "uplink"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cell-names = "mac-address"; + nvmem-cells = <&label_mac 0>; }; }; +&swport1 { + label = "lan1"; + nvmem-cell-names = "mac-address"; + nvmem-cells = <&label_mac 1>; +}; + &mdio { qca8081: ethernet-phy@16 { compatible = "ethernet-phy-id004d.d101"; @@ -69,21 +77,6 @@ }; }; -&dp1 { - label = "lan1"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&label_mac 1>; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8081>; - phy-mode = "sgmii"; - label = "uplink"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&label_mac 0>; -}; - &wifi { qcom,ath11k-calibration-variant = "Zyxel-NWA210AX"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-301w.dts b/target/linux/qualcommax/dts/ipq8072-301w.dts index 5edb4e1936bd3c..ce8a4ff4ace93e 100644 --- a/target/linux/qualcommax/dts/ipq8072-301w.dts +++ b/target/linux/qualcommax/dts/ipq8072-301w.dts @@ -24,13 +24,13 @@ led-failsafe = &led_system_red; led-running = &led_pwr_green; led-upgrade = &led_system_red; - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5; - ethernet5 = &dp6_syn; - label-mac-device = &dp1; + ethernet0 = &lan4; + ethernet1 = &lan3; + ethernet2 = &lan2; + ethernet3 = &lan1; + ethernet4 = &port_10g_1; + ethernet5 = &port_10g_2; + label-mac-device = &lan4; }; chosen { @@ -438,92 +438,89 @@ vqmmc-supply = <&l11>; }; -&switch { +&uniphy0 { status = "okay"; - - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ - - qcom,port_phyinfo { - port@0 { - port_id = <1>; - phy_address = <16>; - }; - port@1 { - port_id = <2>; - phy_address = <17>; - }; - port@2 { - port_id = <3>; - phy_address = <18>; - }; - port@3 { - port_id = <4>; - phy_address = <19>; - }; - port@4 { - port_id = <5>; - phy_address = <8>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; - }; - port@5 { - port_id = <6>; - phy_address = <0>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; - }; - }; }; -&edma { +&uniphy1 { status = "okay"; }; -&dp1 { +&uniphy2 { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_16>; - label = "lan4"; }; -&dp2 { +&switch { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_17>; - label = "lan3"; -}; -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_18>; - label = "lan2"; -}; + ports { + #address-cells = <1>; + #size-cells = <0>; -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_19>; - label = "lan1"; -}; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; -&dp5 { - status = "okay"; - qcom,mactype = <1>; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c_8>; - label = "10g-1"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + lan4: port@1 { + reg = <1>; + label = "lan4"; + phy-handle = <&qca8075_16>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + }; + + lan3: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_17>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + }; + + lan2: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_18>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + }; + + + lan1: port@4 { + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_19>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + }; + + port_10g_1: port@5 { + reg = <5>; + label = "10g-1"; + phy-handle = <&aqr113c_8>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy1 0>; + }; + + port_10g_2: port@6 { + reg = <6>; + label = "10g-2"; + phy-handle = <&aqr113c_0>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + }; + }; }; -&dp6_syn { +&edma { status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c_0>; - label = "10g-2"; }; &wifi { diff --git a/target/linux/qualcommax/dts/ipq8072-aw1000.dts b/target/linux/qualcommax/dts/ipq8072-aw1000.dts index 09adde5dcf771a..33fa341390d123 100644 --- a/target/linux/qualcommax/dts/ipq8072-aw1000.dts +++ b/target/linux/qualcommax/dts/ipq8072-aw1000.dts @@ -24,12 +24,12 @@ * Aliases as required by u-boot * to patch MAC addresses */ - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp6_syn; - label-mac-device = &dp1; + ethernet0 = &swport1; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + ethernet4 = &swport6; + label-mac-device = &swport1; }; chosen { @@ -301,35 +301,70 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -338,40 +373,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_0>; - label = "lan1"; -}; - -&dp2 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan2"; -}; - -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan3"; -}; - -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan4"; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8072-ax880.dts b/target/linux/qualcommax/dts/ipq8072-ax880.dts index 70310daf0fb344..6e6576b1c454ec 100644 --- a/target/linux/qualcommax/dts/ipq8072-ax880.dts +++ b/target/linux/qualcommax/dts/ipq8072-ax880.dts @@ -22,9 +22,9 @@ led-running = &led_system; led-upgrade = &led_system; /* Aliases as required by u-boot to patch MAC addresses */ - ethernet0 = &dp5_syn; - ethernet1 = &dp6_syn; - label-mac-device = &dp5_syn; + ethernet0 = &swport5; + ethernet1 = &swport6; + label-mac-device = &swport5; }; chosen { @@ -349,24 +349,46 @@ }; }; +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081_24>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + }; + + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -375,18 +397,6 @@ status = "okay"; }; -&dp5_syn { - status = "okay"; - phy-handle = <&qca8081_24>; - label = "wan"; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "lan"; -}; - &wifi { status = "okay"; qcom,ath11k-calibration-variant = "Yuncore-AX880"; diff --git a/target/linux/qualcommax/dts/ipq8072-ax9000.dts b/target/linux/qualcommax/dts/ipq8072-ax9000.dts index c879c5ef730826..6e7f552ffe6c9a 100644 --- a/target/linux/qualcommax/dts/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/dts/ipq8072-ax9000.dts @@ -21,7 +21,7 @@ led-failsafe = &led_system_yellow; led-running = &led_system_blue; led-upgrade = &led_system_yellow; - label-mac-device = &dp5; + label-mac-device = &wan; }; chosen { @@ -460,86 +460,86 @@ }; }; -&switch { +&uniphy0 { status = "okay"; - - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; - }; - port@2 { - port_id = <2>; - phy_address = <1>; - }; - port@3 { - port_id = <3>; - phy_address = <2>; - }; - port@4 { - port_id = <4>; - phy_address = <3>; - }; - port@5 { - port_id = <5>; - phy_address = <24>; - port_mac_sel = "QGMAC_PORT"; - }; - }; }; -&edma { +&uniphy1 { status = "okay"; }; -&dp1 { +&switch { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_0>; - label = "lan4"; - nvmem-cells = <&macaddr_dp1>; - nvmem-cell-names = "mac-address"; -}; -&dp2 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan3"; - nvmem-cells = <&macaddr_dp2>; - nvmem-cell-names = "mac-address"; -}; + ports { + #address-cells = <1>; + #size-cells = <0>; -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan2"; - nvmem-cells = <&macaddr_dp3>; - nvmem-cell-names = "mac-address"; -}; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan1"; - nvmem-cells = <&macaddr_dp4>; - nvmem-cell-names = "mac-address"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + lan4: port@1 { + reg = <1>; + label = "lan4"; + phy-handle = <&qca8075_0>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_dp1>; + nvmem-cell-names = "mac-address"; + }; + + lan3: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_dp2>; + nvmem-cell-names = "mac-address"; + }; + + lan2: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_dp3>; + nvmem-cell-names = "mac-address"; + }; + + lan1: port@4 { + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_dp4>; + nvmem-cell-names = "mac-address"; + }; + + wan: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&macaddr_dp5>; + nvmem-cell-names = "mac-address"; + }; + }; }; -&dp5 { +&edma { status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081>; - label = "wan"; - nvmem-cells = <&macaddr_dp5>; - nvmem-cell-names = "mac-address"; }; &pcie_qmp0 { diff --git a/target/linux/qualcommax/dts/ipq8072-dl-wrx36.dts b/target/linux/qualcommax/dts/ipq8072-dl-wrx36.dts index fa3c8ea0113ebb..1d1e7fc1ee30d9 100644 --- a/target/linux/qualcommax/dts/ipq8072-dl-wrx36.dts +++ b/target/linux/qualcommax/dts/ipq8072-dl-wrx36.dts @@ -232,35 +232,80 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { port@1 { - port_id = <1>; - phy_address = <0>; + reg = <1>; + label = "lan4"; + phy-handle = <&qca8075_0>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_art_18>; + nvmem-cell-names = "mac-address"; }; + port@2 { - port_id = <2>; - phy_address = <1>; + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_art_12>; + nvmem-cell-names = "mac-address"; }; + port@3 { - port_id = <3>; - phy_address = <2>; + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_art_c>; + nvmem-cell-names = "mac-address"; }; + port@4 { - port_id = <4>; - phy_address = <3>; + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_art_6>; + nvmem-cell-names = "mac-address"; }; + port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + reg = <6>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_art_0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -269,50 +314,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_0>; - label = "lan4"; - nvmem-cells = <&macaddr_art_18>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan3"; - nvmem-cells = <&macaddr_art_12>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan2"; - nvmem-cells = <&macaddr_art_c>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan1"; - nvmem-cells = <&macaddr_art_6>; - nvmem-cell-names = "mac-address"; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081>; - label = "wan"; - nvmem-cells = <&macaddr_art_0>; - nvmem-cell-names = "mac-address"; -}; - &wifi { status = "okay"; qcom,ath11k-calibration-variant = "Dynalink-DL-WRX36"; diff --git a/target/linux/qualcommax/dts/ipq8072-eap620hd-v1.dts b/target/linux/qualcommax/dts/ipq8072-eap620hd-v1.dts index 18a3759e79d165..4932509ab9841a 100644 --- a/target/linux/qualcommax/dts/ipq8072-eap620hd-v1.dts +++ b/target/linux/qualcommax/dts/ipq8072-eap620hd-v1.dts @@ -82,21 +82,34 @@ }; }; -&dp6 { +&uniphy2 { status = "okay"; - phy-handle = <&ar8031>; - label = "lan"; }; &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode2 = ; - qcom,port_phyinfo { - port@6 { - phy_address = <4>; - port_id = <6>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&ar8031>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy2 0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq8072-eap660hd-v1.dts b/target/linux/qualcommax/dts/ipq8072-eap660hd-v1.dts index 62d40d7e1b0a85..aea73fe82d45ff 100644 --- a/target/linux/qualcommax/dts/ipq8072-eap660hd-v1.dts +++ b/target/linux/qualcommax/dts/ipq8072-eap660hd-v1.dts @@ -81,23 +81,34 @@ }; }; -&dp5 { +&uniphy1 { status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081_28>; - label = "lan"; }; &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode1 = ; - - qcom,port_phyinfo { - port@5 { - phy_address = <28>; - port_id = <5>; - port_mac_sel = "QGMAC_PORT"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport5: port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; }; }; }; diff --git a/target/linux/qualcommax/dts/ipq8072-haze.dts b/target/linux/qualcommax/dts/ipq8072-haze.dts index 0b390e9298fee7..cb3de6a2593ae0 100644 --- a/target/linux/qualcommax/dts/ipq8072-haze.dts +++ b/target/linux/qualcommax/dts/ipq8072-haze.dts @@ -16,11 +16,11 @@ aliases { serial0 = &blsp1_uart5; /* Aliases are required by U-Boot to patch MAC addresses */ - ethernet0 = &dp6_syn; - ethernet1 = &dp4; - ethernet2 = &dp3; - ethernet3 = &dp2; - label-mac-device = &dp6_syn; + ethernet0 = &swport6; + ethernet1 = &swport4; + ethernet2 = &swport3; + ethernet3 = &swport2; + label-mac-device = &swport6; led-boot = &led_system_blue; led-failsafe = &led_system_red; led-running = &led_system_green; @@ -198,37 +198,71 @@ vqmmc-supply = <&l11>; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport1: port@1 { + reg = <1>; + label = "lan4"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + status = "disabled"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@6 { - port_id = <6>; - phy_address = <8>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; + + swport4: port@4 { + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&aqr113c>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -237,39 +271,6 @@ status = "okay"; }; -/* Dummy LAN port */ -&dp1 { - status = "disabled"; - phy-handle = <&qca8075_0>; - label = "lan4"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan3"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan2"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan1"; -}; - -&dp6_syn { - status = "okay"; - qcom,mactype = <1>; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c>; - label = "wan"; -}; - &pcie_qmp0 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-linkhub-hh500v.dts b/target/linux/qualcommax/dts/ipq8072-linkhub-hh500v.dts index 2a91807bdda17c..3c40fc16ae4e4f 100644 --- a/target/linux/qualcommax/dts/ipq8072-linkhub-hh500v.dts +++ b/target/linux/qualcommax/dts/ipq8072-linkhub-hh500v.dts @@ -338,42 +338,52 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@4 { - phy_address = <3>; - port_id = <4>; - }; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - port@6 { - phy_address = <16>; - port_id = <6>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; }; }; -}; -&edma { - status = "okay"; -}; + swport4: port@4 { + reg = <4>; + label = "lan"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan"; + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; + }; + }; }; -&dp6_syn { +&edma { status = "okay"; - phy-handle = <&qca8081>; - label = "wan"; }; &pcie_qmp0 { diff --git a/target/linux/qualcommax/dts/ipq8072-mx5300.dts b/target/linux/qualcommax/dts/ipq8072-mx5300.dts index ea93cdcf4c7e8c..f7defd66555a97 100644 --- a/target/linux/qualcommax/dts/ipq8072-mx5300.dts +++ b/target/linux/qualcommax/dts/ipq8072-mx5300.dts @@ -19,7 +19,7 @@ led-running = &led_system_blue; led-failsafe = &led_system_red; led-upgrade = &led_system_green; - label-mac-device = &dp2; + label-mac-device = &swport2; }; chosen { @@ -438,33 +438,76 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; + }; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -473,46 +516,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - &ssphy_0 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-mx8500.dts b/target/linux/qualcommax/dts/ipq8072-mx8500.dts index f7837debbccedf..1025775d5151e0 100644 --- a/target/linux/qualcommax/dts/ipq8072-mx8500.dts +++ b/target/linux/qualcommax/dts/ipq8072-mx8500.dts @@ -409,40 +409,80 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@2 { - port_id = <2>; - phy_address = <1>; + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&hw_mac_addr 1>; + nvmem-cell-names = "mac-address"; }; - port@6 { - port_id = <6>; - phy_address = <8>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&aqr114c>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -451,51 +491,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_0>; - label = "lan1"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan2"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan4"; - nvmem-cells = <&hw_mac_addr 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp6_syn { - status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr114c>; - label = "wan"; - nvmem-cells = <&hw_mac_addr 0>; - nvmem-cell-names = "mac-address"; -}; - &ssphy_0 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-sax1v1k.dts b/target/linux/qualcommax/dts/ipq8072-sax1v1k.dts index 91804b862fbeb2..e522a3efe18c26 100644 --- a/target/linux/qualcommax/dts/ipq8072-sax1v1k.dts +++ b/target/linux/qualcommax/dts/ipq8072-sax1v1k.dts @@ -20,11 +20,11 @@ led-upgrade = &led_system_red; serial0 = &blsp1_uart5; /* Aliases as required by u-boot to patch MAC addresses */ - ethernet0 = &dp6_syn; - ethernet1 = &dp4; - ethernet2 = &dp3; - ethernet3 = &dp2; - label-mac-device = &dp6_syn; + ethernet0 = &swport6; + ethernet1 = &swport4; + ethernet2 = &swport3; + ethernet3 = &swport2; + label-mac-device = &swport6; }; chosen { @@ -173,33 +173,62 @@ status = "okay"; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ status = "okay"; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport2: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + swport4: port@4 { + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -208,33 +237,6 @@ status = "okay"; }; -&dp2 { - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan3"; - status = "okay"; -}; - -&dp3 { - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan2"; - status = "okay"; -}; - -&dp4 { - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan1"; - status = "okay"; -}; - -&dp6_syn { - phy-handle = <&qca8081>; - label = "wan"; - status = "okay"; -}; - &wifi { qcom,ath11k-calibration-variant = "Spectrum-SAX1V1K"; status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8072-wax218.dts b/target/linux/qualcommax/dts/ipq8072-wax218.dts index e9a9c12edfb138..570ff0aca55d6e 100644 --- a/target/linux/qualcommax/dts/ipq8072-wax218.dts +++ b/target/linux/qualcommax/dts/ipq8072-wax218.dts @@ -89,18 +89,36 @@ status = "okay"; }; +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -135,14 +153,6 @@ }; }; -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "lan"; - nvmem-cells = <&macaddr_ubootenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - &qpic_bam { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-wax620.dts b/target/linux/qualcommax/dts/ipq8072-wax620.dts index f410f79495ef18..286bb7c60b8a33 100644 --- a/target/linux/qualcommax/dts/ipq8072-wax620.dts +++ b/target/linux/qualcommax/dts/ipq8072-wax620.dts @@ -14,8 +14,8 @@ aliases { serial0 = &blsp1_uart5; - ethernet0 = &dp6; - label-mac-device = &dp6; + ethernet0 = &swport6; + label-mac-device = &swport6; led-boot = &led_system_blue; led-failsafe = &led_system_red; @@ -115,18 +115,34 @@ status = "okay"; }; +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = ; - switch_mac_mode = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -161,12 +177,6 @@ }; }; -&dp6 { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "lan"; -}; - &qpic_bam { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-wpq873.dts b/target/linux/qualcommax/dts/ipq8072-wpq873.dts index f0fd1331e60423..7fe6c9b5bd3c65 100644 --- a/target/linux/qualcommax/dts/ipq8072-wpq873.dts +++ b/target/linux/qualcommax/dts/ipq8072-wpq873.dts @@ -21,11 +21,11 @@ led-running = &led_system_green; led-upgrade = &led_system_blue; /* Aliases as required by u-boot to patch MAC addresses */ - ethernet0 = &dp6; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - label-mac-device = &dp6; + ethernet0 = &swport6; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + label-mac-device = &swport6; }; chosen { @@ -384,32 +384,62 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport4: port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -418,30 +448,6 @@ status = "okay"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan1"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan2"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan3"; -}; - -&dp6 { - status = "okay"; - phy-handle = <&qca8081>; - label = "wan"; -}; - &pcie_qmp0 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8072-zbt-z800ax.dts b/target/linux/qualcommax/dts/ipq8072-zbt-z800ax.dts index be7c77d3feb759..6db9345e347d70 100644 --- a/target/linux/qualcommax/dts/ipq8072-zbt-z800ax.dts +++ b/target/linux/qualcommax/dts/ipq8072-zbt-z800ax.dts @@ -22,12 +22,12 @@ * Aliases as required by u-boot * to patch MAC addresses */ - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5; - label-mac-device = &dp1; + ethernet0 = &swport1; + ethernet1 = &swport2; + ethernet2 = &swport3; + ethernet3 = &swport4; + ethernet4 = &swport5; + label-mac-device = &swport1; }; chosen { @@ -379,33 +379,66 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + }; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; @@ -414,36 +447,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8074-deco-x80-5g.dts b/target/linux/qualcommax/dts/ipq8074-deco-x80-5g.dts index 2f14b554ccb8ba..b43f5b6bb5b002 100644 --- a/target/linux/qualcommax/dts/ipq8074-deco-x80-5g.dts +++ b/target/linux/qualcommax/dts/ipq8074-deco-x80-5g.dts @@ -443,24 +443,46 @@ to suit the TP-Link Deco X80-5G target */ }; }; +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; &switch { status = "okay"; - switch_wan_bmp = ; /* wan port bitmap */ - switch_lan_bmp = ; /* lan port bitmap */ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@5 { - port_id = <5>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@6 { - port_id = <6>; - phy_address = <4>; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + }; + + swport6: port@6 { + reg = <6>; + label = "lan"; + phy-handle = <&qca8033>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -469,18 +491,6 @@ to suit the TP-Link Deco X80-5G target */ status = "okay"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8081>; - label = "wan"; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8033>; - label = "lan"; -}; - &wifi { status = "okay"; qcom,ath11k-calibration-variant = "tplink_deco-x80-5g"; diff --git a/target/linux/qualcommax/dts/ipq8074-nbg7815.dts b/target/linux/qualcommax/dts/ipq8074-nbg7815.dts index 35dd01967f87ad..ecf2a899ebd8e1 100644 --- a/target/linux/qualcommax/dts/ipq8074-nbg7815.dts +++ b/target/linux/qualcommax/dts/ipq8074-nbg7815.dts @@ -20,9 +20,7 @@ aliases { serial0 = &blsp1_uart5; serial1 = &blsp1_uart3; - /* Alias as required by u-boot to patch MAC addresses */ - ethernet0 = &dp1; - label-mac-device = &dp1; + label-mac-device = &swport1; }; chosen { @@ -300,46 +298,94 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode1 = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@2 { - port_id = <2>; - phy_address = <1>; + swport1: port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; + }; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&macaddr_lan 1>; + nvmem-cell-names = "mac-address"; }; - port@6 { - port_id = <6>; - ethernet-phy-ieee802.3-c45; - phy_address = <8>; + swport6: port@6 { + reg = <6>; + label = "10g"; + phy-handle = <&aqr113c>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -348,56 +394,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan1"; - nvmem-cells = <&macaddr_lan 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; - nvmem-cells = <&macaddr_lan 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&macaddr_lan 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; - nvmem-cells = <&macaddr_lan 0>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-mode = "sgmii"; - phy-handle = <&qca8081>; - label = "wan"; - nvmem-cells = <&macaddr_lan 1>; - nvmem-cell-names = "mac-address"; -}; - -&dp6_syn { - status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c>; - label = "10g"; - nvmem-cells = <&macaddr_lan 0>; - nvmem-cell-names = "mac-address"; -}; - &blsp1_i2c2 { pinctrl-0 = <&i2c_0_pins>; pinctrl-names = "default"; diff --git a/target/linux/qualcommax/dts/ipq8074-rax120v2.dts b/target/linux/qualcommax/dts/ipq8074-rax120v2.dts index 4822cbe9a69dd1..2cc4b5dd8b77a1 100644 --- a/target/linux/qualcommax/dts/ipq8074-rax120v2.dts +++ b/target/linux/qualcommax/dts/ipq8074-rax120v2.dts @@ -19,7 +19,7 @@ led-running = &led_system_white; led-upgrade = &led_system_white; led-internet = &led_wan_white; - label-mac-device = &dp5; + label-mac-device = &swport5; }; chosen { @@ -190,40 +190,90 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + swport1: port@1 { + reg = <1>; + label = "lan4"; + phy-handle = <&qca8075_0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@2 { - port_id = <2>; - phy_address = <1>; + + swport2: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport4: port@4 { + reg = <4>; + label = "lan1"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_wan>; + nvmem-cell-names = "mac-address"; }; - port@6 { - port_id = <6>; - phy_address = <7>; - compatible = "ethernet-phy-ieee802.3-c45"; - ethernet-phy-ieee802.3-c45; + + swport6: port@6 { + reg = <6>; + label = "lan5"; + phy-handle = <&aqr111b0>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -232,55 +282,6 @@ status = "okay"; }; -&dp1 { - status = "okay"; - phy-handle = <&qca8075_0>; - label = "lan4"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan3"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan2"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan1"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "wan"; - nvmem-cells = <&macaddr_wan>; - nvmem-cell-names = "mac-address"; -}; - -&dp6_syn { - status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr111b0>; - label = "lan5"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address"; -}; - &blsp1_uart5 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8074-rbs750.dts b/target/linux/qualcommax/dts/ipq8074-rbs750.dts index 9982abd803739a..54588badf1de7d 100644 --- a/target/linux/qualcommax/dts/ipq8074-rbs750.dts +++ b/target/linux/qualcommax/dts/ipq8074-rbs750.dts @@ -12,10 +12,10 @@ compatible = "netgear,rbs750", "qcom,ipq8074"; }; -&dp1 { +&swport1 { status = "disabled"; }; -&dp2 { +&swport2 { status = "disabled"; }; diff --git a/target/linux/qualcommax/dts/ipq8074-rbx750.dtsi b/target/linux/qualcommax/dts/ipq8074-rbx750.dtsi index 55474c82e3a4e5..097cb6ca7196bf 100644 --- a/target/linux/qualcommax/dts/ipq8074-rbx750.dtsi +++ b/target/linux/qualcommax/dts/ipq8074-rbx750.dtsi @@ -18,7 +18,7 @@ led-failsafe = &lp5562_red; led-upgrade = &lp5562_blue; serial0 = &blsp1_uart5; - label-mac-device = &dp5; + label-mac-device = &swport5; }; chosen { @@ -98,32 +98,66 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT4 | ESS_PORT5)>; - switch_wan_bmp = ; - switch_mac_mode = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport1: port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&phy0>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_boarddata 1>; + nvmem-cell-names = "mac-address"; }; - port@2 { - port_id = <2>; - phy_address = <1>; + swport2: port@2 { + reg = <2>; + label = "lan3"; + phy-handle = <&phy1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_boarddata 1>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&phy3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_boarddata 1>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + swport5: port@5 { + reg = <5>; + label = "lan1"; + phy-handle = <&phy4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_boarddata 0>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -162,38 +196,6 @@ }; }; -&dp1 { - status = "okay"; - phy-handle = <&phy0>; - label = "wan"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_boarddata 1>; -}; - -&dp2 { - status = "okay"; - phy-handle = <&phy1>; - label = "lan3"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_boarddata 2>; -}; - -&dp4 { - status = "okay"; - phy-handle = <&phy3>; - label = "lan2"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_boarddata 1>; -}; - -&dp5 { - status = "okay"; - phy-handle = <&phy4>; - label = "lan1"; - nvmem-cell-names = "mac-address"; - nvmem-cells = <&macaddr_boarddata 0>; -}; - &qpic_bam { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8074-rt-ax89x.dts b/target/linux/qualcommax/dts/ipq8074-rt-ax89x.dts index 1fdf394d3fab32..467dec01d613cb 100644 --- a/target/linux/qualcommax/dts/ipq8074-rt-ax89x.dts +++ b/target/linux/qualcommax/dts/ipq8074-rt-ax89x.dts @@ -17,12 +17,6 @@ aliases { serial0 = &blsp1_uart5; mdio-gpio0 = &mdio1; - ethernet0 = &dp1; - ethernet1 = &dp2; - ethernet2 = &dp3; - ethernet3 = &dp4; - ethernet4 = &dp5_syn; - ethernet5 = &dp6_syn; led-boot = &led_pwr; led-failsafe = &led_pwr; led-running = &led_pwr; @@ -160,6 +154,16 @@ enable-active-high; regulator-boot-on; }; + + sfp: sfp { + compatible = "sff,sfp"; + + i2c-bus = <&blsp1_i2c2>; + + mod-def0-gpios = <&tlmm 46 GPIO_ACTIVE_LOW>; + tx-disable-gpios = <&tlmm 48 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>; + }; }; &cpu0_thermal { @@ -455,6 +459,12 @@ partition@3e0000 { label = "0:appsblenv"; reg = <0x003e0000 0x20000>; + + nvmem-layout { + compatible = "u-boot,env"; + + macaddr_ubootenv_ethaddr: ethaddr {}; + }; }; partition@400000 { @@ -552,6 +562,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x10>; + dsa,member = <1 0>; ports { #address-cells = <1>; @@ -560,7 +571,7 @@ port@0 { reg = <0>; label = "cpu"; - ethernet = <&dp1>; + ethernet = <&port_switch>; phy-mode = "rgmii-rxid"; phy-handle = <&qca8035>; }; @@ -569,30 +580,40 @@ reg = <1>; label = "lan7"; phy-handle = <&qca8337_0>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; port@2 { reg = <2>; label = "lan6"; phy-handle = <&qca8337_1>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; port@3 { reg = <3>; label = "lan5"; phy-handle = <&qca8337_2>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; port@4 { reg = <4>; label = "lan4"; phy-handle = <&qca8337_3>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; port@5 { reg = <5>; label = "lan3"; phy-handle = <&qca8337_4>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; port@6 { @@ -602,6 +623,8 @@ phy-handle = <&qca8033>; managed = "in-band-status"; qca,sgmii-enable-pll; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -639,97 +662,103 @@ &switch { status = "okay"; + dsa,member = <0 0>; pinctrl-0 = <&uniphy_pins>; pinctrl-names = "default"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT5 | ESS_PORT6)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode1 = ; /* mac mode for uniphy instance1*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; - qcom,port_phyinfo { port@0 { - port_id = <1>; - phy_address = <0x8>; - }; - port@1 { - port_id = <2>; - phy_address = <0x9>; - }; - port@2 { - port_id = <3>; - phy_address = <0xa>; + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <4>; - phy_address = <0xb>; + + port_switch: port@1 { + reg = <1>; + label = "switch"; + phy-handle = <&qca8075_8>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 0>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - sfp: port@4 { - port_id = <5>; - phy_address = <30>; - phy_i2c_address = <30>; - phy-i2c-mode; /*i2c access phy */ - media-type = "sfp"; /* fiber mode */ - sfp_tx_dis_pin = <&tlmm 48 GPIO_ACTIVE_HIGH>; - sfp_mod_present_pin = <&tlmm 46 GPIO_ACTIVE_LOW>; + port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_9>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - /* PCB R5.00, AQR113C */ - port@5_113c { - status = "disabled"; - port_id = <6>; - phy_address = <8>; - ethernet-phy-ieee802.3-c45; - mdiobus = <&mdio1>; + port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8075_a>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; + }; + + port@4 { + reg = <4>; + label = "wan"; + phy-handle = <&qca8075_b>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; + }; + + port@5 { + reg = <5>; + label = "10g-sfp"; + sfp = <&sfp>; + phy-mode = "10gbase-r"; + managed = "in-band-status"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; + }; + + port@6 { + reg = <6>; + label = "10g-copper"; + phy-handle = <&aqr113c>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_ubootenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; }; }; -&edma { - status = "okay"; -}; - -&dp1 { +&uniphy0 { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_8>; - label = "switch"; }; -&dp2 { +&uniphy1 { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_9>; - label = "lan2"; }; -&dp3 { +&uniphy2 { status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_a>; - label = "lan1"; }; -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_b>; - label = "wan"; -}; - -&dp5_syn { - status = "okay"; - phy-handle = <&sfp>; - label = "10g-sfp"; -}; - -&dp6_syn { +&edma { status = "okay"; - phy-handle = <&aqr113c>; - label = "10g-copper"; }; &wifi { diff --git a/target/linux/qualcommax/dts/ipq8074-sxk80.dtsi b/target/linux/qualcommax/dts/ipq8074-sxk80.dtsi index db0e4475c31b6f..9abdbdc0a59553 100644 --- a/target/linux/qualcommax/dts/ipq8074-sxk80.dtsi +++ b/target/linux/qualcommax/dts/ipq8074-sxk80.dtsi @@ -20,7 +20,7 @@ led-failsafe = &led_front_red; led-running = &led_front_green; led-upgrade = &led_front_white; - label-mac-device = &dp2; + label-mac-device = &swport2; }; chosen { @@ -458,35 +458,80 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ - switch_mac_mode2 = ; /* mac mode for uniphy instance2*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; }; - port@3 { - port_id = <3>; - phy_address = <2>; + + swport2: port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_boarddata1_0>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <3>; + + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_boarddata1_0>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - phy_address = <4>; + + swport4: port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_boarddata1_0>; + nvmem-cell-names = "mac-address"; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + + swport5: port@5 { + reg = <5>; + label = "lan5"; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; + nvmem-cells = <&macaddr_boarddata1_0>; + nvmem-cell-names = "mac-address"; + }; + + swport6: port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&qca8081_28>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_boarddata1_6>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -495,46 +540,6 @@ status = "okay"; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; - label = "lan2"; - nvmem-cells = <&macaddr_boarddata1_0>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&macaddr_boarddata1_0>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan4"; - nvmem-cells = <&macaddr_boarddata1_0>; - nvmem-cell-names = "mac-address"; -}; - -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; - label = "lan5"; - nvmem-cells = <&macaddr_boarddata1_0>; - nvmem-cell-names = "mac-address"; -}; - -&dp6 { - status = "okay"; - phy-handle = <&qca8081_28>; - label = "wan"; - nvmem-cells = <&macaddr_boarddata1_6>; - nvmem-cell-names = "mac-address"; -}; - &wifi { status = "okay"; diff --git a/target/linux/qualcommax/dts/ipq8074-wax630.dts b/target/linux/qualcommax/dts/ipq8074-wax630.dts index 3393efd7b550f3..0764800bbc9264 100644 --- a/target/linux/qualcommax/dts/ipq8074-wax630.dts +++ b/target/linux/qualcommax/dts/ipq8074-wax630.dts @@ -16,9 +16,9 @@ aliases { serial0 = &blsp1_uart5; - ethernet0 = &dp6_syn; - ethernet1 = &dp4; - label-mac-device = &dp6_syn; + ethernet0 = &swport6; + ethernet1 = &swport4; + label-mac-device = &swport6; led-boot = &led_system_blue; led-failsafe = &led_system_red; @@ -148,23 +148,46 @@ status = "okay"; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT4 | ESS_PORT6)>; - switch_mac_mode = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; - port@6 { - port_id = <6>; - phy_address = <28>; - port_mac_sel = "QGMAC_PORT"; + swport6: port@6 { + reg = <6>; + label = "lan1"; + phy-handle = <&qca8081>; + phy-mode = "2500base-x"; + pcs-handle = <&uniphy2 0>; }; }; }; @@ -214,18 +237,6 @@ }; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; - label = "lan2"; -}; - -&dp6_syn { - status = "okay"; - phy-handle = <&qca8081>; - label = "lan1"; -}; - &qpic_bam { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/dts/ipq8074-wxr-5950ax12.dts index f6ba5731c89a7b..60fb04d46c803a 100644 --- a/target/linux/qualcommax/dts/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/dts/ipq8074-wxr-5950ax12.dts @@ -19,7 +19,7 @@ led-failsafe = &led_power_red; led-running = &led_power_white; led-upgrade = &led_power_white; - label-mac-device = &dp5_syn; + label-mac-device = &swport5; }; chosen { @@ -255,41 +255,84 @@ }; }; +&uniphy0 { + status = "okay"; +}; + +&uniphy1 { + status = "okay"; +}; + +&uniphy2 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; - switch_wan_bmp = ; - switch_mac_mode = ; - switch_mac_mode1 = ; - switch_mac_mode2 = ; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <0x19>; + swport2: port@2 { + reg = <2>; + label = "lan4"; + phy-handle = <&qca8075_1>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 1>; + nvmem-cells = <&macaddr_appsblenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - port@3 { - port_id = <3>; - phy_address = <0x1a>; + swport3: port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8075_2>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 2>; + nvmem-cells = <&macaddr_appsblenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - port@4 { - port_id = <4>; - phy_address = <0x1b>; + swport4: port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8075_3>; + phy-mode = "qsgmii"; + pcs-handle = <&uniphy0 3>; + nvmem-cells = <&macaddr_appsblenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - port@5 { - port_id = <5>; - ethernet-phy-ieee802.3-c45; - phy_address = <0x0>; + swport5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&aqr113c_1>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy1 0>; + nvmem-cells = <&macaddr_appsblenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; - port@6 { - port_id = <6>; - ethernet-phy-ieee802.3-c45; - phy_address = <0x8>; + swport6: port@6 { + reg = <6>; + label = "lan1"; + phy-handle = <&aqr113c_2>; + phy-mode = "usxgmii"; + pcs-handle = <&uniphy2 0>; + nvmem-cells = <&macaddr_appsblenv_ethaddr>; + nvmem-cell-names = "mac-address"; }; }; }; @@ -298,51 +341,6 @@ status = "okay"; }; -&dp2 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_1>; - label = "lan4"; - nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - -&dp3 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_2>; - label = "lan3"; - nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - -&dp4 { - status = "okay"; - phy-mode = "qsgmii"; - phy-handle = <&qca8075_3>; - label = "lan2"; - nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - -&dp5_syn { - status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c_1>; - label = "wan"; - nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - -&dp6_syn { - status = "okay"; - phy-mode = "usxgmii"; - phy-handle = <&aqr113c_2>; - label = "lan1"; - nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address"; -}; - &ssphy_0 { status = "okay"; }; diff --git a/target/linux/qualcommax/dts/ipq807x-nwax10ax.dtsi b/target/linux/qualcommax/dts/ipq807x-nwax10ax.dtsi index 7c2bd698ea662a..5f6e75410a9a25 100644 --- a/target/linux/qualcommax/dts/ipq807x-nwax10ax.dtsi +++ b/target/linux/qualcommax/dts/ipq807x-nwax10ax.dtsi @@ -89,13 +89,33 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - phyinfo: qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <1>; + swports: ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swport1: port@1 { + reg = <1>; + phy-handle = <&ar8033>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy0 0>; }; }; }; @@ -112,12 +132,6 @@ }; }; -&dp1 { - status = "okay"; - phy-handle = <&ar8033>; - phy-mode = "sgmii"; -}; - &blsp1_spi1 { pinctrl-0 = <&spi_0_pins>; pinctrl-names = "default"; diff --git a/target/linux/qualcommax/dts/ipq8174-homewrk.dts b/target/linux/qualcommax/dts/ipq8174-homewrk.dts index 3e028fc8c6b3d0..3682114ad3ecfb 100644 --- a/target/linux/qualcommax/dts/ipq8174-homewrk.dts +++ b/target/linux/qualcommax/dts/ipq8174-homewrk.dts @@ -46,33 +46,25 @@ }; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "wan"; nvmem-cells = <&mac_address 0>; nvmem-cell-names = "mac-address"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan3"; nvmem-cells = <&mac_address 1>; nvmem-cell-names = "mac-address"; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; +&swport4 { label = "lan2"; nvmem-cells = <&mac_address 1>; nvmem-cell-names = "mac-address"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; +&swport5 { label = "lan1"; nvmem-cells = <&mac_address 1>; nvmem-cell-names = "mac-address"; diff --git a/target/linux/qualcommax/dts/ipq8174-mx4200.dtsi b/target/linux/qualcommax/dts/ipq8174-mx4200.dtsi index c2f2ac563b5c71..20f83c72f8cf23 100644 --- a/target/linux/qualcommax/dts/ipq8174-mx4200.dtsi +++ b/target/linux/qualcommax/dts/ipq8174-mx4200.dtsi @@ -5,7 +5,7 @@ / { aliases { - label-mac-device = &dp2; + label-mac-device = &swport2; }; }; @@ -242,33 +242,25 @@ }; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; label = "wan"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; label = "lan1"; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; +&swport4 { nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; label = "lan2"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; +&swport5 { nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; label = "lan3"; diff --git a/target/linux/qualcommax/dts/ipq8174-mx4300.dts b/target/linux/qualcommax/dts/ipq8174-mx4300.dts index 5010d96c28b4d2..df0f1875e9a76c 100644 --- a/target/linux/qualcommax/dts/ipq8174-mx4300.dts +++ b/target/linux/qualcommax/dts/ipq8174-mx4300.dts @@ -22,7 +22,7 @@ }; aliases { - label-mac-device = &dp2; + label-mac-device = &swport2; }; }; @@ -256,33 +256,25 @@ }; }; -&dp2 { - status = "okay"; - phy-handle = <&qca8075_1>; +&swport2 { label = "wan"; nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; -&dp3 { - status = "okay"; - phy-handle = <&qca8075_2>; +&swport3 { label = "lan3"; nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; -&dp4 { - status = "okay"; - phy-handle = <&qca8075_3>; +&swport4 { label = "lan2"; nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; }; -&dp5 { - status = "okay"; - phy-handle = <&qca8075_4>; +&swport5 { label = "lan1"; nvmem-cells = <&hw_mac_addr 0>; nvmem-cell-names = "mac-address"; diff --git a/target/linux/qualcommax/dts/ipq8174-mx4x00.dtsi b/target/linux/qualcommax/dts/ipq8174-mx4x00.dtsi index 1bd150c160bedb..297dbf8d163aed 100644 --- a/target/linux/qualcommax/dts/ipq8174-mx4x00.dtsi +++ b/target/linux/qualcommax/dts/ipq8174-mx4x00.dtsi @@ -151,32 +151,54 @@ }; }; +&uniphy0 { + status = "okay"; +}; + &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; /* lan port bitmap */ - switch_wan_bmp = ; /* wan port bitmap */ - switch_mac_mode = ; /* mac mode for uniphy instance0*/ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; - qcom,port_phyinfo { - port@2 { - port_id = <2>; - phy_address = <1>; + swport2: port@2 { + reg = <2>; + phy-handle = <&qca8075_1>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 1>; }; - port@3 { - port_id = <3>; - phy_address = <2>; + swport3: port@3 { + reg = <3>; + phy-handle = <&qca8075_2>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 2>; }; - port@4 { - port_id = <4>; - phy_address = <3>; + swport4: port@4 { + reg = <4>; + phy-handle = <&qca8075_3>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 3>; }; - port@5 { - port_id = <5>; - phy_address = <4>; + swport5: port@5 { + reg = <5>; + phy-handle = <&qca8075_4>; + phy-mode = "psgmii"; + pcs-handle = <&uniphy0 4>; }; }; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-ess.dtsi index a42b7bbeaa32ab..a2abf9f20c1068 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-ess.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-ess.dtsi @@ -1,116 +1,78 @@ -#include - &soc { - ess_instance: ess-instance { - #address-cells = <1>; - #size-cells = <1>; - num_devices = <1>; - - switch: ess-switch@39c00000 { - compatible = "qcom,ess-switch-ipq50xx"; - device_id = <0>; - cmnblk_clk = "internal_96MHz"; - reg = <0x39c00000 0x200000>; - switch_access_mode = "local bus"; - clocks = <&gcc GCC_CMN_BLK_AHB_CLK>, - <&gcc GCC_CMN_BLK_SYS_CLK>, - <&gcc GCC_UNIPHY_AHB_CLK>, - <&gcc GCC_UNIPHY_SYS_CLK>, - <&gcc GCC_MDIO0_AHB_CLK>, - <&gcc GCC_MDIO1_AHB_CLK>, - <&gcc GCC_GMAC0_CFG_CLK>, - <&gcc GCC_GMAC0_SYS_CLK>, - <&gcc GCC_GMAC1_CFG_CLK>, - <&gcc GCC_GMAC1_SYS_CLK>, - <&gcc GCC_GEPHY_RX_CLK>, - <&gcc GCC_GEPHY_TX_CLK>, - <&gcc GCC_UNIPHY_RX_CLK>, - <&gcc GCC_UNIPHY_TX_CLK>, - <&gcc GCC_GMAC0_RX_CLK>, - <&gcc GCC_GMAC0_TX_CLK>, - <&gcc GCC_GMAC1_RX_CLK>, - <&gcc GCC_GMAC1_TX_CLK>, - <&gcc GCC_SNOC_GMAC0_AHB_CLK>, - <&gcc GCC_SNOC_GMAC1_AHB_CLK>, - <&gcc GCC_GMAC0_PTP_CLK>, - <&gcc GCC_GMAC1_PTP_CLK>; - clock-names = "cmn_ahb_clk", - "cmn_sys_clk", - "uniphy_ahb_clk", - "uniphy_sys_clk", - "gcc_mdio0_ahb_clk", - "gcc_mdio1_ahb_clk", - "gcc_gmac0_cfg_clk", - "gcc_gmac0_sys_clk", - "gcc_gmac1_cfg_clk", - "gcc_gmac1_sys_clk", - "uniphy0_port1_rx_clk", - "uniphy0_port1_tx_clk", - "uniphy1_port5_rx_clk", - "uniphy1_port5_tx_clk", - "nss_port1_rx_clk", - "nss_port1_tx_clk", - "nss_port2_rx_clk", - "nss_port2_tx_clk", - "gcc_snoc_gmac0_ahb_clk", - "gcc_snoc_gmac1_ahb_clk", - "gcc_gmac0_ptp_clk", - "gcc_gmac1_ptp_clk"; - resets = <&gcc GCC_GMAC0_BCR>, - <&gcc GCC_GMAC1_BCR>, - <&gcc GCC_UNIPHY_BCR>, - <&gcc GCC_UNIPHY_SOFT_RESET>; - reset-names = "gmac0_bcr_rst", - "gmac1_bcr_rst", - "uniphy_bcr_rst", - "uniphy1_soft_rst"; - - status = "disabled"; - }; - }; - - ess-uniphy@98000 { - compatible = "qcom,ess-uniphy"; - reg = <0x98000 0x800>; - uniphy_access_mode = "local bus"; - }; - - nss-dp-common { - compatible = "qcom,nss-dp-common"; - qcom,tcsr-base = <0x01937000>; - }; - - dp1: dp1 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <1>; - - reg = <0x39C00000 0x10000>; + gmac0: ethernet@39c00000 { + compatible = "qcom,ipq5018-gmac", "snps,dwmac"; + reg = <0x39c00000 0x10000>; + reg-names = "stmmaceth"; + clocks = <&gcc GCC_GMAC0_SYS_CLK>, + <&gcc GCC_GMAC0_CFG_CLK>, + <&gcc GCC_GMAC0_PTP_CLK>, + <&gcc GCC_SNOC_GMAC0_AHB_CLK>, + <&gcc GCC_SNOC_GMAC0_AXI_CLK>, + <&gcc GCC_GMAC0_RX_CLK>, + <&gcc GCC_GMAC0_TX_CLK>; + clock-names = "stmmaceth", + "pclk", + "ptp_ref", + "ahb", + "axi", + "rx", + "tx"; + assigned-clocks = <&gcc GCC_GMAC0_SYS_CLK>, + <&gcc GCC_GMAC0_CFG_CLK>, + <&gcc GCC_GMAC0_PTP_CLK>, + <&gcc GCC_SNOC_GMAC0_AHB_CLK>, + <&gcc GCC_SNOC_GMAC0_AXI_CLK>; + assigned-clock-rates = <240000000>, + <240000000>, + <240000000>, + <240000000>, + <240000000>; + resets = <&gcc GCC_GMAC0_BCR>; + reset-names = "stmmaceth"; interrupts = ; - clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>; - clock-names = "nss-snoc-gmac-axi-clk"; + interrupt-names = "macirq"; - qcom,mactype = <2>; /* GMAC_HAL_TYPE_SYN_GMAC */ - local-mac-address = [000000000000]; - phy-mode = "internal"; phy-handle = <&ge_phy>; + phy-mode = "sgmii"; status = "disabled"; }; - dp2: dp2 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <2>; - - reg = <0x39D00000 0x10000>; + gmac1: ethernet@39d00000 { + compatible = "qcom,ipq5018-gmac", "snps,dwmac"; + reg = <0x39d00000 0x10000>; + reg-names = "stmmaceth"; + clocks = <&gcc GCC_GMAC1_SYS_CLK>, + <&gcc GCC_GMAC1_CFG_CLK>, + <&gcc GCC_GMAC1_PTP_CLK>, + <&gcc GCC_SNOC_GMAC1_AHB_CLK>, + <&gcc GCC_SNOC_GMAC1_AXI_CLK>, + <&gcc GCC_GMAC1_RX_CLK>, + <&gcc GCC_GMAC1_TX_CLK>; + clock-names = "stmmaceth", + "pclk", + "ptp_ref", + "ahb", + "axi", + "rx", + "tx"; + assigned-clocks = <&gcc GCC_GMAC1_SYS_CLK>, + <&gcc GCC_GMAC1_CFG_CLK>, + <&gcc GCC_GMAC1_PTP_CLK>, + <&gcc GCC_SNOC_GMAC1_AHB_CLK>, + <&gcc GCC_SNOC_GMAC1_AXI_CLK>; + assigned-clock-rates = <240000000>, + <240000000>, + <240000000>, + <240000000>, + <240000000>; + resets = <&gcc GCC_GMAC1_BCR>; + reset-names = "stmmaceth"; interrupts = ; - clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>; - clock-names = "nss-snoc-gmac-axi-clk"; + interrupt-names = "macirq"; + + pcs-handle = <&uniphy0>; - qcom,mactype = <2>; /* GMAC_HAL_TYPE_SYN_GMAC */ - local-mac-address = [000000000000]; - phy-mode = "sgmii"; status = "disabled"; }; -}; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi index b54f53f29ce147..0de37caf7da1c6 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi @@ -1,518 +1,166 @@ -#include +#include &soc { - bias_pll_cc_clk: bias-pll-cc-clk { + cmn_pll_ref_clk: cmn-pll-ref-clk { compatible = "fixed-clock"; - clock-frequency = <300000000>; - clock-output-names = "bias_pll_cc_clk"; + clock-frequency = <48000000>; #clock-cells = <0>; }; - bias_pll_nss_noc_clk: bias-pll-nss-noc-clk { - compatible = "fixed-clock"; - clock-frequency = <416500000>; - clock-output-names = "bias_pll_nss_noc_clk"; - #clock-cells = <0>; + cmn_pll: clock-controller@9b000 { + compatible = "qcom,ipq6018-cmn-pll"; + reg = <0x0 0x0009b000 0x0 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 IPQ6018_CMN_PLL_CLK>; + assigned-clock-rates-u64 = /bits/ 64 <12000000000>; + }; + + uniphy0: ethernet-pcs@7a00000 { + compatible = "qualcomm,ipq6018-uniphy"; + reg = <0x0 0x07a00000 0x0 0x10000>; + #pcs-cells = <1>; + qcom,psgmii; + clocks = <&gcc GCC_UNIPHY0_AHB_CLK>, + <&gcc GCC_UNIPHY0_SYS_CLK>, + <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx"; + clock-output-names = "uniphy0_gcc_tx_clk", + "uniphy0_gcc_rx_clk"; + resets = <&gcc GCC_UNIPHY0_SOFT_RESET>, + <&gcc GCC_UNIPHY0_XPCS_RESET>, + <&gcc GCC_UNIPHY0_PORT1_ARES>, + <&gcc GCC_UNIPHY0_PORT2_ARES>, + <&gcc GCC_UNIPHY0_PORT3_ARES>, + <&gcc GCC_UNIPHY0_PORT4_ARES>, + <&gcc GCC_UNIPHY0_PORT5_ARES>; + reset-names = "soft", "xpcs", + "port1", "port2", "port3", + "port4", "port5"; + status = "disabled"; + }; + + uniphy1: ethernet-pcs@7a10000 { + compatible = "qualcomm,ipq6018-uniphy"; + reg = <0x0 0x07a10000 0x0 0x10000>; + #pcs-cells = <1>; + clocks = <&gcc GCC_UNIPHY1_AHB_CLK>, + <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port5_rx", "port5_tx"; + clock-output-names = "uniphy1_gcc_tx_clk", + "uniphy1_gcc_rx_clk"; + resets = <&gcc GCC_UNIPHY1_SOFT_RESET>, + <&gcc GCC_UNIPHY1_XPCS_RESET>; + reset-names = "soft", "xpcs"; + status = "disabled"; }; edma: edma@3ab00000 { - compatible = "qcom,edma"; - reg = <0x0 0x3ab00000 0x0 0xabe00>; - reg-names = "edma-reg-base"; - qcom,txdesc-ring-start = <23>; - qcom,txdesc-rings = <1>; - qcom,txcmpl-ring-start = <23>; - qcom,txcmpl-rings = <1>; - qcom,rxfill-ring-start = <7>; - qcom,rxfill-rings = <1>; - qcom,rxdesc-ring-start = <15>; - qcom,rxdesc-rings = <1>; + compatible = "qualcomm,ipq6018-edma"; + reg = <0x0 0x3ab00000 0x0 0xb0000>; interrupts = , , , ; resets = <&gcc GCC_EDMA_HW_RESET>; reset-names = "edma_rst"; + clocks = <&gcc GCC_NSS_EDMA_CLK>, + <&gcc GCC_NSS_EDMA_CFG_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_SNOC_NSSNOC_CLK>; + clock-names = "nss_edma_clk", "nss_edma_cfg_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "gcc_nss_noc_clk", "gcc_nssnoc_snoc_clk", + "gcc_snoc_nssnoc_clk"; status = "disabled"; }; - ess_instance: ess-instance { - #address-cells = <1>; - #size-cells = <1>; - num_devices = <1>; - - switch: ess-switch@3a000000 { - compatible = "qcom,ess-switch-ipq60xx"; - reg = <0x3a000000 0x1000000>; - switch_access_mode = "local bus"; - clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, - <&gcc GCC_CMN_12GPLL_SYS_CLK>, - <&gcc GCC_UNIPHY0_AHB_CLK>, - <&gcc GCC_UNIPHY0_SYS_CLK>, - <&gcc GCC_UNIPHY1_AHB_CLK>, - <&gcc GCC_UNIPHY1_SYS_CLK>, - <&gcc GCC_PORT1_MAC_CLK>, - <&gcc GCC_PORT2_MAC_CLK>, - <&gcc GCC_PORT3_MAC_CLK>, - <&gcc GCC_PORT4_MAC_CLK>, - <&gcc GCC_PORT5_MAC_CLK>, - <&gcc GCC_NSS_PPE_CLK>, - <&gcc GCC_NSS_PPE_CFG_CLK>, - <&gcc GCC_NSSNOC_PPE_CLK>, - <&gcc GCC_NSSNOC_PPE_CFG_CLK>, - <&gcc GCC_NSS_EDMA_CLK>, - <&gcc GCC_NSS_EDMA_CFG_CLK>, - <&gcc GCC_NSS_PPE_IPE_CLK>, - <&gcc GCC_MDIO_AHB_CLK>, - <&gcc GCC_NSS_NOC_CLK>, - <&gcc GCC_NSSNOC_SNOC_CLK>, - <&gcc GCC_NSS_CRYPTO_CLK>, - <&gcc GCC_NSS_PTP_REF_CLK>, - <&gcc GCC_NSS_PORT1_RX_CLK>, - <&gcc GCC_NSS_PORT1_TX_CLK>, - <&gcc GCC_NSS_PORT2_RX_CLK>, - <&gcc GCC_NSS_PORT2_TX_CLK>, - <&gcc GCC_NSS_PORT3_RX_CLK>, - <&gcc GCC_NSS_PORT3_TX_CLK>, - <&gcc GCC_NSS_PORT4_RX_CLK>, - <&gcc GCC_NSS_PORT4_TX_CLK>, - <&gcc GCC_NSS_PORT5_RX_CLK>, - <&gcc GCC_NSS_PORT5_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT5_TX_CLK>, - <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, - <&gcc GCC_UNIPHY1_PORT5_TX_CLK>, - <&gcc NSS_PORT5_RX_CLK_SRC>, - <&gcc NSS_PORT5_TX_CLK_SRC>, - <&gcc GCC_SNOC_NSSNOC_CLK>; - clock-names = "cmn_ahb_clk", "cmn_sys_clk", - "uniphy0_ahb_clk", "uniphy0_sys_clk", - "uniphy1_ahb_clk", "uniphy1_sys_clk", - "port1_mac_clk", "port2_mac_clk", - "port3_mac_clk", "port4_mac_clk", - "port5_mac_clk", - "nss_ppe_clk", "nss_ppe_cfg_clk", - "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", - "nss_edma_clk", "nss_edma_cfg_clk", - "nss_ppe_ipe_clk", - "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", - "gcc_nssnoc_snoc_clk", - "gcc_nss_crypto_clk", - "gcc_nss_ptp_ref_clk", - "nss_port1_rx_clk", "nss_port1_tx_clk", - "nss_port2_rx_clk", "nss_port2_tx_clk", - "nss_port3_rx_clk", "nss_port3_tx_clk", - "nss_port4_rx_clk", "nss_port4_tx_clk", - "nss_port5_rx_clk", "nss_port5_tx_clk", - "uniphy0_port1_rx_clk", - "uniphy0_port1_tx_clk", - "uniphy0_port2_rx_clk", - "uniphy0_port2_tx_clk", - "uniphy0_port3_rx_clk", - "uniphy0_port3_tx_clk", - "uniphy0_port4_rx_clk", - "uniphy0_port4_tx_clk", - "uniphy0_port5_rx_clk", - "uniphy0_port5_tx_clk", - "uniphy1_port5_rx_clk", - "uniphy1_port5_tx_clk", - "nss_port5_rx_clk_src", - "nss_port5_tx_clk_src", - "gcc_snoc_nssnoc_clk"; - resets = <&gcc GCC_PPE_FULL_RESET>, - <&gcc GCC_UNIPHY0_SOFT_RESET>, - <&gcc GCC_UNIPHY0_XPCS_RESET>, - <&gcc GCC_UNIPHY1_SOFT_RESET>, - <&gcc GCC_UNIPHY1_XPCS_RESET>, - <&gcc GCC_NSSPORT1_RESET>, - <&gcc GCC_NSSPORT2_RESET>, - <&gcc GCC_NSSPORT3_RESET>, - <&gcc GCC_NSSPORT4_RESET>, - <&gcc GCC_NSSPORT5_RESET>, - <&gcc GCC_UNIPHY0_PORT1_ARES>, - <&gcc GCC_UNIPHY0_PORT2_ARES>, - <&gcc GCC_UNIPHY0_PORT3_ARES>, - <&gcc GCC_UNIPHY0_PORT4_ARES>, - <&gcc GCC_UNIPHY0_PORT5_ARES>, - <&gcc GCC_UNIPHY0_PORT_4_5_RESET>, - <&gcc GCC_UNIPHY0_PORT_4_RESET>; - reset-names = "ppe_rst", "uniphy0_soft_rst", - "uniphy0_xpcs_rst", "uniphy1_soft_rst", - "uniphy1_xpcs_rst", "nss_port1_rst", - "nss_port2_rst", "nss_port3_rst", - "nss_port4_rst", "nss_port5_rst", - "uniphy0_port1_dis", - "uniphy0_port2_dis", - "uniphy0_port3_dis", - "uniphy0_port4_dis", - "uniphy0_port5_dis", - "uniphy0_port_4_5_rst", - "uniphy0_port_4_rst"; - mdio-bus = <&mdio>; - - switch_cpu_bmp = ; /* cpu port bitmap */ - switch_inner_bmp = <(ESS_PORT6 | ESS_PORT7)>; /*inner port bitmap*/ - switch_mac_mode = ; /* MAC mode for UNIPHY instance 0 */ - switch_mac_mode1 = ; /* MAC mode for UNIPHY instance 1 */ - switch_mac_mode2 = ; /* MAC mode for UNIPHY instance 2 */ - - status = "disabled"; - - bm_tick_mode = <0>; /* bm tick mode */ - tm_tick_mode = <0>; /* tm tick mode */ - - port_scheduler_resource { - port@0 { - port_id = <0>; - ucast_queue = <0 143>; - mcast_queue = <256 271>; - l0sp = <0 35>; - l0cdrr = <0 47>; - l0edrr = <0 47>; - l1cdrr = <0 7>; - l1edrr = <0 7>; - }; - port@1 { - port_id = <1>; - ucast_queue = <144 159>; - mcast_queue = <272 275>; - l0sp = <36 39>; - l0cdrr = <48 63>; - l0edrr = <48 63>; - l1cdrr = <8 11>; - l1edrr = <8 11>; - }; - port@2 { - port_id = <2>; - ucast_queue = <160 175>; - mcast_queue = <276 279>; - l0sp = <40 43>; - l0cdrr = <64 79>; - l0edrr = <64 79>; - l1cdrr = <12 15>; - l1edrr = <12 15>; - }; - port@3 { - port_id = <3>; - ucast_queue = <176 191>; - mcast_queue = <280 283>; - l0sp = <44 47>; - l0cdrr = <80 95>; - l0edrr = <80 95>; - l1cdrr = <16 19>; - l1edrr = <16 19>; - }; - port@4 { - port_id = <4>; - ucast_queue = <192 207>; - mcast_queue = <284 287>; - l0sp = <48 51>; - l0cdrr = <96 111>; - l0edrr = <96 111>; - l1cdrr = <20 23>; - l1edrr = <20 23>; - }; - port@5 { - port_id = <5>; - ucast_queue = <208 223>; - mcast_queue = <288 291>; - l0sp = <52 55>; - l0cdrr = <112 127>; - l0edrr = <112 127>; - l1cdrr = <24 27>; - l1edrr = <24 27>; - }; - port@6 { - port_id = <6>; - ucast_queue = <224 239>; - mcast_queue = <292 295>; - l0sp = <56 59>; - l0cdrr = <128 143>; - l0edrr = <128 143>; - l1cdrr = <28 31>; - l1edrr = <28 31>; - }; - port@7 { - port_id = <7>; - ucast_queue = <240 255>; - mcast_queue = <296 299>; - l0sp = <60 63>; - l0cdrr = <144 159>; - l0edrr = <144 159>; - l1cdrr = <32 35>; - l1edrr = <32 35>; - }; - }; - port_scheduler_config { - port@0 { - port_id = <0>; - l1scheduler { - group@0 { - sp = <0 1>; /*L0 SPs*/ - /*cpri cdrr epri edrr*/ - cfg = <0 0 0 0>; - }; - }; - l0scheduler { - group@0 { - /*unicast queues*/ - ucast_queue = <0 4 8>; - /*multicast queues*/ - mcast_queue = <256 260>; - /*sp cpricdrrepriedrr*/ - cfg = <0 0 0 0 0>; - }; - group@1 { - ucast_queue = <1 5 9>; - mcast_queue = <257 261>; - cfg = <0 1 1 1 1>; - }; - group@2 { - ucast_queue = <2 6 10>; - mcast_queue = <258 262>; - cfg = <0 2 2 2 2>; - }; - group@3 { - ucast_queue = <3 7 11>; - mcast_queue = <259 263>; - cfg = <0 3 3 3 3>; - }; - }; - }; - port@1 { - port_id = <1>; - l1scheduler { - group@0 { - sp = <36>; - cfg = <0 8 0 8>; - }; - group@1 { - sp = <37>; - cfg = <1 9 1 9>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <144>; - ucast_loop_pri = <16>; - mcast_queue = <272>; - mcast_loop_pri = <4>; - cfg = <36 0 48 0 48>; - }; - }; - }; - port@2 { - port_id = <2>; - l1scheduler { - group@0 { - sp = <40>; - cfg = <0 12 0 12>; - }; - group@1 { - sp = <41>; - cfg = <1 13 1 13>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <160>; - ucast_loop_pri = <16>; - mcast_queue = <276>; - mcast_loop_pri = <4>; - cfg = <40 0 64 0 64>; - }; - }; - }; - port@3 { - port_id = <3>; - l1scheduler { - group@0 { - sp = <44>; - cfg = <0 16 0 16>; - }; - group@1 { - sp = <45>; - cfg = <1 17 1 17>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <176>; - ucast_loop_pri = <16>; - mcast_queue = <280>; - mcast_loop_pri = <4>; - cfg = <44 0 80 0 80>; - }; - }; - }; - port@4 { - port_id = <4>; - l1scheduler { - group@0 { - sp = <48>; - cfg = <0 20 0 20>; - }; - group@1 { - sp = <49>; - cfg = <1 21 1 21>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <192>; - ucast_loop_pri = <16>; - mcast_queue = <284>; - mcast_loop_pri = <4>; - cfg = <48 0 96 0 96>; - }; - }; - }; - port@5 { - port_id = <5>; - l1scheduler { - group@0 { - sp = <52>; - cfg = <0 24 0 24>; - }; - group@1 { - sp = <53>; - cfg = <1 25 1 25>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <208>; - ucast_loop_pri = <16>; - mcast_queue = <288>; - mcast_loop_pri = <4>; - cfg = <52 0 112 0 112>; - }; - }; - }; - port@6 { - port_id = <6>; - l1scheduler { - group@0 { - sp = <56>; - cfg = <0 28 0 28>; - }; - group@1 { - sp = <57>; - cfg = <1 29 1 29>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <224>; - ucast_loop_pri = <16>; - mcast_queue = <292>; - mcast_loop_pri = <4>; - cfg = <56 0 128 0 128>; - }; - }; - }; - port@7 { - port_id = <7>; - l1scheduler { - group@0 { - sp = <60>; - cfg = <0 32 0 32>; - }; - group@1 { - sp = <61>; - cfg = <1 33 1 33>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <240>; - ucast_loop_pri = <16>; - mcast_queue = <296>; - cfg = <60 0 144 0 144>; - }; - }; - }; - }; - }; - - ess-uniphy@7a00000 { - compatible = "qcom,ess-uniphy"; - reg = <0x7a00000 0x30000>; - uniphy_access_mode = "local bus"; - }; - }; - - dp1: dp1 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <1>; - reg = <0x0 0x3a001000 0x0 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp2: dp2 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <2>; - reg = <0x0 0x3a001200 0x0 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp3: dp3 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <3>; - reg = <0x0 0x3a001400 0x0 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp4: dp4 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <4>; - reg = <0x0 0x3a001600 0x0 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp5: dp5 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <5>; - reg = <0x0 0x3a001800 0x0 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp5_syn: dp5-syn { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <5>; - reg = <0x0 0x3a003000 0x0 0x3fff>; - qcom,mactype = <1>; - local-mac-address = [000000000000]; - phy-mode = "usxgmii"; + switch: ppe@3a000000 { + compatible = "qualcomm,ipq6018-ppe"; + reg = <0x0 0x3a000000 0x0 0x900000>; + clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, + <&gcc GCC_CMN_12GPLL_SYS_CLK>, + <&gcc GCC_PORT1_MAC_CLK>, + <&gcc GCC_PORT2_MAC_CLK>, + <&gcc GCC_PORT3_MAC_CLK>, + <&gcc GCC_PORT4_MAC_CLK>, + <&gcc GCC_PORT5_MAC_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_PPE_IPE_CLK>, + <&gcc GCC_MDIO_AHB_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_PORT1_RX_CLK>, + <&gcc GCC_NSS_PORT1_TX_CLK>, + <&gcc GCC_NSS_PORT2_RX_CLK>, + <&gcc GCC_NSS_PORT2_TX_CLK>, + <&gcc GCC_NSS_PORT3_RX_CLK>, + <&gcc GCC_NSS_PORT3_TX_CLK>, + <&gcc GCC_NSS_PORT4_RX_CLK>, + <&gcc GCC_NSS_PORT4_TX_CLK>, + <&gcc GCC_NSS_PORT5_RX_CLK>, + <&gcc GCC_NSS_PORT5_TX_CLK>, + <&gcc GCC_SNOC_NSSNOC_CLK>; + clock-names = "cmn_ahb_clk", "cmn_sys_clk", + "port1_mac_clk", "port2_mac_clk", + "port3_mac_clk", "port4_mac_clk", + "port5_mac_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "nss_ppe_ipe_clk", + "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", + "gcc_nssnoc_snoc_clk", + "gcc_nss_crypto_clk", + "gcc_nss_ptp_ref_clk", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx", + "gcc_snoc_nssnoc_clk"; + assigned-clocks = <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>; + assigned-clock-rates = <300000000>, <600000000>; + resets = <&gcc GCC_PPE_FULL_RESET>, + <&gcc GCC_NSSPORT1_RESET>, + <&gcc GCC_NSSPORT2_RESET>, + <&gcc GCC_NSSPORT3_RESET>, + <&gcc GCC_NSSPORT4_RESET>, + <&gcc GCC_NSSPORT5_RESET>; + reset-names = "ppe_rst", "nss_port1_rst", + "nss_port2_rst", "nss_port3_rst", + "nss_port4_rst", "nss_port5_rst"; status = "disabled"; }; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi index 194540aac11c00..fe59cb81b3cdab 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi @@ -1,547 +1,186 @@ -// SPDX-License-Identifier: GPL-2.0-only +#include -#include - -&clocks { - bias_pll_cc_clk { +&soc { + cmn_pll_ref_clk: cmn-pll-ref-clk { compatible = "fixed-clock"; - clock-frequency = <300000000>; + clock-frequency = <48000000>; #clock-cells = <0>; }; - bias_pll_nss_noc_clk { - compatible = "fixed-clock"; - clock-frequency = <416500000>; - #clock-cells = <0>; + cmn_pll: clock-controller@9b000 { + compatible = "qcom,ipq8074-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 IPQ8074_CMN_PLL_CLK>; + assigned-clock-rates-u64 = /bits/ 64 <12000000000>; }; -}; - -&soc { - ess_instance: ess-instance { - #address-cells = <1>; - #size-cells = <1>; - num_devices = <1>; - - switch: ess-switch@3a000000 { - compatible = "qcom,ess-switch-ipq807x"; - reg = <0x3a000000 0x1000000>; - switch_access_mode = "local bus"; - switch_cpu_bmp = ; /* cpu port bitmap */ - switch_inner_bmp = ; /*inner port bitmap*/ - clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, - <&gcc GCC_CMN_12GPLL_SYS_CLK>, - <&gcc GCC_UNIPHY0_AHB_CLK>, - <&gcc GCC_UNIPHY0_SYS_CLK>, - <&gcc GCC_UNIPHY1_AHB_CLK>, - <&gcc GCC_UNIPHY1_SYS_CLK>, - <&gcc GCC_UNIPHY2_AHB_CLK>, - <&gcc GCC_UNIPHY2_SYS_CLK>, - <&gcc GCC_PORT1_MAC_CLK>, - <&gcc GCC_PORT2_MAC_CLK>, - <&gcc GCC_PORT3_MAC_CLK>, - <&gcc GCC_PORT4_MAC_CLK>, - <&gcc GCC_PORT5_MAC_CLK>, - <&gcc GCC_PORT6_MAC_CLK>, - <&gcc GCC_NSS_PPE_CLK>, - <&gcc GCC_NSS_PPE_CFG_CLK>, - <&gcc GCC_NSSNOC_PPE_CLK>, - <&gcc GCC_NSSNOC_PPE_CFG_CLK>, - <&gcc GCC_NSS_EDMA_CLK>, - <&gcc GCC_NSS_EDMA_CFG_CLK>, - <&gcc GCC_NSS_PPE_IPE_CLK>, - <&gcc GCC_NSS_PPE_BTQ_CLK>, - <&gcc GCC_MDIO_AHB_CLK>, - <&gcc GCC_NSS_NOC_CLK>, - <&gcc GCC_NSSNOC_SNOC_CLK>, - <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, - <&gcc GCC_NSS_CRYPTO_CLK>, - <&gcc GCC_NSS_IMEM_CLK>, - <&gcc GCC_NSS_PTP_REF_CLK>, - <&gcc GCC_NSS_PORT1_RX_CLK>, - <&gcc GCC_NSS_PORT1_TX_CLK>, - <&gcc GCC_NSS_PORT2_RX_CLK>, - <&gcc GCC_NSS_PORT2_TX_CLK>, - <&gcc GCC_NSS_PORT3_RX_CLK>, - <&gcc GCC_NSS_PORT3_TX_CLK>, - <&gcc GCC_NSS_PORT4_RX_CLK>, - <&gcc GCC_NSS_PORT4_TX_CLK>, - <&gcc GCC_NSS_PORT5_RX_CLK>, - <&gcc GCC_NSS_PORT5_TX_CLK>, - <&gcc GCC_NSS_PORT6_RX_CLK>, - <&gcc GCC_NSS_PORT6_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, - <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, - <&gcc GCC_UNIPHY0_PORT5_TX_CLK>, - <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, - <&gcc GCC_UNIPHY1_PORT5_TX_CLK>, - <&gcc GCC_UNIPHY2_PORT6_RX_CLK>, - <&gcc GCC_UNIPHY2_PORT6_TX_CLK>, - <&gcc NSS_PORT5_RX_CLK_SRC>, - <&gcc NSS_PORT5_TX_CLK_SRC>; - clock-names = "cmn_ahb_clk", "cmn_sys_clk", - "uniphy0_ahb_clk", "uniphy0_sys_clk", - "uniphy1_ahb_clk", "uniphy1_sys_clk", - "uniphy2_ahb_clk", "uniphy2_sys_clk", - "port1_mac_clk", "port2_mac_clk", - "port3_mac_clk", "port4_mac_clk", - "port5_mac_clk", "port6_mac_clk", - "nss_ppe_clk", "nss_ppe_cfg_clk", - "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", - "nss_edma_clk", "nss_edma_cfg_clk", - "nss_ppe_ipe_clk", "nss_ppe_btq_clk", - "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", - "gcc_nssnoc_snoc_clk", - "gcc_mem_noc_nss_axi_clk", - "gcc_nss_crypto_clk", - "gcc_nss_imem_clk", - "gcc_nss_ptp_ref_clk", - "nss_port1_rx_clk", "nss_port1_tx_clk", - "nss_port2_rx_clk", "nss_port2_tx_clk", - "nss_port3_rx_clk", "nss_port3_tx_clk", - "nss_port4_rx_clk", "nss_port4_tx_clk", - "nss_port5_rx_clk", "nss_port5_tx_clk", - "nss_port6_rx_clk", "nss_port6_tx_clk", - "uniphy0_port1_rx_clk", - "uniphy0_port1_tx_clk", - "uniphy0_port2_rx_clk", - "uniphy0_port2_tx_clk", - "uniphy0_port3_rx_clk", - "uniphy0_port3_tx_clk", - "uniphy0_port4_rx_clk", - "uniphy0_port4_tx_clk", - "uniphy0_port5_rx_clk", - "uniphy0_port5_tx_clk", - "uniphy1_port5_rx_clk", - "uniphy1_port5_tx_clk", - "uniphy2_port6_rx_clk", - "uniphy2_port6_tx_clk", - "nss_port5_rx_clk_src", - "nss_port5_tx_clk_src"; - resets = <&gcc GCC_PPE_FULL_RESET>, - <&gcc GCC_UNIPHY0_SOFT_RESET>, - <&gcc GCC_UNIPHY0_XPCS_RESET>, - <&gcc GCC_UNIPHY1_SOFT_RESET>, - <&gcc GCC_UNIPHY1_XPCS_RESET>, - <&gcc GCC_UNIPHY2_SOFT_RESET>, - <&gcc GCC_UNIPHY2_XPCS_RESET>, - <&gcc GCC_NSSPORT1_RESET>, - <&gcc GCC_NSSPORT2_RESET>, - <&gcc GCC_NSSPORT3_RESET>, - <&gcc GCC_NSSPORT4_RESET>, - <&gcc GCC_NSSPORT5_RESET>, - <&gcc GCC_NSSPORT6_RESET>; - reset-names = "ppe_rst", "uniphy0_soft_rst", - "uniphy0_xpcs_rst", "uniphy1_soft_rst", - "uniphy1_xpcs_rst", "uniphy2_soft_rst", - "uniphy2_xpcs_rst", "nss_port1_rst", - "nss_port2_rst", "nss_port3_rst", - "nss_port4_rst", "nss_port5_rst", - "nss_port6_rst"; - mdio-bus = <&mdio>; - - switch_mac_mode = ; /* MAC mode for UNIPHY instance 0 */ - switch_mac_mode1 = ; /* MAC mode for UNIPHY instance 1 */ - switch_mac_mode2 = ; /* MAC mode for UNIPHY instance 2 */ - bm_tick_mode = <0>; /* bm tick mode */ - tm_tick_mode = <0>; /* tm tick mode */ - - status = "disabled"; + uniphy0: ethernet-pcs@7a00000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x07a00000 0x10000>; + #pcs-cells = <1>; + clocks = <&gcc GCC_UNIPHY0_AHB_CLK>, + <&gcc GCC_UNIPHY0_SYS_CLK>, + <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx"; + clock-output-names = "uniphy0_gcc_tx_clk", + "uniphy0_gcc_rx_clk"; + resets = <&gcc GCC_UNIPHY0_SOFT_RESET>, + <&gcc GCC_UNIPHY0_XPCS_RESET>; + reset-names = "soft", "xpcs"; + status = "disabled"; + }; - port_scheduler_resource { - port@0 { - port_id = <0>; - ucast_queue = <0 143>; - mcast_queue = <256 271>; - l0sp = <0 35>; - l0cdrr = <0 47>; - l0edrr = <0 47>; - l1cdrr = <0 7>; - l1edrr = <0 7>; - }; - port@1 { - port_id = <1>; - ucast_queue = <144 159>; - mcast_queue = <272 275>; - l0sp = <36 39>; - l0cdrr = <48 63>; - l0edrr = <48 63>; - l1cdrr = <8 11>; - l1edrr = <8 11>; - }; - port@2 { - port_id = <2>; - ucast_queue = <160 175>; - mcast_queue = <276 279>; - l0sp = <40 43>; - l0cdrr = <64 79>; - l0edrr = <64 79>; - l1cdrr = <12 15>; - l1edrr = <12 15>; - }; - port@3 { - port_id = <3>; - ucast_queue = <176 191>; - mcast_queue = <280 283>; - l0sp = <44 47>; - l0cdrr = <80 95>; - l0edrr = <80 95>; - l1cdrr = <16 19>; - l1edrr = <16 19>; - }; - port@4 { - port_id = <4>; - ucast_queue = <192 207>; - mcast_queue = <284 287>; - l0sp = <48 51>; - l0cdrr = <96 111>; - l0edrr = <96 111>; - l1cdrr = <20 23>; - l1edrr = <20 23>; - }; - port@5 { - port_id = <5>; - ucast_queue = <208 223>; - mcast_queue = <288 291>; - l0sp = <52 55>; - l0cdrr = <112 127>; - l0edrr = <112 127>; - l1cdrr = <24 27>; - l1edrr = <24 27>; - }; - port@6 { - port_id = <6>; - ucast_queue = <224 239>; - mcast_queue = <292 295>; - l0sp = <56 59>; - l0cdrr = <128 143>; - l0edrr = <128 143>; - l1cdrr = <28 31>; - l1edrr = <28 31>; - }; - port@7 { - port_id = <7>; - ucast_queue = <240 255>; - mcast_queue = <296 299>; - l0sp = <60 63>; - l0cdrr = <144 159>; - l0edrr = <144 159>; - l1cdrr = <32 35>; - l1edrr = <32 35>; - }; - }; - port_scheduler_config { - port@0 { - port_id = <0>; - l1scheduler { - group@0 { - sp = <0 1>; /*L0 SPs*/ - /*cpri cdrr epri edrr*/ - cfg = <0 0 0 0>; - }; - }; - l0scheduler { - group@0 { - /*unicast queues*/ - ucast_queue = <0 4 8>; - /*multicast queues*/ - mcast_queue = <256 260>; - /*sp cpri cdrr epri edrr*/ - cfg = <0 0 0 0 0>; - }; - group@1 { - ucast_queue = <1 5 9>; - mcast_queue = <257 261>; - cfg = <0 1 1 1 1>; - }; - group@2 { - ucast_queue = <2 6 10>; - mcast_queue = <258 262>; - cfg = <0 2 2 2 2>; - }; - group@3 { - ucast_queue = <3 7 11>; - mcast_queue = <259 263>; - cfg = <0 3 3 3 3>; - }; - }; - }; - port@1 { - port_id = <1>; - l1scheduler { - group@0 { - sp = <36>; - cfg = <0 8 0 8>; - }; - group@1 { - sp = <37>; - cfg = <1 9 1 9>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <144>; - ucast_loop_pri = <16>; - mcast_queue = <272>; - mcast_loop_pri = <4>; - cfg = <36 0 48 0 48>; - }; - }; - }; - port@2 { - port_id = <2>; - l1scheduler { - group@0 { - sp = <40>; - cfg = <0 12 0 12>; - }; - group@1 { - sp = <41>; - cfg = <1 13 1 13>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <160>; - ucast_loop_pri = <16>; - mcast_queue = <276>; - mcast_loop_pri = <4>; - cfg = <40 0 64 0 64>; - }; - }; - }; - port@3 { - port_id = <3>; - l1scheduler { - group@0 { - sp = <44>; - cfg = <0 16 0 16>; - }; - group@1 { - sp = <45>; - cfg = <1 17 1 17>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <176>; - ucast_loop_pri = <16>; - mcast_queue = <280>; - mcast_loop_pri = <4>; - cfg = <44 0 80 0 80>; - }; - }; - }; - port@4 { - port_id = <4>; - l1scheduler { - group@0 { - sp = <48>; - cfg = <0 20 0 20>; - }; - group@1 { - sp = <49>; - cfg = <1 21 1 21>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <192>; - ucast_loop_pri = <16>; - mcast_queue = <284>; - mcast_loop_pri = <4>; - cfg = <48 0 96 0 96>; - }; - }; - }; - port@5 { - port_id = <5>; - l1scheduler { - group@0 { - sp = <52>; - cfg = <0 24 0 24>; - }; - group@1 { - sp = <53>; - cfg = <1 25 1 25>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <208>; - ucast_loop_pri = <16>; - mcast_queue = <288>; - mcast_loop_pri = <4>; - cfg = <52 0 112 0 112>; - }; - }; - }; - port@6 { - port_id = <6>; - l1scheduler { - group@0 { - sp = <56>; - cfg = <0 28 0 28>; - }; - group@1 { - sp = <57>; - cfg = <1 29 1 29>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <224>; - ucast_loop_pri = <16>; - mcast_queue = <292>; - mcast_loop_pri = <4>; - cfg = <56 0 128 0 128>; - }; - }; - }; - port@7 { - port_id = <7>; - l1scheduler { - group@0 { - sp = <60>; - cfg = <0 32 0 32>; - }; - group@1 { - sp = <61>; - cfg = <1 33 1 33>; - }; - }; - l0scheduler { - group@0 { - ucast_queue = <240>; - ucast_loop_pri = <16>; - mcast_queue = <296>; - cfg = <60 0 144 0 144>; - }; - }; - }; - }; - }; + uniphy1: ethernet-pcs@7a10000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x07a10000 0x10000>; + #pcs-cells = <1>; + clocks = <&gcc GCC_UNIPHY1_AHB_CLK>, + <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port5_rx", "port5_tx"; + clock-output-names = "uniphy1_gcc_tx_clk", + "uniphy1_gcc_rx_clk"; + resets = <&gcc GCC_UNIPHY1_SOFT_RESET>, + <&gcc GCC_UNIPHY1_XPCS_RESET>; + reset-names = "soft", "xpcs"; + status = "disabled"; }; - ess-uniphy@7a00000 { - compatible = "qcom,ess-uniphy"; - reg = <0x7a00000 0x30000>; - uniphy_access_mode = "local bus"; + uniphy2: ethernet-pcs@7a20000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x07a20000 0x10000>; + #pcs-cells = <1>; + clocks = <&gcc GCC_UNIPHY2_AHB_CLK>, + <&gcc GCC_UNIPHY2_SYS_CLK>, + <&gcc GCC_UNIPHY2_PORT6_RX_CLK>, + <&gcc GCC_UNIPHY2_PORT6_TX_CLK>; + clock-names = "ahb", "sys", + "port6_rx", "port6_tx"; + clock-output-names = "uniphy2_gcc_tx_clk", + "uniphy2_gcc_rx_clk"; + resets = <&gcc GCC_UNIPHY2_SOFT_RESET>, + <&gcc GCC_UNIPHY2_XPCS_RESET>; + reset-names = "soft", "xpcs"; + status = "disabled"; }; edma: edma@3ab00000 { - compatible = "qcom,edma"; - reg = <0x3ab00000 0x76900>; - reg-names = "edma-reg-base"; - qcom,txdesc-ring-start = <23>; - qcom,txdesc-rings = <1>; - qcom,txcmpl-ring-start = <7>; - qcom,txcmpl-rings = <1>; - qcom,rxfill-ring-start = <7>; - qcom,rxfill-rings = <1>; - qcom,rxdesc-ring-start = <15>; - qcom,rxdesc-rings = <1>; + compatible = "qualcomm,ipq8074-edma"; + reg = <0x3ab00000 0xb0000>; interrupts = , , , ; resets = <&gcc GCC_EDMA_HW_RESET>; reset-names = "edma_rst"; + clocks = <&gcc GCC_NSS_EDMA_CLK>, + <&gcc GCC_NSS_EDMA_CFG_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>; + clock-names = "nss_edma_clk", "nss_edma_cfg_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "gcc_nss_noc_clk", "gcc_nssnoc_snoc_clk", + "gcc_mem_noc_nss_axi_clk"; status = "disabled"; }; - dp1: dp1@3a001000 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <1>; - reg = <0x3a001000 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp2: dp2@3a001200 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <2>; - reg = <0x3a001200 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp3: dp3@3a001400 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <3>; - reg = <0x3a001400 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp4: dp4@3a001600 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <4>; - reg = <0x3a001600 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp5: dp5@3a001800 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <5>; - reg = <0x3a001800 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "psgmii"; - status = "disabled"; - }; - - dp6: dp6@3a001a00 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <6>; - reg = <0x3a001a00 0x200>; - qcom,mactype = <0>; - local-mac-address = [000000000000]; - phy-mode = "sgmii"; - status = "disabled"; - }; - - dp5_syn: dp5-syn@3a003000 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <5>; - reg = <0x3a003000 0x3fff>; - qcom,mactype = <1>; - local-mac-address = [000000000000]; - phy-mode = "sgmii"; - status = "disabled"; - }; - - dp6_syn: dp6-syn@3a007000 { - device_type = "network"; - compatible = "qcom,nss-dp"; - qcom,id = <6>; - reg = <0x3a007000 0x3fff>; - qcom,mactype = <1>; - local-mac-address = [000000000000]; - phy-mode = "sgmii"; + switch: ppe@3a000000 { + compatible = "qualcomm,ipq8074-ppe"; + reg = <0x3a000000 0x900000>; + clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, + <&gcc GCC_CMN_12GPLL_SYS_CLK>, + <&gcc GCC_PORT1_MAC_CLK>, + <&gcc GCC_PORT2_MAC_CLK>, + <&gcc GCC_PORT3_MAC_CLK>, + <&gcc GCC_PORT4_MAC_CLK>, + <&gcc GCC_PORT5_MAC_CLK>, + <&gcc GCC_PORT6_MAC_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_PPE_IPE_CLK>, + <&gcc GCC_NSS_PPE_BTQ_CLK>, + <&gcc GCC_MDIO_AHB_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_PORT1_RX_CLK>, + <&gcc GCC_NSS_PORT1_TX_CLK>, + <&gcc GCC_NSS_PORT2_RX_CLK>, + <&gcc GCC_NSS_PORT2_TX_CLK>, + <&gcc GCC_NSS_PORT3_RX_CLK>, + <&gcc GCC_NSS_PORT3_TX_CLK>, + <&gcc GCC_NSS_PORT4_RX_CLK>, + <&gcc GCC_NSS_PORT4_TX_CLK>, + <&gcc GCC_NSS_PORT5_RX_CLK>, + <&gcc GCC_NSS_PORT5_TX_CLK>, + <&gcc GCC_NSS_PORT6_RX_CLK>, + <&gcc GCC_NSS_PORT6_TX_CLK>; + clock-names = "cmn_ahb_clk", "cmn_sys_clk", + "port1_mac_clk", "port2_mac_clk", + "port3_mac_clk", "port4_mac_clk", + "port5_mac_clk", "port6_mac_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "nss_ppe_ipe_clk", "nss_ppe_btq_clk", + "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", + "gcc_nssnoc_snoc_clk", + "gcc_mem_noc_nss_axi_clk", + "gcc_nss_crypto_clk", + "gcc_nss_imem_clk", + "gcc_nss_ptp_ref_clk", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx", + "port6_rx", "port6_tx"; + assigned-clocks = <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSS_IMEM_CLK>; + assigned-clock-rates = <300000000>, <600000000>, <400000000>; + resets = <&gcc GCC_PPE_FULL_RESET>, + <&gcc GCC_NSSPORT1_RESET>, + <&gcc GCC_NSSPORT2_RESET>, + <&gcc GCC_NSSPORT3_RESET>, + <&gcc GCC_NSSPORT4_RESET>, + <&gcc GCC_NSSPORT5_RESET>, + <&gcc GCC_NSSPORT6_RESET>; + reset-names = "ppe_rst", "nss_port1_rst", + "nss_port2_rst", "nss_port3_rst", + "nss_port4_rst", "nss_port5_rst", + "nss_port6_rst"; status = "disabled"; }; }; diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.c new file mode 100644 index 00000000000000..f3dc7d7afaafbd --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.c @@ -0,0 +1,1255 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qca_edma.h" + +static void edma_irq_disable_all(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + int i; + + for (i = 0; i <= soc->txdesc_ring; i++) + regmap_write(priv->regmap, + EDMA_REG_TX_INT_MASK(soc->tx_int_base, i), + 0); + + for (i = 0; i <= soc->rxfill_ring; i++) + regmap_write(priv->regmap, EDMA_REG_RXFILL_INT_MASK(i), 0); + + for (i = 0; i <= soc->rxdesc_ring; i++) { + regmap_write(priv->regmap, EDMA_REG_RXDESC_INT_MASK(i), 0); + regmap_write(priv->regmap, EDMA_REG_RX_INT_CTRL(i), 0); + } +} + +static void edma_tx_irq_mask(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_TX_INT_MASK(soc->tx_int_base, soc->txcmpl_ring), + 0); +} + +static void edma_tx_irq_unmask(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_TX_INT_MASK(soc->tx_int_base, soc->txcmpl_ring), + EDMA_TX_INT_MASK); +} + +static void edma_rx_irq_mask(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_RXFILL_INT_MASK(soc->rxfill_ring), 0); + regmap_write(priv->regmap, + EDMA_REG_RXDESC_INT_MASK(soc->rxdesc_ring), 0); +} + +static void edma_rx_irq_unmask(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_RXFILL_INT_MASK(soc->rxfill_ring), + EDMA_RXFILL_INT_MASK); + regmap_write(priv->regmap, + EDMA_REG_RXDESC_INT_MASK(soc->rxdesc_ring), + EDMA_RXDESC_INT_MASK_PKT_INT); +} + +static irqreturn_t edma_tx_irq_handle(int irq, void *ctx) +{ + const struct edma_soc_data *soc; + struct edma_priv *priv = ctx; + u32 val; + + soc = priv->soc; + + regmap_read(priv->regmap, + EDMA_REG_TX_INT_STAT(soc->tx_int_base, + soc->txcmpl_ring), &val); + if (!val) + return IRQ_NONE; + + edma_tx_irq_mask(priv); + + if (likely(napi_schedule_prep(&priv->tx_napi))) + __napi_schedule(&priv->tx_napi); + + return IRQ_HANDLED; +} + +static irqreturn_t edma_rx_irq_handle(int irq, void *ctx) +{ + const struct edma_soc_data *soc; + struct edma_priv *priv = ctx; + u32 val, status = 0; + + soc = priv->soc; + + regmap_read(priv->regmap, + EDMA_REG_RXDESC_INT_STAT(soc->rxdesc_ring), + &val); + status |= val; + regmap_read(priv->regmap, + EDMA_REG_RXFILL_INT_STAT(soc->rxfill_ring), + &val); + status |= val; + + if (!status) + return IRQ_NONE; + + edma_rx_irq_mask(priv); + + if (likely(napi_schedule_prep(&priv->rx_napi))) + __napi_schedule(&priv->rx_napi); + + return IRQ_HANDLED; +} + +static irqreturn_t edma_misc_irq_handle(int irq, void *ctx) +{ + struct edma_priv *priv = ctx; + u32 val; + + regmap_read(priv->regmap, EDMA_REG_MISC_INT_STAT, &val); + if (!val) + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static int edma_ring_alloc(struct edma_priv *priv, struct edma_ring *ring, int count, + int desc_size) +{ + struct device *dev = &priv->pdev->dev; + + ring->count = count; + ring->desc = dma_alloc_coherent(dev, count * desc_size, &ring->dma, + GFP_KERNEL); + if (!ring->desc) + return -ENOMEM; + + return 0; +} + +static int edma_tx_ring_alloc(struct edma_priv *priv, struct edma_ring *ring, + int count, int desc_size) +{ + int ret; + + ret = edma_ring_alloc(priv, ring, count, desc_size); + if (ret) + return ret; + + ring->skb_store = kcalloc(count, sizeof(struct sk_buff *), GFP_KERNEL); + if (!ring->skb_store) { + dma_free_coherent(&priv->pdev->dev, count * desc_size, + ring->desc, ring->dma); + ring->desc = NULL; + return -ENOMEM; + } + + return 0; +} + +static void edma_ring_free(struct edma_priv *priv, struct edma_ring *ring, + int desc_size) +{ + if (ring->desc) { + dma_free_coherent(&priv->pdev->dev, ring->count * desc_size, + ring->desc, ring->dma); + ring->desc = NULL; + } +} + +static void edma_tx_ring_free(struct edma_priv *priv, struct edma_ring *ring, + int desc_size) +{ + int i; + + if (ring->skb_store) { + for (i = 0; i < ring->count; i++) + dev_kfree_skb_any(ring->skb_store[i]); + kfree(ring->skb_store); + ring->skb_store = NULL; + } + + edma_ring_free(priv, ring, desc_size); +} + +static int edma_rx_fill(struct edma_priv *priv, struct edma_ring *rxfill_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct edma_rxfill_desc *rxfill_desc; + u16 prod, cons, next; + struct page *page; + u16 filled = 0; + dma_addr_t dma; + u32 val; + + regmap_read(priv->regmap, EDMA_REG_RXFILL_PROD_IDX(soc->rxfill_ring), + &val); + prod = val & EDMA_RXFILL_PROD_IDX_MASK & (rxfill_ring->count - 1); + + regmap_read(priv->regmap, EDMA_REG_RXFILL_CONS_IDX(soc->rxfill_ring), + &val); + cons = val & EDMA_RXFILL_CONS_IDX_MASK & (rxfill_ring->count - 1); + + while (1) { + next = prod + 1; + if (next == rxfill_ring->count) + next = 0; + + if (next == cons) + break; + + page = page_pool_dev_alloc_pages(priv->page_pool); + if (unlikely(!page)) + break; + + rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, prod); + + dma = page_pool_get_dma_addr(page) + NET_SKB_PAD; + rxfill_desc->buffer_addr = cpu_to_le32(dma); + rxfill_desc->word1 = cpu_to_le32(EDMA_RX_BUFFER_SIZE & + EDMA_RXFILL_BUF_SIZE_MASK); + + filled++; + prod = next; + } + + if (filled) { + wmb(); + regmap_write(priv->regmap, + EDMA_REG_RXFILL_PROD_IDX(soc->rxfill_ring), + prod & EDMA_RXFILL_PROD_IDX_MASK); + } + + return filled; +} + +static u32 edma_clean_tx(struct edma_priv *priv, struct edma_ring *txcmpl_ring, + int budget) +{ + const struct edma_soc_data *soc = priv->soc; + struct platform_device *pdev = priv->pdev; + struct edma_txcmpl *txcmpl; + struct edma_txdesc *txdesc; + u32 cleaned = 0, bytes = 0; + u16 prod, cons; + struct sk_buff *skb; + u32 val, len; + int idx; + + regmap_read(priv->regmap, + EDMA_REG_TXCMPL_PROD_IDX(soc->txcmpl_base, + soc->txcmpl_ring), + &val); + prod = val & EDMA_TXCMPL_PROD_IDX_MASK; + + regmap_read(priv->regmap, + EDMA_REG_TXCMPL_CONS_IDX(soc->txcmpl_base, + soc->txcmpl_ring), + &val); + cons = val & EDMA_TXCMPL_CONS_IDX_MASK; + + while (cons != prod && cleaned < budget) { + txcmpl = EDMA_TXCMPL_DESC(txcmpl_ring, cons); + + idx = txcmpl->buffer_addr; + skb = priv->txdesc_ring.skb_store[idx]; + priv->txdesc_ring.skb_store[idx] = NULL; + + if (unlikely(!skb)) { + dev_warn(&pdev->dev, + "invalid skb: cons:%u prod:%u status %x\n", + cons, prod, txcmpl->status); + goto next; + } + + txdesc = EDMA_TXDESC_DESC(&priv->txdesc_ring, idx); + len = skb_headlen(skb); + + dma_unmap_single(&pdev->dev, + le32_to_cpu(txdesc->buffer_addr), + len, DMA_TO_DEVICE); + bytes += len - EDMA_TX_PREHDR_SIZE; + napi_consume_skb(skb, budget); + +next: + if (++cons == txcmpl_ring->count) + cons = 0; + + cleaned++; + } + + if (cleaned == 0) + return 0; + + netdev_tx_completed_queue(netdev_get_tx_queue(priv->netdev, 0), cleaned, + bytes); + + /* Ensure all TX completions are processed before updating cons idx */ + wmb(); + regmap_write(priv->regmap, + EDMA_REG_TXCMPL_CONS_IDX(soc->txcmpl_base, + soc->txcmpl_ring), + cons); + + return cleaned; +} + +static u32 edma_clean_rx(struct edma_priv *priv, int budget, + struct edma_ring *rxdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct platform_device *pdev = priv->pdev; + struct dsa_oob_tag_info *tag_info; + struct edma_rx_preheader *rxph; + struct edma_rxdesc *rxdesc; + struct sk_buff *skb; + u16 prod, cons; + struct page *page; + u32 done = 0; + u32 src_port; + int pkt_len; + u32 val; + + regmap_read(priv->regmap, EDMA_REG_RXDESC_PROD_IDX(soc->rxdesc_ring), + &val); + prod = val & EDMA_RXDESC_PROD_IDX_MASK; + + regmap_read(priv->regmap, EDMA_REG_RXDESC_CONS_IDX(soc->rxdesc_ring), + &val); + cons = val & EDMA_RXDESC_CONS_IDX_MASK; + + while (cons != prod && done < budget) { + rxdesc = EDMA_RXDESC_DESC(rxdesc_ring, cons); + + rxph = phys_to_virt(rxdesc->buffer_addr); + page = virt_to_head_page(rxph); + + pkt_len = rxdesc->status & EDMA_RXDESC_PACKET_LEN_MASK; + + page_pool_dma_sync_for_cpu(priv->page_pool, page, 0, + EDMA_RX_PREHDR_SIZE + pkt_len); + + if (EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) != + EDMA_PREHDR_DSTINFO_PORTID_IND) { + dev_warn( + &pdev->dev, + "rx drop: src_info_type=0x%x src_info=0x%04x dst_info=0x%04x\n", + EDMA_RXPH_SRC_INFO_TYPE_GET(rxph), + rxph->src_info, rxph->dst_info); + page_pool_put_full_page(priv->page_pool, page, true); + goto next; + } + + src_port = rxph->src_info & EDMA_SRC_PORT_MASK; + + skb = napi_build_skb(page_address(page), PAGE_SIZE); + if (unlikely(!skb)) { + page_pool_put_full_page(priv->page_pool, page, true); + goto next; + } + + skb_mark_for_recycle(skb); + skb_reserve(skb, NET_SKB_PAD + EDMA_RX_PREHDR_SIZE); + skb_put(skb, pkt_len); + + skb->protocol = eth_type_trans(skb, priv->netdev); + + tag_info = skb_ext_add(skb, SKB_EXT_DSA_OOB); + if (unlikely(!tag_info)) { + dev_kfree_skb_any(skb); + goto next; + } + tag_info->port = src_port; + + dev_sw_netstats_rx_add(priv->netdev, pkt_len); + napi_gro_receive(&priv->rx_napi, skb); + +next: + if (++cons == rxdesc_ring->count) + cons = 0; + + done++; + } + + edma_rx_fill(priv, &priv->rxfill_ring); + + wmb(); + regmap_write(priv->regmap, + EDMA_REG_RXDESC_CONS_IDX(soc->rxdesc_ring), + cons); + return done; +} + +static int edma_tx_napi(struct napi_struct *napi, int budget) +{ + struct edma_priv *priv = container_of(napi, struct edma_priv, tx_napi); + int work = edma_clean_tx(priv, &priv->txcmpl_ring, budget); + const struct edma_soc_data *soc = priv->soc; + u32 val; + + if (priv->netdev && netif_queue_stopped(priv->netdev) && + netif_carrier_ok(priv->netdev)) { + u16 prod, cons, free; + + regmap_read(priv->regmap, + EDMA_REG_TXDESC_PROD_IDX(soc->txdesc_ring), &val); + prod = val & EDMA_TXDESC_PROD_IDX_MASK; + regmap_read(priv->regmap, + EDMA_REG_TXDESC_CONS_IDX(soc->txdesc_ring), &val); + cons = val & EDMA_TXDESC_CONS_IDX_MASK; + free = (cons - prod - 1) & (priv->txdesc_ring.count - 1); + + if (free > EDMA_TX_RING_THRESH) + netif_wake_queue(priv->netdev); + } + + if (work < budget) { + regmap_read(priv->regmap, + EDMA_REG_TX_INT_STAT(soc->tx_int_base, + soc->txcmpl_ring), + &val); + if (val) + return budget; + + if (napi_complete_done(napi, work)) + edma_tx_irq_unmask(priv); + } + + return work; +} + +static int edma_rx_napi(struct napi_struct *napi, int budget) +{ + struct edma_priv *priv = container_of(napi, struct edma_priv, rx_napi); + const struct edma_soc_data *soc = priv->soc; + int done; + u16 prod, cons; + + done = edma_clean_rx(priv, budget, &priv->rxdesc_ring); + + if (done < budget) { + u32 val; + + regmap_read(priv->regmap, + EDMA_REG_RXDESC_INT_STAT(soc->rxdesc_ring), + &val); + prod = val; + regmap_read(priv->regmap, + EDMA_REG_RXFILL_INT_STAT(soc->rxfill_ring), + &val); + cons = val; + if (prod || cons) + return budget; + + regmap_read(priv->regmap, + EDMA_REG_RXFILL_PROD_IDX(soc->rxfill_ring), + &val); + prod = val & (priv->rxfill_ring.count - 1); + regmap_read(priv->regmap, + EDMA_REG_RXFILL_CONS_IDX(soc->rxfill_ring), + &val); + cons = val & (priv->rxfill_ring.count - 1); + if (prod == cons) { + dev_warn_ratelimited(&priv->pdev->dev, + "RXFILL ring starved\n"); + edma_rx_fill(priv, &priv->rxfill_ring); + return budget; + } + + if (napi_complete_done(napi, done)) + edma_rx_irq_unmask(priv); + } + + return done; +} + +static netdev_tx_t edma_ring_xmit(struct edma_priv *priv, struct net_device *netdev, + struct sk_buff *skb, + struct edma_ring *txdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct edma_tx_preheader *txph; + struct dsa_oob_tag_info *tag_info; + struct edma_txdesc *txdesc; + u16 prod, cons, next; + u16 buf_len, dst_info; + dma_addr_t dma; + u32 val, idx; + + spin_lock_bh(&priv->tx_lock); + + regmap_read(priv->regmap, + EDMA_REG_TXDESC_PROD_IDX(soc->txdesc_ring), + &val); + prod = val & EDMA_TXDESC_PROD_IDX_MASK; + + regmap_read(priv->regmap, + EDMA_REG_TXDESC_CONS_IDX(soc->txdesc_ring), + &val); + cons = val & EDMA_TXDESC_CONS_IDX_MASK; + + next = (prod + 1) & (txdesc_ring->count - 1); + + if (next == cons) { + spin_unlock_bh(&priv->tx_lock); + return NETDEV_TX_BUSY; + } + + buf_len = skb_headlen(skb); + + tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB); + if (tag_info) + dst_info = (EDMA_DST_PORT_TYPE << 8) | + (tag_info->port & EDMA_DST_PORT_ID_MASK); + else + dst_info = 0; + + txph = (struct edma_tx_preheader *)skb_push(skb, EDMA_TX_PREHDR_SIZE); + memset((void *)txph, 0, EDMA_TX_PREHDR_SIZE); + + txph->dst_info = dst_info; + + idx = prod & (txdesc_ring->count - 1); + if (unlikely(txdesc_ring->skb_store[idx] != NULL)) { + spin_unlock_bh(&priv->tx_lock); + return NETDEV_TX_BUSY; + } + + txdesc_ring->skb_store[idx] = skb; + txph->opaque = idx; + + txdesc = EDMA_TXDESC_DESC(txdesc_ring, prod); + + dma = dma_map_single(&priv->pdev->dev, skb->data, + buf_len + EDMA_TX_PREHDR_SIZE, DMA_TO_DEVICE); + if (dma_mapping_error(&priv->pdev->dev, dma)) { + dev_kfree_skb_any(skb); + txdesc_ring->skb_store[idx] = NULL; + spin_unlock_bh(&priv->tx_lock); + return NETDEV_TX_OK; + } + txdesc->buffer_addr = cpu_to_le32(dma); + + txdesc->word1 = (1 << EDMA_TXDESC_PREHEADER_SHIFT) | + ((EDMA_TX_PREHDR_SIZE & EDMA_TXDESC_DATA_OFFSET_MASK) + << EDMA_TXDESC_DATA_OFFSET_SHIFT) | + (buf_len & EDMA_TXDESC_DATA_LENGTH_MASK); + + prod = (prod + 1) & (txdesc_ring->count - 1); + + dev_sw_netstats_tx_add(netdev, 1, buf_len); + netdev_tx_sent_queue(netdev_get_tx_queue(netdev, 0), buf_len); + + /* Ensure descriptor writes are visible before updating prod idx */ + wmb(); + regmap_write(priv->regmap, + EDMA_REG_TXDESC_PROD_IDX(soc->txdesc_ring), + prod & EDMA_TXDESC_PROD_IDX_MASK); + + if (((cons - prod - 1) & (txdesc_ring->count - 1)) < + EDMA_TX_RING_THRESH) + netif_stop_queue(netdev); + + spin_unlock_bh(&priv->tx_lock); + return NETDEV_TX_OK; +} + +static void edma_rxfill_drain(struct edma_priv *priv, struct edma_ring *rxfill_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct edma_rxfill_desc *rxfill_desc; + u16 cons, prod; + dma_addr_t dma; + struct page *page; + u32 val; + + regmap_read(priv->regmap, + EDMA_REG_RXFILL_PROD_IDX(soc->rxfill_ring), + &val); + prod = val & EDMA_RXFILL_PROD_IDX_MASK & (rxfill_ring->count - 1); + + regmap_read(priv->regmap, + EDMA_REG_RXFILL_CONS_IDX(soc->rxfill_ring), + &val); + cons = val & EDMA_RXFILL_CONS_IDX_MASK & (rxfill_ring->count - 1); + + while (prod != cons) { + rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, cons); + dma = le32_to_cpu(rxfill_desc->buffer_addr); + page = virt_to_head_page(phys_to_virt(dma)); + page_pool_put_full_page(priv->page_pool, page, false); + + if (++cons == rxfill_ring->count) + cons = 0; + } +} + +static void edma_rxdesc_drain(struct edma_priv *priv, struct edma_ring *rxdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct edma_rxdesc *rxdesc; + struct page *page; + u16 prod, cons; + u32 val; + + regmap_read(priv->regmap, + EDMA_REG_RXDESC_CONS_IDX(soc->rxdesc_ring), + &val); + cons = val & EDMA_RXDESC_CONS_IDX_MASK; + + regmap_read(priv->regmap, + EDMA_REG_RXDESC_PROD_IDX(soc->rxdesc_ring), + &val); + prod = val & EDMA_RXDESC_PROD_IDX_MASK; + + while (cons != prod) { + rxdesc = EDMA_RXDESC_DESC(rxdesc_ring, cons); + page = virt_to_head_page(phys_to_virt(rxdesc->buffer_addr)); + page_pool_put_full_page(priv->page_pool, page, false); + + if (++cons == rxdesc_ring->count) + cons = 0; + } + + regmap_write(priv->regmap, + EDMA_REG_RXDESC_CONS_IDX(soc->rxdesc_ring), + cons); +} + +static void edma_txdesc_drain(struct edma_priv *priv, struct edma_ring *txdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + struct platform_device *pdev = priv->pdev; + struct edma_txdesc *txdesc; + struct sk_buff *skb; + u16 prod, cons; + size_t buf_len; + u32 val; + + regmap_read(priv->regmap, + EDMA_REG_TXDESC_PROD_IDX(soc->txdesc_ring), + &val); + prod = val & EDMA_TXDESC_PROD_IDX_MASK; + + regmap_read(priv->regmap, + EDMA_REG_TXDESC_CONS_IDX(soc->txdesc_ring), + &val); + cons = val & EDMA_TXDESC_CONS_IDX_MASK; + + while (cons != prod) { + txdesc = EDMA_TXDESC_DESC(txdesc_ring, cons); + + skb = txdesc_ring->skb_store[cons]; + txdesc_ring->skb_store[cons] = NULL; + + if (!skb) + goto next; + + buf_len = txdesc->word1 & EDMA_TXDESC_DATA_LENGTH_MASK; + + dma_unmap_single(&pdev->dev, + le32_to_cpu(txdesc->buffer_addr), + buf_len + EDMA_TX_PREHDR_SIZE, DMA_TO_DEVICE); + + dev_kfree_skb_any(skb); +next: + if (++cons == txdesc_ring->count) + cons = 0; + } +} + +static int edma_rings_alloc(struct edma_priv *priv) +{ + int ret; + + ret = edma_tx_ring_alloc(priv, &priv->txdesc_ring, EDMA_TX_RING_SIZE, + sizeof(struct edma_txdesc)); + if (ret) + return ret; + + ret = edma_ring_alloc(priv, &priv->txcmpl_ring, EDMA_TX_RING_SIZE, + sizeof(struct edma_txcmpl)); + if (ret) + goto err_txcmpl; + + ret = edma_ring_alloc(priv, &priv->rxfill_ring, EDMA_RX_RING_SIZE, + sizeof(struct edma_rxfill_desc)); + if (ret) + goto err_rxfill; + + ret = edma_ring_alloc(priv, &priv->rxdesc_ring, EDMA_RX_RING_SIZE, + sizeof(struct edma_rxdesc)); + if (ret) + goto err_rxdesc; + + return 0; + +err_rxdesc: + edma_ring_free(priv, &priv->rxfill_ring, + sizeof(struct edma_rxfill_desc)); +err_rxfill: + edma_ring_free(priv, &priv->txcmpl_ring, sizeof(struct edma_txcmpl)); +err_txcmpl: + edma_tx_ring_free(priv, &priv->txdesc_ring, sizeof(struct edma_txdesc)); + return ret; +} + +static void edma_rings_drain(struct edma_priv *priv) +{ + edma_txdesc_drain(priv, &priv->txdesc_ring); + edma_clean_tx(priv, &priv->txcmpl_ring, INT_MAX); + edma_rxfill_drain(priv, &priv->rxfill_ring); + edma_rxdesc_drain(priv, &priv->rxdesc_ring); + + edma_tx_ring_free(priv, &priv->txdesc_ring, sizeof(struct edma_txdesc)); + edma_ring_free(priv, &priv->txcmpl_ring, sizeof(struct edma_txcmpl)); + edma_ring_free(priv, &priv->rxfill_ring, + sizeof(struct edma_rxfill_desc)); + edma_ring_free(priv, &priv->rxdesc_ring, sizeof(struct edma_rxdesc)); +} + +static void edma_configure_txdesc_ring(struct edma_priv *priv, + struct edma_ring *txdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + u32 val; + + regmap_write(priv->regmap, EDMA_REG_TXDESC_BA(soc->txdesc_ring), + (u32)txdesc_ring->dma); + + regmap_write(priv->regmap, + EDMA_REG_TXDESC_RING_SIZE(soc->txdesc_ring), + txdesc_ring->count & EDMA_TXDESC_RING_SIZE_MASK); + + regmap_read(priv->regmap, EDMA_REG_TXDESC_CONS_IDX(soc->txdesc_ring), + &val); + val &= ~EDMA_TXDESC_CONS_IDX_MASK; + + regmap_update_bits(priv->regmap, + EDMA_REG_TXDESC_PROD_IDX(soc->txdesc_ring), + EDMA_TXDESC_PROD_IDX_MASK, val); +} + +static void edma_configure_txcmpl_ring(struct edma_priv *priv, + struct edma_ring *txcmpl_ring) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_TXCMPL_BA(soc->txcmpl_base, soc->txcmpl_ring), + (u32)txcmpl_ring->dma); + regmap_write(priv->regmap, + EDMA_REG_TXCMPL_RING_SIZE(soc->txcmpl_base, + soc->txcmpl_ring), + txcmpl_ring->count & EDMA_TXDESC_RING_SIZE_MASK); + + regmap_write(priv->regmap, + EDMA_REG_TXCMPL_CTRL(soc->txcmpl_base, + soc->txcmpl_ring), + EDMA_TXCMPL_RETMODE_OPAQUE); + + regmap_write(priv->regmap, + EDMA_REG_TX_MOD_TIMER(soc->tx_int_base, + soc->txcmpl_ring), + EDMA_TX_MOD_TIMER); + + regmap_write(priv->regmap, + EDMA_REG_TX_INT_CTRL(soc->tx_int_base, + soc->txcmpl_ring), + 0x2); +} + +static void edma_configure_rxdesc_ring(struct edma_priv *priv, + struct edma_ring *rxdesc_ring) +{ + const struct edma_soc_data *soc = priv->soc; + u32 val; + + regmap_write(priv->regmap, + EDMA_REG_RXDESC_BA(soc->rxdesc_ring), + (u32)rxdesc_ring->dma); + + val = rxdesc_ring->count & EDMA_RXDESC_RING_SIZE_MASK; + val |= (EDMA_RX_PREHDR_SIZE & EDMA_RXDESC_PL_OFFSET_MASK) + << EDMA_RXDESC_PL_OFFSET_SHIFT; + regmap_write(priv->regmap, + EDMA_REG_RXDESC_RING_SIZE(soc->rxdesc_ring), + val); + + regmap_write(priv->regmap, + EDMA_REG_RX_MOD_TIMER(soc->rxdesc_ring), + EDMA_RX_MOD_TIMER_INIT); + + regmap_write(priv->regmap, + EDMA_REG_RX_INT_CTRL(soc->rxdesc_ring), + 0x2); +} + +static void edma_configure_rxfill_ring(struct edma_priv *priv, + struct edma_ring *rxfill_ring) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_write(priv->regmap, + EDMA_REG_RXFILL_BA(soc->rxfill_ring), + (u32)rxfill_ring->dma); + + regmap_write(priv->regmap, + EDMA_REG_RXFILL_RING_SIZE(soc->rxfill_ring), + rxfill_ring->count & EDMA_RXFILL_RING_SIZE_MASK); + + edma_rx_fill(priv, rxfill_ring); +} + +static void edma_configure_rings(struct edma_priv *priv) +{ + edma_configure_txdesc_ring(priv, &priv->txdesc_ring); + edma_configure_txcmpl_ring(priv, &priv->txcmpl_ring); + edma_configure_rxfill_ring(priv, &priv->rxfill_ring); + edma_configure_rxdesc_ring(priv, &priv->rxdesc_ring); +} + +static void edma_rings_disable(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + int i; + + for (i = 0; i <= soc->rxdesc_ring; i++) + regmap_clear_bits(priv->regmap, EDMA_REG_RXDESC_CTRL(i), + EDMA_RXDESC_RX_EN); + + for (i = 0; i <= soc->rxfill_ring; i++) + regmap_clear_bits(priv->regmap, EDMA_REG_RXFILL_RING_EN(i), + EDMA_RXFILL_RING_EN); + + for (i = 0; i <= soc->txdesc_ring; i++) + regmap_clear_bits(priv->regmap, EDMA_REG_TXDESC_CTRL(i), + EDMA_TXDESC_TX_EN); +} + +static void edma_rings_enable(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + + regmap_set_bits(priv->regmap, + EDMA_REG_RXDESC_CTRL(soc->rxdesc_ring), + EDMA_RXDESC_RX_EN); + + regmap_set_bits(priv->regmap, + EDMA_REG_RXFILL_RING_EN(soc->rxfill_ring), + EDMA_RXFILL_RING_EN); + + regmap_set_bits(priv->regmap, + EDMA_REG_TXDESC_CTRL(soc->txdesc_ring), + EDMA_TXDESC_TX_EN); +} + +static void edma_hw_stop(struct edma_priv *priv) +{ + edma_irq_disable_all(priv); + edma_rings_disable(priv); + regmap_write(priv->regmap, EDMA_REG_PORT_CTRL, 0); +} + +static void edma_hw_reset(struct edma_priv *priv) +{ + reset_control_assert(priv->rst); + udelay(100); + reset_control_deassert(priv->rst); + udelay(100); +} + +static int edma_hw_init(struct edma_priv *priv) +{ + const struct edma_soc_data *soc = priv->soc; + int ret; + u32 val; + + edma_hw_reset(priv); + edma_hw_stop(priv); + + regmap_write(priv->regmap, EDMA_QID2RID_TABLE_MEM(0), + soc->rxdesc_ring & 0xF); + + ret = edma_rings_alloc(priv); + if (ret) + return ret; + + edma_configure_rings(priv); + + regmap_write(priv->regmap, EDMA_REG_RXDESC2FILL_MAP_0, 0); + regmap_write(priv->regmap, EDMA_REG_RXDESC2FILL_MAP_1, + (soc->rxfill_ring & 0x7) + << ((soc->rxdesc_ring % 10) * 3)); + + if (soc->txcmpl_ring != soc->txdesc_ring) { + int map_idx, bit_pos; + int i; + + for (i = 0; i < 3; i++) + regmap_write(priv->regmap, EDMA_REG_TXDESC2CMPL_MAP(i), 0); + + map_idx = soc->txdesc_ring / 10; + bit_pos = (soc->txdesc_ring % 10) * 3; + regmap_set_bits(priv->regmap, EDMA_REG_TXDESC2CMPL_MAP(map_idx), + (soc->txcmpl_ring & 0x7) << bit_pos); + } + + val = EDMA_DMAR_BURST_LEN_SET(soc->burst_enable) | + EDMA_DMAR_REQ_PRI_SET(0) | EDMA_DMAR_TXDATA_NUM_SET(31) | + EDMA_DMAR_TXDESC_NUM_SET(7) | EDMA_DMAR_RXFILL_NUM_SET(7); + regmap_write(priv->regmap, EDMA_REG_DMAR_CTRL, val); + + if (soc->axiw_enable) + regmap_set_bits(priv->regmap, EDMA_REG_AXIW_CTRL, + EDMA_AXIW_MAX_WR_SIZE_EN); + + regmap_write(priv->regmap, EDMA_REG_MISC_INT_MASK, soc->misc_int_mask); + + regmap_write(priv->regmap, EDMA_REG_PORT_CTRL, + EDMA_PORT_PAD_EN | EDMA_PORT_EDMA_EN); + + edma_rings_enable(priv); + + return 0; +} + +static void edma_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + strscpy(info->driver, "qca-edma", sizeof(info->driver)); + strscpy(info->bus_info, dev_name(netdev->dev.parent), + sizeof(info->bus_info)); +} + +static void edma_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +{ + ring->tx_max_pending = EDMA_TX_RING_SIZE; + ring->rx_max_pending = EDMA_RX_RING_SIZE; + ring->tx_pending = EDMA_TX_RING_SIZE; + ring->rx_pending = EDMA_RX_RING_SIZE; +} + +static const struct ethtool_ops edma_ethtool_ops = { + .get_drvinfo = edma_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_ringparam = edma_get_ringparam, +}; + +static int edma_ndo_open(struct net_device *netdev) +{ + struct edma_priv *priv = netdev_priv(netdev); + + netdev_tx_reset_queue(netdev_get_tx_queue(netdev, 0)); + napi_enable(&priv->tx_napi); + napi_enable(&priv->rx_napi); + netif_start_queue(netdev); + edma_tx_irq_unmask(priv); + edma_rx_irq_unmask(priv); + + return 0; +} + +static int edma_ndo_stop(struct net_device *netdev) +{ + struct edma_priv *priv = netdev_priv(netdev); + + edma_tx_irq_mask(priv); + edma_rx_irq_mask(priv); + netif_stop_queue(netdev); + napi_disable(&priv->tx_napi); + napi_disable(&priv->rx_napi); + + return 0; +} + +static netdev_tx_t edma_ndo_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct edma_priv *priv = netdev_priv(netdev); + const struct edma_soc_data *soc = priv->soc; + netdev_tx_t ret; + u32 nhead, ntail; + + if (skb->len < ETH_HLEN) + goto drop; + + if (skb_is_nonlinear(skb) && skb_linearize(skb)) + goto drop; + + if (soc->tx_min_size && skb->len < soc->tx_min_size) { + if (skb_padto(skb, soc->tx_min_size)) { + netdev->stats.tx_dropped++; + return NETDEV_TX_OK; + } + skb->len = soc->tx_min_size; + } + + nhead = netdev->needed_headroom; + ntail = netdev->needed_tailroom; + + if ((skb_cloned(skb) || skb_headroom(skb) < nhead || + skb_tailroom(skb) < ntail) && + pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC)) + goto drop; + + ret = edma_ring_xmit(priv, netdev, skb, &priv->txdesc_ring); + if (ret == NETDEV_TX_BUSY) + netif_stop_queue(netdev); + + return ret; + +drop: + dev_kfree_skb_any(skb); + netdev->stats.tx_dropped++; + + return NETDEV_TX_OK; +} + +static const struct net_device_ops edma_netdev_ops = { + .ndo_open = edma_ndo_open, + .ndo_stop = edma_ndo_stop, + .ndo_start_xmit = edma_ndo_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_get_stats64 = dev_get_tstats64, +}; + +static int edma_irq_init(struct edma_priv *priv) +{ + struct platform_device *pdev = priv->pdev; + struct device *dev = &pdev->dev; + int ret; + + priv->txcmpl_irq = platform_get_irq(pdev, 0); + if (priv->txcmpl_irq < 0) + return priv->txcmpl_irq; + + priv->rxfill_irq = platform_get_irq(pdev, 1); + if (priv->rxfill_irq < 0) + return priv->rxfill_irq; + + priv->rxdesc_irq = platform_get_irq(pdev, 2); + if (priv->rxdesc_irq < 0) + return priv->rxdesc_irq; + + priv->misc_irq = platform_get_irq(pdev, 3); + if (priv->misc_irq < 0) + return priv->misc_irq; + + ret = devm_request_irq(dev, priv->txcmpl_irq, edma_tx_irq_handle, 0, + "edma_txcmpl", priv); + if (ret) + return ret; + + ret = devm_request_irq(dev, priv->rxfill_irq, edma_rx_irq_handle, 0, + "edma_rxfill", priv); + if (ret) + return ret; + + ret = devm_request_irq(dev, priv->rxdesc_irq, edma_rx_irq_handle, 0, + "edma_rxdesc", priv); + if (ret) + return ret; + + ret = devm_request_irq(dev, priv->misc_irq, edma_misc_irq_handle, 0, + "edma_misc", priv); + if (ret) + return ret; + + return 0; +} + +static int edma_page_pool_create(struct edma_priv *priv) +{ + struct page_pool_params pp = { + .pool_size = EDMA_RX_RING_SIZE, + .nid = NUMA_NO_NODE, + .dev = &priv->pdev->dev, + .dma_dir = DMA_FROM_DEVICE, + .offset = NET_SKB_PAD, + .max_len = EDMA_RX_BUFFER_SIZE, + .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, + }; + + priv->page_pool = page_pool_create(&pp); + return PTR_ERR_OR_ZERO(priv->page_pool); +} + +static const struct regmap_config edma_regmap_cfg = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +}; + +static int edma_probe(struct platform_device *pdev) +{ + struct clk_bulk_data *clks; + struct device *dev = &pdev->dev; + struct reset_control *rst; + struct net_device *netdev; + struct edma_priv *priv; + struct regmap *regmap; + void __iomem *base; + int ret; + + ret = devm_clk_bulk_get_all_enabled(dev, &clks); + if (ret < 0) + return ret; + + rst = devm_reset_control_get(dev, EDMA_HW_RESET_ID); + if (IS_ERR(rst)) + return PTR_ERR(rst); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(dev, PTR_ERR(base), "failed to ioremap resource"); + + regmap = devm_regmap_init_mmio(dev, base, &edma_regmap_cfg); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "failed to init regmap"); + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + netdev = devm_alloc_etherdev(dev, sizeof(*priv)); + if (!netdev) + return -ENOMEM; + + priv = netdev_priv(netdev); + priv->regmap = regmap; + priv->rst = rst; + spin_lock_init(&priv->tx_lock); + priv->pdev = pdev; + priv->soc = device_get_match_data(dev); + + ret = edma_page_pool_create(priv); + if (ret) + return ret; + + ret = edma_hw_init(priv); + if (ret) + goto err_page_pool; + + SET_NETDEV_DEV(netdev, dev); + netdev->dev.of_node = dev->of_node; + eth_hw_addr_random(netdev); + netdev->netdev_ops = &edma_netdev_ops; + netdev->features = NETIF_F_GRO; + netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; + netdev->watchdog_timeo = 5 * HZ; + netdev->max_mtu = EDMA_RX_BUFFER_SIZE - ETH_HLEN - (2 * VLAN_HLEN); + netdev->needed_headroom = EDMA_TX_PREHDR_SIZE; + netdev->ethtool_ops = &edma_ethtool_ops; + + priv->netdev = netdev; + + netif_napi_add(netdev, &priv->tx_napi, edma_tx_napi); + netif_napi_add(netdev, &priv->rx_napi, edma_rx_napi); + + ret = edma_irq_init(priv); + if (ret) + goto err_irq; + + ret = register_netdev(netdev); + if (ret) { + dev_warn(dev, "failed to register conduit netdevice\n"); + goto err_irq; + } + + platform_set_drvdata(pdev, priv); + + return 0; + +err_irq: + netif_napi_del(&priv->tx_napi); + netif_napi_del(&priv->rx_napi); + edma_hw_stop(priv); + edma_rings_drain(priv); +err_page_pool: + page_pool_destroy(priv->page_pool); + return ret; +} + +static void edma_remove(struct platform_device *pdev) +{ + struct edma_priv *priv = platform_get_drvdata(pdev); + + unregister_netdev(priv->netdev); + netif_napi_del(&priv->tx_napi); + netif_napi_del(&priv->rx_napi); + edma_hw_stop(priv); + edma_rings_drain(priv); + page_pool_destroy(priv->page_pool); +} + +static const struct edma_soc_data ipq60xx_data = { + .txcmpl_base = 0x79000, + .tx_int_base = 0x91000, + .misc_int_mask = 0xff, + .txdesc_ring = 23, + .txcmpl_ring = 23, + .rxfill_ring = 7, + .rxdesc_ring = 15, + .burst_enable = true, + .axiw_enable = true, +}; + +static const struct edma_soc_data ipq807x_data = { + .txcmpl_base = 0x19000, + .tx_int_base = 0x21000, + .misc_int_mask = 0x1ff, + .txdesc_ring = 23, + .txcmpl_ring = 7, + .rxfill_ring = 7, + .rxdesc_ring = 15, + .tx_min_size = 33, +}; + +static const struct of_device_id edma_of_match[] = { + { .compatible = "qualcomm,ipq6018-edma", .data = &ipq60xx_data }, + { .compatible = "qualcomm,ipq8074-edma", .data = &ipq807x_data }, + {}, +}; + +static struct platform_driver edma_driver = { + .driver = { + .name = "qca-edma", + .of_match_table = edma_of_match, + }, + .probe = edma_probe, + .remove = edma_remove, +}; + +module_platform_driver(edma_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm IPQ EDMA Ethernet driver"); diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.h b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.h new file mode 100644 index 00000000000000..d6e7cbe816f181 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_edma.h @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016, 2018-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef __QCA_EDMA_H__ +#define __QCA_EDMA_H__ + +#include +#include +#include +#include +#include + +#define EDMA_HW_RESET_ID "edma_rst" + +/* Global / control registers */ +#define EDMA_REG_MAS_CTRL 0x0 +#define EDMA_REG_PORT_CTRL 0x4 +#define EDMA_REG_RXDESC2FILL_MAP_0 0x18 +#define EDMA_REG_RXDESC2FILL_MAP_1 0x1c +#define EDMA_REG_DMAR_CTRL 0x48 +#define EDMA_REG_AXIW_CTRL 0x50 +#define EDMA_REG_MISC_INT_STAT 0x5c +#define EDMA_REG_MISC_INT_MASK 0x60 + +#define EDMA_PORT_PAD_EN 0x1 +#define EDMA_PORT_EDMA_EN 0x2 + +#define EDMA_DMAR_REQ_PRI_MASK 0x7 +#define EDMA_DMAR_REQ_PRI_SHIFT 0 +#define EDMA_DMAR_BURST_LEN_MASK 0x1 +#define EDMA_DMAR_BURST_LEN_SHIFT 3 +#define EDMA_DMAR_TXDATA_NUM_MASK 0x1f +#define EDMA_DMAR_TXDATA_NUM_SHIFT 4 +#define EDMA_DMAR_TXDESC_NUM_MASK 0x7 +#define EDMA_DMAR_TXDESC_NUM_SHIFT 9 +#define EDMA_DMAR_RXFILL_NUM_MASK 0x7 +#define EDMA_DMAR_RXFILL_NUM_SHIFT 12 + +#define EDMA_DMAR_REQ_PRI_SET(x) \ + (((x)&EDMA_DMAR_REQ_PRI_MASK) << EDMA_DMAR_REQ_PRI_SHIFT) +#define EDMA_DMAR_TXDATA_NUM_SET(x) \ + (((x)&EDMA_DMAR_TXDATA_NUM_MASK) << EDMA_DMAR_TXDATA_NUM_SHIFT) +#define EDMA_DMAR_TXDESC_NUM_SET(x) \ + (((x)&EDMA_DMAR_TXDESC_NUM_MASK) << EDMA_DMAR_TXDESC_NUM_SHIFT) +#define EDMA_DMAR_RXFILL_NUM_SET(x) \ + (((x)&EDMA_DMAR_RXFILL_NUM_MASK) << EDMA_DMAR_RXFILL_NUM_SHIFT) +#define EDMA_DMAR_BURST_LEN_SET(x) \ + (((x)&EDMA_DMAR_BURST_LEN_MASK) << EDMA_DMAR_BURST_LEN_SHIFT) + +#define EDMA_AXIW_MAX_WR_SIZE_EN 0x400 + +/* TX descriptor ring registers */ +#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_TXDESC_PROD_IDX_MASK 0xffff +#define EDMA_TXDESC_CONS_IDX_MASK 0xffff +#define EDMA_TXDESC_RING_SIZE_MASK 0xffff +#define EDMA_TXDESC_TX_EN 0x1 + +/* TX completion ring registers */ +#define EDMA_REG_TXCMPL_BA(b, n) ((b) + (0x1000 * (n))) +#define EDMA_REG_TXCMPL_PROD_IDX(b, n) ((b) + 0x004 + (0x1000 * (n))) +#define EDMA_REG_TXCMPL_CONS_IDX(b, n) ((b) + 0x008 + (0x1000 * (n))) +#define EDMA_REG_TXCMPL_RING_SIZE(b, n) ((b) + 0x00c + (0x1000 * (n))) +#define EDMA_REG_TXCMPL_CTRL(b, n) ((b) + 0x014 + (0x1000 * (n))) + +#define EDMA_TXCMPL_PROD_IDX_MASK 0xffff +#define EDMA_TXCMPL_CONS_IDX_MASK 0xffff +#define EDMA_TXCMPL_RETMODE_OPAQUE 0x0 + +/* TX interrupt registers */ +#define EDMA_REG_TX_INT_STAT(b, n) ((b) + (0x1000 * (n))) +#define EDMA_REG_TX_INT_MASK(b, n) ((b) + 0x004 + (0x1000 * (n))) +#define EDMA_REG_TX_MOD_TIMER(b, n) ((b) + 0x008 + (0x1000 * (n))) +#define EDMA_REG_TX_INT_CTRL(b, n) ((b) + 0x00c + (0x1000 * (n))) + +#define EDMA_TX_INT_MASK 0x3 +#define EDMA_TX_MOD_TIMER 150 + +/* RX fill ring registers */ +#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_RING_EN(n) (0x2901c + (0x1000 * (n))) + +#define EDMA_RXFILL_PROD_IDX_MASK 0xffff +#define EDMA_RXFILL_CONS_IDX_MASK 0xffff +#define EDMA_RXFILL_RING_SIZE_MASK 0xffff +#define EDMA_RXFILL_BUF_SIZE_MASK 0x3fff +#define EDMA_RXFILL_RING_EN 0x1 +#define EDMA_RXFILL_INT_MASK 0x1 + +/* RX fill ring interrupt registers */ +#define EDMA_REG_RXFILL_INT_STAT(n) (0x31000 + (0x1000 * (n))) +#define EDMA_REG_RXFILL_INT_MASK(n) (0x31004 + (0x1000 * (n))) + +/* RX descriptor ring registers */ +#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_CTRL(n) (0x39018 + (0x1000 * (n))) + +#define EDMA_RXDESC_PROD_IDX_MASK 0xffff +#define EDMA_RXDESC_CONS_IDX_MASK 0xffff +#define EDMA_RXDESC_RING_SIZE_MASK 0xffff +#define EDMA_RXDESC_PL_OFFSET_MASK 0x1ff +#define EDMA_RXDESC_PL_OFFSET_SHIFT 16 +#define EDMA_RXDESC_RX_EN 0x1 +#define EDMA_RXDESC_PACKET_LEN_MASK 0x3fff + +/* RX descriptor ring interrupt registers */ +#define EDMA_REG_RXDESC_INT_STAT(n) (0x49000 + (0x1000 * (n))) +#define EDMA_REG_RXDESC_INT_MASK(n) (0x49004 + (0x1000 * (n))) +#define EDMA_REG_RX_MOD_TIMER(n) (0x49008 + (0x1000 * (n))) +#define EDMA_REG_RX_INT_CTRL(n) (0x4900c + (0x1000 * (n))) + +#define EDMA_RXDESC_INT_MASK_PKT_INT 0x1 +#define EDMA_RX_MOD_TIMER_INIT 1000 + +/* QID to ring mapping */ +#define EDMA_QID2RID_TABLE_MEM(q) (0x5a000 + (0x4 * (q))) + +/* TXDESC to TXCMPL ring mapping */ +#define EDMA_REG_TXDESC2CMPL_MAP(n) (0x0c + 0x4 * (n)) + +/* Misc error interrupt masks */ +#define EDMA_MISC_AXI_RD_ERR_MASK_EN 0x1 +#define EDMA_MISC_AXI_WR_ERR_MASK_EN 0x2 +#define EDMA_MISC_RX_DESC_FIFO_FULL_MASK_EN 0x4 +#define EDMA_MISC_RX_ERR_BUF_SIZE_MASK_EN 0x8 +#define EDMA_MISC_TX_SRAM_FULL_MASK_EN 0x10 +#define EDMA_MISC_TX_CMPL_BUF_FULL_MASK_EN 0x20 +#define EDMA_MISC_DATA_LEN_ERR_MASK_EN 0x40 +#define EDMA_MISC_TX_TIMEOUT_MASK_EN 0x80 + +/* Sizes and ring configuration */ +#define EDMA_RX_BUFFER_SIZE 1984 +#define EDMA_RX_PREHDR_SIZE (sizeof(struct edma_rx_preheader)) +#define EDMA_TX_PREHDR_SIZE (sizeof(struct edma_tx_preheader)) +#define EDMA_TX_RING_SIZE 128 +#define EDMA_RX_RING_SIZE 2048 +#define EDMA_TX_RING_THRESH 16 + +/* Descriptor accessors */ +#define EDMA_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) +#define EDMA_RXFILL_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxfill_desc) +#define EDMA_RXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxdesc) +#define EDMA_TXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_txdesc) +#define EDMA_TXCMPL_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_txcmpl) + +/* TX descriptor fields */ +#define EDMA_TXDESC_PREHEADER_SHIFT 29 +#define EDMA_TXDESC_DATA_OFFSET_SHIFT 16 +#define EDMA_TXDESC_DATA_OFFSET_MASK 0xff +#define EDMA_TXDESC_DATA_LENGTH_MASK 0xffff + +/* Preheader fields */ +#define EDMA_DST_PORT_TYPE 0x20 +#define EDMA_DST_PORT_ID_MASK 0x1f +#define EDMA_SRC_PORT_MASK 0x0fff +#define EDMA_PREHDR_DSTINFO_PORTID_IND 0x20 +#define EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph)->src_info >> 8) & 0xf0) + +struct edma_txdesc { + u32 buffer_addr; + u32 word1; +}; + +struct edma_txcmpl { + u32 buffer_addr; + u32 status; +}; + +struct edma_rxdesc { + u32 buffer_addr; + u32 status; +}; + +struct edma_rxfill_desc { + u32 buffer_addr; + u32 word1; +}; + +struct edma_tx_preheader { + u32 opaque; + u16 src_info; + u16 dst_info; + u32 tx_pre2; + u32 tx_pre3; + u32 tx_pre4; + u32 tx_pre5; + u32 tx_pre6; + u32 tx_pre7; +}; + +struct edma_rx_preheader { + u32 opaque; + u16 src_info; + u16 dst_info; + u32 rx_pre2; + u32 rx_pre3; + u32 rx_pre4; + u32 rx_pre5; + u32 rx_pre6; + u32 rx_pre7; +}; + +struct edma_soc_data { + u32 txcmpl_base; + u32 tx_int_base; + u32 misc_int_mask; + u8 txdesc_ring; + u8 txcmpl_ring; + u8 rxfill_ring; + u8 rxdesc_ring; + u8 tx_min_size; + bool burst_enable; + bool axiw_enable; +}; + +struct edma_ring { + void *desc; + dma_addr_t dma; + u16 count; + struct sk_buff **skb_store; +}; + +struct edma_priv { + const struct edma_soc_data *soc; + struct napi_struct tx_napi; + struct napi_struct rx_napi; + struct net_device *netdev; + struct platform_device *pdev; + struct regmap *regmap; + struct reset_control *rst; + struct page_pool *page_pool; + + struct edma_ring txdesc_ring; + struct edma_ring txcmpl_ring; + struct edma_ring rxfill_ring; + struct edma_ring rxdesc_ring; + + spinlock_t tx_lock; + + int txcmpl_irq; + int rxfill_irq; + int rxdesc_irq; + int misc_irq; +}; + +#endif /* __QCA_EDMA_H__ */ diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h new file mode 100644 index 00000000000000..39329df983010b --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h @@ -0,0 +1,545 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later OR MIT */ + +#ifndef __QCA_PPE_H +#define __QCA_PPE_H + +#include +#include +#include +#include +#include +#include +#include + +#define QCA_PPE_MAX_PORTS 8 +#define QCA_PPE_CPU_PORT 0 +#define QCA_PPE_MAX_BRIDGES 8 + + +/* --- Global --- */ +#define PPE_PORT_MUX_CTRL 0x10 + +/* CPPE (IPQ60xx) PORT_MUX_CTRL bit layout */ +#define CPPE_PORT3_PCS_SEL GENMASK(1, 0) +#define CPPE_PORT5_PCS_SEL GENMASK(5, 4) +#define CPPE_PORT5_GMAC_SEL BIT(6) +#define CPPE_PCS0_CH4_SEL BIT(7) +#define CPPE_PORT3_PCS0_CH4 1 +#define CPPE_PORT5_PCS1_CH0 1 + +/* HPPE (IPQ807x) PORT_MUX_CTRL bit layout */ +#define HPPE_PORT4_PCS_SEL BIT(0) +#define HPPE_PORT5_PCS_SEL GENMASK(2, 1) +#define HPPE_PORT5_GMAC_SEL BIT(3) +#define HPPE_PORT6_PCS_SEL BIT(4) +#define HPPE_PORT6_GMAC_SEL BIT(5) +#define HPPE_PORT4_PCS0 1 +#define HPPE_PORT5_PCS0 1 +#define HPPE_PORT5_PCS1 2 +#define HPPE_PORT6_PCS2 1 +#define HPPE_PORT5_GMAC_SEL_GMAC 1 +#define HPPE_PORT6_GMAC_SEL_GMAC 1 + +/* --- MAC CSR (base 0x001000) --- */ +#define PPE_MAC_CSR_BASE 0x001000 + +#define PPE_GMAC_ENABLE(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200) +#define PPE_MAC_ENABLE_RXMAC_EN BIT(0) +#define PPE_MAC_ENABLE_TXMAC_EN BIT(1) +#define PPE_MAC_ENABLE_DUPLEX BIT(4) +#define PPE_MAC_ENABLE_RX_FLOW_EN BIT(5) +#define PPE_MAC_ENABLE_TX_FLOW_EN BIT(6) + +#define PPE_LPBK_ENABLE(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200) +#define PPE_LPBK_EN BIT(0) +#define PPE_LPBK_CRC_STRIP_EN BIT(3) + +#define PPE_GMAC_SPEED(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x4) +#define PPE_GMAC_SPEED_MASK GENMASK(1, 0) + +#define PPE_LPBK_PPS_CTRL(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x0c) +#define PPE_LPBK_PPS_THRESHOLD GENMASK(8, 0) + +#define PPE_GMAC_CTRL2(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x18) +#define PPE_GMAC_CTRL2_MAXFR GENMASK(21, 8) +#define PPE_GMAC_CTRL2_CRS_SEL BIT(6) +#define PPE_GMAC_CTRL2_TX_THD GENMASK(27, 24) + +#define PPE_GMAC_DBG_CTRL(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x1c) +#define PPE_GMAC_DBG_CTRL_HIHG_IPG GENMASK(15, 8) + +#define PPE_GMAC_JUMBO_SIZE(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x30) + +#define PPE_GMAC_MIB_CTRL(gmac) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + 0x34) +#define PPE_MIB_EN BIT(0) +#define PPE_MIB_RD_CLR BIT(2) + +#define PPE_GMAC_MIB(gmac, off) (PPE_MAC_CSR_BASE + (gmac) * 0x200 + (off)) +#define PPE_MIB_RXBROAD 0x40 +#define PPE_MIB_RXPAUSE 0x44 +#define PPE_MIB_RXMULTI 0x48 +#define PPE_MIB_RXFCSERR 0x4c +#define PPE_MIB_RXALIGNERR 0x50 +#define PPE_MIB_RXRUNT 0x54 +#define PPE_MIB_RXFRAG 0x58 +#define PPE_MIB_RXJUMBOFCSERR 0x5c +#define PPE_MIB_RXJUMBOALIGNERR 0x60 +#define PPE_MIB_RXPKT64 0x64 +#define PPE_MIB_RXPKT65TO127 0x68 +#define PPE_MIB_RXPKT128TO255 0x6c +#define PPE_MIB_RXPKT256TO511 0x70 +#define PPE_MIB_RXPKT512TO1023 0x74 +#define PPE_MIB_RXPKT1024TO1518 0x78 +#define PPE_MIB_RXPKT1519TOX 0x7c +#define PPE_MIB_RXTOOLONG 0x80 +#define PPE_MIB_RXGOODBYTE_L 0x84 +#define PPE_MIB_RXGOODBYTE_H 0x88 +#define PPE_MIB_RXBADBYTE_L 0x8c +#define PPE_MIB_RXBADBYTE_H 0x90 +#define PPE_MIB_RXUNI 0x94 +#define PPE_MIB_TXBROAD 0xa0 +#define PPE_MIB_TXPAUSE 0xa4 +#define PPE_MIB_TXMULTI 0xa8 +#define PPE_MIB_TXUNDERRUN 0xac +#define PPE_MIB_TXPKT64 0xb0 +#define PPE_MIB_TXPKT65TO127 0xb4 +#define PPE_MIB_TXPKT128TO255 0xb8 +#define PPE_MIB_TXPKT256TO511 0xbc +#define PPE_MIB_TXPKT512TO1023 0xc0 +#define PPE_MIB_TXPKT1024TO1518 0xc4 +#define PPE_MIB_TXPKT1519TOX 0xc8 +#define PPE_MIB_TXBYTE_L 0xcc +#define PPE_MIB_TXBYTE_H 0xd0 +#define PPE_MIB_TXCOLLISIONS 0xd4 +#define PPE_MIB_TXABORTCOL 0xd8 +#define PPE_MIB_TXMULTICOL 0xdc +#define PPE_MIB_TXSINGLECOL 0xe0 +#define PPE_MIB_TXEXCESSIVEDEFER 0xe4 +#define PPE_MIB_TXDEFER 0xe8 +#define PPE_MIB_TXLATECOL 0xec +#define PPE_MIB_TXUNI 0xf0 + +/* --- XGMAC (base 0x003000) --- */ +#define PPE_MAC_XGMAC_CSR_BASE 0x003000 + +#define PPE_XGMAC_TX_CONF(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000) +#define PPE_XGMAC_TX_ENABLE BIT(0) +#define PPE_XGMAC_JABBER_DISABLE BIT(16) /* Called JD */ +#define PPE_XGMAC_SPEED_SELECT GENMASK(30, 29) +#define PPE_XGMAC_SPEED_SELECT_10000 FIELD_PREP_CONST(PPE_XGMAC_SPEED_SELECT, 0x0) +#define PPE_XGMAC_SPEED_SELECT_5000 FIELD_PREP_CONST(PPE_XGMAC_SPEED_SELECT, 0x1) +#define PPE_XGMAC_SPEED_SELECT_2500 FIELD_PREP_CONST(PPE_XGMAC_SPEED_SELECT, 0x2) +#define PPE_XGMAC_SPEED_SELECT_1000 FIELD_PREP_CONST(PPE_XGMAC_SPEED_SELECT, 0x3) +#define PPE_XGMAC_USXGMII_SELECT BIT(31) + +#define PPE_XGMAC_RX_CONF(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000 + 0x4) +#define PPE_XGMAC_RX_ENABLE BIT(0) +#define PPE_XGMAC_AUTO_CRC_STRIP BIT(1) /* Called ACS */ +#define PPE_XGMAC_CRC_STRIP_TYPE BIT(2) /* Called CST */ +#define PPE_XGMAC_GMII_MPLS_LAYER_CK BIT(6) /* Called GMPSLCE */ +#define PPE_XGMAC_WATCHDOG_DISABLE BIT(7) /* Called WD */ + +#define PPE_XGMAC_PACKET_FILTER(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000 + 0x8) +#define PPE_XGMAC_PROMISCUOUS BIT(0) /* Called PR */ +#define PPE_XGMAC_PASS_CONTROL_FRAME GENMASK(7, 6) /* Called PCF */ +#define PPE_XGMAC_RATE_ADAPTATION BIT(31) /* Called RA */ + +#define PPE_XGMAC_WATCHDOG_TIMEOUT(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000 + 0xc) +#define PPE_XGMAC_WATCHDOG_THRESHOLD GENMASK(3, 0) +#define PPE_XGMAC_WATCHDOG_ENABLE BIT(8) + +#define PPE_XGMAC_TX_FLOW_CTRL(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000 + 0x70) +#define PPE_XGMAC_TX_FLOW_ENABLE BIT(1) +#define PPE_XGMAC_PAUSE_TIME GENMASK(31, 16) + +#define PPE_XGMAC_RX_FLOW_CTRL(xgmac) (PPE_MAC_XGMAC_CSR_BASE + (xgmac) * 0x4000 + 0x90) +#define PPE_XGMAC_RX_FLOW_ENABLE BIT(0) + +/* --- PRX (base 0x00b000) --- */ +#define PPE_PRX_BASE 0x00b000 + +#define PPE_PRX_TDM_CTRL (PPE_PRX_BASE + 0x0) +#define PPE_TDM_DEPTH GENMASK(7, 0) +#define PPE_TDM_EN BIT(31) + +#define PPE_PRX_TDM_CFG(i) (PPE_PRX_BASE + 0x1000 + (i) * 0x10) +#define PPE_TDM_PORT_NUM GENMASK(3, 0) +#define PPE_TDM_DIR BIT(4) +#define PPE_TDM_VALID BIT(5) + +#define PPE_PRX_MRU_MTU_W1(p) (PPE_PRX_BASE + 0x3000 + (p) * 0x10 + 0x4) +#define PPE_QOS_PCP_GRP BIT(4) +#define PPE_QOS_DSCP_GRP BIT(5) +#define PPE_QOS_PREHEADER_PREC GENMASK(10, 8) +#define PPE_QOS_PCP_PREC GENMASK(13, 11) +#define PPE_QOS_DSCP_PREC GENMASK(16, 14) +#define PPE_QOS_FLOW_PREC GENMASK(19, 17) +#define PPE_QOS_ACL_PREC GENMASK(22, 20) + +/* --- Ingress VLAN (base 0x00f000) --- */ +#define PPE_IVLAN_BASE 0x00f000 + +#define PPE_PORT_DEF_VID(port) (PPE_IVLAN_BASE + 0x10 + (port) * 0x4) +#define PPE_PORT_DEF_CVID GENMASK(27, 16) +#define PPE_PORT_DEF_CVID_EN BIT(28) + +#define PPE_PORT_VLAN_CFG(port) (PPE_IVLAN_BASE + 0x50 + (port) * 0x4) +#define PPE_VLAN_XLT_MISS_FWD GENMASK(6, 5) + +#define PPE_XLT_RULE_TBL(idx) (PPE_IVLAN_BASE + 0x2000 + (idx) * 0x10) +#define PPE_XLT_VALID BIT(0) +#define PPE_XLT_PORT_BMP GENMASK(8, 1) +#define PPE_XLT_CKEY_FMT_0 BIT(31) + +#define PPE_XLT_RULE_W1(idx) (PPE_IVLAN_BASE + 0x2000 + (idx) * 0x10 + 0x4) +#define PPE_XLT_CKEY_FMT_1 GENMASK(1, 0) +#define PPE_XLT_CKEY_VID_INCL BIT(2) +#define PPE_XLT_CKEY_VID GENMASK(14, 3) + +#define PPE_XLT_ACTION_TBL(idx) (PPE_IVLAN_BASE + 0x4000 + (idx) * 0x10) +#define PPE_XLT_CVID_CMD GENMASK(16, 15) + +#define PPE_XLT_ACTION_W1(idx) (PPE_IVLAN_BASE + 0x4000 + (idx) * 0x10 + 0x4) +#define PPE_XLT_VSI_CMD BIT(11) +#define PPE_XLT_VSI GENMASK(16, 12) + +/* --- PTX (base 0x020000) --- */ +#define PPE_PTX_BASE 0x020000 + +#define PPE_EG_VSI_TAG(vsi) (PPE_PTX_BASE + (vsi) * 0x4) +#define PPE_EG_VSI_TAG_UNMODIFIED 0xaaaa + +#define PPE_EG_BRIDGE_CONFIG (PPE_PTX_BASE + 0x6000) +#define PPE_EG_L2_EDIT_EN BIT(1) +#define PPE_EG_QUEUE_CNT_EN BIT(2) + +#define PPE_PORT_EG_VLAN(port) (PPE_PTX_BASE + 0x420 + (port) * 0x4) +#define PPE_PORT_EG_VLAN_CTAG_MODE GENMASK(2, 1) +#define PPE_PORT_EG_VLAN_STAG_MODE GENMASK(4, 3) +#define PPE_PORT_EG_VSI_TAG_EN BIT(5) +#define PPE_PORT_EG_VLAN_TX_CNT_EN BIT(8) + +#define PPE_EG_UNTOUCHED 3 + +/* --- L2 (base 0x060000) --- */ +#define PPE_L2_BASE 0x060000 + +#define PPE_FDB_OP (PPE_L2_BASE + 0x8) +#define PPE_FDB_RD_OP (PPE_L2_BASE + 0x10) +#define PPE_FDB_OP_RSLT (PPE_L2_BASE + 0x20) +#define PPE_FDB_RD_OP_RSLT (PPE_L2_BASE + 0x30) + +#define PPE_AGE_TIMER (PPE_L2_BASE + 0x34) +#define PPE_AGE_TIMER_MASK GENMASK(19, 0) + +#define PPE_L2_GLOBAL_CONF (PPE_L2_BASE + 0x38) +#define PPE_L2_LRN_EN BIT(6) +#define PPE_L2_AGE_EN BIT(7) + +#define PPE_CST_STATE(port) (PPE_L2_BASE + 0x100 + (port) * 0x4) +#define PPE_STP_DISABLED 0 +#define PPE_STP_BLOCKING 1 +#define PPE_STP_LEARNING 2 +#define PPE_STP_FORWARDING 3 +#define PPE_STP_STATE_MASK GENMASK(1, 0) + +#define PPE_FDB_RD_RSLT_DATA0 (PPE_L2_BASE + 0x200) +#define PPE_FDB_RD_RSLT_DATA1 (PPE_L2_BASE + 0x204) +#define PPE_FDB_RD_RSLT_DATA2 (PPE_L2_BASE + 0x208) + +#define PPE_FDB_OP_DATA0 (PPE_L2_BASE + 0x230) +#define PPE_FDB_OP_DATA1 (PPE_L2_BASE + 0x234) +#define PPE_FDB_OP_DATA2 (PPE_L2_BASE + 0x238) + +#define PPE_FDB_RD_OP_DATA0 (PPE_L2_BASE + 0x260) +#define PPE_FDB_RD_OP_DATA1 (PPE_L2_BASE + 0x264) +#define PPE_FDB_RD_OP_DATA2 (PPE_L2_BASE + 0x268) + +#define PPE_PORT_BRIDGE_CTRL(port) (PPE_L2_BASE + 0x300 + (port) * 0x4) +#define PPE_BRIDGE_NEW_LRN_EN BIT(0) +#define PPE_BRIDGE_STA_MOVE_EN BIT(3) +#define PPE_BRIDGE_PORT_ISOL GENMASK(15, 8) +#define PPE_PORT_BRIDGE_CTRL_TXMAC_EN BIT(16) + +#define PPE_MC_MTU_CTRL(port) (PPE_L2_BASE + 0xa00 + (port) * 0x4) +#define PPE_MC_MTU_CTRL_TX_CNT_EN BIT(16) + +#define PPE_RFDB_TBL(idx) (PPE_L2_BASE + 0x1000 + (idx) * 0x8) + +#define PPE_APP_CTRL(idx) (PPE_L2_BASE + 0x1400 + (idx) * 0x10) + +#define PPE_VSI_TBL(vsi) (PPE_L2_BASE + 0x1800 + (vsi) * 0x10) +#define PPE_VSI_TBL_MEMBER GENMASK(7, 0) +#define PPE_VSI_TBL_UUC GENMASK(15, 8) +#define PPE_VSI_TBL_UMC GENMASK(23, 16) +#define PPE_VSI_TBL_BC GENMASK(31, 24) +#define PPE_VSI_TBL_NEW_ADDR_LRN_EN BIT(0) +#define PPE_VSI_TBL_STA_MOVE_LRN_EN BIT(3) + +#define PPE_MRU_MTU_CTRL(port) (PPE_L2_BASE + 0x3000 + (port) * 0x10) +#define PPE_MRU_MTU_CTRL_RX_CNT_EN BIT(0) +#define PPE_MRU_MTU_CTRL_TX_CNT_EN BIT(1) + +/* --- L3 (base 0x200000) --- */ +#define PPE_L3_BASE 0x200000 + +#define PPE_L3_VP_PORT_TBL(port) (PPE_L3_BASE + 0x1000 + (port) * 0x10) +#define PPE_L3_VP_VSI_VALID BIT(9) +#define PPE_L3_VP_VSI GENMASK(14, 10) + +/* --- Traffic Manager (base 0x400000) --- */ +#define PPE_TM_BASE 0x400000 + +#define PPE_TM_TDM_DEPTH (PPE_TM_BASE + 0x0) +#define PPE_TM_TDM_DEPTH_MASK GENMASK(7, 0) + +#define PPE_TM_L0_FLOW_MAP(i) (PPE_TM_BASE + 0x2000 + (i) * 0x10) +#define PPE_L0_SP_ID GENMASK(5, 0) +#define PPE_L0_C_PRI GENMASK(8, 6) +#define PPE_L0_E_PRI GENMASK(11, 9) +#define PPE_L0_C_DRR_WT GENMASK(21, 12) +#define PPE_L0_E_DRR_WT GENMASK(31, 22) + +#define PPE_TM_L0_C_SP(i) (PPE_TM_BASE + 0x4000 + (i) * 0x10) +#define PPE_TM_L0_E_SP(i) (PPE_TM_BASE + 0x6000 + (i) * 0x10) +#define PPE_L0_SP_DRR_ID GENMASK(7, 0) + +#define PPE_TM_L0_PORT_MAP(i) (PPE_TM_BASE + 0x8000 + (i) * 0x10) +#define PPE_L0_PORT_NUM GENMASK(3, 0) + +#define PPE_TM_RING_Q_MAP(r) (PPE_TM_BASE + 0x2a000 + (r) * 0x40) + +#define PPE_TM_L1_FLOW_MAP(i) (PPE_TM_BASE + 0x40000 + (i) * 0x10) +#define PPE_L1_SP_ID GENMASK(3, 0) +#define PPE_L1_C_PRI GENMASK(6, 4) +#define PPE_L1_E_PRI GENMASK(9, 7) +#define PPE_L1_C_DRR_WT GENMASK(19, 10) +#define PPE_L1_E_DRR_WT GENMASK(29, 20) + +#define PPE_TM_L1_C_SP(i) (PPE_TM_BASE + 0x42000 + (i) * 0x10) +#define PPE_TM_L1_E_SP(i) (PPE_TM_BASE + 0x44000 + (i) * 0x10) +#define PPE_L1_SP_DRR_ID GENMASK(5, 0) + +#define PPE_TM_L1_PORT_MAP(i) (PPE_TM_BASE + 0x46000 + (i) * 0x10) +#define PPE_L1_PORT_NUM GENMASK(3, 0) + +#define PPE_TM_PSCH_TDM(i) (PPE_TM_BASE + 0x7a000 + (i) * 0x10) +#define PPE_PSCH_DES_PORT GENMASK(3, 0) +#define PPE_PSCH_ENS_PORT GENMASK(7, 4) +#define PPE_PSCH_ENS_PORT_BMP GENMASK(15, 8) + +/* --- Buffer Manager (base 0x600000) --- */ +#define PPE_BM_BASE 0x600000 + +#define PPE_BM_FC_MODE(i) (PPE_BM_BASE + 0x100 + (i) * 0x4) +#define PPE_BM_FC_EN BIT(0) + +#define PPE_BM_GROUP_ID(i) (PPE_BM_BASE + 0x180 + (i) * 0x4) + +#define PPE_BM_SHARED_GRP(g) (PPE_BM_BASE + 0x290 + (g) * 0x4) +#define PPE_BM_SHARED_LIMIT GENMASK(10, 0) + +#define PPE_BM_PORT_FC_W0(i) (PPE_BM_BASE + 0x1000 + (i) * 0x10) +#define PPE_BM_PORT_FC_W1(i) (PPE_BM_BASE + 0x1000 + (i) * 0x10 + 0x4) +#define PPE_BM_REACT_LIMIT GENMASK(8, 0) +#define PPE_BM_RESUME_FLOOR GENMASK(17, 9) +#define PPE_BM_RESUME_OFF GENMASK(28, 18) +#define PPE_BM_CEILING_LO GENMASK(31, 29) +#define PPE_BM_CEILING_HI GENMASK(7, 0) +#define PPE_BM_WEIGHT GENMASK(10, 8) +#define PPE_BM_DYNAMIC BIT(11) +#define PPE_BM_PREALLOC GENMASK(22, 12) + +/* --- Queue Manager (base 0x800000) --- */ +#define PPE_QM_BASE 0x800000 + +#define PPE_QM_UCAST_MAP(i) (PPE_QM_BASE + 0x10000 + (i) * 0x10) +#define PPE_QM_PROFILE_ID GENMASK(3, 0) +#define PPE_QM_QUEUE_ID GENMASK(11, 4) + +#define PPE_QM_UCAST_HASH_MAP(i) (PPE_QM_BASE + 0x30000 + (i) * 0x10) +#define PPE_QM_HASH_CLASS GENMASK(3, 0) + +#define PPE_QM_UCAST_PRI_MAP(i) (PPE_QM_BASE + 0x42000 + (i) * 0x10) +#define PPE_QM_PRI_CLASS GENMASK(3, 0) + +#define PPE_QM_AC_UNI_W0(i) (PPE_QM_BASE + 0x48000 + (i) * 0x10) +#define PPE_QM_AC_UNI_W1(i) (PPE_QM_BASE + 0x48000 + (i) * 0x10 + 0x4) +#define PPE_QM_AC_UNI_W2(i) (PPE_QM_BASE + 0x48000 + (i) * 0x10 + 0x8) +#define PPE_QM_AC_UNI_W3(i) (PPE_QM_BASE + 0x48000 + (i) * 0x10 + 0xc) +#define PPE_AC_EN BIT(0) +#define PPE_AC_GRP_ID GENMASK(5, 4) +#define PPE_AC_SHARED_DYNAMIC BIT(17) +#define PPE_AC_SHARED_WEIGHT GENMASK(20, 18) +#define PPE_AC_SHARED_CEILING GENMASK(31, 21) +#define PPE_AC_GRN_RESUME_OFF GENMASK(23, 13) + +#define PPE_QM_AC_MUL_W0(i) (PPE_QM_BASE + 0x4a000 + (i) * 0x10) +#define PPE_QM_AC_MUL_W1(i) (PPE_QM_BASE + 0x4a000 + (i) * 0x10 + 0x4) +#define PPE_QM_AC_MUL_W2(i) (PPE_QM_BASE + 0x4a000 + (i) * 0x10 + 0x8) +#define PPE_AC_MUL_EN BIT(0) +#define PPE_AC_MUL_CEILING GENMASK(26, 16) +#define PPE_AC_MUL_GRN_MAX_LO GENMASK(31, 27) +#define PPE_AC_MUL_GRN_MAX_HI GENMASK(5, 0) +#define PPE_AC_MUL_GRN_RESUME_HI GENMASK(17, 11) + +#define PPE_QM_AC_GRP_W0(g) (PPE_QM_BASE + 0x4c000 + (g) * 0x10) +#define PPE_QM_AC_GRP_W1(g) (PPE_QM_BASE + 0x4c000 + (g) * 0x10 + 0x4) +#define PPE_QM_AC_GRP_W2(g) (PPE_QM_BASE + 0x4c000 + (g) * 0x10 + 0x8) +#define PPE_AC_GRP_LIMIT GENMASK(14, 4) +#define PPE_AC_GRP_PALLOC GENMASK(26, 16) + +/* --- FDB fields --- */ +#define PPE_FDB_OP_CMD_ID GENMASK(3, 0) +#define PPE_FDB_OP_TYPE GENMASK(7, 5) +#define PPE_FDB_OP_HASH_BLOCK GENMASK(9, 8) +#define PPE_FDB_OP_MODE BIT(10) +#define PPE_FDB_OP_ENTRY_IDX GENMASK(21, 11) + +#define PPE_FDB_RSLT_CMD_ID GENMASK(3, 0) + +#define PPE_FDB_DATA1_VALID BIT(16) +#define PPE_FDB_DATA1_LKP_VALID BIT(17) +#define PPE_FDB_DATA1_VSI GENMASK(22, 18) +#define PPE_FDB_DATA1_DST_LO GENMASK(31, 23) + +#define PPE_FDB_DATA2_DST_HI GENMASK(2, 0) +#define PPE_FDB_DATA2_DST_TYPE GENMASK(4, 3) +#define PPE_FDB_DATA2_HIT_AGE GENMASK(10, 9) + +/* --- Constants --- */ +#define PPE_NUM_PORTS 8 +#define PPE_MAX_SP_PRI 8 +#define PPE_L0_QUEUES 300 +#define PPE_L0_UCAST_QUEUES 256 + +#define PPE_BM_PORTS 15 +#define PPE_BM_PHY_START 8 + +#define PPE_VSI_MAX 32 +#define PPE_VSI_INVALID U32_MAX +#define PPE_DEFAULT_MTU 1514 +#define PPE_MTU_SHIFT 16 +#define PPE_MAX_FRAME_SIZE 0x3000 +#define PPE_AGE_UNIT_MS 8000 + +#define PPE_FDB_TBL_NUM 2048 +#define PPE_FDB_OP_ADD 0 +#define PPE_FDB_OP_DEL 1 +#define PPE_FDB_OP_GET 2 +#define PPE_FDB_DST_PORT 2 +#define PPE_FDB_DST_PORTMAP 3 +#define PPE_FDB_AGE_STATIC 3 +#define PPE_FDB_OP_FLUSH 4 + +#define PPE_XLT_TBL_NUM 64 +#define PPE_XLT_MISS_FWD_DROP 3 +#define PPE_XLT_CVID_DEL 2 +#define PPE_XLT_CKEY_TAGGED 4 + +#define PPE_EG_UNTAGGED 0 +#define PPE_EG_TAGGED 1 +#define PPE_EG_UNMODIFIED 2 + +#define PPE_MAX_SERVICE_CODES 256 +#define PPE_MAX_CPU_CODES 256 +#define PPE_MAX_VPORT 256 + +#define QM_VP_PORT_OFFSET 0 +#define QM_CPU_CODE_OFFSET 1024 +#define QM_SERVICE_CODE_OFFSET 2048 + +struct psch_tdm_data { + const struct psch_tdm_entry *entries; + int num; +}; + +struct bm_tdm_data { + const struct bm_tdm_entry *entries; + int num; +}; + +enum ppe_type { + PPE_TYPE_IPQ6018, + PPE_TYPE_IPQ8074, +}; + +struct ppe_data { + enum ppe_type type; + u8 num_ports; + u8 num_gmacs; + u8 loopback_port; + u8 bm_phy_end; + u8 bm_internal_start; + u16 bm_group_buf; + u16 bm_ceiling; + u16 qm_total_buf; + u16 qm_ceiling; + u16 qm_green_max; + const struct psch_tdm_data *psch_tdm; + const struct bm_tdm_data *bm_tdm; +}; + +struct qca_ppe_bridge_vsi { + struct net_device *br_dev; + u32 vsi; + int refcount; +}; + +struct qca_ppe_vlan_entry { + struct net_device *br_dev; + u16 vid; + u32 vsi; + u8 ports; + u8 pvid_ports; + int xlt_idx; + int xlt_pvid_idx; +}; + +struct qca_ppe_priv { + struct dsa_switch ds; + struct regmap *regmap; + const struct ppe_data *data; + struct clk_bulk_data *clks; + int num_clks; + spinlock_t fdb_lock; + DECLARE_BITMAP(vsi_bitmap, PPE_VSI_MAX); + DECLARE_BITMAP(xlt_bitmap, PPE_XLT_TBL_NUM); + u32 port_vsi[QCA_PPE_MAX_PORTS]; + struct qca_ppe_bridge_vsi bridges[QCA_PPE_MAX_BRIDGES]; + struct qca_ppe_vlan_entry vlans[PPE_VSI_MAX]; + struct net_device *port_br_dev[QCA_PPE_MAX_PORTS]; + u16 port_pvid[QCA_PPE_MAX_PORTS]; + struct clk *port_rx_clk[QCA_PPE_MAX_PORTS]; + struct clk *port_tx_clk[QCA_PPE_MAX_PORTS]; + struct reset_control *port_rst[QCA_PPE_MAX_PORTS]; +}; + +extern const struct psch_tdm_data cppe_psch_tdm_data; +extern const struct psch_tdm_data hppe_psch_tdm_data; + +extern const struct bm_tdm_data cppe_bm_tdm_data; +extern const struct bm_tdm_data hppe_bm_tdm_data; + +static inline struct qca_ppe_priv *ds_to_priv(struct dsa_switch *ds) +{ + return container_of(ds, struct qca_ppe_priv, ds); +} + +void ppe_scheduler_init(struct qca_ppe_priv *priv); + +int ppe_vsi_alloc(struct qca_ppe_priv *priv); +void ppe_vsi_free(struct qca_ppe_priv *priv, u32 vsi); +void ppe_vsi_member_set(struct qca_ppe_priv *priv, u32 vsi, u32 portmask); + +int qca_ppe_vlan_setup(struct dsa_switch *ds); +int qca_ppe_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering, + struct netlink_ext_ack *extack); +int qca_ppe_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack); +int qca_ppe_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); + +#endif diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c new file mode 100644 index 00000000000000..6f7a8906b84205 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c @@ -0,0 +1,1587 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qca_ppe.h" + +static void ppe_port_gmac_set(struct qca_ppe_priv *priv, int port, + bool tx_en, bool rx_en) +{ + int gmac = port - 1; + u32 val = 0; + + if (port < 1 || port >= priv->data->num_ports) + return; + + if (tx_en) + val |= PPE_MAC_ENABLE_TXMAC_EN; + if (rx_en) + val |= PPE_MAC_ENABLE_RXMAC_EN; + regmap_update_bits(priv->regmap, PPE_GMAC_ENABLE(gmac), + PPE_MAC_ENABLE_TXMAC_EN | PPE_MAC_ENABLE_RXMAC_EN, + val); +} + +static void ppe_port_xgmac_set(struct qca_ppe_priv *priv, int port, + bool tx_en, bool rx_en) +{ + int xgmac = port - 5; + + if (port < 5 || port >= priv->data->num_ports) + return; + + regmap_update_bits(priv->regmap, PPE_XGMAC_TX_CONF(xgmac), + PPE_XGMAC_TX_ENABLE, + tx_en ? PPE_XGMAC_TX_ENABLE : 0); + + regmap_update_bits(priv->regmap, PPE_XGMAC_RX_CONF(xgmac), + PPE_XGMAC_RX_ENABLE, + rx_en ? PPE_XGMAC_RX_ENABLE : 0); +} + +static void ppe_port_bridge_txmac_set(struct qca_ppe_priv *priv, int port, + bool enable) +{ + regmap_update_bits(priv->regmap, PPE_PORT_BRIDGE_CTRL(port), + PPE_PORT_BRIDGE_CTRL_TXMAC_EN, + enable ? PPE_PORT_BRIDGE_CTRL_TXMAC_EN : 0); +} + +static void ppe_gmac_link_up(struct qca_ppe_priv *priv, int port, + int speed, int duplex, + bool tx_pause, bool rx_pause) +{ + int gmac = port - 1; + u32 val; + + regmap_read(priv->regmap, PPE_GMAC_SPEED(gmac), &val); + val &= ~PPE_GMAC_SPEED_MASK; + switch (speed) { + case SPEED_100: + val |= FIELD_PREP(PPE_GMAC_SPEED_MASK, 1); + break; + case SPEED_2500: + case SPEED_1000: + val |= FIELD_PREP(PPE_GMAC_SPEED_MASK, 2); + break; + } + regmap_write(priv->regmap, PPE_GMAC_SPEED(gmac), val); + + val = 0; + if (duplex == DUPLEX_FULL) + val |= PPE_MAC_ENABLE_DUPLEX; + if (tx_pause) + val |= PPE_MAC_ENABLE_TX_FLOW_EN; + if (rx_pause) + val |= PPE_MAC_ENABLE_RX_FLOW_EN; + regmap_update_bits(priv->regmap, PPE_GMAC_ENABLE(gmac), + PPE_MAC_ENABLE_DUPLEX | PPE_MAC_ENABLE_TX_FLOW_EN | + PPE_MAC_ENABLE_RX_FLOW_EN, val); +} + +static void ppe_xgmac_link_up(struct qca_ppe_priv *priv, int port, + phy_interface_t interface, int speed, + bool tx_pause, bool rx_pause) +{ + int xgmac = port - 5; + u32 val; + + switch (speed) { + case SPEED_10: + case SPEED_100: + case SPEED_1000: + val = PPE_XGMAC_SPEED_SELECT_1000; + break; + case SPEED_2500: + val = PPE_XGMAC_SPEED_SELECT_2500; + break; + case SPEED_5000: + val = PPE_XGMAC_SPEED_SELECT_5000; + break; + case SPEED_10000: + val = PPE_XGMAC_SPEED_SELECT_10000; + break; + default: + return; + } + + if (interface == PHY_INTERFACE_MODE_USXGMII || + interface == PHY_INTERFACE_MODE_10GBASER) { + switch (speed) { + case SPEED_2500: + case SPEED_5000: + case SPEED_10000: + val |= PPE_XGMAC_USXGMII_SELECT; + break; + default: + break; + } + } + + regmap_update_bits(priv->regmap, PPE_XGMAC_TX_CONF(xgmac), + PPE_XGMAC_SPEED_SELECT | + PPE_XGMAC_USXGMII_SELECT, val); + + regmap_write_bits(priv->regmap, PPE_XGMAC_RX_CONF(xgmac), + PPE_XGMAC_AUTO_CRC_STRIP | + PPE_XGMAC_CRC_STRIP_TYPE, + PPE_XGMAC_AUTO_CRC_STRIP | + PPE_XGMAC_CRC_STRIP_TYPE); + + regmap_write_bits(priv->regmap, PPE_XGMAC_TX_FLOW_CTRL(xgmac), + PPE_XGMAC_TX_FLOW_ENABLE, + tx_pause ? PPE_XGMAC_RX_FLOW_ENABLE : 0); + + regmap_write_bits(priv->regmap, PPE_XGMAC_RX_FLOW_CTRL(xgmac), + PPE_XGMAC_RX_FLOW_ENABLE, + rx_pause ? PPE_XGMAC_RX_FLOW_ENABLE : 0); +} + +static void ppe_port_cnt_enable(struct qca_ppe_priv *priv, int port) +{ + regmap_update_bits(priv->regmap, PPE_MRU_MTU_CTRL(port) + 4, + PPE_MRU_MTU_CTRL_RX_CNT_EN | PPE_MRU_MTU_CTRL_TX_CNT_EN, + PPE_MRU_MTU_CTRL_RX_CNT_EN | PPE_MRU_MTU_CTRL_TX_CNT_EN); + + regmap_update_bits(priv->regmap, PPE_MC_MTU_CTRL(port), + PPE_MC_MTU_CTRL_TX_CNT_EN, PPE_MC_MTU_CTRL_TX_CNT_EN); + + regmap_update_bits(priv->regmap, PPE_PORT_EG_VLAN(port), + PPE_PORT_EG_VLAN_TX_CNT_EN, PPE_PORT_EG_VLAN_TX_CNT_EN); +} + +int ppe_vsi_alloc(struct qca_ppe_priv *priv) +{ + int vsi; + + vsi = find_first_zero_bit(priv->vsi_bitmap, PPE_VSI_MAX); + if (vsi >= PPE_VSI_MAX) + return -ENOSPC; + + set_bit(vsi, priv->vsi_bitmap); + + regmap_write(priv->regmap, PPE_VSI_TBL(vsi), 0); + regmap_write(priv->regmap, PPE_VSI_TBL(vsi) + 4, + PPE_VSI_TBL_NEW_ADDR_LRN_EN | PPE_VSI_TBL_STA_MOVE_LRN_EN); + + return vsi; +} + +void ppe_vsi_free(struct qca_ppe_priv *priv, u32 vsi) +{ + regmap_write(priv->regmap, PPE_VSI_TBL(vsi), 0); + regmap_write(priv->regmap, PPE_VSI_TBL(vsi) + 4, 0); + clear_bit(vsi, priv->vsi_bitmap); +} + +void ppe_vsi_member_set(struct qca_ppe_priv *priv, u32 vsi, + u32 portmask) +{ + u32 val; + + val = FIELD_PREP(PPE_VSI_TBL_MEMBER, portmask) | + FIELD_PREP(PPE_VSI_TBL_UUC, portmask) | + FIELD_PREP(PPE_VSI_TBL_UMC, portmask) | + FIELD_PREP(PPE_VSI_TBL_BC, portmask); + regmap_write(priv->regmap, PPE_VSI_TBL(vsi), val); + regmap_write(priv->regmap, PPE_VSI_TBL(vsi) + 4, + PPE_VSI_TBL_NEW_ADDR_LRN_EN | PPE_VSI_TBL_STA_MOVE_LRN_EN); +} + +static void ppe_port_vsi_set(struct qca_ppe_priv *priv, int port, u32 vsi) +{ + u32 val; + + regmap_read(priv->regmap, PPE_L3_VP_PORT_TBL(port) + 4, &val); + val &= ~(PPE_L3_VP_VSI_VALID | PPE_L3_VP_VSI); + if (vsi != PPE_VSI_INVALID) { + val |= PPE_L3_VP_VSI_VALID; + val |= FIELD_PREP(PPE_L3_VP_VSI, vsi); + } + regmap_write(priv->regmap, PPE_L3_VP_PORT_TBL(port) + 4, val); +} + +static int ppe_fdb_op_wait(struct qca_ppe_priv *priv, u32 rslt_reg, + u32 cmd_id) +{ + u32 val; + int i; + + for (i = 0; i < 100; i++) { + regmap_read(priv->regmap, rslt_reg, &val); + if (FIELD_GET(PPE_FDB_RSLT_CMD_ID, val) == cmd_id) + return 0; + udelay(1); + } + + return -ETIMEDOUT; +} + +static void ppe_fdb_encode(const unsigned char *addr, int port, u16 vid, + bool is_static, u32 *data0, u32 *data1, u32 *data2) +{ + *data0 = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; + + *data1 = (addr[0] << 8) | addr[1]; + *data1 |= PPE_FDB_DATA1_VALID | PPE_FDB_DATA1_LKP_VALID; + *data1 |= FIELD_PREP(PPE_FDB_DATA1_VSI, vid); + *data1 |= FIELD_PREP(PPE_FDB_DATA1_DST_LO, port); + + *data2 = FIELD_PREP(PPE_FDB_DATA2_DST_TYPE, PPE_FDB_DST_PORT) | + FIELD_PREP(PPE_FDB_DATA2_HIT_AGE, + is_static ? PPE_FDB_AGE_STATIC : 2); +} + +static int ppe_fdb_op(struct qca_ppe_priv *priv, const unsigned char *addr, + int port, u16 vid, u32 op_type) +{ + u32 data0, data1, data2; + int ret; + + ppe_fdb_encode(addr, port, vid, op_type == PPE_FDB_OP_ADD, + &data0, &data1, &data2); + + spin_lock_bh(&priv->fdb_lock); + + regmap_write(priv->regmap, PPE_FDB_OP_DATA0, data0); + regmap_write(priv->regmap, PPE_FDB_OP_DATA1, data1); + regmap_write(priv->regmap, PPE_FDB_OP_DATA2, data2); + regmap_write(priv->regmap, PPE_FDB_OP, + FIELD_PREP(PPE_FDB_OP_TYPE, op_type) | + FIELD_PREP(PPE_FDB_OP_HASH_BLOCK, 3)); + + ret = ppe_fdb_op_wait(priv, PPE_FDB_OP_RSLT, 0); + + spin_unlock_bh(&priv->fdb_lock); + + return ret; +} + +static int ppe_fdb_read_entry(struct qca_ppe_priv *priv, u32 index, + unsigned char *addr, u16 *vid, int *port, + bool *is_static) +{ + u32 data0, data1, data2, cmd_id, val; + int ret; + + cmd_id = index % 15; + + spin_lock_bh(&priv->fdb_lock); + + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA0, 0); + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA1, 0); + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA2, 0); + + val = FIELD_PREP(PPE_FDB_OP_CMD_ID, cmd_id) | + FIELD_PREP(PPE_FDB_OP_TYPE, PPE_FDB_OP_GET) | + FIELD_PREP(PPE_FDB_OP_HASH_BLOCK, 3) | + PPE_FDB_OP_MODE | + FIELD_PREP(PPE_FDB_OP_ENTRY_IDX, index); + regmap_write(priv->regmap, PPE_FDB_RD_OP, val); + + ret = ppe_fdb_op_wait(priv, PPE_FDB_RD_OP_RSLT, cmd_id); + if (ret) + goto unlock; + + regmap_read(priv->regmap, PPE_FDB_RD_RSLT_DATA0, &data0); + regmap_read(priv->regmap, PPE_FDB_RD_RSLT_DATA1, &data1); + regmap_read(priv->regmap, PPE_FDB_RD_RSLT_DATA2, &data2); + +unlock: + spin_unlock_bh(&priv->fdb_lock); + + if (ret) + return ret; + + if (!(data1 & PPE_FDB_DATA1_VALID)) + return -ENOENT; + + if (FIELD_GET(PPE_FDB_DATA2_DST_TYPE, data2) != PPE_FDB_DST_PORT) + return -ENOENT; + + addr[2] = (data0 >> 24) & 0xff; + addr[3] = (data0 >> 16) & 0xff; + addr[4] = (data0 >> 8) & 0xff; + addr[5] = data0 & 0xff; + addr[0] = (data1 >> 8) & 0xff; + addr[1] = data1 & 0xff; + + *vid = FIELD_GET(PPE_FDB_DATA1_VSI, data1); + *port = FIELD_GET(PPE_FDB_DATA1_DST_LO, data1) | + (FIELD_GET(PPE_FDB_DATA2_DST_HI, data2) << 9); + *is_static = FIELD_GET(PPE_FDB_DATA2_HIT_AGE, data2) == PPE_FDB_AGE_STATIC; + + return 0; +} + +static int ppe_fdb_flush(struct qca_ppe_priv *priv) +{ + int ret; + + spin_lock_bh(&priv->fdb_lock); + + regmap_write(priv->regmap, PPE_FDB_OP, + FIELD_PREP(PPE_FDB_OP_TYPE, PPE_FDB_OP_FLUSH)); + + ret = ppe_fdb_op_wait(priv, PPE_FDB_OP_RSLT, 0); + + spin_unlock_bh(&priv->fdb_lock); + + return ret; +} + +static void ppe_fdb_encode_mcast(const unsigned char *addr, u32 portmap, + u16 vid, u32 *data0, u32 *data1, u32 *data2) +{ + *data0 = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; + + *data1 = (addr[0] << 8) | addr[1]; + *data1 |= PPE_FDB_DATA1_VALID | PPE_FDB_DATA1_LKP_VALID; + *data1 |= FIELD_PREP(PPE_FDB_DATA1_VSI, vid); + *data1 |= FIELD_PREP(PPE_FDB_DATA1_DST_LO, portmap); + + *data2 = FIELD_PREP(PPE_FDB_DATA2_DST_HI, portmap >> 9) | + FIELD_PREP(PPE_FDB_DATA2_DST_TYPE, PPE_FDB_DST_PORTMAP) | + FIELD_PREP(PPE_FDB_DATA2_HIT_AGE, PPE_FDB_AGE_STATIC); +} + +static int ppe_fdb_lookup(struct qca_ppe_priv *priv, + const unsigned char *addr, u16 vid, u32 *portmap) +{ + u32 data1, data2; + int ret; + + spin_lock_bh(&priv->fdb_lock); + + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA0, + (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]); + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA1, + ((addr[0] << 8) | addr[1]) | + FIELD_PREP(PPE_FDB_DATA1_VSI, vid)); + regmap_write(priv->regmap, PPE_FDB_RD_OP_DATA2, 0); + + regmap_write(priv->regmap, PPE_FDB_RD_OP, + FIELD_PREP(PPE_FDB_OP_TYPE, PPE_FDB_OP_GET) | + FIELD_PREP(PPE_FDB_OP_HASH_BLOCK, 3)); + + ret = ppe_fdb_op_wait(priv, PPE_FDB_RD_OP_RSLT, 0); + if (ret) + goto out; + + regmap_read(priv->regmap, PPE_FDB_RD_RSLT_DATA1, &data1); + regmap_read(priv->regmap, PPE_FDB_RD_RSLT_DATA2, &data2); + + if (!(data1 & PPE_FDB_DATA1_VALID)) { + ret = -ENOENT; + goto out; + } + + *portmap = FIELD_GET(PPE_FDB_DATA1_DST_LO, data1) | + (FIELD_GET(PPE_FDB_DATA2_DST_HI, data2) << 9); + +out: + spin_unlock_bh(&priv->fdb_lock); + return ret; +} + +static int ppe_fdb_mcast_op(struct qca_ppe_priv *priv, + const unsigned char *addr, u32 portmap, + u16 vid, u32 op_type) +{ + u32 data0, data1, data2; + int ret; + + ppe_fdb_encode_mcast(addr, portmap, vid, &data0, &data1, &data2); + + spin_lock_bh(&priv->fdb_lock); + + regmap_write(priv->regmap, PPE_FDB_OP_DATA0, data0); + regmap_write(priv->regmap, PPE_FDB_OP_DATA1, data1); + regmap_write(priv->regmap, PPE_FDB_OP_DATA2, data2); + regmap_write(priv->regmap, PPE_FDB_OP, + FIELD_PREP(PPE_FDB_OP_TYPE, op_type) | + FIELD_PREP(PPE_FDB_OP_HASH_BLOCK, 3)); + + ret = ppe_fdb_op_wait(priv, PPE_FDB_OP_RSLT, 0); + + spin_unlock_bh(&priv->fdb_lock); + + return ret; +} + +static enum dsa_tag_protocol +qca_ppe_get_tag_protocol(struct dsa_switch *ds, int port, + enum dsa_tag_protocol mprot) +{ + return DSA_TAG_PROTO_OOB; +} + +static int qca_ppe_setup(struct dsa_switch *ds) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + int num_ports = ds->num_ports; + u32 port_mask; + u32 val; + int i; + + port_mask = BIT(num_ports) - 1; + + for (i = 0; i < num_ports; i++) + priv->port_vsi[i] = PPE_VSI_INVALID; + + regmap_write(priv->regmap, PPE_FDB_OP, 0); + + for (i = 0; i < num_ports; i++) { + regmap_write(priv->regmap, PPE_CST_STATE(i), PPE_STP_FORWARDING); + + regmap_write(priv->regmap, PPE_MRU_MTU_CTRL(i), + PPE_DEFAULT_MTU | (PPE_DEFAULT_MTU << PPE_MTU_SHIFT)); + + if (i >= 1) + regmap_write(priv->regmap, PPE_GMAC_MIB_CTRL(i - 1), + PPE_MIB_EN); + + val = PPE_BRIDGE_NEW_LRN_EN | + PPE_BRIDGE_STA_MOVE_EN | + FIELD_PREP(PPE_BRIDGE_PORT_ISOL, port_mask); + if (dsa_is_cpu_port(ds, i)) + val |= PPE_PORT_BRIDGE_CTRL_TXMAC_EN; + regmap_update_bits(priv->regmap, PPE_PORT_BRIDGE_CTRL(i), + PPE_BRIDGE_NEW_LRN_EN | + PPE_BRIDGE_STA_MOVE_EN | + PPE_BRIDGE_PORT_ISOL | + PPE_PORT_BRIDGE_CTRL_TXMAC_EN, + val); + + ppe_port_cnt_enable(priv, i); + } + + qca_ppe_vlan_setup(ds); + + set_bit(0, priv->vsi_bitmap); + val = FIELD_PREP(PPE_VSI_TBL_MEMBER, + dsa_user_ports(ds) | BIT(QCA_PPE_CPU_PORT)) | + FIELD_PREP(PPE_VSI_TBL_UUC, BIT(QCA_PPE_CPU_PORT)) | + FIELD_PREP(PPE_VSI_TBL_UMC, BIT(QCA_PPE_CPU_PORT)) | + FIELD_PREP(PPE_VSI_TBL_BC, BIT(QCA_PPE_CPU_PORT)); + regmap_write(priv->regmap, PPE_VSI_TBL(0), val); + regmap_write(priv->regmap, PPE_VSI_TBL(0) + 4, + PPE_VSI_TBL_NEW_ADDR_LRN_EN | PPE_VSI_TBL_STA_MOVE_LRN_EN); + + for (i = 1; i < num_ports; i++) + ppe_port_vsi_set(priv, i, 0); + + ppe_fdb_flush(priv); + + regmap_update_bits(priv->regmap, PPE_L2_GLOBAL_CONF, + PPE_L2_LRN_EN | PPE_L2_AGE_EN, + PPE_L2_LRN_EN | PPE_L2_AGE_EN); + + ds->ageing_time_min = PPE_AGE_UNIT_MS; + ds->ageing_time_max = (unsigned int)min_t(u64, + (u64)PPE_AGE_UNIT_MS * PPE_AGE_TIMER_MASK, U32_MAX); + ds->assisted_learning_on_cpu_port = true; + + return 0; +} + +static int qca_ppe_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + u32 timer = msecs / PPE_AGE_UNIT_MS; + + regmap_update_bits(priv->regmap, PPE_AGE_TIMER, PPE_AGE_TIMER_MASK, + FIELD_PREP(PPE_AGE_TIMER_MASK, timer)); + + return 0; +} + +static int qca_ppe_port_enable(struct dsa_switch *ds, int port, + struct phy_device *phy) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + + ppe_port_bridge_txmac_set(priv, port, true); + + return 0; +} + +static void qca_ppe_port_disable(struct dsa_switch *ds, int port) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + + ppe_port_bridge_txmac_set(priv, port, false); +} + +static struct qca_ppe_bridge_vsi * +bridge_vsi_find(struct qca_ppe_priv *priv, struct net_device *br_dev) +{ + int i; + + for (i = 0; i < QCA_PPE_MAX_BRIDGES; i++) + if (priv->bridges[i].br_dev == br_dev) + return &priv->bridges[i]; + + return NULL; +} + +static struct qca_ppe_bridge_vsi * +bridge_vsi_alloc(struct qca_ppe_priv *priv, struct net_device *br_dev) +{ + int vsi, i; + + vsi = ppe_vsi_alloc(priv); + if (vsi < 0) + return NULL; + + for (i = 0; i < QCA_PPE_MAX_BRIDGES; i++) { + if (priv->bridges[i].br_dev) + continue; + + priv->bridges[i].br_dev = br_dev; + priv->bridges[i].vsi = vsi; + priv->bridges[i].refcount = 0; + return &priv->bridges[i]; + } + + ppe_vsi_free(priv, vsi); + return NULL; +} + +static void bridge_vsi_put(struct qca_ppe_priv *priv, + struct qca_ppe_bridge_vsi *bvsi) +{ + bvsi->refcount--; + if (bvsi->refcount > 0) + return; + + ppe_vsi_free(priv, bvsi->vsi); + bvsi->br_dev = NULL; + bvsi->vsi = 0; +} + +static void bridge_vsi_members_update(struct qca_ppe_priv *priv, + struct qca_ppe_bridge_vsi *bvsi) +{ + u32 portmask = 0; + int i; + + for (i = 0; i < priv->ds.num_ports; i++) + if (priv->port_vsi[i] != PPE_VSI_INVALID && + priv->port_vsi[i] == bvsi->vsi) + portmask |= BIT(i); + + portmask |= BIT(QCA_PPE_CPU_PORT); + + ppe_vsi_member_set(priv, bvsi->vsi, portmask); +} + +static int qca_ppe_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + struct qca_ppe_bridge_vsi *bvsi; + + bvsi = bridge_vsi_find(priv, bridge.dev); + if (!bvsi) { + bvsi = bridge_vsi_alloc(priv, bridge.dev); + if (!bvsi) + return -ENOSPC; + } + + bvsi->refcount++; + priv->port_vsi[port] = bvsi->vsi; + priv->port_br_dev[port] = bridge.dev; + + ppe_port_vsi_set(priv, port, bvsi->vsi); + bridge_vsi_members_update(priv, bvsi); + + return 0; +} + +static void qca_ppe_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + struct qca_ppe_bridge_vsi *bvsi; + + bvsi = bridge_vsi_find(priv, bridge.dev); + if (!bvsi) + return; + + priv->port_vsi[port] = PPE_VSI_INVALID; + priv->port_br_dev[port] = NULL; + ppe_port_vsi_set(priv, port, PPE_VSI_INVALID); + bridge_vsi_members_update(priv, bvsi); + bridge_vsi_put(priv, bvsi); +} + +static int qca_ppe_port_fdb_add(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + + return ppe_fdb_op(priv, addr, port, vid, PPE_FDB_OP_ADD); +} + +static int qca_ppe_port_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + + return ppe_fdb_op(priv, addr, port, vid, PPE_FDB_OP_DEL); +} + +static int qca_ppe_port_fdb_dump(struct dsa_switch *ds, int port, + dsa_fdb_dump_cb_t *cb, void *data) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + unsigned char addr[ETH_ALEN]; + bool is_static; + int fdb_port; + u16 vid; + u32 i; + + for (i = 0; i < PPE_FDB_TBL_NUM; i++) { + if (ppe_fdb_read_entry(priv, i, addr, &vid, &fdb_port, + &is_static)) + continue; + + if (fdb_port != port) + continue; + + if (cb(addr, vid, is_static, data)) + break; + } + + return 0; +} + +static int qca_ppe_port_mdb_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + u32 portmap; + int ret; + + ret = ppe_fdb_lookup(priv, mdb->addr, mdb->vid, &portmap); + if (ret) + portmap = BIT(QCA_PPE_CPU_PORT); + + portmap |= BIT(port); + + return ppe_fdb_mcast_op(priv, mdb->addr, portmap, + mdb->vid, PPE_FDB_OP_ADD); +} + +static int qca_ppe_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + u32 portmap; + int ret; + + ret = ppe_fdb_lookup(priv, mdb->addr, mdb->vid, &portmap); + if (ret) + return ret; + + portmap &= ~BIT(port); + + if (!portmap || portmap == BIT(QCA_PPE_CPU_PORT)) + return ppe_fdb_mcast_op(priv, mdb->addr, 0, + mdb->vid, PPE_FDB_OP_DEL); + + return ppe_fdb_mcast_op(priv, mdb->addr, portmap, + mdb->vid, PPE_FDB_OP_ADD); +} + +static int qca_ppe_fill_available_pcs(struct phylink_config *config, + struct phylink_pcs **available_pcs, + unsigned int num_available_pcs) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + + return fwnode_phylink_pcs_parse(of_fwnode_handle(dp->dn), available_pcs, + &num_available_pcs); +} + +static void qca_ppe_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config) +{ + struct dsa_port *dp = dsa_to_port(ds, port); + int ret; + + if (port != 0) { + ret = fwnode_phylink_pcs_parse(of_fwnode_handle(dp->dn), NULL, + &config->num_available_pcs); + if (ret) + return; + + config->fill_available_pcs = qca_ppe_fill_available_pcs; + } + + switch (port) { + case 0: + config->mac_capabilities = + MAC_1000FD | MAC_SYM_PAUSE | MAC_ASYM_PAUSE; + + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + config->supported_interfaces); + break; + case 1 ... 4: + config->mac_capabilities = + MAC_1000FD | MAC_100FD | MAC_10FD | + MAC_SYM_PAUSE | MAC_ASYM_PAUSE; + + __set_bit(PHY_INTERFACE_MODE_QSGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_PSGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RGMII_ID, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, + config->supported_interfaces); + break; + case 5 ... 6: + config->mac_capabilities = + MAC_10000FD | MAC_5000FD | MAC_2500FD | + MAC_1000FD | MAC_100FD | MAC_10FD | + MAC_SYM_PAUSE | MAC_ASYM_PAUSE; + + __set_bit(PHY_INTERFACE_MODE_PSGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_USXGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, + config->supported_interfaces); + break; + } + + if (port != 0) + phy_interface_copy(config->pcs_interfaces, + config->supported_interfaces); +} + +static void ppe_pcs_set_mux_hppe(struct qca_ppe_priv *priv, int port, + unsigned int mode, phy_interface_t interface) +{ + u32 mask, val; + + switch (port) { + case 4: + mask = HPPE_PORT4_PCS_SEL; + if (interface == PHY_INTERFACE_MODE_QSGMII || + interface == PHY_INTERFACE_MODE_PSGMII) + val = FIELD_PREP(HPPE_PORT4_PCS_SEL, + HPPE_PORT4_PCS0); + break; + case 5: + mask = HPPE_PORT5_PCS_SEL | HPPE_PORT5_GMAC_SEL; + switch (interface) { + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + val = FIELD_PREP(HPPE_PORT5_PCS_SEL, + HPPE_PORT5_PCS0) | + FIELD_PREP(HPPE_PORT5_GMAC_SEL, + HPPE_PORT5_GMAC_SEL_GMAC); + break; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + val = FIELD_PREP(HPPE_PORT5_PCS_SEL, + HPPE_PORT5_PCS1) | + FIELD_PREP(HPPE_PORT5_GMAC_SEL, + HPPE_PORT5_GMAC_SEL_GMAC); + break; + case PHY_INTERFACE_MODE_2500BASEX: + val = FIELD_PREP(HPPE_PORT5_PCS_SEL, + HPPE_PORT5_PCS1); + /* In-Band is only supported by XGMAC */ + if (!phylink_autoneg_inband(mode)) + val |= FIELD_PREP(HPPE_PORT5_GMAC_SEL, + HPPE_PORT5_GMAC_SEL_GMAC); + break; + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + val = FIELD_PREP(HPPE_PORT5_PCS_SEL, + HPPE_PORT5_PCS1); + break; + default: + return; + } + break; + case 6: + mask = HPPE_PORT6_PCS_SEL | HPPE_PORT6_GMAC_SEL; + val = FIELD_PREP(HPPE_PORT6_PCS_SEL, HPPE_PORT6_PCS2); + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + val |= FIELD_PREP(HPPE_PORT6_GMAC_SEL, + HPPE_PORT6_GMAC_SEL_GMAC); + break; + case PHY_INTERFACE_MODE_2500BASEX: + /* In-Band is only supported by XGMAC */ + if (!phylink_autoneg_inband(mode)) + val |= FIELD_PREP(HPPE_PORT6_GMAC_SEL, + HPPE_PORT6_GMAC_SEL_GMAC); + + break; + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + break; + default: + return; + } + break; + default: + return; + } + + regmap_update_bits(priv->regmap, PPE_PORT_MUX_CTRL, mask, val); +} + +static void ppe_pcs_set_mux_cppe(struct qca_ppe_priv *priv, int port, + unsigned int mode, phy_interface_t interface) +{ + u32 mask, val = 0; + + switch (port) { + case 5: + mask = CPPE_PORT5_PCS_SEL | CPPE_PORT5_GMAC_SEL; + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + val = FIELD_PREP(CPPE_PORT5_PCS_SEL, + CPPE_PORT5_PCS1_CH0) | + CPPE_PORT5_GMAC_SEL; + break; + case PHY_INTERFACE_MODE_2500BASEX: + val = FIELD_PREP(CPPE_PORT5_PCS_SEL, + CPPE_PORT5_PCS1_CH0); + /* In-Band is only supported by XGMAC */ + if (!phylink_autoneg_inband(mode)) + val |= CPPE_PORT5_GMAC_SEL; + break; + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + val = FIELD_PREP(CPPE_PORT5_PCS_SEL, + CPPE_PORT5_PCS1_CH0); + break; + default: + return; + } + break; + default: + return; + } + + regmap_update_bits(priv->regmap, PPE_PORT_MUX_CTRL, mask, val); +} + +static int qca_ppe_mac_prepare(struct phylink_config *config, unsigned int mode, + phy_interface_t interface) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct qca_ppe_priv *priv = ds_to_priv(dp->ds); + const struct ppe_data *d = priv->data; + int port = dp->index; + + if (d->type == PPE_TYPE_IPQ8074) + ppe_pcs_set_mux_hppe(priv, port, mode, interface); + else + ppe_pcs_set_mux_cppe(priv, port, mode, interface); + + return 0; +} + +static void qca_ppe_xgmac_config(struct qca_ppe_priv *priv, int port) +{ + int xgmac = port - 5; + + regmap_set_bits(priv->regmap, PPE_XGMAC_TX_CONF(xgmac), + PPE_XGMAC_JABBER_DISABLE); + + regmap_update_bits(priv->regmap, PPE_XGMAC_RX_CONF(xgmac), + PPE_XGMAC_GMII_MPLS_LAYER_CK | + PPE_XGMAC_WATCHDOG_DISABLE, + PPE_XGMAC_GMII_MPLS_LAYER_CK); + + regmap_update_bits(priv->regmap, PPE_XGMAC_PACKET_FILTER(xgmac), + PPE_XGMAC_PROMISCUOUS | + PPE_XGMAC_PASS_CONTROL_FRAME | + PPE_XGMAC_RATE_ADAPTATION, + PPE_XGMAC_PROMISCUOUS | + FIELD_PREP(PPE_XGMAC_PASS_CONTROL_FRAME, 0x2) | + PPE_XGMAC_RATE_ADAPTATION); + + regmap_update_bits(priv->regmap, PPE_XGMAC_WATCHDOG_TIMEOUT(xgmac), + PPE_XGMAC_WATCHDOG_ENABLE | + PPE_XGMAC_WATCHDOG_THRESHOLD, + PPE_XGMAC_WATCHDOG_ENABLE | + FIELD_PREP(PPE_XGMAC_WATCHDOG_THRESHOLD, 0xb)); + + regmap_update_bits(priv->regmap, PPE_XGMAC_TX_FLOW_CTRL(xgmac), + PPE_XGMAC_PAUSE_TIME, + FIELD_PREP(PPE_XGMAC_PAUSE_TIME, 0xffff)); +} + +static void qca_ppe_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct qca_ppe_priv *priv = ds_to_priv(dp->ds); + int port = dp->index; + + if (state->interface == PHY_INTERFACE_MODE_USXGMII || + state->interface == PHY_INTERFACE_MODE_10GBASER) { + qca_ppe_xgmac_config(priv, port); + } + + if (priv->port_rst[port]) { + reset_control_assert(priv->port_rst[port]); + msleep(150); + reset_control_deassert(priv->port_rst[port]); + } +} + +static void qca_ppe_mac_link_down(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct qca_ppe_priv *priv = ds_to_priv(dp->ds); + int port = dp->index; + + /* + * Disable the PPE switch-fabric TX-MAC for this port before the MAC is + * torn down, and leave it disabled until the MAC is fully back up (see + * qca_ppe_mac_link_up). Across a carrier flap the fabric must not dequeue + * into a MAC that is still being re-clocked: on IPQ807x that can latch the + * port's egress queue-manager scheduler into a state that no longer + * drains, silently black-holing the port's egress until reboot. The + * reference ssdk switch driver gates the bridge TX-MAC the same way on + * every link change (qca_hppe_mac_sw_sync_task); the qca_ppe rewrite + * dropped it. + */ + ppe_port_bridge_txmac_set(priv, port, false); + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + ppe_port_gmac_set(priv, port, false, false); + break; + case PHY_INTERFACE_MODE_2500BASEX: + if (!phylink_autoneg_inband(mode)) + ppe_port_gmac_set(priv, port, false, false); + else + ppe_port_xgmac_set(priv, port, false, false); + break; + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + ppe_port_xgmac_set(priv, port, false, false); + break; + default: + return; + } + + return; +} + +static void qca_ppe_mac_link_up(struct phylink_config *config, + struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, + int speed, int duplex, + bool tx_pause, bool rx_pause) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct qca_ppe_priv *priv = ds_to_priv(dp->ds); + int port = dp->index; + unsigned long rate; + + /* Invalid mode for port < 5 */ + if ((interface == PHY_INTERFACE_MODE_2500BASEX || + interface == PHY_INTERFACE_MODE_USXGMII || + interface == PHY_INTERFACE_MODE_10GBASER) && + port < 5) + return; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + ppe_gmac_link_up(priv, port, speed, duplex, + tx_pause, rx_pause); + break; + case PHY_INTERFACE_MODE_2500BASEX: + if (!phylink_autoneg_inband(mode)) + ppe_gmac_link_up(priv, port, speed, duplex, + tx_pause, rx_pause); + else + ppe_xgmac_link_up(priv, port, interface, speed, + tx_pause, rx_pause); + break; + case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_USXGMII: + ppe_xgmac_link_up(priv, port, interface, speed, + tx_pause, rx_pause); + break; + default: + return; + } + + 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_2500BASEX: + switch (speed) { + case SPEED_10: + rate = 2500000; + break; + case SPEED_100: + rate = 25000000; + break; + case SPEED_1000: + rate = 125000000; + break; + case SPEED_2500: + rate = 312500000; + break; + } + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + switch (speed) { + case SPEED_10: + rate = 1250000; + break; + case SPEED_100: + rate = 12500000; + break; + case SPEED_1000: + rate = 125000000; + break; + case SPEED_2500: + rate = 78125000; + break; + case SPEED_5000: + rate = 156250000; + break; + case SPEED_10000: + rate = 312500000; + break; + } + break; + default: + rate = 125000000; + break; + } + + if (priv->port_rx_clk[port]) + clk_set_rate(priv->port_rx_clk[port], rate); + if (priv->port_tx_clk[port]) + clk_set_rate(priv->port_tx_clk[port], rate); + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + ppe_port_gmac_set(priv, port, true, true); + break; + case PHY_INTERFACE_MODE_2500BASEX: + if (!phylink_autoneg_inband(mode)) + ppe_port_gmac_set(priv, port, true, true); + else + ppe_port_xgmac_set(priv, port, true, true); + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + ppe_port_xgmac_set(priv, port, true, true); + break; + default: + return; + } + + /* + * Re-enable switch-fabric forwarding into the port only now, as the very + * last step, after the MAC has been fully brought back up above. See the + * matching disable in qca_ppe_mac_link_down for why the ordering matters. + */ + ppe_port_bridge_txmac_set(priv, port, true); +} + +static const struct phylink_mac_ops qca_ppe_phylink_mac_ops = { + .mac_prepare = qca_ppe_mac_prepare, + .mac_config = qca_ppe_mac_config, + .mac_link_down = qca_ppe_mac_link_down, + .mac_link_up = qca_ppe_mac_link_up, +}; + +struct qca_ppe_mib_desc { + unsigned int offset; + unsigned int size; + const char name[ETH_GSTRING_LEN]; +}; + +#define MIB32(_off, _name) { .offset = (_off), .size = 1, .name = _name } +#define MIB64(_off, _name) { .offset = (_off), .size = 2, .name = _name } + +static const struct qca_ppe_mib_desc qca_ppe_mib[] = { + MIB32(PPE_MIB_RXBROAD, "rx_broadcast"), + MIB32(PPE_MIB_RXPAUSE, "rx_pause"), + MIB32(PPE_MIB_RXMULTI, "rx_multicast"), + MIB32(PPE_MIB_RXFCSERR, "rx_fcs_error"), + MIB32(PPE_MIB_RXALIGNERR, "rx_align_error"), + MIB32(PPE_MIB_RXRUNT, "rx_runt"), + MIB32(PPE_MIB_RXFRAG, "rx_fragment"), + MIB32(PPE_MIB_RXJUMBOFCSERR, "rx_jumbo_fcs_error"), + MIB32(PPE_MIB_RXJUMBOALIGNERR, "rx_jumbo_align_error"), + MIB32(PPE_MIB_RXPKT64, "rx_64byte"), + MIB32(PPE_MIB_RXPKT65TO127, "rx_65_127byte"), + MIB32(PPE_MIB_RXPKT128TO255, "rx_128_255byte"), + MIB32(PPE_MIB_RXPKT256TO511, "rx_256_511byte"), + MIB32(PPE_MIB_RXPKT512TO1023, "rx_512_1023byte"), + MIB32(PPE_MIB_RXPKT1024TO1518, "rx_1024_1518byte"), + MIB32(PPE_MIB_RXPKT1519TOX, "rx_1519_maxbyte"), + MIB32(PPE_MIB_RXTOOLONG, "rx_too_long"), + MIB64(PPE_MIB_RXGOODBYTE_L, "rx_good_bytes"), + MIB64(PPE_MIB_RXBADBYTE_L, "rx_bad_bytes"), + MIB32(PPE_MIB_RXUNI, "rx_unicast"), + MIB32(PPE_MIB_TXBROAD, "tx_broadcast"), + MIB32(PPE_MIB_TXPAUSE, "tx_pause"), + MIB32(PPE_MIB_TXMULTI, "tx_multicast"), + MIB32(PPE_MIB_TXUNDERRUN, "tx_underrun"), + MIB32(PPE_MIB_TXPKT64, "tx_64byte"), + MIB32(PPE_MIB_TXPKT65TO127, "tx_65_127byte"), + MIB32(PPE_MIB_TXPKT128TO255, "tx_128_255byte"), + MIB32(PPE_MIB_TXPKT256TO511, "tx_256_511byte"), + MIB32(PPE_MIB_TXPKT512TO1023, "tx_512_1023byte"), + MIB32(PPE_MIB_TXPKT1024TO1518, "tx_1024_1518byte"), + MIB32(PPE_MIB_TXPKT1519TOX, "tx_1519_maxbyte"), + MIB64(PPE_MIB_TXBYTE_L, "tx_bytes"), + MIB32(PPE_MIB_TXCOLLISIONS, "tx_collisions"), + MIB32(PPE_MIB_TXABORTCOL, "tx_abort_collision"), + MIB32(PPE_MIB_TXMULTICOL, "tx_multi_collision"), + MIB32(PPE_MIB_TXSINGLECOL, "tx_single_collision"), + MIB32(PPE_MIB_TXEXCESSIVEDEFER, "tx_excessive_defer"), + MIB32(PPE_MIB_TXDEFER, "tx_defer"), + MIB32(PPE_MIB_TXLATECOL, "tx_late_collision"), + MIB32(PPE_MIB_TXUNI, "tx_unicast"), +}; + +static void qca_ppe_get_strings(struct dsa_switch *ds, int port, + u32 stringset, uint8_t *data) +{ + int i; + + if (stringset != ETH_SS_STATS) + return; + + for (i = 0; i < ARRAY_SIZE(qca_ppe_mib); i++) + ethtool_puts(&data, qca_ppe_mib[i].name); +} + +static int qca_ppe_get_sset_count(struct dsa_switch *ds, int port, + int sset) +{ + if (sset != ETH_SS_STATS) + return 0; + + return ARRAY_SIZE(qca_ppe_mib); +} + +static void qca_ppe_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *data) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + int gmac = port - 1; + int i; + + if (port < 1 || port >= ds->num_ports) { + memset(data, 0, sizeof(u64) * ARRAY_SIZE(qca_ppe_mib)); + return; + } + + for (i = 0; i < ARRAY_SIZE(qca_ppe_mib); i++) { + const struct qca_ppe_mib_desc *mib = &qca_ppe_mib[i]; + u32 val, hi; + + regmap_read(priv->regmap, PPE_GMAC_MIB(gmac, mib->offset), &val); + if (mib->size == 2) + regmap_read(priv->regmap, + PPE_GMAC_MIB(gmac, mib->offset + 4), &hi); + + data[i] = val; + if (mib->size == 2) + data[i] |= (u64)hi << 32; + } +} + +static void qca_ppe_port_stp_state_set(struct dsa_switch *ds, int port, + u8 state) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + u32 stp_state; + + switch (state) { + case BR_STATE_DISABLED: + stp_state = PPE_STP_DISABLED; + break; + case BR_STATE_BLOCKING: + case BR_STATE_LISTENING: + stp_state = PPE_STP_BLOCKING; + break; + case BR_STATE_LEARNING: + stp_state = PPE_STP_LEARNING; + break; + case BR_STATE_FORWARDING: + default: + stp_state = PPE_STP_FORWARDING; + break; + } + + regmap_update_bits(priv->regmap, PPE_CST_STATE(port), + PPE_STP_STATE_MASK, stp_state); +} + +static const struct dsa_switch_ops qca_ppe_ops = { + .get_tag_protocol = qca_ppe_get_tag_protocol, + .setup = qca_ppe_setup, + .set_ageing_time = qca_ppe_set_ageing_time, + .port_enable = qca_ppe_port_enable, + .port_disable = qca_ppe_port_disable, + .port_stp_state_set = qca_ppe_port_stp_state_set, + .port_bridge_join = qca_ppe_port_bridge_join, + .port_bridge_leave = qca_ppe_port_bridge_leave, + .port_fdb_add = qca_ppe_port_fdb_add, + .port_fdb_del = qca_ppe_port_fdb_del, + .port_fdb_dump = qca_ppe_port_fdb_dump, + .port_mdb_add = qca_ppe_port_mdb_add, + .port_mdb_del = qca_ppe_port_mdb_del, + .phylink_get_caps = qca_ppe_phylink_get_caps, + .port_vlan_filtering = qca_ppe_port_vlan_filtering, + .port_vlan_add = qca_ppe_port_vlan_add, + .port_vlan_del = qca_ppe_port_vlan_del, + .get_strings = qca_ppe_get_strings, + .get_sset_count = qca_ppe_get_sset_count, + .get_ethtool_stats = qca_ppe_get_ethtool_stats, +}; + +static void ppe_vsi_init(struct qca_ppe_priv *priv) +{ + int i; + + /* All three words must be written back for the HW to latch the entry */ + for (i = 1; i < priv->data->num_ports; i++) { + u32 val[3]; + + regmap_read(priv->regmap, PPE_L3_VP_PORT_TBL(i), &val[0]); + regmap_read(priv->regmap, PPE_L3_VP_PORT_TBL(i) + 4, &val[1]); + regmap_read(priv->regmap, PPE_L3_VP_PORT_TBL(i) + 8, &val[2]); + + val[1] &= ~(PPE_L3_VP_VSI_VALID | PPE_L3_VP_VSI); + val[1] |= PPE_L3_VP_VSI_VALID; + + regmap_write(priv->regmap, PPE_L3_VP_PORT_TBL(i), val[0]); + regmap_write(priv->regmap, PPE_L3_VP_PORT_TBL(i) + 4, val[1]); + regmap_write(priv->regmap, PPE_L3_VP_PORT_TBL(i) + 8, val[2]); + } +} + +static void ppe_mac_hw_init(struct qca_ppe_priv *priv) +{ + const struct ppe_data *d = priv->data; + int lpbk_gmac = d->loopback_port - 1; + int gmac; + + for (gmac = 0; gmac < d->num_gmacs; gmac++) { + regmap_update_bits(priv->regmap, PPE_GMAC_CTRL2(gmac), + PPE_GMAC_CTRL2_MAXFR | PPE_GMAC_CTRL2_CRS_SEL | + PPE_GMAC_CTRL2_TX_THD, + FIELD_PREP(PPE_GMAC_CTRL2_MAXFR, PPE_MAX_FRAME_SIZE) | + FIELD_PREP(PPE_GMAC_CTRL2_TX_THD, 1)); + + regmap_update_bits(priv->regmap, PPE_GMAC_DBG_CTRL(gmac), + PPE_GMAC_DBG_CTRL_HIHG_IPG, + FIELD_PREP(PPE_GMAC_DBG_CTRL_HIHG_IPG, 0xc)); + + regmap_write(priv->regmap, PPE_GMAC_JUMBO_SIZE(gmac), + PPE_MAX_FRAME_SIZE); + } + + regmap_update_bits(priv->regmap, PPE_LPBK_PPS_CTRL(lpbk_gmac), + PPE_LPBK_PPS_THRESHOLD, + FIELD_PREP(PPE_LPBK_PPS_THRESHOLD, 21)); + regmap_write(priv->regmap, PPE_LPBK_ENABLE(lpbk_gmac), + PPE_LPBK_EN | PPE_LPBK_CRC_STRIP_EN); + msleep(100); + ppe_port_bridge_txmac_set(priv, d->loopback_port, true); +} + +static void ppe_ctrlpkt_init(struct qca_ppe_priv *priv) +{ + /* RFDB_TBL[31]: STP multicast MAC 01:80:c2:00:00:00 */ + regmap_write(priv->regmap, PPE_RFDB_TBL(31), 0xc2000000); + regmap_write(priv->regmap, PPE_RFDB_TBL(31) + 4, 0x00010180); + + /* APP_CTRL[0]: match RFDB profile 31, bypass STP, redirect to CPU */ + regmap_write(priv->regmap, PPE_APP_CTRL(0), 0x00000003); + regmap_write(priv->regmap, PPE_APP_CTRL(0) + 4, 0x00000002); + regmap_write(priv->regmap, PPE_APP_CTRL(0) + 8, 0x000093fc); +} + +static int ppe_ipq6018_mux_setup(struct qca_ppe_priv *priv) +{ + struct device_node *ports_np, *port_np; + struct of_phandle_args pcs_args; + int port3_ch = -1; + u32 port; + int ret; + + ports_np = of_get_child_by_name(priv->ds.dev->of_node, "ports"); + if (!ports_np) + return -ENODEV; + + for_each_available_child_of_node(ports_np, port_np) { + ret = of_property_read_u32(port_np, "reg", &port); + if (ret) + continue; + + if (port != 3) + continue; + + ret = of_parse_phandle_with_args(port_np, "pcs-handle", + "#pcs-cells", 0, &pcs_args); + if (ret) + continue; + + port3_ch = pcs_args.args[0]; + } + + of_node_put(ports_np); + + /* FIXME: better investigate this */ + if (port3_ch == 4) + regmap_update_bits(priv->regmap, PPE_PORT_MUX_CTRL, + CPPE_PORT3_PCS_SEL | CPPE_PCS0_CH4_SEL, + FIELD_PREP(CPPE_PORT3_PCS_SEL, + CPPE_PORT3_PCS0_CH4) | + CPPE_PCS0_CH4_SEL); + + return 0; +} + +static const struct regmap_config ppe_regmap_cfg = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +}; + +static int qca_ppe_probe(struct platform_device *pdev) +{ + const struct ppe_data *data; + struct device_node *ports; + struct qca_ppe_priv *priv; + struct reset_control *rst; + struct dsa_switch *ds; + void __iomem *base; + int ret, i; + + data = of_device_get_match_data(&pdev->dev); + if (!data) + return -ENODEV; + + ports = of_get_child_by_name(pdev->dev.of_node, "ports"); + if (!ports) + return -ENODEV; + of_node_put(ports); + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->data = data; + + priv->num_clks = devm_clk_bulk_get_all(&pdev->dev, &priv->clks); + if (priv->num_clks < 0) + return priv->num_clks; + + ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); + if (ret) + return ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), "failed to ioremap resource"); + + priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &ppe_regmap_cfg); + if (IS_ERR(priv->regmap)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->regmap), "failed to init regmap"); + + rst = devm_reset_control_get(&pdev->dev, "ppe_rst"); + if (IS_ERR(rst)) { + ret = PTR_ERR(rst); + goto err_clk; + } + reset_control_assert(rst); + msleep(100); + reset_control_deassert(rst); + msleep(100); + + spin_lock_init(&priv->fdb_lock); + + ds = &priv->ds; + ds->dev = &pdev->dev; + ds->num_ports = data->num_ports; + ds->ops = &qca_ppe_ops; + ds->priv = priv; + ds->phylink_mac_ops = &qca_ppe_phylink_mac_ops; + + for (i = 1; i < data->num_ports; i++) { + char name[32]; + + snprintf(name, sizeof(name), "port%d_rx", i); + priv->port_rx_clk[i] = devm_clk_get_optional(&pdev->dev, name); + if (IS_ERR(priv->port_rx_clk[i])) { + ret = PTR_ERR(priv->port_rx_clk[i]); + goto err_clk; + } + + snprintf(name, sizeof(name), "port%d_tx", i); + priv->port_tx_clk[i] = devm_clk_get_optional(&pdev->dev, name); + if (IS_ERR(priv->port_tx_clk[i])) { + ret = PTR_ERR(priv->port_tx_clk[i]); + goto err_clk; + } + + snprintf(name, sizeof(name), "nss_port%d_rst", i); + priv->port_rst[i] = devm_reset_control_get_optional_exclusive( + &pdev->dev, name); + if (IS_ERR(priv->port_rst[i])) { + ret = PTR_ERR(priv->port_rst[i]); + goto err_clk; + } + } + + ppe_vsi_init(priv); + + ppe_scheduler_init(priv); + + ppe_mac_hw_init(priv); + ppe_ctrlpkt_init(priv); + + + if (data->type == PPE_TYPE_IPQ6018) { + ret = ppe_ipq6018_mux_setup(priv); + if (ret) + goto err_clk; + } + + ret = dsa_register_switch(ds); + if (ret) + goto err_clk; + + platform_set_drvdata(pdev, priv); + + return 0; + +err_clk: + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); + return ret; +} + +static void qca_ppe_remove(struct platform_device *pdev) +{ + struct qca_ppe_priv *priv = platform_get_drvdata(pdev); + + dsa_unregister_switch(&priv->ds); + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); +} + +static const struct ppe_data ipq6018_ppe_data = { + .type = PPE_TYPE_IPQ6018, + .num_ports = 7, + .num_gmacs = 5, + .loopback_port = 6, + .bm_phy_end = 12, + .bm_internal_start = 13, + .bm_group_buf = 1024, + .bm_ceiling = 216, + .qm_total_buf = 1506, + .qm_ceiling = 216, + .qm_green_max = 144, + .psch_tdm = &cppe_psch_tdm_data, + .bm_tdm = &cppe_bm_tdm_data, +}; + +static const struct ppe_data ipq8074_ppe_data = { + .type = PPE_TYPE_IPQ8074, + .num_ports = 8, + .num_gmacs = 6, + .loopback_port = 7, + .bm_phy_end = 13, + .bm_internal_start = 14, + .bm_group_buf = 1400, + .bm_ceiling = 250, + .qm_total_buf = 2000, + .qm_ceiling = 400, + .qm_green_max = 250, + .psch_tdm = &hppe_psch_tdm_data, + .bm_tdm = &hppe_bm_tdm_data, +}; + +static const struct of_device_id qca_ppe_of_match[] = { + { .compatible = "qualcomm,ipq6018-ppe", .data = &ipq6018_ppe_data }, + { .compatible = "qualcomm,ipq8074-ppe", .data = &ipq8074_ppe_data }, + {}, +}; +MODULE_DEVICE_TABLE(of, qca_ppe_of_match); + +static struct platform_driver qca_ppe_driver = { + .driver = { + .name = "qca-ppe", + .of_match_table = qca_ppe_of_match, + }, + .probe = qca_ppe_probe, + .remove = qca_ppe_remove, +}; +module_platform_driver(qca_ppe_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Driver for Qualcomm PPE switches"); diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_scheduler.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_scheduler.c new file mode 100644 index 00000000000000..481f3439bec3b2 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_scheduler.c @@ -0,0 +1,781 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca_ppe.h" + +struct psch_tdm_entry { + u8 en_port; + u8 de_port; +}; + +struct bm_tdm_entry { + u8 port; + u8 dir; +}; + +enum psch_tdm_port { + TDM_PORT_CPU = 0, + TDM_PORT_PHY_1, + TDM_PORT_PHY_2, + TDM_PORT_PHY_3, + TDM_PORT_PHY_4, + TDM_PORT_FAB_0, + TDM_PORT_FAB_1, + TDM_PORT_PHY_7, +}; + +enum bm_tdm_dir { + TDM_DIR_INGRESS = 0, + TDM_DIR_EGRESS, +}; + +/* CPPE (IPQ60xx) port scheduler TDM -- 50 entries */ +const struct psch_tdm_entry cppe_psch_tdm[] = { + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_PHY_3, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_PHY_1 }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_PHY_1, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_4 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_7 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_2 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_PHY_2, TDM_PORT_FAB_0 }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_4 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_7 }, + { TDM_PORT_FAB_1, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_7, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_3 }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_4 }, + { TDM_PORT_PHY_3, TDM_PORT_CPU }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_PHY_1, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_7 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_4 }, + { TDM_PORT_FAB_1, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_2 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_2, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_7 }, + { TDM_PORT_CPU, TDM_PORT_PHY_4 }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_1 }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_0 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_PHY_3 }, +}; + +/* HPPE (IPQ807x) port scheduler TDM -- 50 entries + * Source: ssdk_hppe.c port_schedulerTDM_PORT_CPU_tbl[] */ +const struct psch_tdm_entry hppe_psch_tdm[] = { + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_7 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_1 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_1, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_2 }, + { TDM_PORT_FAB_1, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_2, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_7 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_PHY_3 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_3, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_4 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_4, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_CPU }, + { TDM_PORT_FAB_1, TDM_PORT_PHY_7 }, + { TDM_PORT_CPU, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_7, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_1 }, + { TDM_PORT_FAB_1, TDM_PORT_FAB_0 }, + { TDM_PORT_PHY_1, TDM_PORT_CPU }, + { TDM_PORT_FAB_0, TDM_PORT_FAB_1 }, + { TDM_PORT_CPU, TDM_PORT_PHY_2 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_2, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_PHY_7 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_7, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_PHY_3 }, + { TDM_PORT_FAB_1, TDM_PORT_CPU }, + { TDM_PORT_PHY_3, TDM_PORT_FAB_0 }, + { TDM_PORT_CPU, TDM_PORT_FAB_1 }, + { TDM_PORT_FAB_0, TDM_PORT_PHY_4 }, +}; + +/* CPPE buffer manager TDM -- 98 entries */ +const struct bm_tdm_entry cppe_bm_tdm[] = { + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_2, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_3, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_1, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_2, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_3, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, +}; + +/* HPPE buffer manager TDM -- 96 entries + * Source: ssdk_hppe.c port_tdmTDM_PORT_CPU_tbl[] */ +const struct bm_tdm_entry hppe_bm_tdm[] = { + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_3, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_2, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_4, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_3, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_2, TDM_DIR_EGRESS }, + { TDM_PORT_CPU, TDM_DIR_INGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_0, TDM_DIR_EGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_INGRESS }, + { TDM_PORT_CPU, TDM_DIR_EGRESS }, + { TDM_PORT_PHY_7, TDM_DIR_INGRESS }, + { TDM_PORT_FAB_1, TDM_DIR_EGRESS }, +}; + +static void ppe_tdm_init(struct qca_ppe_priv *priv) +{ + const struct ppe_data *data = priv->data; + const struct psch_tdm_entry *psch; + const struct bm_tdm_entry *bm; + int psch_num, bm_num; + u8 prev_de_port; + int i; + + psch = data->psch_tdm->entries; + psch_num = data->psch_tdm->num; + + bm = data->bm_tdm->entries; + bm_num = data->bm_tdm->num; + + /* + * The port scheduler TDM is circular with the bitmap + * composed of the + * NOT (dequeue port (de_port) OR the previous dequeue port) + * Each bit correspond to a port from 0 to 7. + * + * For the first element, we refer to the last dequeue port + * (since it's circular). + * + * Taking an example for the first element: + * We dequeue port 6 and the last element dequeue port 3 + * So the bitmap will be ~(BIT(6) | BIT(3)) = 0xb7 + * + * Example for the second element: + * We dequeque port 0 and previously we dequeued port 6 + * So the bitmap will be ~(BIT(0) | BIT(6)) = 0xbe + */ + prev_de_port = psch[psch_num - 1].de_port; + for (i = 0; i < psch_num; i++) { + u8 bmp = ~(BIT(prev_de_port) | BIT(psch[i].de_port)); + + regmap_write(priv->regmap, PPE_TM_PSCH_TDM(i), + FIELD_PREP(PPE_PSCH_ENS_PORT_BMP, bmp) | + FIELD_PREP(PPE_PSCH_ENS_PORT, psch[i].en_port) | + FIELD_PREP(PPE_PSCH_DES_PORT, psch[i].de_port)); + + prev_de_port = BIT(psch[i].de_port); + } + + regmap_write(priv->regmap, PPE_TM_TDM_DEPTH, + FIELD_PREP(PPE_TM_TDM_DEPTH_MASK, psch_num)); + + for (i = 0; i < bm_num; i++) + regmap_write(priv->regmap, PPE_PRX_TDM_CFG(i), + FIELD_PREP(PPE_TDM_PORT_NUM, bm[i].port) | + FIELD_PREP(PPE_TDM_DIR, bm[i].dir) | + PPE_TDM_VALID); + + regmap_write(priv->regmap, PPE_PRX_TDM_CTRL, + FIELD_PREP(PPE_TDM_DEPTH, bm_num) | + PPE_TDM_EN); +} + +static void ppe_bm_init(struct qca_ppe_priv *priv) +{ + const struct ppe_data *d = priv->data; + int i; + + for (i = 0; i < PPE_BM_PORTS; i++) { + bool fc_en = (i < PPE_BM_PHY_START || i > d->bm_phy_end); + + regmap_write(priv->regmap, PPE_BM_FC_MODE(i), + fc_en ? PPE_BM_FC_EN : 0); + regmap_write(priv->regmap, PPE_BM_GROUP_ID(i), 0); + } + + regmap_write(priv->regmap, PPE_BM_SHARED_GRP(0), + FIELD_PREP(PPE_BM_SHARED_LIMIT, d->bm_group_buf)); + + for (i = 0; i < PPE_BM_PORTS; i++) { + u16 react; + u32 w0, w1; + + if (i < PPE_BM_PHY_START) + react = 100; + else if (i >= d->bm_internal_start) + react = 40; + else + react = 128; + + w0 = FIELD_PREP(PPE_BM_REACT_LIMIT, react) | + FIELD_PREP(PPE_BM_RESUME_OFF, 36) | + FIELD_PREP(PPE_BM_CEILING_LO, d->bm_ceiling & 0x7); + w1 = FIELD_PREP(PPE_BM_CEILING_HI, d->bm_ceiling >> 3) | + FIELD_PREP(PPE_BM_WEIGHT, 4) | + PPE_BM_DYNAMIC; + + regmap_write(priv->regmap, PPE_BM_PORT_FC_W0(i), w0); + regmap_write(priv->regmap, PPE_BM_PORT_FC_W1(i), w1); + } +} + +static void ppe_qm_map_set(struct qca_ppe_priv *priv, u32 index, + u8 queue_base, u8 profile) +{ + regmap_write(priv->regmap, PPE_QM_UCAST_MAP(index), + FIELD_PREP(PPE_QM_PROFILE_ID, profile) | + FIELD_PREP(PPE_QM_QUEUE_ID, queue_base)); +} + +static const u8 port_queue_base[PPE_NUM_PORTS] = { + 0, 144, 160, 176, 192, 208, 224, 240, +}; + +static const u8 port_l0_cdrr_num[PPE_NUM_PORTS] = { + 48, 16, 16, 16, 16, 16, 16, 16, +}; + +static void ppe_qm_init(struct qca_ppe_priv *priv) +{ + const struct ppe_data *d = priv->data; + int i, pri; + + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 2, 8, 0); + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 3, 128, 8); + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 4, 128, 8); + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 5, 0, 0); + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 6, 8, 0); + ppe_qm_map_set(priv, QM_SERVICE_CODE_OFFSET + 7, 240, 0); + + for (i = 0; i < PPE_NUM_PORTS; i++) + ppe_qm_map_set(priv, QM_VP_PORT_OFFSET + i, + port_queue_base[i], i); + + for (i = 0; i < PPE_NUM_PORTS; i++) { + u8 max_pri = port_l0_cdrr_num[i]; + u8 profile; + + if (max_pri > 16) + max_pri = 1; + + for (pri = 0; pri < 16; pri++) { + u8 cls = (pri >= max_pri) ? max_pri - 1 : pri; + + if (i == 0) { + profile = 0; + regmap_write(priv->regmap, + PPE_QM_UCAST_PRI_MAP(profile * 16 + pri), + FIELD_PREP(PPE_QM_PRI_CLASS, cls)); + profile = 15; + regmap_write(priv->regmap, + PPE_QM_UCAST_PRI_MAP(profile * 16 + pri), + FIELD_PREP(PPE_QM_PRI_CLASS, cls)); + } else { + regmap_write(priv->regmap, + PPE_QM_UCAST_PRI_MAP(i * 16 + pri), + FIELD_PREP(PPE_QM_PRI_CLASS, cls)); + } + } + } + + for (i = 0; i < 256; i++) { + regmap_write(priv->regmap, PPE_QM_UCAST_HASH_MAP(15 * 256 + i), 0); + regmap_write(priv->regmap, PPE_QM_UCAST_HASH_MAP(14 * 256 + i), 0); + } + + ppe_qm_map_set(priv, QM_CPU_CODE_OFFSET + 101, + port_queue_base[0] + 0, 0); + + for (i = 0; i < PPE_MAX_SERVICE_CODES; i++) { + u32 idx = QM_SERVICE_CODE_OFFSET + (1 << 8) + i; + + if (i == 2 || i == 6) + ppe_qm_map_set(priv, idx, 8, 0); + else if (i == 3 || i == 4) + ppe_qm_map_set(priv, idx, 128, 8); + else + ppe_qm_map_set(priv, idx, 4, 0); + } + + for (i = 0; i < PPE_MAX_CPU_CODES; i++) + ppe_qm_map_set(priv, QM_CPU_CODE_OFFSET + (1 << 8) + i, 4, 0); + + for (i = 0; i < PPE_NUM_PORTS; i++) + ppe_qm_map_set(priv, QM_VP_PORT_OFFSET + (1 << 8) + i, + port_queue_base[i], i); + + for (i = PPE_NUM_PORTS; i < PPE_MAX_VPORT; i++) + ppe_qm_map_set(priv, QM_VP_PORT_OFFSET + (1 << 8) + i, 4, 0); + + for (i = 0; i < PPE_L0_UCAST_QUEUES; i++) { + regmap_write(priv->regmap, PPE_QM_AC_UNI_W0(i), + PPE_AC_EN | + PPE_AC_SHARED_DYNAMIC | + FIELD_PREP(PPE_AC_SHARED_WEIGHT, 4) | + FIELD_PREP(PPE_AC_SHARED_CEILING, d->qm_ceiling)); + regmap_write(priv->regmap, PPE_QM_AC_UNI_W1(i), 0); + regmap_write(priv->regmap, PPE_QM_AC_UNI_W2(i), 0); + regmap_write(priv->regmap, PPE_QM_AC_UNI_W3(i), + FIELD_PREP(PPE_AC_GRN_RESUME_OFF, 36)); + } + + for (i = 0; i < PPE_L0_QUEUES - PPE_L0_UCAST_QUEUES; i++) { + regmap_write(priv->regmap, PPE_QM_AC_MUL_W0(i), + PPE_AC_MUL_EN | + FIELD_PREP(PPE_AC_MUL_CEILING, d->qm_ceiling) | + FIELD_PREP(PPE_AC_MUL_GRN_MAX_LO, d->qm_green_max & 0x1f)); + regmap_write(priv->regmap, PPE_QM_AC_MUL_W1(i), + FIELD_PREP(PPE_AC_MUL_GRN_MAX_HI, d->qm_green_max >> 5)); + regmap_write(priv->regmap, PPE_QM_AC_MUL_W2(i), + FIELD_PREP(PPE_AC_MUL_GRN_RESUME_HI, 36)); + } + + regmap_write(priv->regmap, PPE_QM_AC_GRP_W0(0), 0); + regmap_write(priv->regmap, PPE_QM_AC_GRP_W1(0), + FIELD_PREP(PPE_AC_GRP_LIMIT, d->qm_total_buf)); + regmap_write(priv->regmap, PPE_QM_AC_GRP_W2(0), 0); + + regmap_update_bits(priv->regmap, PPE_EG_BRIDGE_CONFIG, + PPE_EG_QUEUE_CNT_EN, PPE_EG_QUEUE_CNT_EN); +} + +struct l1_cfg { + u8 index; + u8 port; + u8 pri; + u8 drr; +}; + +static const struct l1_cfg l1_cfg[] = { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 36, 1, 0, 8 }, + { 37, 1, 1, 9 }, + { 40, 2, 0, 12 }, + { 41, 2, 1, 13 }, + { 44, 3, 0, 16 }, + { 45, 3, 1, 17 }, + { 48, 4, 0, 20 }, + { 49, 4, 1, 21 }, + { 52, 5, 0, 24 }, + { 53, 5, 1, 25 }, + { 56, 6, 0, 28 }, + { 57, 6, 1, 29 }, + { 60, 7, 0, 32 }, + { 61, 7, 1, 33 }, +}; + +static void ppe_l1_scheduler_init(struct qca_ppe_priv *priv) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(l1_cfg); i++) { + const struct l1_cfg *c = &l1_cfg[i]; + u32 sp_idx; + + regmap_write(priv->regmap, PPE_TM_L1_FLOW_MAP(c->index), + FIELD_PREP(PPE_L1_SP_ID, c->port) | + FIELD_PREP(PPE_L1_C_PRI, c->pri) | + FIELD_PREP(PPE_L1_E_PRI, c->pri) | + FIELD_PREP(PPE_L1_C_DRR_WT, 1) | + FIELD_PREP(PPE_L1_E_DRR_WT, 1)); + + sp_idx = c->port * 8 + c->pri; + regmap_write(priv->regmap, PPE_TM_L1_C_SP(sp_idx), + FIELD_PREP(PPE_L1_SP_DRR_ID, c->drr)); + + regmap_write(priv->regmap, PPE_TM_L1_E_SP(sp_idx), + FIELD_PREP(PPE_L1_SP_DRR_ID, c->drr)); + + regmap_write(priv->regmap, PPE_TM_L1_PORT_MAP(c->index), + FIELD_PREP(PPE_L1_PORT_NUM, c->port)); + } +} + +struct l0_cfg { + u16 queue; + u8 port; + u8 sp; + u8 cpri; + u8 cdrr; + u8 epri; + u8 edrr; +}; + +static const struct l0_cfg l0_port0[] = { + { 0, 0, 0, 0, 0, 0, 0 }, { 4, 0, 0, 0, 0, 0, 0 }, + { 8, 0, 0, 0, 0, 0, 0 }, { 256, 0, 0, 0, 0, 0, 0 }, + { 260, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 1, 1, 1, 1 }, { 5, 0, 0, 1, 1, 1, 1 }, + { 9, 0, 0, 1, 1, 1, 1 }, { 257, 0, 0, 1, 1, 1, 1 }, + { 261, 0, 0, 1, 1, 1, 1 }, + { 2, 0, 0, 2, 2, 2, 2 }, { 6, 0, 0, 2, 2, 2, 2 }, + { 10, 0, 0, 2, 2, 2, 2 }, { 258, 0, 0, 2, 2, 2, 2 }, + { 262, 0, 0, 2, 2, 2, 2 }, + { 3, 0, 0, 3, 3, 3, 3 }, { 7, 0, 0, 3, 3, 3, 3 }, + { 11, 0, 0, 3, 3, 3, 3 }, { 259, 0, 0, 3, 3, 3, 3 }, + { 263, 0, 0, 3, 3, 3, 3 }, +}; + +static void ppe_l0_entry_write(struct qca_ppe_priv *priv, const struct l0_cfg *c) +{ + u32 sp_idx; + + regmap_write(priv->regmap, PPE_TM_L0_FLOW_MAP(c->queue), + FIELD_PREP(PPE_L0_SP_ID, c->sp) | + FIELD_PREP(PPE_L0_C_PRI, c->cpri) | + FIELD_PREP(PPE_L0_E_PRI, c->epri) | + FIELD_PREP(PPE_L0_C_DRR_WT, 1) | + FIELD_PREP(PPE_L0_E_DRR_WT, 1)); + + sp_idx = c->sp * 8 + c->cpri; + regmap_write(priv->regmap, PPE_TM_L0_C_SP(sp_idx), + FIELD_PREP(PPE_L0_SP_DRR_ID, c->cdrr)); + + sp_idx = c->sp * 8 + c->epri; + regmap_write(priv->regmap, PPE_TM_L0_E_SP(sp_idx), + FIELD_PREP(PPE_L0_SP_DRR_ID, c->edrr)); + + regmap_write(priv->regmap, PPE_TM_L0_PORT_MAP(c->queue), + FIELD_PREP(PPE_L0_PORT_NUM, c->port)); +} + +struct port_l0_params { + u16 ucast_base; + u8 ucast_count; + u16 mcast_base; + u8 mcast_count; + u8 sp_base; + u8 cdrr_base; + u8 port; +}; + +static const struct port_l0_params port_l0[] = { + { 144, 16, 272, 4, 36, 48, 1 }, + { 160, 16, 276, 4, 40, 64, 2 }, + { 176, 16, 280, 4, 44, 80, 3 }, + { 192, 16, 284, 4, 48, 96, 4 }, + { 208, 16, 288, 4, 52, 112, 5 }, + { 224, 16, 292, 4, 56, 128, 6 }, + { 240, 16, 296, 1, 60, 144, 7 }, +}; + +static void ppe_l0_scheduler_init(struct qca_ppe_priv *priv) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(l0_port0); i++) + ppe_l0_entry_write(priv, &l0_port0[i]); + + for (i = 0; i < ARRAY_SIZE(port_l0); i++) { + const struct port_l0_params *p = &port_l0[i]; + u16 bases[] = { p->ucast_base, p->mcast_base }; + u8 counts[] = { p->ucast_count, p->mcast_count }; + int k; + + for (k = 0; k < 2; k++) { + for (j = 0; j < counts[k]; j++) { + struct l0_cfg c = { + .queue = bases[k] + j, + .port = p->port, + .sp = p->sp_base + j / PPE_MAX_SP_PRI, + .cpri = j % PPE_MAX_SP_PRI, + .cdrr = p->cdrr_base + j, + .epri = j % PPE_MAX_SP_PRI, + .edrr = p->cdrr_base + j, + }; + + ppe_l0_entry_write(priv, &c); + } + } + } +} + +static void ppe_edma_ring_map_init(struct qca_ppe_priv *priv) +{ + int i; + + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(0), 0xf); + for (i = 1; i < 10; i++) + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(0) + i * 4, 0); + + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(3), 0xf0); + for (i = 1; i < 10; i++) + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(3) + i * 4, 0); + + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(1), 0xf00); + for (i = 1; i < 10; i++) + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(1) + i * 4, 0); + + for (i = 0; i < 10; i++) + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(2) + i * 4, 0); + regmap_write(priv->regmap, PPE_TM_RING_Q_MAP(2) + 4 * 4, 0xffff); +} + +static void ppe_qos_init(struct qca_ppe_priv *priv) +{ + int i; + u32 qos_bits; + + qos_bits = FIELD_PREP(PPE_QOS_PREHEADER_PREC, 3) | + FIELD_PREP(PPE_QOS_DSCP_PREC, 1) | + FIELD_PREP(PPE_QOS_FLOW_PREC, 4) | + FIELD_PREP(PPE_QOS_ACL_PREC, 2); + + for (i = 0; i < PPE_NUM_PORTS; i++) + regmap_update_bits(priv->regmap, PPE_PRX_MRU_MTU_W1(i), + PPE_QOS_PCP_GRP | PPE_QOS_DSCP_GRP | + PPE_QOS_PREHEADER_PREC | PPE_QOS_PCP_PREC | + PPE_QOS_DSCP_PREC | PPE_QOS_FLOW_PREC | + PPE_QOS_ACL_PREC, + qos_bits); +} + +const struct psch_tdm_data cppe_psch_tdm_data = { + .entries = cppe_psch_tdm, + .num = ARRAY_SIZE(cppe_psch_tdm), +}; + +const struct psch_tdm_data hppe_psch_tdm_data = { + .entries = hppe_psch_tdm, + .num = ARRAY_SIZE(hppe_psch_tdm), +}; + +const struct bm_tdm_data cppe_bm_tdm_data = { + .entries = cppe_bm_tdm, + .num = ARRAY_SIZE(cppe_bm_tdm), +}; + +const struct bm_tdm_data hppe_bm_tdm_data = { + .entries = hppe_bm_tdm, + .num = ARRAY_SIZE(hppe_bm_tdm), +}; + +void ppe_scheduler_init(struct qca_ppe_priv *priv) +{ + ppe_tdm_init(priv); + ppe_bm_init(priv); + ppe_qm_init(priv); + ppe_l1_scheduler_init(priv); + ppe_l0_scheduler_init(priv); + ppe_edma_ring_map_init(priv); + ppe_qos_init(priv); +} diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_vlan.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_vlan.c new file mode 100644 index 00000000000000..f2c3e2ef2e7e39 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_vlan.c @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include +#include + +#include "qca_ppe.h" + +static int ppe_xlt_idx_alloc(struct qca_ppe_priv *priv) +{ + int idx; + + idx = find_first_zero_bit(priv->xlt_bitmap, PPE_XLT_TBL_NUM); + if (idx >= PPE_XLT_TBL_NUM) + return -ENOSPC; + + set_bit(idx, priv->xlt_bitmap); + return idx; +} + +static void ppe_xlt_rule_set(struct qca_ppe_priv *priv, int idx, + u8 port_bmp, u16 vid, bool untagged) +{ + u32 w0, w1; + + w0 = PPE_XLT_VALID | FIELD_PREP(PPE_XLT_PORT_BMP, port_bmp); + w1 = 0; + + if (untagged) { + w0 |= PPE_XLT_CKEY_FMT_0; + } else { + w1 |= FIELD_PREP(PPE_XLT_CKEY_FMT_1, + PPE_XLT_CKEY_TAGGED >> 1); + w1 |= PPE_XLT_CKEY_VID_INCL; + w1 |= FIELD_PREP(PPE_XLT_CKEY_VID, vid); + } + + regmap_write(priv->regmap, PPE_XLT_RULE_TBL(idx), w0); + regmap_write(priv->regmap, PPE_XLT_RULE_W1(idx), w1); + regmap_write(priv->regmap, PPE_XLT_RULE_TBL(idx) + 8, 0); +} + +static void ppe_xlt_action_set(struct qca_ppe_priv *priv, int idx, + u32 vsi, bool strip_ctag) +{ + u32 w0 = 0, w1; + + if (strip_ctag) + w0 = FIELD_PREP(PPE_XLT_CVID_CMD, PPE_XLT_CVID_DEL); + + w1 = PPE_XLT_VSI_CMD | FIELD_PREP(PPE_XLT_VSI, vsi); + + regmap_write(priv->regmap, PPE_XLT_ACTION_TBL(idx), w0); + regmap_write(priv->regmap, PPE_XLT_ACTION_W1(idx), w1); +} + +static void ppe_xlt_clear(struct qca_ppe_priv *priv, int idx) +{ + regmap_write(priv->regmap, PPE_XLT_RULE_TBL(idx), 0); + regmap_write(priv->regmap, PPE_XLT_RULE_W1(idx), 0); + regmap_write(priv->regmap, PPE_XLT_RULE_TBL(idx) + 8, 0); + regmap_write(priv->regmap, PPE_XLT_ACTION_TBL(idx), 0); + regmap_write(priv->regmap, PPE_XLT_ACTION_W1(idx), 0); +} + +static void ppe_xlt_idx_free(struct qca_ppe_priv *priv, int *idx) +{ + ppe_xlt_clear(priv, *idx); + clear_bit(*idx, priv->xlt_bitmap); + *idx = -1; +} + +static void ppe_eg_vsi_tag_port_set(struct qca_ppe_priv *priv, + u32 vsi, int port, u32 mode) +{ + regmap_update_bits(priv->regmap, PPE_EG_VSI_TAG(vsi), + 0x3 << (port * 2), (mode & 0x3) << (port * 2)); +} + +static void ppe_port_def_cvid_set(struct qca_ppe_priv *priv, + int port, u16 vid, bool enable) +{ + regmap_update_bits(priv->regmap, PPE_PORT_DEF_VID(port), + PPE_PORT_DEF_CVID | PPE_PORT_DEF_CVID_EN, + enable ? FIELD_PREP(PPE_PORT_DEF_CVID, vid) | + PPE_PORT_DEF_CVID_EN : 0); +} + +static struct qca_ppe_vlan_entry * +ppe_vlan_find(struct qca_ppe_priv *priv, struct net_device *br_dev, + u16 vid) +{ + int i; + + for (i = 0; i < PPE_VSI_MAX; i++) + if (priv->vlans[i].br_dev == br_dev && + priv->vlans[i].vid == vid) + return &priv->vlans[i]; + + return NULL; +} + +static struct qca_ppe_vlan_entry * +ppe_vlan_alloc(struct qca_ppe_priv *priv, struct net_device *br_dev, + u16 vid) +{ + struct qca_ppe_vlan_entry *entry; + int vsi, i; + + vsi = ppe_vsi_alloc(priv); + if (vsi < 0) + return NULL; + + for (i = 0; i < PPE_VSI_MAX; i++) { + if (priv->vlans[i].br_dev) + continue; + + entry = &priv->vlans[i]; + entry->br_dev = br_dev; + entry->vid = vid; + entry->vsi = vsi; + entry->ports = 0; + entry->pvid_ports = 0; + entry->xlt_idx = -1; + entry->xlt_pvid_idx = -1; + return entry; + } + + ppe_vsi_free(priv, vsi); + return NULL; +} + +static void ppe_vlan_free(struct qca_ppe_priv *priv, + struct qca_ppe_vlan_entry *entry) +{ + if (entry->xlt_idx >= 0) + ppe_xlt_idx_free(priv, &entry->xlt_idx); + if (entry->xlt_pvid_idx >= 0) + ppe_xlt_idx_free(priv, &entry->xlt_pvid_idx); + ppe_vsi_free(priv, entry->vsi); + entry->br_dev = NULL; +} + +static void ppe_vlan_members_update(struct qca_ppe_priv *priv, + struct qca_ppe_vlan_entry *entry) +{ + ppe_vsi_member_set(priv, entry->vsi, + entry->ports | BIT(QCA_PPE_CPU_PORT)); +} + +static void ppe_vlan_pvid_update(struct qca_ppe_priv *priv, + struct qca_ppe_vlan_entry *entry) +{ + if (!entry->pvid_ports && entry->xlt_pvid_idx >= 0) { + ppe_xlt_idx_free(priv, &entry->xlt_pvid_idx); + return; + } + + if (entry->pvid_ports) + ppe_xlt_rule_set(priv, entry->xlt_pvid_idx, + entry->pvid_ports, 0, true); +} + +int qca_ppe_vlan_setup(struct dsa_switch *ds) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + int i; + + for (i = 0; i < ds->num_ports; i++) { + u32 mode = dsa_is_user_port(ds, i) ? + PPE_EG_UNMODIFIED : PPE_EG_UNTOUCHED; + + regmap_update_bits(priv->regmap, PPE_PORT_EG_VLAN(i), + PPE_PORT_EG_VLAN_CTAG_MODE | + PPE_PORT_EG_VLAN_STAG_MODE, + FIELD_PREP(PPE_PORT_EG_VLAN_CTAG_MODE, mode) | + FIELD_PREP(PPE_PORT_EG_VLAN_STAG_MODE, mode)); + } + + for (i = 0; i < PPE_VSI_MAX; i++) { + regmap_write(priv->regmap, PPE_EG_VSI_TAG(i), + PPE_EG_VSI_TAG_UNMODIFIED); + priv->vlans[i].xlt_idx = -1; + priv->vlans[i].xlt_pvid_idx = -1; + } + + regmap_update_bits(priv->regmap, PPE_EG_BRIDGE_CONFIG, + PPE_EG_L2_EDIT_EN, PPE_EG_L2_EDIT_EN); + + ds->configure_vlan_while_not_filtering = false; + + return 0; +} + +int qca_ppe_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering, + struct netlink_ext_ack *extack) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + + regmap_update_bits(priv->regmap, PPE_PORT_EG_VLAN(port), + PPE_PORT_EG_VSI_TAG_EN, + vlan_filtering ? PPE_PORT_EG_VSI_TAG_EN : 0); + + regmap_update_bits(priv->regmap, PPE_PORT_VLAN_CFG(port), + PPE_VLAN_XLT_MISS_FWD, + vlan_filtering ? + FIELD_PREP(PPE_VLAN_XLT_MISS_FWD, PPE_XLT_MISS_FWD_DROP) : 0); + + return 0; +} + +int qca_ppe_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + struct net_device *br_dev = priv->port_br_dev[port]; + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; + struct qca_ppe_vlan_entry *entry; + u16 vid = vlan->vid; + int idx; + + if (!br_dev) + return 0; + + entry = ppe_vlan_find(priv, br_dev, vid); + if (!entry) { + entry = ppe_vlan_alloc(priv, br_dev, vid); + if (!entry) + return -ENOSPC; + } + + entry->ports |= BIT(port); + + if (entry->xlt_idx < 0) { + idx = ppe_xlt_idx_alloc(priv); + if (idx < 0) { + entry->ports &= ~BIT(port); + if (!entry->ports) + ppe_vlan_free(priv, entry); + return -ENOSPC; + } + entry->xlt_idx = idx; + } + + ppe_xlt_rule_set(priv, entry->xlt_idx, + entry->ports | BIT(QCA_PPE_CPU_PORT), vid, false); + ppe_xlt_action_set(priv, entry->xlt_idx, entry->vsi, true); + + ppe_eg_vsi_tag_port_set(priv, entry->vsi, port, + untagged ? PPE_EG_UNTAGGED : PPE_EG_TAGGED); + + if (pvid) { + ppe_port_def_cvid_set(priv, port, vid, true); + priv->port_pvid[port] = vid; + entry->pvid_ports |= BIT(port); + + if (entry->xlt_pvid_idx < 0) { + idx = ppe_xlt_idx_alloc(priv); + if (idx < 0) + return -ENOSPC; + entry->xlt_pvid_idx = idx; + } + ppe_xlt_rule_set(priv, entry->xlt_pvid_idx, + entry->pvid_ports, 0, true); + ppe_xlt_action_set(priv, entry->xlt_pvid_idx, entry->vsi, + false); + } else if (priv->port_pvid[port] == vid) { + ppe_port_def_cvid_set(priv, port, 0, false); + priv->port_pvid[port] = 0; + entry->pvid_ports &= ~BIT(port); + + ppe_vlan_pvid_update(priv, entry); + } + + ppe_vlan_members_update(priv, entry); + + return 0; +} + +int qca_ppe_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + struct net_device *br_dev = priv->port_br_dev[port]; + struct qca_ppe_vlan_entry *entry; + u16 vid = vlan->vid; + + if (!br_dev) + return 0; + + entry = ppe_vlan_find(priv, br_dev, vid); + if (!entry) + return 0; + + entry->ports &= ~BIT(port); + ppe_eg_vsi_tag_port_set(priv, entry->vsi, port, PPE_EG_UNMODIFIED); + + if (priv->port_pvid[port] == vid) { + ppe_port_def_cvid_set(priv, port, 0, false); + priv->port_pvid[port] = 0; + entry->pvid_ports &= ~BIT(port); + } + + if (!entry->ports) { + ppe_vlan_free(priv, entry); + return 0; + } + + ppe_xlt_rule_set(priv, entry->xlt_idx, + entry->ports | BIT(QCA_PPE_CPU_PORT), vid, false); + + ppe_vlan_pvid_update(priv, entry); + + ppe_vlan_members_update(priv, entry); + + return 0; +} diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq5018.c b/target/linux/qualcommax/files/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq5018.c new file mode 100644 index 00000000000000..78f22e1c8b8646 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq5018.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Qualcomm IPQ5018 DWMAC glue layer + * + * Copyright (C) 2026 The OpenWrt Project + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MAX_FRAME_SIZE 16383 /* 14 bits */ +/* MAX_MTU = (MAX_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN - (2 * VLAN_HLEN)) */ +#define MAX_MTU 16357 + +static struct clk_bulk_data ipq5018_gmac_clks[] = { + { .id = "stmmaceth" }, + { .id = "pclk" }, + { .id = "ptp_ref" }, + { .id = "ahb" }, + { .id = "axi" }, + { .id = "rx" }, + { .id = "tx" }, +}; + +struct ipq5018_gmac { + struct device *dev; + struct clk *rx_clk; + struct clk *tx_clk; +}; + +static void ipq5018_gmac_fix_speed(void *priv, unsigned int speed, unsigned int mode) +{ + struct ipq5018_gmac *gmac = priv; + unsigned long rate; + + switch(speed) { + case SPEED_10: + rate = 2500000; + break; + case SPEED_100: + rate = 25000000; + break; + case SPEED_1000: + rate = 125000000; + break; + case SPEED_2500: + rate = 312500000; + break; + default: + dev_err(gmac->dev, "Unsupported speed: %d\n", speed); + rate = 125000000; + break; + } + + clk_set_rate(gmac->rx_clk, rate); + clk_set_rate(gmac->tx_clk, rate); +} + +static int ipq5018_gmac_pcs_init(struct stmmac_priv *priv) +{ + struct phylink_pcs *pcs; + int ret; + + pcs = fwnode_pcs_get(dev_fwnode(priv->device), 0); + if (!pcs) + return 0; + else if (IS_ERR(pcs)) { + ret = PTR_ERR(pcs); + if (ret == -ENOENT) + return 0; + dev_err(priv->device, "failed to parse PCS from fwnode\n"); + return ret; + } + + priv->hw->phylink_pcs = pcs; + + return 0; +} + +static struct phylink_pcs *ipq5018_gmac_select_pcs(struct stmmac_priv *priv, + phy_interface_t interface) +{ + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_2500BASEX: + if (priv->hw->phylink_pcs) + return priv->hw->phylink_pcs; + default: + break; + } + + return NULL; +} + +static void ipq5018_gmac_get_interfaces(struct stmmac_priv *priv, void *bsp_priv, + unsigned long *interfaces) +{ + struct mac_device_info *mac = priv->hw; + + /* + * IPQ5018 has two GMACs: + * - GMAC0 supports SGMII and is wired to the SoC's internal GE PHY + * - GMAC1 supports SGMII and 2500BaseX, configurable by the UNIPHY PCS + */ + __set_bit(PHY_INTERFACE_MODE_SGMII, interfaces); + if (priv->hw->phylink_pcs) { + __set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces); + + /* + * Synopsys DWMAC IP version 3.7 is limited to 1 Gpbs. + * This vendor specific implementation supports 2.5 Gbps, so override + * the default mac link capabilities. + */ + mac->link.caps |= MAC_2500FD; + } +} + +static int ipq5018_gmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct device *dev = &pdev->dev; + struct ipq5018_gmac *gmac; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return dev_err_probe(dev, ret, + "failed to get stmmac platform resources\n"); + + plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); + if (IS_ERR_OR_NULL(plat_dat)) + return dev_err_probe(dev, PTR_ERR(plat_dat), + "failed to parse stmmac dt parameters\n"); + + gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); + if (!gmac) + return dev_err_probe(dev, -ENOMEM, + "failed to allocate priv\n"); + + gmac->dev = dev; + + gmac->rx_clk = devm_clk_get(dev, "rx"); + if (IS_ERR(gmac->rx_clk)) + return dev_err_probe(dev, PTR_ERR(gmac->rx_clk), + "failed to get RX clock\n"); + + gmac->tx_clk = devm_clk_get(dev, "tx"); + if (IS_ERR(gmac->tx_clk)) + return dev_err_probe(dev, PTR_ERR(gmac->tx_clk), + "failed to get TX clock\n"); + + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(ipq5018_gmac_clks), + ipq5018_gmac_clks); + if (ret) + return dev_err_probe(dev, ret, "failed to get clocks\n"); + + ret = clk_bulk_prepare_enable(ARRAY_SIZE(ipq5018_gmac_clks), + ipq5018_gmac_clks); + if (ret) + return dev_err_probe(dev, ret, "failed to enable clocks\n"); + + plat_dat->bsp_priv = gmac; + plat_dat->max_speed = 2500; + plat_dat->maxmtu = MAX_MTU; + plat_dat->rx_fifo_size = MAX_FRAME_SIZE; + plat_dat->tx_fifo_size = MAX_FRAME_SIZE; + plat_dat->get_interfaces = ipq5018_gmac_get_interfaces; + plat_dat->fix_mac_speed = ipq5018_gmac_fix_speed; + plat_dat->pcs_init = ipq5018_gmac_pcs_init; + plat_dat->select_pcs = ipq5018_gmac_select_pcs; + + return stmmac_dvr_probe(dev, plat_dat, &stmmac_res); +} + +static const struct of_device_id ipq5018_gmac_dwmac_match[] = { + { .compatible = "qcom,ipq5018-gmac" }, + { } +}; +MODULE_DEVICE_TABLE(of, ipq5018_gmac_dwmac_match); + +static struct platform_driver ipq5018_gmac_dwmac_driver = { + .probe = ipq5018_gmac_probe, + .driver = { + .name = "ipq5018-gmac-dwmac", + .of_match_table = ipq5018_gmac_dwmac_match, + }, +}; +module_platform_driver(ipq5018_gmac_dwmac_driver); + +MODULE_DESCRIPTION("Qualcomm IPQ5018 DWMAC glue layer"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/target/linux/qualcommax/files/drivers/net/pcs/pcs-qca-uniphy.c b/target/linux/qualcommax/files/drivers/net/pcs/pcs-qca-uniphy.c new file mode 100644 index 00000000000000..df64bef104a680 --- /dev/null +++ b/target/linux/qualcommax/files/drivers/net/pcs/pcs-qca-uniphy.c @@ -0,0 +1,1000 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Qualcomm IPQ6018 UNIPHY PCS driver + * + * Copyright (c) 2025 The OpenWrt Project + * + * Standalone PCS driver for the UNIPHY SerDes blocks in IPQ6018 SoCs. + * Each UNIPHY instance provides up to 5 SGMII channels (PSGMII mode) + * or a single channel for SGMII/USXGMII. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const struct qca_uniphy_match_data ipq5018_data = { + .uniphy_type = UNIPHY_IPQ5018, + .ref_clk_enable = true, +}; + +static const struct qca_uniphy_match_data ipq6018_data = { + .uniphy_type = UNIPHY_IPQ6018, + .ref_clk_enable = false, +}; + +static const struct qca_uniphy_match_data ipq8074_data = { + .uniphy_type = UNIPHY_IPQ8074, + .ref_clk_enable = false, +}; + +static unsigned long +qca_uniphy_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct qca_uniphy_clk *uclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = uclk->uniphy; + u32 val; + + /* + * UNIPHY switch reference clock based on the configured + * PHY mode. + */ + regmap_read(uniphy->regmap, UNIPHY_MODE_CTRL, &val); + if (val & UNIPHY_SGMII_MODE || + val & UNIPHY_CH0_PSGMII_QSGMII || + val & UNIPHY_CH0_QSGMII_SGMII) + return 125000000; + else if (val & UNIPHY_SGPLUS_MODE || + val & UNIPHY_XPCS_MODE) + return 312500000; + + return 0; +} + +static const struct clk_ops qca_uniphy_clk_ops = { + .recalc_rate = qca_uniphy_clk_recalc_rate, +}; + +static int qca_uniphy_clk_register(struct qca_uniphy *uniphy, + struct qca_uniphy_clk *uclk, + const char *name) +{ + struct clk_init_data init = { + .name = name, + .ops = &qca_uniphy_clk_ops, + /* always derive rate from the UNIPHY register */ + .flags = CLK_GET_RATE_NOCACHE, + }; + + uclk->hw.init = &init; + uclk->uniphy = uniphy; + + return devm_clk_hw_register(uniphy->dev, &uclk->hw); +} + +static int +qca_uniphy_refclk_enable(struct clk_hw *hw) +{ + struct qca_uniphy_clk *uclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = uclk->uniphy; + + switch (uniphy->data->uniphy_type) { + case UNIPHY_IPQ5018: + if (!clk_hw_is_enabled(&uclk->hw)) { + regmap_update_bits(uniphy->regmap, IPQ5018_UNIPHY_REFCLK, + IPQ5018_UNIPHY_REFCLK_EN | + IPQ5018_UNIPHY_REFCLK_DS, + IPQ5018_UNIPHY_REFCLK_EN | + FIELD_PREP(IPQ5018_UNIPHY_REFCLK_DS, 1)); + } + break; + default: + break; + } + + return 0; +} + +static int +qca_uniphy_refclk_is_enabled(struct clk_hw *hw) +{ + struct qca_uniphy_clk *uclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = uclk->uniphy; + u32 val; + + switch (uniphy->data->uniphy_type) { + case UNIPHY_IPQ5018: + regmap_read(uniphy->regmap, IPQ5018_UNIPHY_REFCLK, &val); + return !!(val & IPQ5018_UNIPHY_REFCLK_EN); + default: + break; + } + + return 0; +} + +static int +qca_uniphy_refclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct qca_uniphy_clk *uclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = uclk->uniphy; + + switch (uniphy->data->uniphy_type) { + case UNIPHY_IPQ5018: + switch (req->rate) { + case UNIPHY_REFCLK_25MHZ: + case UNIPHY_REFCLK_50MHZ: + return 0; + default: + return -EINVAL; + } + default: + return 0; + } +} + +static unsigned long +qca_uniphy_refclk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct qca_uniphy_clk *uclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = uclk->uniphy; + u32 val; + + switch (uniphy->data->uniphy_type) { + case UNIPHY_IPQ5018: + regmap_read(uniphy->regmap, IPQ5018_UNIPHY_REFCLK, &val); + if (val & IPQ5018_UNIPHY_REFCLK_DIV) + return UNIPHY_REFCLK_25MHZ; + else + return UNIPHY_REFCLK_50MHZ; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int +qca_uniphy_refclk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct qca_uniphy_clk *refclk = + container_of(hw, struct qca_uniphy_clk, hw); + struct qca_uniphy *uniphy = refclk->uniphy; + u32 val = 0; + + switch (uniphy->data->uniphy_type) { + case UNIPHY_IPQ5018: + if (parent_rate != UNIPHY_REFCLK_50MHZ) + return -EINVAL; + + if (rate == UNIPHY_REFCLK_50MHZ) + val = FIELD_PREP(IPQ5018_UNIPHY_REFCLK_DIV, 0x0); + else if (rate == UNIPHY_REFCLK_25MHZ) + val = FIELD_PREP(IPQ5018_UNIPHY_REFCLK_DIV, 0x1); + + regmap_update_bits(uniphy->regmap, IPQ5018_UNIPHY_REFCLK, + IPQ5018_UNIPHY_REFCLK_DIV, val); + break; + default: + return 0; + } + + return 0; +} + +static const struct clk_ops qca_uniphy_refclk_ops = { + .enable = qca_uniphy_refclk_enable, + .determine_rate = qca_uniphy_refclk_determine_rate, + .recalc_rate = qca_uniphy_refclk_recalc_rate, + .set_rate = qca_uniphy_refclk_set_rate, +}; + +static int qca_uniphy_refclk_register(struct qca_uniphy *uniphy, + const char *name) { + struct clk_parent_data pdata = { .fw_name = "ref" }; + struct clk_init_data init = {}; + + init.name = name, + init.parent_data = &pdata; + init.num_parents = 1; + init.ops = &qca_uniphy_refclk_ops, + /* always derive rate from the UNIPHY register */ + init.flags = CLK_GET_RATE_NOCACHE, + + uniphy->ref_clk.hw.init = &init; + uniphy->ref_clk.uniphy = uniphy; + + return devm_clk_hw_register(uniphy->dev, &uniphy->ref_clk.hw); +} + +static int qca_uniphy_register_clks(struct qca_uniphy *uniphy) { + struct clk_hw_onecell_data *hw_data; + struct device *dev = uniphy->dev; + const char *name; + int num_clks; + int ret; + + num_clks = (uniphy->data->ref_clk_enable) ? 3 : 2; + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + if (of_property_read_string_index(dev->of_node, "clock-output-names", + UNIPHY_CLK_RX, &name)) + return -ENODEV; + + ret = qca_uniphy_clk_register(uniphy, &uniphy->rx_clk, name); + if (ret) + return ret; + hw_data->hws[UNIPHY_CLK_RX] = &uniphy->rx_clk.hw; + + if (of_property_read_string_index(dev->of_node, "clock-output-names", + UNIPHY_CLK_TX, &name)) + return -ENODEV; + + ret = qca_uniphy_clk_register(uniphy, &uniphy->tx_clk, name); + if (ret) + return ret; + hw_data->hws[UNIPHY_CLK_TX] = &uniphy->tx_clk.hw; + + if (uniphy->data->ref_clk_enable) { + if (of_property_read_string_index(dev->of_node, + "clock-output-names", + UNIPHY_CLK_REF, &name)) + return -ENODEV; + + ret = qca_uniphy_refclk_register(uniphy, name); + if (ret) + return ret; + hw_data->hws[UNIPHY_CLK_REF] = &uniphy->ref_clk.hw; + } + + hw_data->num = num_clks; + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data); +} + +static unsigned int +qca_uniphy_pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface) +{ + return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; +} + +static void qca_uniphy_pcs_get_state_sgmii(struct qca_uniphy *uniphy, + int channel, + struct phylink_link_state *state) +{ + u32 val; + + regmap_read(uniphy->regmap, + UNIPHY_CH_STS(channel), + &val); + + state->link = !!(val & UNIPHY_CH_STS_LINK); + if (!state->link) + return; + + state->duplex = (val & UNIPHY_CH_STS_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF; + + switch (FIELD_GET(UNIPHY_CH_STS_SPEED_MODE, val)) { + case 0: + state->speed = SPEED_10; + break; + case 1: + state->speed = SPEED_100; + break; + case 2: + state->speed = SPEED_1000; + break; + default: + state->link = false; + return; + } + + state->pause = 0; + if (val & UNIPHY_CH_STS_RX_PAUSE) + state->pause |= MLO_PAUSE_RX; + if (val & UNIPHY_CH_STS_TX_PAUSE) + state->pause |= MLO_PAUSE_TX; + + state->an_complete = state->link; +} + +static void qca_uniphy_pcs_get_state_hsgmii(struct qca_uniphy *uniphy, + int channel, + struct phylink_link_state *state) +{ + u32 val; + + regmap_read(uniphy->regmap, + UNIPHY_CH_STS(channel), + &val); + + state->link = !!(val & UNIPHY_CH_STS_LINK); + if (!state->link) + return; + + state->speed = SPEED_2500; + state->duplex = DUPLEX_FULL; + + state->pause = 0; + if (val & UNIPHY_CH_STS_RX_PAUSE) + state->pause |= MLO_PAUSE_RX; + if (val & UNIPHY_CH_STS_TX_PAUSE) + state->pause |= MLO_PAUSE_TX; + + state->an_complete = state->link; +} + +static void qca_uniphy_pcs_get_state_usxgmii(struct qca_uniphy *uniphy, + struct phylink_link_state *state) +{ + unsigned int val; + int ret; + + ret = regmap_read(uniphy->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 void qca_uniphy_pcs_get_state_10base_r(struct qca_uniphy *uniphy, + struct phylink_link_state *state) +{ + unsigned int val; + int ret; + + ret = regmap_read(uniphy->regmap, XPCS_KR_STS1, &val); + if (ret) { + state->link = 0; + return; + } + + state->link = !!(val & XPCS_KR_STS1_PLU); + + if (!state->link) + return; + + state->speed = SPEED_10000; + state->duplex = DUPLEX_FULL; +} + +static void qca_uniphy_pcs_get_state(struct phylink_pcs *pcs, + struct phylink_link_state *state) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + + switch (state->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + qca_uniphy_pcs_get_state_sgmii(uniphy, upcs->channel, + state); + break; + case PHY_INTERFACE_MODE_2500BASEX: + qca_uniphy_pcs_get_state_hsgmii(uniphy, upcs->channel, + state); + break; + case PHY_INTERFACE_MODE_USXGMII: + qca_uniphy_pcs_get_state_usxgmii(uniphy, state); + break; + case PHY_INTERFACE_MODE_10GBASER: + qca_uniphy_pcs_get_state_10base_r(uniphy, state); + break; + default: + break; + } +} + +static int qca_uniphy_pcs_config_mode(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + u32 misc2_phy_mode, mode_ctrl, val; + int ret; + + dev_dbg(uniphy->dev, "Configuring PCS: chan=%d, interface=%s, neg_mode=0x%x\n", + upcs->channel, phy_modes(interface), neg_mode); + + switch (interface) { + case PHY_INTERFACE_MODE_1000BASEX: + misc2_phy_mode = UNIPHY_MISC2_SGMII; + mode_ctrl = UNIPHY_SGMII_MODE; + break; + case PHY_INTERFACE_MODE_SGMII: + misc2_phy_mode = UNIPHY_MISC2_SGMII; + mode_ctrl = UNIPHY_SGMII_MODE; + mode_ctrl |= FIELD_PREP(UNIPHY_CH0_MODE_CTRL_25M, UNIPHY_CH0_MODE_MAC); + mode_ctrl |= UNIPHY_AUTONEG_MODE_ATH; + break; + case PHY_INTERFACE_MODE_QSGMII: + mode_ctrl = UNIPHY_CH0_QSGMII_SGMII; + misc2_phy_mode = UNIPHY_MISC2_SGMII; + break; + case PHY_INTERFACE_MODE_PSGMII: + mode_ctrl = UNIPHY_CH0_PSGMII_QSGMII; + misc2_phy_mode = 0; + break; + case PHY_INTERFACE_MODE_USXGMII: + mode_ctrl = UNIPHY_XPCS_MODE; + misc2_phy_mode = UNIPHY_MISC2_USXGMII; + break; + case PHY_INTERFACE_MODE_10GBASER: + mode_ctrl = UNIPHY_XPCS_MODE; + misc2_phy_mode = 0; + break; + case PHY_INTERFACE_MODE_2500BASEX: + misc2_phy_mode = UNIPHY_MISC2_SGMIIPLUS; + mode_ctrl = UNIPHY_SGPLUS_MODE; + mode_ctrl |= FIELD_PREP(UNIPHY_CH0_MODE_CTRL_25M, UNIPHY_CH0_MODE_MAC); + mode_ctrl |= UNIPHY_AUTONEG_MODE_ATH; + break; + default: + return -EINVAL; + } + + /* + * The clock could have been enabled by the bootloader. + * Increase enable count (>0) CCF can properly account for clock state. + */ + if (uniphy->data->ref_clk_enable) { + if (!clk_hw_is_enabled(&uniphy->ref_clk.hw) && + qca_uniphy_refclk_is_enabled(&uniphy->ref_clk.hw)) + clk_prepare_enable(uniphy->ref_clk.hw.clk); + } + + /* First update misc2 PHY mode... */ + regmap_update_bits(uniphy->regmap, UNIPHY_MISC2_PHY_MODE, + UNIPHY_MISC2_PHY_MODE_MASK, misc2_phy_mode); + + /* ...and reset Analog */ + regmap_clear_bits(uniphy->regmap, UNIPHY_PLL_POWER_ON_AND_RESET, + UNIPHY_PLL_RESET_ANALOG); + msleep(100); + regmap_set_bits(uniphy->regmap, UNIPHY_PLL_POWER_ON_AND_RESET, + UNIPHY_PLL_RESET_ANALOG); + msleep(100); + + /* Second assert XPCS... */ + if (uniphy->rst_xpcs) + reset_control_assert(uniphy->rst_xpcs); + + /* ...and disable PHY clock */ + clk_disable(uniphy->clks[port_rx_clk_idx(upcs)].clk); + clk_disable(uniphy->clks[port_tx_clk_idx(upcs)].clk); + + /* TODO: Fix for IPQ6018 and IPQ8074 */ + if (uniphy->data->uniphy_type == UNIPHY_IPQ5018) { + //set force mode for fixed link + if (neg_mode == PHYLINK_PCS_NEG_OUTBAND && !phylink_expects_phy(pcs->phylink)) { + regmap_set_bits(uniphy->regmap, + UNIPHY_CH_CTRL(upcs->channel), + UNIPHY_CH_FORCE_MODE); + } + } + + /* Third update the mode ctrl... */ + regmap_update_bits(uniphy->regmap, UNIPHY_MODE_CTRL, + UNIPHY_MODE_SEL_MASK | UNIPHY_CH0_MODE_CTRL_25M | + UNIPHY_AUTONEG_MODE_ATH, + mode_ctrl); + + /* + * ...and execute soft reset... + * + * (soft reset is XPCS + all the UNIPHY PHY port reset, + * XPCS gets indirectly deassert by the soft reset deassert. + * It seems that resetting all at once is mandatory as from + * lots of testing it has been verified that operating + * on the single reset is problematic) + */ + reset_control_assert(uniphy->rst_soft); + msleep(100); + reset_control_deassert(uniphy->rst_soft); + + /* ...and wait for calibration */ + ret = regmap_read_poll_timeout(uniphy->regmap, UNIPHY_OFFSET_CALIB_4, + val, val & UNIPHY_CALIBRATION_DONE, + UNIPHY_CALIBRATION_POLL_US, + UNIPHY_CALIBRATION_TIMEOUT_US); + if (ret) { + dev_err(uniphy->dev, "PCS calibration timeout\n"); + return -EINVAL; + } + + /* Trigger UNIPHY ref clock to recal rate */ + clk_hw_recalc_rate(&uniphy->rx_clk.hw); + clk_hw_recalc_rate(&uniphy->tx_clk.hw); + + /* As last step enable PHY clock... */ + clk_enable(uniphy->clks[port_rx_clk_idx(upcs)].clk); + clk_enable(uniphy->clks[port_tx_clk_idx(upcs)].clk); + + if (interface == PHY_INTERFACE_MODE_USXGMII || + interface == PHY_INTERFACE_MODE_10GBASER) + reset_control_deassert(uniphy->rst_xpcs); + + if (!uniphy->data->ref_clk_enable) + return 0; + + /* Trigger UNIPHY ref output clock to recalc rate */ + clk_hw_recalc_rate(&uniphy->ref_clk.hw); + /* Trigger assigned-clock-rates in DT to be applied */ + of_clk_set_defaults(uniphy->dev->of_node, true); + if (!qca_uniphy_refclk_is_enabled(&uniphy->ref_clk.hw)) + qca_uniphy_refclk_enable(&uniphy->ref_clk.hw); + + return 0; +} + +static int qca_uniphy_pcs_config_usxgmii(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + int ret; + + ret = qca_uniphy_pcs_config_mode(pcs, neg_mode, interface, advertising, permit_pause_to_mac); + if (ret) + return ret; + + ret = regmap_update_bits(uniphy->regmap, XPCS_DIG_CTRL, + XPCS_USXG_EN, + interface == PHY_INTERFACE_MODE_USXGMII ? XPCS_USXG_EN : 0); + if (ret) + return ret; + + ret = regmap_update_bits(uniphy->regmap, XPCS_MII_AN_CTRL, + XPCS_MII_AN_8BIT, + interface == PHY_INTERFACE_MODE_USXGMII ? XPCS_MII_AN_8BIT : 0); + if (ret) + return ret; + + return regmap_update_bits(uniphy->regmap, XPCS_MII_CTRL, + XPCS_MII_AN_EN, + interface == PHY_INTERFACE_MODE_USXGMII ? XPCS_MII_AN_EN : 0); +} + +static int qca_uniphy_pcs_config(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) +{ + 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_2500BASEX: + return qca_uniphy_pcs_config_mode(pcs, neg_mode, interface, advertising, permit_pause_to_mac); + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + return qca_uniphy_pcs_config_usxgmii(pcs, neg_mode, interface, advertising, permit_pause_to_mac); + default: + return -EOPNOTSUPP; + } +} + +static int uniphy_link_up_sgmii(struct phylink_pcs *pcs, + phy_interface_t interface, + int speed) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + unsigned long uniphy_rate; + int ret; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_PSGMII: + switch (speed) { + case SPEED_10: + uniphy_rate = 2500000; + break; + case SPEED_100: + uniphy_rate = 25000000; + break; + case SPEED_1000: + uniphy_rate = 125000000; + break; + default: + dev_err(uniphy->dev, "Invalid SGMII speed %d\n", speed); + return -EINVAL; + } + break; + case PHY_INTERFACE_MODE_1000BASEX: + switch (speed) { + case SPEED_1000: + uniphy_rate = 125000000; + break; + default: + dev_err(uniphy->dev, "Invalid 1000BaseX speed %d\n", speed); + return -EINVAL; + } + break; + case PHY_INTERFACE_MODE_2500BASEX: + switch (speed) { + case SPEED_2500: + uniphy_rate = 312500000; + break; + default: + dev_err(uniphy->dev, "Invalid 2500BaseX speed %d\n", speed); + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + clk_set_rate(uniphy->clks[port_rx_clk_idx(upcs)].clk, uniphy_rate); + clk_set_rate(uniphy->clks[port_tx_clk_idx(upcs)].clk, uniphy_rate); + + ret = regmap_clear_bits(uniphy->regmap, UNIPHY_CH_CTRL(upcs->channel), + UNIPHY_CH_ADP_SW_RSTN); + if (ret) + return ret; + + usleep_range(1000, 2000); + + return regmap_set_bits(uniphy->regmap, UNIPHY_CH_CTRL(upcs->channel), + UNIPHY_CH_ADP_SW_RSTN); +} + +static int uniphy_link_up_usxgmii(struct phylink_pcs *pcs, int speed) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + unsigned int val, uniphy_rate; + int ret; + + switch (speed) { + case SPEED_10000: + val = XPCS_SPEED_10000; + uniphy_rate = 312500000; + break; + case SPEED_5000: + val = XPCS_SPEED_5000; + uniphy_rate = 156250000; + break; + case SPEED_2500: + val = XPCS_SPEED_2500; + uniphy_rate = 78125000; + break; + case SPEED_1000: + val = XPCS_SPEED_1000; + uniphy_rate = 125000000; + break; + case SPEED_100: + val = XPCS_SPEED_100; + uniphy_rate = 12500000; + break; + case SPEED_10: + val = XPCS_SPEED_10; + uniphy_rate = 1250000; + break; + default: + dev_err(uniphy->dev, "Invalid USXGMII speed %d\n", speed); + return -EINVAL; + } + + clk_set_rate(uniphy->clks[port_rx_clk_idx(upcs)].clk, uniphy_rate); + clk_set_rate(uniphy->clks[port_tx_clk_idx(upcs)].clk, uniphy_rate); + + /* Configure XPCS speed */ + ret = regmap_update_bits(uniphy->regmap, XPCS_MII_CTRL, + XPCS_SPEED_MASK, val | XPCS_DUPLEX_FULL); + if (ret) + return ret; + + /* XPCS adapter reset */ + return regmap_set_bits(uniphy->regmap, XPCS_DIG_CTRL, XPCS_USXG_ADPT_RESET); +} + +static void qca_uniphy_pcs_link_up(struct phylink_pcs *pcs, + unsigned int neg_mode, + phy_interface_t interface, + int speed, int duplex) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + int ret = 0; + + 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_2500BASEX: + ret = uniphy_link_up_sgmii(pcs, interface, speed); + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + ret = uniphy_link_up_usxgmii(pcs, speed); + break; + default: + return; + } + + if (ret) + dev_err(uniphy->dev, "PCS link up fail for interface %s\n", + phy_modes(interface)); +} + +static int qca_uniphy_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: + case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + return 0; + default: + return -EINVAL; + } +} + +static void qca_uniphy_pcs_disable(struct phylink_pcs *pcs) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + + if (uniphy->data->uniphy_type == UNIPHY_IPQ5018) { + clk_disable(uniphy->clks[port_rx_clk_idx(upcs)].clk); + clk_disable(uniphy->clks[port_tx_clk_idx(upcs)].clk); + } +} + +static int qca_uniphy_pcs_enable(struct phylink_pcs *pcs) +{ + struct qca_uniphy_pcs *upcs = to_qca_uniphy_pcs(pcs); + struct qca_uniphy *uniphy = upcs->uniphy; + int ret; + + if (uniphy->data->uniphy_type == UNIPHY_IPQ5018) { + ret = clk_enable(uniphy->clks[port_rx_clk_idx(upcs)].clk); + if (ret) { + dev_err(uniphy->dev, "Failed to enable RX clock for channel %d\n", + upcs->channel); + return ret; + } + ret = clk_enable(uniphy->clks[port_tx_clk_idx(upcs)].clk); + if (ret) { + dev_err(uniphy->dev, "Failed to enable TX clock for channel %d\n", + upcs->channel); + return ret; + } + } + + return 0; +} + +static void qca_uniphy_pcs_an_restart(struct phylink_pcs *pcs) { } + +static const struct phylink_pcs_ops qca_uniphy_pcs_ops = { + .pcs_validate = qca_uniphy_pcs_validate, + .pcs_inband_caps = qca_uniphy_pcs_inband_caps, + .pcs_get_state = qca_uniphy_pcs_get_state, + .pcs_config = qca_uniphy_pcs_config, + .pcs_link_up = qca_uniphy_pcs_link_up, + .pcs_disable = qca_uniphy_pcs_disable, + .pcs_enable = qca_uniphy_pcs_enable, + .pcs_an_restart = qca_uniphy_pcs_an_restart, +}; + +static const struct of_device_id qca_uniphy_of_match[] = { + { .compatible = "qualcomm,ipq5018-uniphy", .data = &ipq5018_data }, + { .compatible = "qualcomm,ipq6018-uniphy", .data = &ipq6018_data }, + { .compatible = "qualcomm,ipq8074-uniphy", .data = &ipq8074_data }, + { }, +}; +MODULE_DEVICE_TABLE(of, qca_uniphy_of_match); + +static int uniphy_pcs_regmap_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct qca_uniphy *uniphy = 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), + uniphy->base + XPCS_INDIRECT_AHB_ADDR); + *val = readl(uniphy->base + XPCS_INDIRECT_DATA_ADDR(reg)); + } else { + *val = readl(uniphy->base + reg); + } + + return 0; +} + +static int uniphy_pcs_regmap_write(void *context, unsigned int reg, + unsigned int val) +{ + struct qca_uniphy *uniphy = 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), + uniphy->base + XPCS_INDIRECT_AHB_ADDR); + writel(val, uniphy->base + XPCS_INDIRECT_DATA_ADDR(reg)); + } else { + writel(val, uniphy->base + reg); + } + + return 0; +} + +static struct phylink_pcs *qca_uniphy_get(struct fwnode_reference_args *pcsspec, + void *data) +{ + struct qca_uniphy *uniphy = data; + struct device *dev = uniphy->dev; + int channel = 0; + + if (pcsspec->nargs > 1) { + dev_err(dev, "Invalid number of cells in 'pcs-handle' property\n"); + return ERR_PTR(-EINVAL); + } + + if (pcsspec->nargs) + channel = pcsspec->args[0]; + + if (channel >= QCA_UNIPHY_CHANNELS) { + dev_err(dev, "Invalid channel in 'pcs-handle' property\n"); + return ERR_PTR(-EINVAL); + } + + return &uniphy->port_pcs[channel].pcs; +} + +static const struct regmap_config uniphy_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_read = uniphy_pcs_regmap_read, + .reg_write = uniphy_pcs_regmap_write, + .fast_io = true, +}; + +static int qca_uniphy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct clk_bulk_data *clks; + struct qca_uniphy *uniphy; + int ret, i, num_clks; + + uniphy = devm_kzalloc(dev, sizeof(*uniphy), GFP_KERNEL); + if (!uniphy) + return -ENOMEM; + + uniphy->dev = dev; + + uniphy->data = device_get_match_data(dev); + if (!uniphy->data) + return -EINVAL; + + uniphy->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(uniphy->base)) + return dev_err_probe(dev, PTR_ERR(uniphy->base), + "Failed to ioremap resource"); + + uniphy->regmap = devm_regmap_init(dev, NULL, uniphy, &uniphy_regmap_cfg); + if (IS_ERR(uniphy->regmap)) + return dev_err_probe(dev, PTR_ERR(uniphy->regmap), + "Failed to init regmap"); + + uniphy->rst_soft = devm_reset_control_get_exclusive(dev, "soft"); + if (IS_ERR(uniphy->rst_soft)) + return dev_err_probe(dev, PTR_ERR(uniphy->rst_soft), + "Failed to get soft reset\n"); + + uniphy->rst_xpcs = devm_reset_control_get_optional_exclusive(dev, "xpcs"); + if (IS_ERR(uniphy->rst_xpcs)) + return dev_err_probe(dev, PTR_ERR(uniphy->rst_xpcs), + "Failed to get xpcs reset\n"); + + num_clks = devm_clk_bulk_get_all_enabled(dev, &clks); + if (num_clks < 0) + return dev_err_probe(dev, num_clks, "Failed to get clocks\n"); + + uniphy->clks = clks; + uniphy->num_clks = num_clks; + + ret = qca_uniphy_register_clks(uniphy); + if (ret) + return dev_err_probe(dev, ret, "Failed to register output clocks\n"); + + for (i = 0; i < QCA_UNIPHY_CHANNELS; i++) { + uniphy->port_pcs[i].pcs.ops = &qca_uniphy_pcs_ops; + uniphy->port_pcs[i].pcs.neg_mode = true; + uniphy->port_pcs[i].pcs.poll = true; + uniphy->port_pcs[i].uniphy = uniphy; + uniphy->port_pcs[i].channel = i; + } + + platform_set_drvdata(pdev, uniphy); + + return fwnode_pcs_add_provider(dev_fwnode(dev), qca_uniphy_get, + uniphy); +} + +static struct platform_driver qca_uniphy_driver = { + .driver = { + .name = "qca-uniphy", + .suppress_bind_attrs = true, + .of_match_table = qca_uniphy_of_match, + }, + .probe = qca_uniphy_probe, +}; +module_platform_driver(qca_uniphy_driver); + +MODULE_DESCRIPTION("Qualcomm IPQ6018 UNIPHY PCS driver"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/pcs/qualcomm,ipq-uniphy.yaml b/target/linux/qualcommax/files/include/dt-bindings/net/pcs/qualcomm,ipq-uniphy.yaml new file mode 100644 index 00000000000000..3548cb51ad5a51 --- /dev/null +++ b/target/linux/qualcommax/files/include/dt-bindings/net/pcs/qualcomm,ipq-uniphy.yaml @@ -0,0 +1,208 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/pcs/qualcomm,ipq-uniphy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm IPQ UNIPHY PCS + +maintainers: + - John Crispin + - Christian Marangi + +description: | + The UNIPHY blocks found in Qualcomm IPQ AX and BE SoCs provide SerDes-based + Physical Coding Sublayer (PCS) controllers. Each SoC contains one or multiple + UNIPHY instances. An instance can operate in PSGMII mode or in single-channel + mode (SGMII, 2500BASE-X, USXGMII). The PPE DSA switch driver references + UNIPHY instances through pcs-handle phandles. + +properties: + compatible: + enum: + - qualcomm,ipq5018-uniphy + - qualcomm,ipq6018-uniphy + - qualcomm,ipq8074-uniphy + + reg: + maxItems: 1 + + '#pcs-cells': + const: 1 + description: + The single cell specifies the channel index within the UNIPHY instance. + + clocks: + minItems: 4 + maxItems: 12 + description: | + Core clocks (AHB, SYS) are always required. Per-channel RX/TX clock + pairs are provided for each port the UNIPHY instance serves. Instances + serving a single port have 4 clocks, PSGMII instances serving 5 ports + have 12. The CMN PLL CC provides a 50MHz reference clock to the UNIPHY + PCS which gates and divides it to pass through either a 25 MHz or 50 MHz + clock to an attached Ethernet PHY or a switch. + items: + - description: ahb clock + - description: sys clock + - description: port1_rx or port5_rx or port6_rx clock + - description: port1_tx or port5_tx or port6_tx clock + - description: port2_rx clock + - description: port2_tx clock + - description: port3_rx clock + - description: port3_tx clock + - description: port4_rx clock + - description: port4_tx clock + - description: port5_rx clock + - description: port5_tx clock + - description: CMN PLL reference clock + + clock-names: + minItems: 4 + maxItems: 12 + items: + - const: ahb + - const: sys + - enum: [port1_rx, port5_rx, port6_rx] + - enum: [port1_tx, port5_tx, port6_tx] + - const: port2_rx + - const: port2_tx + - const: port3_rx + - const: port3_tx + - const: port4_rx + - const: port4_tx + - const: port5_rx + - const: port5_tx + - const: ref + + clock-output-names: + description: Name of the uniphy GCC clock for TX and RX. + items: + - enum: + - uniphy0_gcc_tx_clk + - uniphy1_gcc_tx_clk + - uniphy2_gcc_tx_clk + - enum: + - uniphy0_gcc_rx_clk + - uniphy1_gcc_rx_clk + - uniphy2_gcc_rx_clk + - const: uniphy0_ref_clk + + '#clock-cells': + const: 1 + + resets: + minItems: 1 + items: + - description: soft reset + - description: xpcs reset + + reset-names: + minItems: 1 + items: + - const: soft + - const: xpcs + +required: + - compatible + - reg + - '#pcs-cells' + - clocks + - clock-names + - resets + - reset-names + +additionalProperties: false + +examples: + - | + #include + #include + + ethernet-pcs@7a10000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x7a10000 0x10000>; + + clocks = <&gcc GCC_UNIPHY1_AHB_CLK>, + <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port5_rx", "port5_tx"; + + clock-output-names = "uniphy1_gcc_tx_clk", + "uniphy1_gcc_rx_clk"; + + resets = <&gcc GCC_UNIPHY1_SOFT_RESET>, + <&gcc GCC_UNIPHY1_XPCS_RESET>; + reset-names = "soft", "xpcs"; + + #pcs-cells = <1>; + }; + + - | + #include + #include + + ethernet-pcs@7a00000 { + compatible = "qualcomm,ipq6018-uniphy"; + reg = <0x7a00000 0x10000>; + qcom,psgmii; + + clocks = <&gcc GCC_UNIPHY0_AHB_CLK>, + <&gcc GCC_UNIPHY0_SYS_CLK>, + <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx"; + + clock-output-names = "uniphy0_gcc_tx_clk", + "uniphy0_gcc_rx_clk"; + + resets = <&gcc GCC_UNIPHY0_SOFT_RESET>, + <&gcc GCC_UNIPHY0_XPCS_RESET>; + reset-names = "soft", "xpcs"; + + #pcs-cells = <1>; + }; + + - | + #include + #include + + ethernet-pcs@98000 { + compatible = "qualcomm,ipq5018-uniphy"; + reg = <0x00098000 0x800>; + #clock-cells = <1>; + clocks = <&gcc GCC_UNIPHY_AHB_CLK>, + <&gcc GCC_UNIPHY_SYS_CLK>, + <&gcc GCC_UNIPHY_RX_CLK>, + <&gcc GCC_UNIPHY_TX_CLK>, + <&cmn_pll IPQ5018_ETH_50MHZ_CLK>; + clock-names = "ahb", + "sys", + "port5_rx", + "port5_tx", + "ref"; + assigned-clocks = <&uniphy0 UNIPHY_CLK_REF>; + assigned-clock-rates = ; + clock-output-names = "uniphy0_gcc_rx_clk", + "uniphy0_gcc_tx_clk", + "uniphy0_ref_clk"; + resets = <&gcc GCC_UNIPHY_SOFT_RESET>; + reset-names = "soft"; + + #pcs-cells = <0>; + }; diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/qca-uniphy.h b/target/linux/qualcommax/files/include/dt-bindings/net/qca-uniphy.h new file mode 100644 index 00000000000000..021cd057b043de --- /dev/null +++ b/target/linux/qualcommax/files/include/dt-bindings/net/qca-uniphy.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Device Tree constants for the Qualcomm UNIPHY + */ + +#ifndef _DT_BINDINGS_QCA_UNIPHY_H +#define _DT_BINDINGS_QCA_UNIPHY_H + +#define UNIPHY_CLK_RX 0 +#define UNIPHY_CLK_TX 1 +#define UNIPHY_CLK_REF 2 + +#define UNIPHY_REFCLK_25MHZ 25000000 +#define UNIPHY_REFCLK_50MHZ 50000000 + +#endif diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/qcom,ipq5018-gmac.yaml b/target/linux/qualcommax/files/include/dt-bindings/net/qcom,ipq5018-gmac.yaml new file mode 100644 index 00000000000000..15906428775d28 --- /dev/null +++ b/target/linux/qualcommax/files/include/dt-bindings/net/qcom,ipq5018-gmac.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/qcom,ipq5018-gmac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm IPQ5018 DWMAC glue layer (GMAC) + +maintainers: + - George Moussalem + +description: | + This file documents platform glue layer for Qualcomm IPQ5018 DWMAC (GMAC) + The MAC supports speeds of 10/100/1000/2500 Mbps and supports SGMII and + 2500base-x interface modes. The IPQ5018 SoC has two GMACs: + The first MAC (GMAC0) is connected to an the SoC's internal IPQ5018 ethernet + GE PHY while the second MAC is connected to the SoC's UNIPHY PCS which is turn + can be wired to an external switch or PHY. + This MAC is of Synopsys DesignWare IP version 3.70a. + +# We need a select here so we don't match all nodes with 'snps,dwmac' +select: + properties: + compatible: + contains: + enum: + - qcom,ipq5018-gmac + required: + - compatible + +properties: + compatible: + items: + - enum: + - qcom,ipq5018-gmac + - const: snps,dwmac + + reg: true + + reg-names: + items: + - const: stmmaceth + + clocks: + minItems: 7 + + clock-names: + contains: + enum: + - stmmaceth + - pclk + - ptp_ref + - ahb + - axi + - rx + - tx + + resets: true + + reset-names: + items: + - const: stmmaceth + + interrupts: + minItems: 1 + + interrupt-names: + items: + - const: macirq + + pcs-handle: + $ref: ethernet-controller.yaml#/properties/pcs-handle + description: + A reference to an optional PCS PHY device (GMAC1 <-> UNIPHY PCS) + +required: + - compatible + - clocks + - clock-names + - resets + - reset-names + - interrupts + - interrupt-names + +allOf: + - $ref: snps,dwmac.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + gmac1: ethernet@39d00000 { + compatible = "qcom,ipq5018-gmac", "snps,dwmac"; + reg = <0x39d00000 0x10000>; + reg-names = "stmmaceth"; + clocks = <&gcc GCC_GMAC1_SYS_CLK>, + <&gcc GCC_GMAC1_CFG_CLK>, + <&gcc GCC_GMAC1_PTP_CLK>, + <&gcc GCC_SNOC_GMAC1_AHB_CLK>, + <&gcc GCC_SNOC_GMAC1_AXI_CLK>, + <&gcc GCC_GMAC1_RX_CLK>, + <&gcc GCC_GMAC1_TX_CLK>; + clock-names = "stmmaceth", + "pclk", + "ptp_ref", + "ahb", + "axi", + "rx", + "tx"; + assigned-clocks = <&gcc GCC_GMAC1_SYS_CLK>, + <&gcc GCC_GMAC1_CFG_CLK>, + <&gcc GCC_GMAC1_PTP_CLK>, + <&gcc GCC_SNOC_GMAC1_AHB_CLK>, + <&gcc GCC_SNOC_GMAC1_AXI_CLK>; + assigned-clock-rates = <240000000>, + <240000000>, + <240000000>, + <240000000>, + <240000000>; + resets = <&gcc GCC_GMAC1_BCR>; + reset-names = "stmmaceth"; + interrupts = ; + interrupt-names = "macirq"; + + phy-mode = "sgmii"; + pcs-handle = <&uniphy0>; + }; diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/qcom-ipq-ess.h b/target/linux/qualcommax/files/include/dt-bindings/net/qcom-ipq-ess.h deleted file mode 100644 index baa7c895648029..00000000000000 --- a/target/linux/qualcommax/files/include/dt-bindings/net/qcom-ipq-ess.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef _DT_BINDINGS_NET_QCOM_IPQ_ESS_H -#define _DT_BINDINGS_NET_QCOM_IPQ_ESS_H - -#define ESS_PORT0 0x1 -#define ESS_PORT1 0x2 -#define ESS_PORT2 0x4 -#define ESS_PORT3 0x8 -#define ESS_PORT4 0x10 -#define ESS_PORT5 0x20 -#define ESS_PORT6 0x40 -#define ESS_PORT7 0x80 - -/* SSDK MAC/UNIPHY modes */ -#define MAC_MODE_PSGMII 0x0 -#define MAC_MODE_PSGMII_RGMII5 0x1 -#define MAC_MODE_SGMII0_RGMII5 0x2 -#define MAC_MODE_SGMII1_RGMII5 0x3 -#define MAC_MODE_PSGMII_RMII0 0x4 -#define MAC_MODE_PSGMII_RMII1 0x5 -#define MAC_MODE_PSGMII_RMII0_RMII1 0x6 -#define MAC_MODE_PSGMII_RGMII4 0x7 -#define MAC_MODE_SGMII0_RGMII4 0x8 -#define MAC_MODE_SGMII1_RGMII4 0x9 -#define MAC_MODE_SGMII4_RGMII4 0xa -#define MAC_MODE_QSGMII 0xb -#define MAC_MODE_SGMII_PLUS 0xc -#define MAC_MODE_USXGMII 0xd -#define MAC_MODE_10GBASE_R 0xe -#define MAC_MODE_SGMII_CHANNEL0 0xf -#define MAC_MODE_SGMII_CHANNEL1 0x10 -#define MAC_MODE_SGMII_CHANNEL4 0x11 -#define MAC_MODE_RGMII 0x12 -#define MAC_MODE_PSGMII_FIBER 0x13 -#define MAC_MODE_SGMII_FIBER 0x14 -#define MAC_MODE_UQXGMII 0x15 -#define MAC_MODE_UDXGMII 0x16 -#define MAC_MODE_UQXGMII_3CHANNELS 0x17 -#define MAC_MODE_DISABLED 0xff - -#endif /* _DT_BINDINGS_NET_QCOM_IPQ_ESS_H */ diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-edma.yaml b/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-edma.yaml new file mode 100644 index 00000000000000..93d5ddf5935585 --- /dev/null +++ b/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-edma.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/qualcomm,ipq-edma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm IPQ EDMA Ethernet Controller + +maintainers: + - John Crispin + +description: | + The Enhanced Direct Memory Access (EDMA) controller in Qualcomm IPQ6018 and + IPQ8074 SoCs provides the dataplane for the PPE (Packet Processing Engine) + switch. It registers a network device that serves as the DSA conduit + interface. The EDMA handles packet DMA between the PPE hardware and the + host CPU through dedicated TX/RX descriptor and completion rings. + +properties: + compatible: + enum: + - qualcomm,ipq6018-edma + - qualcomm,ipq8074-edma + + reg: + maxItems: 1 + + interrupts: + items: + - description: TX completion interrupt + - description: RX fill interrupt + - description: RX descriptor interrupt + - description: Miscellaneous interrupt + + clocks: + items: + - description: EDMA core clock + - description: EDMA configuration clock + - description: PPE core clock + - description: PPE configuration clock + - description: NSSNOC PPE clock + - description: NSSNOC PPE configuration clock + - description: NSS NOC clock + - description: NSSNOC SNOC clock + - description: NOC interconnect clock (SoC-specific) + + clock-names: + items: + - const: nss_edma_clk + - const: nss_edma_cfg_clk + - const: nss_ppe_clk + - const: nss_ppe_cfg_clk + - const: nssnoc_ppe_clk + - const: nssnoc_ppe_cfg_clk + - const: gcc_nss_noc_clk + - const: gcc_nssnoc_snoc_clk + - enum: + - gcc_mem_noc_nss_axi_clk + - gcc_snoc_nssnoc_clk + + resets: + maxItems: 1 + + reset-names: + items: + - const: edma_rst + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + - reset-names + +additionalProperties: false + +examples: + - | + #include + #include + + edma@3ab00000 { + compatible = "qualcomm,ipq8074-edma"; + reg = <0x3ab00000 0xb0000>; + + interrupts = , + , + , + ; + + clocks = <&gcc GCC_NSS_EDMA_CLK>, + <&gcc GCC_NSS_EDMA_CFG_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>; + clock-names = "nss_edma_clk", "nss_edma_cfg_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "gcc_nss_noc_clk", "gcc_nssnoc_snoc_clk", + "gcc_mem_noc_nss_axi_clk"; + + resets = <&gcc GCC_EDMA_HW_RESET>; + reset-names = "edma_rst"; + }; diff --git a/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-ppe.yaml b/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-ppe.yaml new file mode 100644 index 00000000000000..ddd727df6267b0 --- /dev/null +++ b/target/linux/qualcommax/files/include/dt-bindings/net/qualcomm,ipq-ppe.yaml @@ -0,0 +1,309 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/dsa/qualcomm,ipq-ppe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm IPQ PPE Ethernet Switch + +maintainers: + - John Crispin + +description: | + The Packet Processing Engine (PPE) in Qualcomm IPQ6018 and IPQ8074 SoCs is a + hardware Ethernet switch with integrated MAC, L2 forwarding, FDB, and QoS + scheduling. It is driven as a DSA switch, using an EDMA network device as the + CPU port conduit and UNIPHY PCS instances for SerDes link management. + + IPQ6018 provides 7 ports (CPU port 0, user ports 1-4 via QSGMII/PSGMII on uniphy0, + and port 5 via uniphy1). IPQ8074 provides 8 ports (CPU port 0, user ports + 1-4 via QSGMII/PSGMII on uniphy0, and ports 5-6 via uniphy1/uniphy2). + +$ref: dsa.yaml# + +properties: + compatible: + enum: + - qualcomm,ipq6018-ppe + - qualcomm,ipq8074-ppe + + reg: + maxItems: 1 + + clocks: + minItems: 21 + maxItems: 33 + description: | + PPE common clocks, per-port MAC clocks, NSS infrastructure clocks, and + per-port RX/TX clocks. The exact set depends on the SoC variant and + the number of active ports. + + clock-names: + minItems: 21 + maxItems: 33 + items: + enum: + - cmn_ahb_clk + - cmn_sys_clk + - port1_mac_clk + - port2_mac_clk + - port3_mac_clk + - port4_mac_clk + - port5_mac_clk + - port6_mac_clk + - nss_ppe_clk + - nss_ppe_cfg_clk + - nssnoc_ppe_clk + - nssnoc_ppe_cfg_clk + - nss_ppe_ipe_clk + - nss_ppe_btq_clk + - gcc_mdio_ahb_clk + - gcc_nss_noc_clk + - gcc_nssnoc_snoc_clk + - gcc_mem_noc_nss_axi_clk + - gcc_nss_crypto_clk + - gcc_nss_imem_clk + - gcc_nss_ptp_ref_clk + - gcc_snoc_nssnoc_clk + - port1_rx + - port1_tx + - port2_rx + - port2_tx + - port3_rx + - port3_tx + - port4_rx + - port4_tx + - port5_rx + - port5_tx + - port6_rx + - port6_tx + + resets: + minItems: 2 + maxItems: 7 + description: | + PPE full reset followed by per-port NSS resets. IPQ6018 has 6 resets + (PPE + 5 ports), IPQ8074 has 7 (PPE + 6 ports). + + reset-names: + minItems: 2 + maxItems: 7 + items: + enum: + - ppe_rst + - nss_port1_rst + - nss_port2_rst + - nss_port3_rst + - nss_port4_rst + - nss_port5_rst + - nss_port6_rst + +patternProperties: + "^(ethernet-)?ports$": + type: object + additionalProperties: true + patternProperties: + "^(ethernet-)?port@[0-7]$": + type: object + description: PPE switch ports + + $ref: dsa-port.yaml# + + properties: + pcs-handle: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle to a UNIPHY PCS instance + - description: Channel index within the UNIPHY + description: + Reference to the UNIPHY PCS instance and channel that provides + SerDes link control for this port. Not used on the CPU port or + ports with RGMII PHY connections. + + unevaluatedProperties: false + +oneOf: + - required: + - ports + - required: + - ethernet-ports + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + + edma: edma@3ab00000 { + compatible = "qualcomm,ipq8074-edma"; + reg = <0x3ab00000 0xb0000>; + + interrupts = , + , + , + ; + + clocks = <&gcc GCC_NSS_EDMA_CLK>, + <&gcc GCC_NSS_EDMA_CFG_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>; + clock-names = "nss_edma_clk", "nss_edma_cfg_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "gcc_nss_noc_clk", "gcc_nssnoc_snoc_clk", + "gcc_mem_noc_nss_axi_clk"; + + resets = <&gcc GCC_EDMA_HW_RESET>; + reset-names = "edma_rst"; + }; + + uniphy1: ethernet-pcs@7a10000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x07a10000 0x10000>; + #pcs-cells = <1>; + + clocks = <&gcc GCC_UNIPHY1_AHB_CLK>, + <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_TX_CLK>; + clock-names = "ahb", "sys", + "port5_rx", "port5_tx"; + + resets = <&gcc GCC_UNIPHY1_SOFT_RESET>, + <&gcc GCC_UNIPHY1_XPCS_RESET>; + reset-names = "soft", "xpcs"; + }; + + uniphy2: ethernet-pcs@7a20000 { + compatible = "qualcomm,ipq8074-uniphy"; + reg = <0x07a20000 0x10000>; + #pcs-cells = <1>; + + clocks = <&gcc GCC_UNIPHY2_AHB_CLK>, + <&gcc GCC_UNIPHY2_SYS_CLK>, + <&gcc GCC_UNIPHY2_PORT6_RX_CLK>, + <&gcc GCC_UNIPHY2_PORT6_TX_CLK>; + clock-names = "ahb", "sys", + "port6_rx", "port6_tx"; + + resets = <&gcc GCC_UNIPHY2_SOFT_RESET>, + <&gcc GCC_UNIPHY2_XPCS_RESET>; + reset-names = "soft", "xpcs"; + }; + + ppe@3a000000 { + compatible = "qualcomm,ipq8074-ppe"; + reg = <0x3a000000 0x900000>; + + clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, + <&gcc GCC_CMN_12GPLL_SYS_CLK>, + <&gcc GCC_PORT1_MAC_CLK>, + <&gcc GCC_PORT2_MAC_CLK>, + <&gcc GCC_PORT3_MAC_CLK>, + <&gcc GCC_PORT4_MAC_CLK>, + <&gcc GCC_PORT5_MAC_CLK>, + <&gcc GCC_PORT6_MAC_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_PPE_IPE_CLK>, + <&gcc GCC_NSS_PPE_BTQ_CLK>, + <&gcc GCC_MDIO_AHB_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_PORT1_RX_CLK>, + <&gcc GCC_NSS_PORT1_TX_CLK>, + <&gcc GCC_NSS_PORT2_RX_CLK>, + <&gcc GCC_NSS_PORT2_TX_CLK>, + <&gcc GCC_NSS_PORT3_RX_CLK>, + <&gcc GCC_NSS_PORT3_TX_CLK>, + <&gcc GCC_NSS_PORT4_RX_CLK>, + <&gcc GCC_NSS_PORT4_TX_CLK>, + <&gcc GCC_NSS_PORT5_RX_CLK>, + <&gcc GCC_NSS_PORT5_TX_CLK>, + <&gcc GCC_NSS_PORT6_RX_CLK>, + <&gcc GCC_NSS_PORT6_TX_CLK>; + clock-names = "cmn_ahb_clk", "cmn_sys_clk", + "port1_mac_clk", "port2_mac_clk", + "port3_mac_clk", "port4_mac_clk", + "port5_mac_clk", "port6_mac_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "nss_ppe_ipe_clk", "nss_ppe_btq_clk", + "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", + "gcc_nssnoc_snoc_clk", + "gcc_mem_noc_nss_axi_clk", + "gcc_nss_crypto_clk", + "gcc_nss_imem_clk", + "gcc_nss_ptp_ref_clk", + "port1_rx", "port1_tx", + "port2_rx", "port2_tx", + "port3_rx", "port3_tx", + "port4_rx", "port4_tx", + "port5_rx", "port5_tx", + "port6_rx", "port6_tx"; + + resets = <&gcc GCC_PPE_FULL_RESET>, + <&gcc GCC_NSSPORT1_RESET>, + <&gcc GCC_NSSPORT2_RESET>, + <&gcc GCC_NSSPORT3_RESET>, + <&gcc GCC_NSSPORT4_RESET>, + <&gcc GCC_NSSPORT5_RESET>, + <&gcc GCC_NSSPORT6_RESET>; + reset-names = "ppe_rst", "nss_port1_rst", + "nss_port2_rst", "nss_port3_rst", + "nss_port4_rst", "nss_port5_rst", + "nss_port6_rst"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&edma>; + phy-mode = "internal"; + + fixed-link { + speed = <10000>; + full-duplex; + }; + }; + + port@5 { + reg = <5>; + label = "lan"; + phy-handle = <&phy1>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy1 0>; + }; + + port@6 { + reg = <6>; + label = "wan"; + phy-handle = <&phy2>; + phy-mode = "sgmii"; + pcs-handle = <&uniphy2 0>; + }; + }; + }; diff --git a/target/linux/qualcommax/files/include/linux/pcs/pcs-qca-uniphy.h b/target/linux/qualcommax/files/include/linux/pcs/pcs-qca-uniphy.h new file mode 100644 index 00000000000000..a3ed045f57f264 --- /dev/null +++ b/target/linux/qualcommax/files/include/linux/pcs/pcs-qca-uniphy.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __QCA_UNIPHY_H +#define __QCA_UNIPHY_H + +#include +#include +#include +#include +#include + +#define QCA_UNIPHY_CHANNELS 5 + +#define IPQ5018_UNIPHY_REFCLK 0x74 +#define IPQ5018_UNIPHY_REFCLK_EN BIT(0) +#define IPQ5018_UNIPHY_REFCLK_DIV BIT(1) /* 0 (default): 50MHz, 1: 25MHz */ +#define IPQ5018_UNIPHY_REFCLK_DS GENMASK(3, 2) /* 0: 2.8V, 1 (default): 1.5V */ + +#define UNIPHY_OFFSET_CALIB_4 0x1e0 +#define UNIPHY_CALIBRATION_DONE BIT(7) + +#define UNIPHY_MISC2_PHY_MODE 0x218 +#define UNIPHY_MISC2_PHY_MODE_MASK GENMASK(6, 4) +#define UNIPHY_MISC2_SGMII FIELD_PREP_CONST(UNIPHY_MISC2_PHY_MODE_MASK, 0x3) +#define UNIPHY_MISC2_SGMIIPLUS FIELD_PREP_CONST(UNIPHY_MISC2_PHY_MODE_MASK, 0x5) +#define UNIPHY_MISC2_USXGMII FIELD_PREP_CONST(UNIPHY_MISC2_PHY_MODE_MASK, 0x7) + +#define UNIPHY_MODE_CTRL 0x46c +#define UNIPHY_MODE_SEL_MASK GENMASK(12, 8) +#define UNIPHY_XPCS_MODE BIT(12) +#define UNIPHY_SGPLUS_MODE BIT(11) +#define UNIPHY_SGMII_MODE BIT(10) +#define UNIPHY_CH0_PSGMII_QSGMII BIT(9) +#define UNIPHY_CH0_QSGMII_SGMII BIT(8) +#define UNIPHY_CH0_MODE_CTRL_25M GENMASK(6, 4) +#define UNIPHY_CH0_MODE_1000BASEX 0 +#define UNIPHY_CH0_MODE_MAC 2 +#define UNIPHY_AUTONEG_MODE_ATH BIT(0) + +#define UNIPHY_PLL_POWER_ON_AND_RESET 0x780 +#define UNIPHY_PLL_RESET_ANALOG BIT(6) + +#define UNIPHY_CH_BASE(ch) (0x480 + (ch) * 0x18) + +#define UNIPHY_CH_CTRL(ch) (UNIPHY_CH_BASE(ch) + 0x0) +#define UNIPHY_CH_SPEED_MODE GENMASK(2, 1) +#define UNIPHY_CH_FORCE_MODE BIT(3) +#define UNIPHY_CH_AN_ENABLE BIT(6) +#define UNIPHY_CH_AN_RESTART BIT(7) +#define UNIPHY_CH_ADP_SW_RSTN BIT(11) + +#define UNIPHY_CH_STS(ch) (UNIPHY_CH_BASE(ch) + 0x8) +#define UNIPHY_CH_STS_RX_PAUSE BIT(0) +#define UNIPHY_CH_STS_TX_PAUSE BIT(1) +#define UNIPHY_CH_STS_SPEED_MODE GENMASK(5, 4) +#define UNIPHY_CH_STS_DUPLEX BIT(6) +#define UNIPHY_CH_STS_LINK BIT(7) + +#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))) + +#define XPCS_KR_STS1 0x30020 +#define XPCS_KR_STS1_PLU 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_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)) +#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_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 +#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 + +#define UNIPHY_CALIBRATION_TIMEOUT_US 100000 +#define UNIPHY_CALIBRATION_POLL_US 1000 + +enum qca_uniphy_type { + UNIPHY_IPQ5018, + UNIPHY_IPQ6018, + UNIPHY_IPQ8074, +}; + +struct qca_uniphy; + +struct qca_uniphy_clk { + struct clk_hw hw; + struct qca_uniphy *uniphy; +}; + +struct qca_uniphy_pcs { + struct phylink_pcs pcs; + struct qca_uniphy *uniphy; + int channel; +}; + +struct qca_uniphy_match_data { + enum qca_uniphy_type uniphy_type; + bool ref_clk_enable; +}; + +#define to_qca_uniphy_pcs(n) container_of(pcs, struct qca_uniphy_pcs, pcs); + +struct qca_uniphy { + struct device *dev; + void __iomem *base; + struct regmap *regmap; + struct reset_control *rst_ahb; + struct reset_control *rst_soft; + struct reset_control *rst_xpcs; + struct clk_bulk_data *clks; + int num_clks; + struct qca_uniphy_pcs port_pcs[QCA_UNIPHY_CHANNELS]; + struct qca_uniphy_clk rx_clk; + struct qca_uniphy_clk tx_clk; + struct qca_uniphy_clk ref_clk; + const struct qca_uniphy_match_data *data; + phy_interface_t interface; +}; + +#define port_rx_clk_idx(upcs) ((upcs)->channel * 2) + 2 +#define port_tx_clk_idx(upcs) (((upcs)->channel * 2) + 1) + 2 + +#endif diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk index 2bd3dab6343f90..dde9c381318de8 100644 --- a/target/linux/qualcommax/image/ipq807x.mk +++ b/target/linux/qualcommax/image/ipq807x.mk @@ -86,7 +86,7 @@ define Device/asus_rt-ax89x PAGESIZE := 2048 DEVICE_DTS_CONFIG := config@hk01 SOC := ipq8074 - DEVICE_PACKAGES := kmod-hwmon-gpiofan ipq-wifi-asus_rt-ax89x + DEVICE_PACKAGES := kmod-hwmon-gpiofan kmod-sfp ipq-wifi-asus_rt-ax89x KERNEL_NAME := vmlinux KERNEL := kernel-bin | libdeflate-gzip KERNEL_IN_UBI := 1 diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/preinit/04_set_netdev_label b/target/linux/qualcommax/ipq50xx/base-files/lib/preinit/04_set_netdev_label new file mode 100755 index 00000000000000..29921af627cce5 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/preinit/04_set_netdev_label @@ -0,0 +1,23 @@ +set_netdev_labels() { + local dir + local label + local netdev + + for dir in /sys/class/net/*; do + [ -r "$dir/device/of_node/label" ] || continue + read -r label < "$dir/device/of_node/label" + netdev="${dir##*/}" + [ "$netdev" = "$label" ] && continue + ip link set "$netdev" name "$label" + done + + for dir in /sys/class/net/*; do + [ -r "$dir/device/of_node/openwrt,netdev-name" ] || continue + read -r label < "$dir/device/of_node/openwrt,netdev-name" + netdev="${dir##*/}" + [ "$netdev" = "$label" ] && continue + ip link set "$netdev" name "$label" + done +} + +boot_hook_add preinit_main set_netdev_labels diff --git a/target/linux/qualcommax/ipq50xx/config-default b/target/linux/qualcommax/ipq50xx/config-default index 5864b7a801af2c..58743b608886a4 100644 --- a/target/linux/qualcommax/ipq50xx/config-default +++ b/target/linux/qualcommax/ipq50xx/config-default @@ -1,15 +1,14 @@ -CONFIG_GRO_CELLS=y +# CONFIG_DWMAC_GENERIC is not set +CONFIG_DWMAC_IPQ5018=y CONFIG_IPQ_CMN_PLL=y CONFIG_IPQ_GCC_5018=y CONFIG_LEDS_PWM=y CONFIG_MAXLINEAR_GPHY=y CONFIG_MTD_SPI_NAND=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y CONFIG_NET_DSA_QCA8K=y CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y CONFIG_NET_DSA_TAG_QCA=y -CONFIG_PHYLINK=y +CONFIG_PCS_XPCS=y CONFIG_PHY_QCOM_M31_USB=y CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP=y CONFIG_PINCTRL_IPQ5018=y @@ -22,3 +21,5 @@ CONFIG_QCOM_Q6V5_MPD=y CONFIG_QCOM_Q6V5_WCSS_SEC=y CONFIG_QCOM_TMEL_QMP_MAILBOX=y CONFIG_SPI_QPIC_SNAND=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y diff --git a/target/linux/qualcommax/ipq60xx/config-default b/target/linux/qualcommax/ipq60xx/config-default index 262468a0b2ff24..0b3a10efe0c27f 100644 --- a/target/linux/qualcommax/ipq60xx/config-default +++ b/target/linux/qualcommax/ipq60xx/config-default @@ -4,8 +4,10 @@ CONFIG_MTD_SPLIT_FIT_FW=y CONFIG_PINCTRL_IPQ6018=y CONFIG_PWM=y CONFIG_PWM_IPQ=y +CONFIG_QCOM_80211AX_PPE=y CONFIG_QCOM_APM=y # CONFIG_QCOM_CLK_SMD_RPM is not set +CONFIG_QCOM_EDMA=y # CONFIG_QCOM_RPMPD is not set CONFIG_QCOM_SMD_RPM=y CONFIG_REGULATOR_CPR3=y diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default index ba4c4631cb7b74..9837d8744a9574 100644 --- a/target/linux/qualcommax/ipq807x/config-default +++ b/target/linux/qualcommax/ipq807x/config-default @@ -1,18 +1,14 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y CONFIG_DT_IDLE_GENPD=y -CONFIG_GRO_CELLS=y CONFIG_IPQ_CMN_PLL=y CONFIG_IPQ_GCC_8074=y CONFIG_MDIO_BITBANG=y CONFIG_MDIO_GPIO=y # CONFIG_MFD_HI6421_SPMI is not set CONFIG_MFD_SPMI_PMIC=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y CONFIG_NET_DSA_QCA8K=y CONFIG_NET_DSA_TAG_QCA=y # CONFIG_NVMEM_SPMI_SDAM is not set -CONFIG_PHYLINK=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y # CONFIG_PM8916_WATCHDOG is not set @@ -20,8 +16,10 @@ CONFIG_PM_GENERIC_DOMAINS=y CONFIG_PM_GENERIC_DOMAINS_OF=y # CONFIG_POWER_RESET_QCOM_PON is not set CONFIG_QCA83XX_PHY=y +CONFIG_QCOM_80211AX_PPE=y CONFIG_QCOM_APM=y # CONFIG_QCOM_COINCELL is not set +CONFIG_QCOM_EDMA=y CONFIG_QCOM_GDSC=y CONFIG_QCOM_SPMI_ADC5=y # CONFIG_QCOM_SPMI_RRADC is not set diff --git a/target/linux/qualcommax/patches-6.12/0722-clk-qcom-gcc-ipq5018-refer-to-uniphy-rx-and-tx-clk-providers-by-name.patch b/target/linux/qualcommax/patches-6.12/0722-clk-qcom-gcc-ipq5018-refer-to-uniphy-rx-and-tx-clk-providers-by-name.patch deleted file mode 100644 index 6ecdee01611ef2..00000000000000 --- a/target/linux/qualcommax/patches-6.12/0722-clk-qcom-gcc-ipq5018-refer-to-uniphy-rx-and-tx-clk-providers-by-name.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ce9e56a436e486690097cfbdda2d0c11b60db4c2 Mon Sep 17 00:00:00 2001 -From: Ziyang Huang -Date: Sun, 8 Sep 2024 16:40:12 +0800 -Subject: [PATCH] clk: gcc-ipq5018: refer to UNIPHY rx and tx clk providers by name - -QCA-SSDK does not register the output clocks of the onboard uniphy so the -GCC and DTS can't reference them by their index. -The SSDK references them by name, so let's change the GCC driver -accordingly. - -Signed-off-by: Ziyang Huang -Signed-off-by: George Moussalem ---- - drivers/clk/qcom/gcc-ipq5018.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/clk/qcom/gcc-ipq5018.c -+++ b/drivers/clk/qcom/gcc-ipq5018.c -@@ -368,8 +368,8 @@ static const struct parent_map gcc_xo_ge - - static const struct clk_parent_data gcc_xo_uniphy_gcc_rx_uniphy_gcc_tx_ubi32_pll_gpll0[] = { - { .index = DT_XO }, -- { .index = DT_UNIPHY_RX_CLK }, -- { .index = DT_UNIPHY_TX_CLK }, -+ { .name = "uniphy_gcc_rx", .index = -1 }, -+ { .name = "uniphy_gcc_tx", .index = -1 }, - { .hw = &ubi32_pll.clkr.hw }, - { .hw = &gpll0.clkr.hw }, - }; -@@ -384,8 +384,8 @@ static const struct parent_map gcc_xo_un - - static const struct clk_parent_data gcc_xo_uniphy_gcc_tx_uniphy_gcc_rx_ubi32_pll_gpll0[] = { - { .index = DT_XO }, -- { .index = DT_UNIPHY_TX_CLK }, -- { .index = DT_UNIPHY_RX_CLK }, -+ { .name = "uniphy_gcc_tx", .index = -1 }, -+ { .name = "uniphy_gcc_rx", .index = -1 }, - { .hw = &ubi32_pll.clkr.hw }, - { .hw = &gpll0.clkr.hw }, - }; diff --git a/target/linux/qualcommax/patches-6.12/0740-01-dt-bindings-net-ethernet-phy-increase-max-clock-count-to-two.patch b/target/linux/qualcommax/patches-6.12/0740-01-dt-bindings-net-ethernet-phy-increase-max-clock-count-to-two.patch new file mode 100644 index 00000000000000..57285d0595f878 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0740-01-dt-bindings-net-ethernet-phy-increase-max-clock-count-to-two.patch @@ -0,0 +1,45 @@ +From 009bdd7a91990982e5b3bab4001318dfe5f6f575 Mon Sep 17 00:00:00 2001 +From: George Moussalem +Date: Sun, 07 Jun 2026 13:00:06 +0400 +Subject: [PATCH v4 1/4] dt-bindings: net: ethernet-phy: increase max clock count to two +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 7bit +Message-Id: <20260607-ipq5018-gephy-clocks-v4-1-15b3a5ba7460@outlook.com> + +The clocks property has a restriction to maximum one. +Yet, some PHYs may require more than 1 clock such as the IPQ5018 PHY +which requires two clocks for RX and TX. As such, increase maxItems to +two. + +Reviewed-by: Rob Herring (Arm) +Signed-off-by: George Moussalem +--- +Commit 350b7a258f20 introduced the clocks property with a restriction to +maximum 1 to the main ethernet-phy.yaml binding for Realtek to add an +optional external clock source. This is restrictive to all PHY bindings, +as some PHYs may require more than 1 clock such as the IPQ5018 PHY which +requires 2 clocks (for RX and TX). +--- + Documentation/devicetree/bindings/net/ethernet-phy.yaml | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/Documentation/devicetree/bindings/net/ethernet-phy.yaml ++++ b/Documentation/devicetree/bindings/net/ethernet-phy.yaml +@@ -102,10 +102,13 @@ properties: + by software. + + clocks: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 2 + description: +- External clock connected to the PHY. If not specified it is assumed +- that the PHY uses a fixed crystal or an internal oscillator. ++ External clock connected to the PHY or RX and TX clocks that the PHY ++ requires to enable explicitly. If not specified it is assumed ++ that the PHY uses a fixed crystal or an internal oscillator or that the ++ RX/TX clocks are hardware enabled by default. + + enet-phy-lane-swap: + $ref: /schemas/types.yaml#/definitions/flag diff --git a/target/linux/qualcommax/patches-6.12/0740-03-arm64-qcom-ipq5018-add-gephy-rx-and-tx-clocks.patch b/target/linux/qualcommax/patches-6.12/0740-03-arm64-qcom-ipq5018-add-gephy-rx-and-tx-clocks.patch new file mode 100644 index 00000000000000..0e2aed96976e81 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0740-03-arm64-qcom-ipq5018-add-gephy-rx-and-tx-clocks.patch @@ -0,0 +1,30 @@ +From ea59840c0b6839c65eaf39887a0762dfc4993f50 Mon Sep 17 00:00:00 2001 +From: George Moussalem +Date: Sun, 07 Jun 2026 13:00:08 +0400 +Subject: [PATCH v4 3/4] arm64: qcom: ipq5018: Add GEPHY RX and TX clocks +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 7bit +Message-Id: <20260607-ipq5018-gephy-clocks-v4-3-15b3a5ba7460@outlook.com> + +Add RX and TX clocks for the IPQ5018 GEPHY to enable the datapath. + +Fixes: f5f2b835e316 ("arm64: dts: qcom: ipq5018: Add GE PHY to internal mdio bus") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: George Moussalem +--- + arch/arm64/boot/dts/qcom/ipq5018.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi +@@ -234,6 +234,9 @@ + compatible = "ethernet-phy-id004d.d0c0"; + reg = <7>; + ++ clocks = <&gcc GCC_GEPHY_RX_CLK>, ++ <&gcc GCC_GEPHY_TX_CLK>; ++ clock-names = "rx", "tx"; + resets = <&gcc GCC_GEPHY_MISC_ARES>; + }; + }; diff --git a/target/linux/qualcommax/patches-6.12/0740-04-net-phy-at803x-add-rx-and-tx-clock-management-for-ipq5018-phy.patch b/target/linux/qualcommax/patches-6.12/0740-04-net-phy-at803x-add-rx-and-tx-clock-management-for-ipq5018-phy.patch new file mode 100644 index 00000000000000..de781809f563dc --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0740-04-net-phy-at803x-add-rx-and-tx-clock-management-for-ipq5018-phy.patch @@ -0,0 +1,54 @@ +From 929c734775fc0e4f576727b47f8a07d7e5cabb4f Mon Sep 17 00:00:00 2001 +From: George Moussalem +Date: Sun, 07 Jun 2026 13:00:09 +0400 +Subject: [PATCH v4 4/4] net: phy: at803x: add RX and TX clock management for IPQ5018 PHY +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 7bit +Message-Id: <20260607-ipq5018-gephy-clocks-v4-4-15b3a5ba7460@outlook.com> + +Acquire and enable the RX and TX clocks for the IPQ5018 PHY. +These clocks are required for the PHY's datapath to function correctly. + +Fixes: d46502279a11 ("net: phy: qcom: at803x: Add Qualcomm IPQ5018 Internal PHY support") +Signed-off-by: George Moussalem +--- + drivers/net/phy/qcom/at803x.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/net/phy/qcom/at803x.c ++++ b/drivers/net/phy/qcom/at803x.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -176,6 +177,8 @@ struct at803x_context { + }; + + struct ipq5018_priv { ++ struct clk *rx_clk; ++ struct clk *tx_clk; + struct reset_control *rst; + bool set_short_cable_dac; + }; +@@ -1099,6 +1102,16 @@ static int ipq5018_probe(struct phy_devi + priv->set_short_cable_dac = of_property_read_bool(dev->of_node, + "qcom,dac-preset-short-cable"); + ++ priv->rx_clk = devm_clk_get_enabled(dev, "rx"); ++ if (IS_ERR(priv->rx_clk)) ++ return dev_err_probe(dev, PTR_ERR(priv->rx_clk), ++ "failed to get and enable RX clock\n"); ++ ++ priv->tx_clk = devm_clk_get_enabled(dev, "tx"); ++ if (IS_ERR(priv->tx_clk)) ++ return dev_err_probe(dev, PTR_ERR(priv->tx_clk), ++ "failed to get and enable TX clock\n"); ++ + priv->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(priv->rst)) + return dev_err_probe(dev, PTR_ERR(priv->rst), diff --git a/target/linux/qualcommax/patches-6.12/0760-net-phy-aquantia-enable-USXGMII-MAC-autoneg.patch b/target/linux/qualcommax/patches-6.12/0760-net-phy-aquantia-enable-USXGMII-MAC-autoneg.patch new file mode 100644 index 00000000000000..6ff9b323381ce2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0760-net-phy-aquantia-enable-USXGMII-MAC-autoneg.patch @@ -0,0 +1,36 @@ +From 54280bff5b17407e8b23cdeafdc63f4d43ad1ee5 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 27 Nov 2025 13:49:06 +0100 +Subject: [PATCH] net: phy: aquantia: enable USXGMII MAC autoneg + +USXGMII MAC autoneg control bit is always set disabled by default, in order +for USXGMII to work properly we must enable it. + +Signed-off-by: Robert Marko +--- + drivers/net/phy/aquantia/aquantia_main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/phy/aquantia/aquantia_main.c ++++ b/drivers/net/phy/aquantia/aquantia_main.c +@@ -46,6 +46,9 @@ + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 + ++#define MDIO_PHYXS_VEND_PROV2 0xc441 ++#define MDIO_PHYXS_VEND_PROV2_USX_AUTONEG_MAC BIT(3) ++ + #define MDIO_AN_VEND_PROV 0xc400 + #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) + #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) +@@ -440,6 +443,10 @@ static int aqr107_read_status(struct phy + break; + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: + phydev->interface = PHY_INTERFACE_MODE_USXGMII; ++ phy_modify_mmd(phydev, MDIO_MMD_PHYXS, ++ MDIO_PHYXS_VEND_PROV2, ++ MDIO_PHYXS_VEND_PROV2_USX_AUTONEG_MAC, ++ MDIO_PHYXS_VEND_PROV2_USX_AUTONEG_MAC); + break; + case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: + phydev->interface = PHY_INTERFACE_MODE_XAUI; diff --git a/target/linux/qualcommax/patches-6.12/0816-arm64-dts-qcom-ipq5018-add-wifi-support.patch b/target/linux/qualcommax/patches-6.12/0816-arm64-dts-qcom-ipq5018-add-wifi-support.patch index c9dcc0d12644c3..8c6b2f9769eca3 100644 --- a/target/linux/qualcommax/patches-6.12/0816-arm64-dts-qcom-ipq5018-add-wifi-support.patch +++ b/target/linux/qualcommax/patches-6.12/0816-arm64-dts-qcom-ipq5018-add-wifi-support.patch @@ -13,7 +13,7 @@ Signed-off-by: George Moussalem --- --- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi -@@ -736,6 +736,118 @@ +@@ -739,6 +739,118 @@ }; }; diff --git a/target/linux/qualcommax/patches-6.12/0818-arm64-dts-qcom-ipq5018-fix-assigned-cmn-pll-clock-rate.patch b/target/linux/qualcommax/patches-6.12/0818-arm64-dts-qcom-ipq5018-fix-assigned-cmn-pll-clock-rate.patch index 6ab9ba3788bad6..8d0ca3741d9ce6 100644 --- a/target/linux/qualcommax/patches-6.12/0818-arm64-dts-qcom-ipq5018-fix-assigned-cmn-pll-clock-rate.patch +++ b/target/linux/qualcommax/patches-6.12/0818-arm64-dts-qcom-ipq5018-fix-assigned-cmn-pll-clock-rate.patch @@ -23,7 +23,7 @@ Signed-off-by: George Moussalem --- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi -@@ -266,7 +266,7 @@ +@@ -269,7 +269,7 @@ "sys"; #clock-cells = <1>; assigned-clocks = <&cmn_pll IPQ5018_CMN_PLL_CLK>; diff --git a/target/linux/qualcommax/patches-6.12/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch b/target/linux/qualcommax/patches-6.12/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch new file mode 100644 index 00000000000000..a4432179777136 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0842-arm64-dts-qcom-ipq5018-add-uniphy-node.patch @@ -0,0 +1,51 @@ +--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -258,6 +259,29 @@ + status = "disabled"; + }; + ++ uniphy0: ethernet-pcs@98000 { ++ compatible = "qualcomm,ipq5018-uniphy"; ++ reg = <0x00098000 0x800>; ++ #clock-cells = <1>; ++ clocks = <&gcc GCC_UNIPHY_AHB_CLK>, ++ <&gcc GCC_UNIPHY_SYS_CLK>, ++ <&gcc GCC_UNIPHY_RX_CLK>, ++ <&gcc GCC_UNIPHY_TX_CLK>, ++ <&cmn_pll IPQ5018_ETH_50MHZ_CLK>; ++ clock-names = "ahb", ++ "sys", ++ "port5_rx", ++ "port5_tx", ++ "ref"; ++ clock-output-names = "uniphy0_gcc_rx_clk", ++ "uniphy0_gcc_tx_clk", ++ "uniphy0_ref_clk"; ++ resets = <&gcc GCC_UNIPHY_SOFT_RESET>; ++ reset-names = "soft"; ++ #pcs-cells = <0>; ++ status = "disabled"; ++ }; ++ + cmn_pll: clock-controller@9b000 { + compatible = "qcom,ipq5018-cmn-pll"; + reg = <0x0009b000 0x800>; +@@ -449,8 +473,8 @@ + <0>, + <&gephy_rx_clk>, + <&gephy_tx_clk>, +- <0>, +- <0>; ++ <&uniphy0 UNIPHY_CLK_RX>, ++ <&uniphy0 UNIPHY_CLK_TX>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/target/linux/qualcommax/patches-6.12/0843-net-stmmac-add-get_interfaces-platform-method.patch b/target/linux/qualcommax/patches-6.12/0843-net-stmmac-add-get_interfaces-platform-method.patch new file mode 100644 index 00000000000000..3e415d24fbd305 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0843-net-stmmac-add-get_interfaces-platform-method.patch @@ -0,0 +1,56 @@ +From ca732e990fc8222a2d6782ae750304719e212fe8 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 1 May 2025 12:45:11 +0100 +Subject: [PATCH] net: stmmac: add get_interfaces() platform method + +Add a get_interfaces() platform method to allow platforms to indicate +to phylink which interface modes they support - which then allows +phylink to validate on initialisation that the configured PHY interface +mode is actually supported. + +Signed-off-by: Russell King (Oracle) +Link: https://patch.msgid.link/E1uASLn-0021Qd-Mi@rmk-PC.armlinux.org.uk +Signed-off-by: Jakub Kicinski +--- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 16 +++++++++++++--- + include/linux/stmmac.h | 2 ++ + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1250,10 +1250,21 @@ static int stmmac_phy_setup(struct stmma + priv->phylink_config.default_an_inband = + mdio_bus_data->default_an_inband; + +- /* Set the platform/firmware specified interface mode. Note, phylink +- * deals with the PHY interface mode, not the MAC interface mode. ++ /* Get the PHY interface modes (at the PHY end of the link) that ++ * are supported by the platform. + */ +- __set_bit(mode, priv->phylink_config.supported_interfaces); ++ if (priv->plat->get_interfaces) ++ priv->plat->get_interfaces(priv, priv->plat->bsp_priv, ++ priv->phylink_config.supported_interfaces); ++ ++ /* Set the platform/firmware specified interface mode if the ++ * supported interfaces have not already been provided using ++ * phy_interface as a last resort. ++ */ ++ if (phy_interface_empty(priv->phylink_config.supported_interfaces)) ++ __set_bit(priv->plat->phy_interface, ++ priv->phylink_config.supported_interfaces); ++ + + /* If we have an xpcs, it defines which PHY interfaces are supported. */ + if (priv->hw->xpcs) +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -229,6 +229,8 @@ struct plat_stmmacenet_data { + u8 tx_sched_algorithm; + struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES]; + struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; ++ void (*get_interfaces)(struct stmmac_priv *priv, void *bsp_priv, ++ unsigned long *interfaces); + void (*fix_mac_speed)(void *priv, unsigned int speed, unsigned int mode); + int (*fix_soc_reset)(void *priv, void __iomem *ioaddr); + int (*serdes_powerup)(struct net_device *ndev, void *priv); diff --git a/target/linux/qualcommax/patches-6.12/0912-arm64-dts-qcom-ipq5018-remove-cpufreq-scaling.patch b/target/linux/qualcommax/patches-6.12/0912-arm64-dts-qcom-ipq5018-remove-cpufreq-scaling.patch index f3e1644b22ae1d..8432679f66e048 100644 --- a/target/linux/qualcommax/patches-6.12/0912-arm64-dts-qcom-ipq5018-remove-cpufreq-scaling.patch +++ b/target/linux/qualcommax/patches-6.12/0912-arm64-dts-qcom-ipq5018-remove-cpufreq-scaling.patch @@ -13,7 +13,7 @@ Signed-off-by: Robert Senderek --- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi -@@ -94,12 +94,6 @@ +@@ -95,12 +95,6 @@ compatible = "operating-points-v2"; opp-shared; diff --git a/target/linux/qualcommax/patches-6.12/0920-clk-add-clk_hw_recalc_rate-to-trigger-HW-clk-rate-re.patch b/target/linux/qualcommax/patches-6.12/0920-clk-add-clk_hw_recalc_rate-to-trigger-HW-clk-rate-re.patch new file mode 100644 index 00000000000000..73444396f802dd --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0920-clk-add-clk_hw_recalc_rate-to-trigger-HW-clk-rate-re.patch @@ -0,0 +1,99 @@ +From 49ae1f081626f1a8c91b283d06868a178a0a2e5a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Mar 2026 17:41:45 +0100 +Subject: [PATCH] clk: add clk_hw_recalc_rate() to trigger HW clk rate + recalculation + +There is currently a latent problem with HW clk that only expose a +.recalc_rate OP and doesn't have a .set_rate() and also have the +CLK_GET_RATE_NOCACHE flag set. In such case the rate in clk core is +parsed only (and set) only at init and when the full clk_set_rate() +is called. In every other case .recalc_rate() is never called. + +It's also possible that an HW clk of this type, initially report 0 as rate +as the register are still not configured and the HW clk effectively doesn't +return any rate. + +This gets especially problematic when a clock provider use such clk as a +parent and require the rate for parent selection for the final rate +calculation. + +In such case, since the HW clk rate is never updated after init, it's still +0 and cause problems with any other HW clk that use .determine_rate() or +.round_rate() and search for the closest rate using clk_hw_get_rate() on +the parents. + +This doesn't happen if the full clk_get_rate() is used instead as it will +check if CLK_GET_RATE_NOCACHE is set and recalculate the rate accordingly. + +Updating the clk_hw_get_rate() to align to what clk_get_rate() does is not +possible as it should be lockless and might cause problems in any user of +clk_hw_get_rate(). + +A more safe approach is the introduction of a direct function that triggers +the HW clk rate recalculation, clk_hw_recalc_rate(). + +Any driver that implement an HW clk that entirely depends on some register +to configure the rate (that are externally configured) and have only +.recalc_rate() and set CLK_GET_RATE_NOCACHE (aka the case where the HW clk +rate actually change and depends on the external register configuration) +will have to call clk_hw_recalc_rate() on the HW clk after changing the +register configuration to sync the CCF with the new rate for the HW clk. + +Example: + + - All register zero -> HW clk rate = 0 + - PCS configure USXGMII mode -> HW clk rate = 0 + - PCS call clk_hw_recalc_rate() -> HW clk rate = 312MHz + - Port goes UP + - PCS/MAC scale the PHY port clock correctly by having + the correct reference clock as parent (instead of 0) + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk.c | 23 +++++++++++++++++++++++ + include/linux/clk-provider.h | 1 + + 2 files changed, 24 insertions(+) + +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1990,6 +1990,29 @@ static unsigned long clk_core_get_rate_r + } + + /** ++ * clk_hw_recalc_rate - trigger rate recalculation for clk_hw ++ * @hw: clk_hw associated with the clk to recalculate for ++ * ++ * Use clk_hw_recalc_rate() for the hw clk where the rate ++ * entirely depend on register configuration and doesn't have ++ * a .set_rate() OP. In such case, after modifying the register ++ * that would change the rate for the hw clk, call ++ * clk_hw_recalc_rate() to sync the CCF with the new clk rate. ++ */ ++void clk_hw_recalc_rate(const struct clk_hw *hw) ++{ ++ struct clk_core *core = hw->core; ++ ++ if (!core || !(core->flags & CLK_GET_RATE_NOCACHE)) ++ return; ++ ++ clk_prepare_lock(); ++ __clk_recalc_rates(core, false, 0); ++ clk_prepare_unlock(); ++} ++EXPORT_SYMBOL_GPL(clk_hw_recalc_rate); ++ ++/** + * clk_get_rate - return the rate of clk + * @clk: the clk whose rate is being returned + * +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -1355,6 +1355,7 @@ int clk_hw_get_parent_index(struct clk_h + int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent); + unsigned int __clk_get_enable_count(struct clk *clk); + unsigned long clk_hw_get_rate(const struct clk_hw *hw); ++void clk_hw_recalc_rate(const struct clk_hw *hw); + unsigned long clk_hw_get_flags(const struct clk_hw *hw); + #define clk_hw_can_set_rate_parent(hw) \ + (clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT) diff --git a/target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch b/target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch new file mode 100644 index 00000000000000..142c8bb698b926 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch @@ -0,0 +1,220 @@ +From a32e16b3c2fc1954ad6e09737439f60e5890278e Mon Sep 17 00:00:00 2001 +From: Maxime Chevallier +Date: Fri, 4 Nov 2022 18:41:49 +0100 +Subject: [PATCH] net: dsa: add out-of-band tagging protocol + +This tagging protocol is designed for the situation where the link +between the MAC and the Switch is designed such that the Destination +Port, which is usually embedded in some part of the Ethernet Header, is +sent out-of-band, and isn't present at all in the Ethernet frame. + +This can happen when the MAC and Switch are tightly integrated on an +SoC, as is the case with the Qualcomm IPQ4019 for example, where the DSA +tag is inserted directly into the DMA descriptors. In that case, +the MAC driver is responsible for sending the tag to the switch using +the out-of-band medium. To do so, the MAC driver needs to have the +information of the destination port for that skb. + +Add a new tagging protocol based on SKB extensions to convey the +information about the destination port to the MAC driver + +Signed-off-by: Maxime Chevallier +--- + Documentation/networking/dsa/dsa.rst | 13 +++++++- + MAINTAINERS | 1 + + include/linux/dsa/oob.h | 16 +++++++++ + include/linux/skbuff.h | 3 ++ + include/net/dsa.h | 2 ++ + net/core/skbuff.c | 10 ++++++ + net/dsa/Kconfig | 9 +++++ + net/dsa/Makefile | 1 + + net/dsa/tag_oob.c | 49 ++++++++++++++++++++++++++++ + 9 files changed, 103 insertions(+), 1 deletion(-) + create mode 100644 include/linux/dsa/oob.h + create mode 100644 net/dsa/tag_oob.c + +--- a/Documentation/networking/dsa/dsa.rst ++++ b/Documentation/networking/dsa/dsa.rst +@@ -70,7 +70,8 @@ Switch tagging protocols + ------------------------ + + DSA supports many vendor-specific tagging protocols, one software-defined +-tagging protocol, and a tag-less mode as well (``DSA_TAG_PROTO_NONE``). ++tagging protocol, a tag-less mode as well (``DSA_TAG_PROTO_NONE``) and an ++out-of-band tagging protocol (``DSA_TAG_PROTO_OOB``). + + The exact format of the tag protocol is vendor specific, but in general, they + all contain something which: +@@ -221,6 +222,16 @@ receive all frames regardless of the val + setting the ``promisc_on_conduit`` property of the ``struct dsa_device_ops``. + Note that this assumes a DSA-unaware conduit driver, which is the norm. + ++Some SoCs have a tight integration between the conduit network interface and the ++embedded switch, such that the DSA tag isn't transmitted in the packet data, ++but through another media, using so-called out-of-band tagging. In that case, ++the host MAC driver is in charge of transmitting the tag to the switch. ++An example is the IPQ4019 SoC, that transmits the tag between the ipqess ++ethernet controller and the qca8k switch using the DMA descriptor. In that ++configuration, tag-chaining is permitted, but the OOB tag will always be the ++top-most switch in the tree. The tagger (``DSA_TAG_PROTO_OOB``) uses skb ++extensions to transmit the tag to and from the MAC driver. ++ + Conduit network devices + ----------------------- + +--- /dev/null ++++ b/include/linux/dsa/oob.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0-only ++ * Copyright (C) 2022 Maxime Chevallier ++ */ ++ ++#ifndef _NET_DSA_OOB_H ++#define _NET_DSA_OOB_H ++ ++#include ++ ++struct dsa_oob_tag_info { ++ u16 port; ++}; ++ ++int dsa_oob_tag_push(struct sk_buff *skb, struct dsa_oob_tag_info *ti); ++int dsa_oob_tag_pop(struct sk_buff *skb, struct dsa_oob_tag_info *ti); ++#endif +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -4852,6 +4852,9 @@ enum skb_ext_id { + #if IS_ENABLED(CONFIG_MCTP_FLOWS) + SKB_EXT_MCTP, + #endif ++#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB) ++ SKB_EXT_DSA_OOB, ++#endif + SKB_EXT_NUM, /* must be last */ + }; + +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -57,6 +57,7 @@ struct tc_action; + #define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE 29 + #define DSA_TAG_PROTO_MXL862_VALUE 30 + #define DSA_TAG_PROTO_MXL862_8021Q_VALUE 31 ++#define DSA_TAG_PROTO_OOB_VALUE 32 + + enum dsa_tag_protocol { + DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, +@@ -91,6 +92,7 @@ enum dsa_tag_protocol { + DSA_TAG_PROTO_VSC73XX_8021Q = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE, + DSA_TAG_PROTO_MXL862 = DSA_TAG_PROTO_MXL862_VALUE, + DSA_TAG_PROTO_MXL862_8021Q = DSA_TAG_PROTO_MXL862_8021Q_VALUE, ++ DSA_TAG_PROTO_OOB = DSA_TAG_PROTO_OOB_VALUE, + }; + + struct dsa_switch; +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -65,8 +65,12 @@ + #include + #include + #include ++#ifdef CONFIG_NET_DSA_TAG_OOB ++#include ++#endif + + #include ++#include + #include + #include + #include +@@ -5097,6 +5101,9 @@ static const u8 skb_ext_type_len[] = { + #if IS_ENABLED(CONFIG_MCTP_FLOWS) + [SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow), + #endif ++#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB) ++ [SKB_EXT_DSA_OOB] = SKB_EXT_CHUNKSIZEOF(struct dsa_oob_tag_info), ++#endif + }; + + static __always_inline unsigned int skb_ext_total_length(void) +--- a/net/dsa/Kconfig ++++ b/net/dsa/Kconfig +@@ -145,6 +145,15 @@ config NET_DSA_TAG_OCELOT_8021Q + this mode, less TCAM resources (VCAP IS1, IS2, ES0) are available for + use with tc-flower. + ++config NET_DSA_TAG_OOB ++ select SKB_EXTENSIONS ++ tristate "Tag driver for Out-of-band tagging drivers" ++ help ++ Say Y or M if you want to enable support for pairs of embedded ++ switches and host MAC drivers which perform demultiplexing and ++ packet steering to ports using out of band metadata processed ++ by the DSA master, rather than tags present in the packets. ++ + config NET_DSA_TAG_QCA + tristate "Tag driver for Qualcomm Atheros QCA8K switches" + help +--- a/net/dsa/Makefile ++++ b/net/dsa/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_NET_DSA_TAG_MXL_862XX_8021Q + obj-$(CONFIG_NET_DSA_TAG_NONE) += tag_none.o + obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o + obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o ++obj-$(CONFIG_NET_DSA_TAG_OOB) += tag_oob.o + obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o + obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o + obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o +--- /dev/null ++++ b/net/dsa/tag_oob.c +@@ -0,0 +1,51 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++ ++/* Copyright (c) 2022, Maxime Chevallier */ ++ ++#include ++#include ++#include ++ ++#include "tag.h" ++ ++#define OOB_NAME "oob" ++ ++static struct sk_buff *oob_tag_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct dsa_oob_tag_info *tag_info = skb_ext_add(skb, SKB_EXT_DSA_OOB); ++ struct dsa_port *dp = dsa_user_to_port(dev); ++ ++ tag_info->port = dp->index; ++ ++ return skb; ++} ++ ++static struct sk_buff *oob_tag_rcv(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct dsa_oob_tag_info *tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB); ++ ++ if (!tag_info) ++ return NULL; ++ ++ skb->dev = dsa_conduit_find_user(dev, 0, tag_info->port); ++ if (!skb->dev) ++ return NULL; ++ ++ return skb; ++} ++ ++static const struct dsa_device_ops oob_tag_dsa_ops = { ++ .name = OOB_NAME, ++ .proto = DSA_TAG_PROTO_OOB, ++ .xmit = oob_tag_xmit, ++ .rcv = oob_tag_rcv, ++}; ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("DSA tag driver for out-of-band tagging"); ++MODULE_AUTHOR("Maxime Chevallier "); ++MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OOB, OOB_NAME); ++ ++module_dsa_tag_driver(oob_tag_dsa_ops); diff --git a/target/linux/qualcommax/patches-6.12/0951-net-pcs-add-uniphy-pcs.patch b/target/linux/qualcommax/patches-6.12/0951-net-pcs-add-uniphy-pcs.patch new file mode 100644 index 00000000000000..05ab18902e5fcb --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0951-net-pcs-add-uniphy-pcs.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -51,4 +51,13 @@ config PCS_RZN1_MIIC + on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in + pass-through mode for MII. + ++config PCS_QCA_UNIPHY ++ tristate "Qualcomm 802.11ax UNIPHY PCS driver" ++ select PHYLINK ++ select FWNODE_PCS ++ help ++ PCS driver for the UNIPHY SerDes blocks in Qualcomm 802.11ax SoCs. ++ Provides PSGMII and SGMII interface modes and registers the UNIPHY ++ PLL clock providers needed for port clock muxing. ++ + endmenu +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -10,3 +10,4 @@ obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o + obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o + obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o + obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o ++obj-$(CONFIG_PCS_QCA_UNIPHY) += pcs-qca-uniphy.o diff --git a/target/linux/qualcommax/patches-6.12/0952-net-ethernet-qca-add-ppe.patch b/target/linux/qualcommax/patches-6.12/0952-net-ethernet-qca-add-ppe.patch new file mode 100644 index 00000000000000..bec14518d67034 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0952-net-ethernet-qca-add-ppe.patch @@ -0,0 +1,27 @@ +--- a/drivers/net/ethernet/qualcomm/Kconfig ++++ b/drivers/net/ethernet/qualcomm/Kconfig +@@ -61,6 +61,13 @@ config QCOM_EMAC + low power, Receive-Side Scaling (RSS), and IEEE 1588-2008 + Precision Clock Synchronization Protocol. + ++config QCOM_80211AX_PPE ++ tristate "Qualcomm 802.11ax PPE switch driver" ++ select PHYLINK ++ help ++ Driver for Qualcomm 802.11ax PPE (Packet Processing Engine) switches. ++ ++ + source "drivers/net/ethernet/qualcomm/rmnet/Kconfig" + + endif # NET_VENDOR_QUALCOMM +--- a/drivers/net/ethernet/qualcomm/Makefile ++++ b/drivers/net/ethernet/qualcomm/Makefile +@@ -8,6 +8,8 @@ obj-$(CONFIG_QCA7000_SPI) += qcaspi.o + qcaspi-objs := qca_7k.o qca_debug.o qca_spi.o + obj-$(CONFIG_QCA7000_UART) += qcauart.o + qcauart-objs := qca_uart.o ++obj-$(CONFIG_QCOM_80211AX_PPE) += qca_ppe.o ++qca_ppe-objs := qca_ppe_main.o qca_ppe_vlan.o qca_ppe_scheduler.o + + obj-y += emac/ + diff --git a/target/linux/qualcommax/patches-6.12/0953-net-ethernet-qca-add-EDMA.patch b/target/linux/qualcommax/patches-6.12/0953-net-ethernet-qca-add-EDMA.patch new file mode 100644 index 00000000000000..6244773c4fac68 --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0953-net-ethernet-qca-add-EDMA.patch @@ -0,0 +1,24 @@ +--- a/drivers/net/ethernet/qualcomm/Kconfig ++++ b/drivers/net/ethernet/qualcomm/Kconfig +@@ -67,6 +67,11 @@ config QCOM_80211AX_PPE + help + Driver for Qualcomm 802.11ax PPE (Packet Processing Engine) switches. + ++config QCOM_EDMA ++ tristate "EDMA dataplane ethernet driver for Qualcomm IPQ platforms" ++ help ++ EDMA dataplane ethernet driver for Qualcomm IPQ platforms. ++ + + source "drivers/net/ethernet/qualcomm/rmnet/Kconfig" + +--- a/drivers/net/ethernet/qualcomm/Makefile ++++ b/drivers/net/ethernet/qualcomm/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_QCA7000_UART) += qcauart.o + qcauart-objs := qca_uart.o + obj-$(CONFIG_QCOM_80211AX_PPE) += qca_ppe.o + qca_ppe-objs := qca_ppe_main.o qca_ppe_vlan.o qca_ppe_scheduler.o ++obj-$(CONFIG_QCOM_EDMA) += qca_edma.o + + obj-y += emac/ + diff --git a/target/linux/qualcommax/patches-6.12/0954-net-stmmac-Introduce-Qualcomm-IPQ5018-DWMAC-driver.patch b/target/linux/qualcommax/patches-6.12/0954-net-stmmac-Introduce-Qualcomm-IPQ5018-DWMAC-driver.patch new file mode 100644 index 00000000000000..f0cf29a1b01e0e --- /dev/null +++ b/target/linux/qualcommax/patches-6.12/0954-net-stmmac-Introduce-Qualcomm-IPQ5018-DWMAC-driver.patch @@ -0,0 +1,27 @@ +--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig ++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig +@@ -78,6 +78,14 @@ config DWMAC_INGENIC + device driver. This driver is used on for the Ingenic SoCs + MAC ethernet controller. + ++config DWMAC_IPQ5018 ++ tristate "Qualcomm IPQ5018 DWMAC driver" ++ depends on OF && (ARCH_QCOM || COMPILE_TEST) ++ help ++ Support for ethernet controller on Qualcomm IPQ5018 SoCs. ++ ++ This selects the IPQ5018 SoC glue layer support for the stmmac driver. ++ + config DWMAC_IPQ806X + tristate "QCA IPQ806x DWMAC support" + default ARCH_QCOM +--- a/drivers/net/ethernet/stmicro/stmmac/Makefile ++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile +@@ -15,6 +15,7 @@ stmmac-$(CONFIG_STMMAC_SELFTESTS) += stm + obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o + obj-$(CONFIG_DWMAC_ANARION) += dwmac-anarion.o + obj-$(CONFIG_DWMAC_INGENIC) += dwmac-ingenic.o ++obj-$(CONFIG_DWMAC_IPQ5018) += dwmac-ipq5018.o + obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o + obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o + obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o