From 4ead11296a30276d5aafb0a326bad18a61fd74b5 Mon Sep 17 00:00:00 2001 From: Eric Fahlgren Date: Sun, 19 Oct 2025 16:33:26 -0700 Subject: [PATCH 001/128] targetwide: imagebuilder: add explicit guards around initramfs rules Additional work building upon f6e0f57be0af Add more explict guards around the unsupported generation of the initramfs images and suppress requirement for certain others. Fixes: https://github.com/openwrt/openwrt/issues/20151 Fixes: https://github.com/openwrt/asu/issues/1499 Signed-off-by: Eric Fahlgren Link: https://github.com/openwrt/openwrt/pull/20460 Signed-off-by: Robert Marko (cherry picked from commit f5fd7ef8886faadc654b627e5e4b4484c6ca31d7) --- target/linux/mediatek/image/filogic.mk | 4 ++-- target/linux/qualcommax/image/ipq807x.mk | 6 ++++++ target/linux/ramips/image/common-sercomm.mk | 2 ++ target/linux/ramips/image/mt7621.mk | 6 ++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index acf956e8ec..186099ad8c 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -864,11 +864,11 @@ define Device/dlink_aquila-pro-ai-m30-a1 DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-leds-gca230718 kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware KERNEL_IN_UBI := 1 - IMAGES += recovery.bin IMAGE_SIZE := 51200k IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata ifeq ($(IB),) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) + IMAGES += recovery.bin IMAGE/recovery.bin := append-image-stage initramfs-kernel.bin | sysupgrade-tar kernel=$$$$@ |\ pad-to $$(IMAGE_SIZE) | dlink-ai-recovery-header DLK6E6110001 \x6A\x28\xEE\x0B \x00\x00\x2C\x00 \x00\x00\x20\x03 \x61\x6E endif @@ -883,11 +883,11 @@ define Device/dlink_aquila-pro-ai-m60-a1 DEVICE_DTS := mt7986a-dlink-aquila-pro-ai-m60-a1 DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-leds-gca230718 kmod-mt7915e kmod-mt7986-firmware mt7986-wo-firmware - IMAGES += recovery.bin IMAGE_SIZE := 51200k IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata ifeq ($(IB),) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) + IMAGES += recovery.bin IMAGE/recovery.bin := append-image-stage initramfs-kernel.bin | sysupgrade-tar kernel=$$$$@ |\ pad-to $$(IMAGE_SIZE) | dlink-ai-recovery-header DLK6E8202001 \x30\x6C\x19\x0C \x00\x00\x2C\x00 \x00\x00\x20\x03 \x82\x6E endif diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk index d72d72a372..4085af4f4b 100644 --- a/target/linux/qualcommax/image/ipq807x.mk +++ b/target/linux/qualcommax/image/ipq807x.mk @@ -298,10 +298,12 @@ define Device/netgear_wax218 BLOCKSIZE := 128k PAGESIZE := 2048 SOC := ipq8072 +ifeq ($(IB),) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) ARTIFACTS := web-ui-factory.fit ARTIFACT/web-ui-factory.fit := append-image initramfs-uImage.itb | \ ubinize-kernel | qsdk-ipq-factory-nand +endif endif DEVICE_PACKAGES := kmod-spi-gpio kmod-spi-bitbang kmod-gpio-nxp-74hc164 \ ipq-wifi-netgear_wax218 @@ -406,10 +408,12 @@ define Device/xiaomi_ax3600 SOC := ipq8071 KERNEL_SIZE := 36608k DEVICE_PACKAGES := ipq-wifi-xiaomi_ax3600 kmod-ath10k-ct-smallbuffers ath10k-firmware-qca9887-ct +ifeq ($(IB),) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) ARTIFACTS := initramfs-factory.ubi ARTIFACT/initramfs-factory.ubi := append-image-stage initramfs-uImage.itb | ubinize-kernel endif +endif endef TARGET_DEVICES += xiaomi_ax3600 @@ -425,10 +429,12 @@ define Device/xiaomi_ax9000 KERNEL_SIZE := 57344k DEVICE_PACKAGES := ipq-wifi-xiaomi_ax9000 kmod-ath11k-pci ath11k-firmware-qcn9074 \ kmod-ath10k-ct ath10k-firmware-qca9887-ct +ifeq ($(IB),) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) ARTIFACTS := initramfs-factory.ubi ARTIFACT/initramfs-factory.ubi := append-image-stage initramfs-uImage.itb | ubinize-kernel endif +endif endef TARGET_DEVICES += xiaomi_ax9000 diff --git a/target/linux/ramips/image/common-sercomm.mk b/target/linux/ramips/image/common-sercomm.mk index 0987010911..89c94c3197 100644 --- a/target/linux/ramips/image/common-sercomm.mk +++ b/target/linux/ramips/image/common-sercomm.mk @@ -182,7 +182,9 @@ define Device/sercomm_cpj IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \ sercomm-sysupgrade-cpj | pad-rootfs | check-size | \ append-metadata +ifeq ($(IB),) ARTIFACTS := initramfs-factory.img +endif DEVICE_PACKAGES := kmod-mt76x2 endef diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 44aa7dda7f..03761edc94 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -1588,9 +1588,11 @@ define Device/iodata_wn-ax1167gr IMAGE_SIZE := 15552k DEVICE_VENDOR := I-O DATA DEVICE_MODEL := WN-AX1167GR +ifeq ($(IB),) ARTIFACTS := initramfs-factory.bin ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \ check-size 7680k | senao-header -r 0x30a -p 0x1055 -t 4 +endif DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 -uboot-envtools endef TARGET_DEVICES += iodata_wn-ax1167gr @@ -1640,10 +1642,12 @@ define Device/iodata_wn-deax1800gr KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +ifeq ($(IB),) ARTIFACTS := initramfs-factory.bin ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \ check-size | xor-image -p 29944a25120984c2 -x | \ iodata-mstc-header2 WN-DEAX1800GR 00021003 +endif DEVICE_PACKAGES := kmod-mt7915-firmware endef TARGET_DEVICES += iodata_wn-deax1800gr @@ -1771,9 +1775,11 @@ define Device/iptime_ax2004m KERNEL_LOADADDR := 0x82000000 KERNEL := kernel-bin | relocate-kernel $(loadaddr-y) | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb +ifeq ($(IB),) ARTIFACTS := initramfs-factory.bin ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \ check-size | iptime-crc32 ax2004m +endif DEVICE_VENDOR := ipTIME DEVICE_MODEL := AX2004M DEVICE_PACKAGES := kmod-mt7915-firmware kmod-usb3 From 4b7728ba8b1105845eeb76f495142ce6e6a89f75 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sat, 12 Apr 2025 00:32:23 +0200 Subject: [PATCH 002/128] bcm63xx-cfe: install into image staging dir Currently, bcm63xx-cfe is being installed into kernel build dir, however that does not work for Image Builder as only certain artifacts from kernel build dir are included in Image Builder. So, simply install bcm63xx-cfe into image staging dir so its artifacts can be used in Image Builder as well. Fixes: #18408 Fixes: #18409 Link: https://github.com/openwrt/openwrt/pull/18463 Signed-off-by: Robert Marko (cherry picked from commit 4a7de50769101962fd9ecc15465f6a11f0e81f9f) --- package/kernel/bcm63xx-cfe/Makefile | 6 +++--- target/linux/bcm4908/image/Makefile | 2 +- target/linux/bmips/image/Makefile | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/kernel/bcm63xx-cfe/Makefile b/package/kernel/bcm63xx-cfe/Makefile index 8b6fa8010c..18f52a0cda 100644 --- a/package/kernel/bcm63xx-cfe/Makefile +++ b/package/kernel/bcm63xx-cfe/Makefile @@ -35,9 +35,9 @@ define Package/bcm63xx-cfe/install endef define Build/InstallDev - rm -rf $(KERNEL_BUILD_DIR)/$(PKG_NAME) - mkdir -p $(KERNEL_BUILD_DIR)/$(PKG_NAME) - $(CP) -r $(PKG_BUILD_DIR)/* $(KERNEL_BUILD_DIR)/$(PKG_NAME) + rm -rf $(STAGING_DIR_IMAGE)/$(PKG_NAME) + mkdir -p $(STAGING_DIR_IMAGE)/$(PKG_NAME) + $(CP) -r $(PKG_BUILD_DIR)/* $(STAGING_DIR_IMAGE)/$(PKG_NAME) endef $(eval $(call BuildPackage,bcm63xx-cfe)) diff --git a/target/linux/bcm4908/image/Makefile b/target/linux/bcm4908/image/Makefile index 658ec810d1..678881fda8 100644 --- a/target/linux/bcm4908/image/Makefile +++ b/target/linux/bcm4908/image/Makefile @@ -33,7 +33,7 @@ define Build/bcm4908img cp -r $(DEVICE_NAME)/* $@-bootfs/ touch $@-bootfs/1-openwrt cp $(DTS_DIR)/$(firstword $(DEVICE_DTS)).dtb $@-bootfs/94908.dtb - cp $(KDIR)/bcm63xx-cfe/$(subst _,$(comma),$(DEVICE_NAME))/cferam.000 $@-bootfs/ + cp $(STAGING_DIR_IMAGE)/bcm63xx-cfe/$(subst _,$(comma),$(DEVICE_NAME))/cferam.000 $@-bootfs/ cp $(IMAGE_KERNEL) $@-bootfs/vmlinux.lz $(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad=0x800000 --little-endian --squash-uids \ diff --git a/target/linux/bmips/image/Makefile b/target/linux/bmips/image/Makefile index b79974931d..95cf35bb52 100644 --- a/target/linux/bmips/image/Makefile +++ b/target/linux/bmips/image/Makefile @@ -136,7 +136,7 @@ define Build/cfe-jffs2-cferam # will have version 0 and let cferam be the second (version 1). touch $@-cferam/1-openwrt # Add cferam as the last file in the JFFS2 partition - cp $(KDIR)/bcm63xx-cfe/$(CFE_RAM_FILE) $@-cferam/$(CFE_RAM_JFFS2_NAME) + cp $(STAGING_DIR_IMAGE)/bcm63xx-cfe/$(CFE_RAM_FILE) $@-cferam/$(CFE_RAM_JFFS2_NAME) # The JFFS2 partition creation should result in the following # layout: From 4108db2bd884d247ef7f483856e43541d3279a43 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 22:57:27 +0200 Subject: [PATCH 003/128] tfa-layerscape: set BUILD_DEVICES Currently, tfa-layerscape packages are being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~trusted-firmware-a-ls1012a-frdm' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the individual TFA packages in DEVICE_PACKAGES we can just do what other targets do and set BUILD_DEVICES so that TFA packages are automatically set. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 03ab770da5a469e81a659574a66dd2f7275d431e) --- package/boot/tfa-layerscape/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/boot/tfa-layerscape/Makefile b/package/boot/tfa-layerscape/Makefile index 7304df55c7..464debe2a8 100644 --- a/package/boot/tfa-layerscape/Makefile +++ b/package/boot/tfa-layerscape/Makefile @@ -43,6 +43,7 @@ endef define Trusted-Firmware-A/Default BUILD_TARGET:=layerscape BUILD_SUBTARGET:=armv8_64b + BUILD_DEVICES:=fsl_$(1) DEPENDS:=+layerscape-rcw +u-boot-fsl_$(1) endef From 975552ea1445cc1d3a25b1ac641ee78d458c7bb9 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 23:18:30 +0200 Subject: [PATCH 004/128] fman-ucode: select by default for layerscape/armv8_64b Currently, fman-ucode package is being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~fman-ucode' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the fman-ucode package in DEVICE_PACKAGES lets select it when layerscape/armv8_64b target is selected. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 22f02beaabf017aa80717f02c37d29a75c552f81) --- package/firmware/layerscape/fman-ucode/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/layerscape/fman-ucode/Makefile b/package/firmware/layerscape/fman-ucode/Makefile index 3dc1bfcb14..2056bc5a99 100644 --- a/package/firmware/layerscape/fman-ucode/Makefile +++ b/package/firmware/layerscape/fman-ucode/Makefile @@ -25,6 +25,8 @@ define Package/layerscape-fman CATEGORY:=Firmware TITLE:=NXP FMan ucode DEPENDS:=@TARGET_layerscape + DEFAULT:=y if TARGET_layerscape_armv8_64b + HIDDEN:=1 endef define Build/Compile From ebcda1d7da1dc4cb470e3de9beace8f63e85ce25 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 23:32:41 +0200 Subject: [PATCH 005/128] ls-mc: select by default for layerscape/armv8_64b Currently, ls-mc package is being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~ls-mc' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the ls-mc package in DEVICE_PACKAGES lets select it when layerscape/armv8_64b target is selected. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 2fb3efda0a2fa82f9401a5fdd9a8c03208d560af) --- package/firmware/layerscape/ls-mc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/layerscape/ls-mc/Makefile b/package/firmware/layerscape/ls-mc/Makefile index 31ed1f98dc..54b17f3e97 100644 --- a/package/firmware/layerscape/ls-mc/Makefile +++ b/package/firmware/layerscape/ls-mc/Makefile @@ -25,6 +25,8 @@ define Package/layerscape-mc CATEGORY:=Firmware TITLE:=NXP MC firmware DEPENDS:=@TARGET_layerscape + DEFAULT:=y if TARGET_layerscape_armv8_64b + HIDDEN:=1 endef define Build/Compile From 9f630a4141ca41f9102a486d979fdc18f475ac60 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 23:33:24 +0200 Subject: [PATCH 006/128] ls-dpl: select by default for layerscape/armv8_64b Currently, ls-dpl package is being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~ls-dpl' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the ls-dpl package in DEVICE_PACKAGES lets select it when layerscape/armv8_64b target is selected. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 84437eeec07716bf68d3e10ffa7baf8d3570fe1f) --- package/firmware/layerscape/ls-dpl/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/layerscape/ls-dpl/Makefile b/package/firmware/layerscape/ls-dpl/Makefile index b4b10b9b0d..ade37d7dff 100644 --- a/package/firmware/layerscape/ls-dpl/Makefile +++ b/package/firmware/layerscape/ls-dpl/Makefile @@ -26,6 +26,8 @@ define Package/layerscape-dpl CATEGORY:=Firmware TITLE:=NXP DPL firmware DEPENDS:=@TARGET_layerscape + DEFAULT:=y if TARGET_layerscape_armv8_64b + HIDDEN:=1 endef MAKE_PATH:=config From c39bc0375f34f5c5467c573886f145ed127a9bd1 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 23:33:57 +0200 Subject: [PATCH 007/128] ls-ddr-phy: select by default for layerscape/armv8_64b Currently, ls-ddr-phy package is being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~ls-ddr-phy' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the ls-ddr-phy package in DEVICE_PACKAGES lets select it when layerscape/armv8_64b target is selected. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 8a28ddafe7a728b8294a8c8ca5fc92aef7af15d2) --- package/firmware/layerscape/ls-ddr-phy/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/layerscape/ls-ddr-phy/Makefile b/package/firmware/layerscape/ls-ddr-phy/Makefile index ce39ea7dc6..322f383bd6 100644 --- a/package/firmware/layerscape/ls-ddr-phy/Makefile +++ b/package/firmware/layerscape/ls-ddr-phy/Makefile @@ -27,6 +27,8 @@ define Package/layerscape-ddr-phy CATEGORY:=Firmware TITLE:=NXP Layerscape DDR PHY firmware DEPENDS:=@TARGET_layerscape + DEFAULT:=y if TARGET_layerscape_armv8_64b + HIDDEN:=1 endef define Build/Compile From 5c6e95c5b45ffef32660b45719f24d6def693f74 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 11 Apr 2025 21:06:18 +0200 Subject: [PATCH 008/128] layerscape: armv8_64b: drop skipped packages Now that all packages that relied on the skip mechanism are selected via BUILD_DEVICES or by defaulting for the subtarget drop them from individual DEVICE_PACKAGES so that Image Builder works again for armv8_64b. Fixes: #18412 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit c04eaad12a28e8d1ae9af41ea8193f6dd5c1cab6) --- target/linux/layerscape/image/armv8_64b.mk | 42 ++-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/target/linux/layerscape/image/armv8_64b.mk b/target/linux/layerscape/image/armv8_64b.mk index c048a81bc4..6c486e73fa 100644 --- a/target/linux/layerscape/image/armv8_64b.mk +++ b/target/linux/layerscape/image/armv8_64b.mk @@ -30,7 +30,6 @@ define Device/fsl_ls1012a-frdm DEVICE_MODEL := FRDM-LS1012A DEVICE_PACKAGES += \ layerscape-ppfe \ - ~trusted-firmware-a-ls1012a-frdm \ kmod-ppfe BLOCKSIZE := 256KiB IMAGE/firmware.bin := \ @@ -56,7 +55,6 @@ define Device/fsl_ls1012a-rdb DEVICE_MODEL := LS1012A-RDB DEVICE_PACKAGES += \ layerscape-ppfe \ - ~trusted-firmware-a-ls1012a-rdb \ kmod-hwmon-ina2xx \ kmod-iio-fxas21002c-i2c \ kmod-iio-fxos8700-i2c \ @@ -80,7 +78,6 @@ define Device/fsl_ls1012a-frwy-sdboot DEVICE_MODEL := FRWY-LS1012A DEVICE_PACKAGES += \ layerscape-ppfe \ - ~trusted-firmware-a-ls1012a-frwy-sdboot \ kmod-ppfe DEVICE_DTS := fsl-ls1012a-frwy IMAGES += firmware.bin @@ -105,7 +102,6 @@ define Device/fsl_ls1028a-rdb DEVICE_VARIANT := Default KERNEL = kernel-bin | gzip | fit gzip $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb DEVICE_PACKAGES += \ - ~trusted-firmware-a-ls1028a-rdb \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 \ kmod-rtc-pcf2127 @@ -130,7 +126,6 @@ define Device/fsl_ls1028a-rdb-sdboot DEVICE_VARIANT := SD Card Boot DEVICE_DTS := fsl-ls1028a-rdb DEVICE_PACKAGES += \ - ~trusted-firmware-a-ls1028a-rdb-sdboot \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 \ kmod-rtc-pcf2127 @@ -151,8 +146,6 @@ define Device/fsl_ls1043a-rdb DEVICE_MODEL := LS1043A-RDB DEVICE_VARIANT := Default DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1043a-rdb \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 @@ -175,8 +168,6 @@ define Device/fsl_ls1043a-rdb-sdboot DEVICE_MODEL := LS1043A-RDB DEVICE_VARIANT := SD Card Boot DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1043a-rdb-sdboot \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 @@ -197,9 +188,6 @@ define Device/fsl_ls1046a-frwy DEVICE_VENDOR := NXP DEVICE_MODEL := FRWY-LS1046A DEVICE_VARIANT := Default - DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1046a-frwy IMAGE/firmware.bin := \ ls-clean | \ ls-append $(1)-bl2.pbl | pad-to 1M | \ @@ -217,9 +205,6 @@ define Device/fsl_ls1046a-frwy-sdboot DEVICE_VENDOR := NXP DEVICE_MODEL := FRWY-LS1046A DEVICE_VARIANT := SD Card Boot - DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1046a-frwy-sdboot DEVICE_DTS := fsl-ls1046a-frwy IMAGE/sdcard.img.gz := \ ls-clean | \ @@ -239,8 +224,6 @@ define Device/fsl_ls1046a-rdb DEVICE_MODEL := LS1046A-RDB DEVICE_VARIANT := Default DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1046a-rdb \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 @@ -263,8 +246,6 @@ define Device/fsl_ls1046a-rdb-sdboot DEVICE_MODEL := LS1046A-RDB DEVICE_VARIANT := SD Card Boot DEVICE_PACKAGES += \ - ~layerscape-fman \ - ~trusted-firmware-a-ls1046a-rdb-sdboot \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ kmod-hwmon-lm90 @@ -287,9 +268,6 @@ define Device/fsl_ls1088a-rdb DEVICE_MODEL := LS1088A-RDB DEVICE_VARIANT := Default DEVICE_PACKAGES += \ - ~layerscape-mc \ - ~layerscape-dpl \ - ~trusted-firmware-a-ls1088a-rdb \ restool \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ @@ -315,9 +293,6 @@ define Device/fsl_ls1088a-rdb-sdboot DEVICE_MODEL := LS1088A-RDB DEVICE_VARIANT := SD Card Boot DEVICE_PACKAGES += \ - ~layerscape-mc \ - ~layerscape-dpl \ - ~trusted-firmware-a-ls1088a-rdb-sdboot \ restool \ kmod-ahci-qoriq \ kmod-hwmon-ina2xx \ @@ -342,9 +317,6 @@ define Device/fsl_ls2088a-rdb DEVICE_VENDOR := NXP DEVICE_MODEL := LS2088ARDB DEVICE_PACKAGES += \ - ~layerscape-mc \ - ~layerscape-dpl \ - ~trusted-firmware-a-ls2088a-rdb \ restool \ kmod-ahci-qoriq IMAGE/firmware.bin := \ @@ -365,12 +337,7 @@ define Device/fsl_lx2160a-rdb DEVICE_VENDOR := NXP DEVICE_MODEL := LX2160A-RDB DEVICE_VARIANT := Rev2.0 silicon - DEVICE_PACKAGES += \ - ~layerscape-mc \ - ~layerscape-dpl \ - ~layerscape-ddr-phy \ - ~trusted-firmware-a-lx2160a-rdb \ - restool + DEVICE_PACKAGES += restool IMAGE/firmware.bin := \ ls-clean | \ ls-append $(1)-bl2.pbl | pad-to 1M | \ @@ -391,12 +358,7 @@ define Device/fsl_lx2160a-rdb-sdboot DEVICE_VENDOR := NXP DEVICE_MODEL := LX2160A-RDB DEVICE_VARIANT := Rev2.0 silicon SD Card Boot - DEVICE_PACKAGES += \ - ~layerscape-mc \ - ~layerscape-dpl \ - ~layerscape-ddr-phy \ - ~trusted-firmware-a-lx2160a-rdb-sdboot \ - restool + DEVICE_PACKAGES += restool DEVICE_DTS := fsl-lx2160a-rdb IMAGE/sdcard.img.gz := \ ls-clean | \ From fa3632f3324194388f87d021ca58b101988a9f30 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sat, 12 Apr 2025 00:06:02 +0200 Subject: [PATCH 009/128] ls-rcw: select by default for layerscape/armv7 Currently, ls-rcw package is being included in the individual profile DEVICE_PACKAGES but using the feature that allows skipping their inclusion in the end image package list if prefixed with a tilde(~) which was added in: 377b66990b97 ("build: introduce support to declare skip package") But it not added to Image Builder so currently trying to build layerscape device images in Image Builder will fail with: ERROR: '~ls-rcw' is not a valid world dependency, format is name(@tag)([<>~=]version) So, instead of having to rely on support for skipping package installation and declaring the ls-rcw package in DEVICE_PACKAGES lets select it when layerscape/armv7 target is selected. Fixes: #18411 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 598a0556b7f953db1d37059bb15759a4d88bbd3f) --- package/firmware/layerscape/ls-rcw/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/layerscape/ls-rcw/Makefile b/package/firmware/layerscape/ls-rcw/Makefile index ca72d45b5b..901b0b72ef 100644 --- a/package/firmware/layerscape/ls-rcw/Makefile +++ b/package/firmware/layerscape/ls-rcw/Makefile @@ -25,6 +25,8 @@ define Package/layerscape-rcw CATEGORY:=Firmware TITLE:=NXP Layerscape RCW binaries DEPENDS:=@TARGET_layerscape + DEFAULT:=y if TARGET_layerscape_armv7 + HIDDEN:=1 endef BOARDS := \ From d4eb33990b0064e27b8aa48c27cca82df0fe7450 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sat, 12 Apr 2025 00:07:16 +0200 Subject: [PATCH 010/128] layerscape: armv7: drop skipped packages Now that all packages that relied on the skip mechanism are selected via BUILD_DEVICES or by defaulting for the subtarget drop them from individual DEVICE_PACKAGES so that Image Builder works again for armv7. Fixes: #18411 Link: https://github.com/openwrt/openwrt/pull/18462 Signed-off-by: Robert Marko (cherry picked from commit 8cb7919a137b4f2b1a207b43ecbac2af49937f24) --- target/linux/layerscape/image/armv7.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/target/linux/layerscape/image/armv7.mk b/target/linux/layerscape/image/armv7.mk index fd617a5e8d..6caccae6c3 100644 --- a/target/linux/layerscape/image/armv7.mk +++ b/target/linux/layerscape/image/armv7.mk @@ -31,7 +31,6 @@ define Device/fsl_ls1021a-twr DEVICE_VENDOR := NXP DEVICE_MODEL := TWR-LS1021A DEVICE_VARIANT := Default - DEVICE_PACKAGES += ~layerscape-rcw IMAGE/firmware.bin := \ ls-clean | \ ls-append $(1)-rcw.bin | pad-to 1M | \ From be73a7f033174eeba36b0a5c950aa0d58fbdee3c Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 4 Apr 2025 11:04:01 +0200 Subject: [PATCH 011/128] at91: add USB kmods only for subtargets that support USB Currently, kmod-usb-ohci,kmod-at91-udc and kmod-usb-gadget-eth are included as the default packages for all at91 subtargets. However, this is breaking image builder as kmod-at91-udc is not being built on sama7 since it depends on USB_SUPPORT and sama7 does not have USB support enabled in the kernel as its not supported upstream so its not even selectable in the config. So, move to include these as default packages only for sama5 and sama9x as both of those have USB support enabled. Fixes: #18407 Link: https://github.com/openwrt/openwrt/pull/18413 Signed-off-by: Robert Marko (cherry picked from commit 02d3aa72bb72af1a9405bc3fef977e48d20157a5) --- target/linux/at91/Makefile | 2 -- target/linux/at91/sam9x/target.mk | 2 ++ target/linux/at91/sama5/target.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/target/linux/at91/Makefile b/target/linux/at91/Makefile index 8fd4a01834..752ac4c398 100644 --- a/target/linux/at91/Makefile +++ b/target/linux/at91/Makefile @@ -16,6 +16,4 @@ include $(INCLUDE_DIR)/target.mk KERNELNAME:=zImage dtbs -DEFAULT_PACKAGES += kmod-usb-ohci kmod-at91-udc kmod-usb-gadget-eth - $(eval $(call BuildTarget)) diff --git a/target/linux/at91/sam9x/target.mk b/target/linux/at91/sam9x/target.mk index f6da7c003c..70f4a2e7e3 100644 --- a/target/linux/at91/sam9x/target.mk +++ b/target/linux/at91/sam9x/target.mk @@ -1,6 +1,8 @@ BOARDNAME:= SAM9X Boards (ARMv5) CPU_TYPE:=arm926ej-s +DEFAULT_PACKAGES += kmod-usb-ohci kmod-at91-udc kmod-usb-gadget-eth + define Target/Description Build generic firmware for Microchip AT91 SAM9x platforms using the ARMv5 instruction set. diff --git a/target/linux/at91/sama5/target.mk b/target/linux/at91/sama5/target.mk index 35df05b70d..c2c3464e49 100644 --- a/target/linux/at91/sama5/target.mk +++ b/target/linux/at91/sama5/target.mk @@ -2,7 +2,7 @@ BOARDNAME:=SAMA5 boards(Cortex-A5) CPU_TYPE:=cortex-a5 CPU_SUBTYPE:=vfpv4 FEATURES+=fpu -DEFAULT_PACKAGES += kmod-usb2 +DEFAULT_PACKAGES += kmod-usb2 kmod-usb-ohci kmod-at91-udc kmod-usb-gadget-eth define Target/Description Build generic firmware for Microchip(Atmel AT91) SAMA5D2, From c5d7ef41f87bcf7b0067bdfd81b2f2572bc3c3a9 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 4 Apr 2025 11:55:08 +0200 Subject: [PATCH 012/128] at91: put u-boot images into image staging directory Currently, building at91 subtargets via image builder will fail as the required built u-boot is not present in the image builder at all since its presumed to be in the binary directory which obviously does not exist yet. So, lets install the u-boot binary into image staging directory and use that instead. Link: https://github.com/openwrt/openwrt/pull/18414 Signed-off-by: Robert Marko (cherry picked from commit 4724331d7037e61527e7da7253cdaa4a90b1d302) --- package/boot/uboot-at91/Makefile | 5 +++++ target/linux/at91/image/sam9x.mk | 2 +- target/linux/at91/image/sama5.mk | 2 +- target/linux/at91/image/sama7.mk | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/package/boot/uboot-at91/Makefile b/package/boot/uboot-at91/Makefile index 81ea22ded6..67c9d8f365 100644 --- a/package/boot/uboot-at91/Makefile +++ b/package/boot/uboot-at91/Makefile @@ -179,4 +179,9 @@ define Build/Compile $(UBOOT_MAKE_FLAGS) endef +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE) +endef + $(eval $(call BuildPackage/U-Boot)) diff --git a/target/linux/at91/image/sam9x.mk b/target/linux/at91/image/sam9x.mk index d0722c5d30..009a41b303 100644 --- a/target/linux/at91/image/sam9x.mk +++ b/target/linux/at91/image/sam9x.mk @@ -16,7 +16,7 @@ define Build/at91-sdcard ::$(DEVICE_NAME)-fit.itb mcopy -i $@.boot \ - $(BIN_DIR)/u-boot-$(if $(findstring sam9x60,$@),$(DEVICE_DTS:at91-%=%),at91sam9x5ek)_mmc/u-boot.bin \ + $(STAGING_DIR_IMAGE)/$(if $(findstring sam9x60,$@),$(DEVICE_DTS:at91-%=%),at91sam9x5ek)_mmc-u-boot.bin \ ::u-boot.bin mcopy -i $@.boot \ diff --git a/target/linux/at91/image/sama5.mk b/target/linux/at91/image/sama5.mk index 7f4dd3316a..036cac4de9 100644 --- a/target/linux/at91/image/sama5.mk +++ b/target/linux/at91/image/sama5.mk @@ -16,7 +16,7 @@ define Build/at91-sdcard ::$(DEVICE_NAME)-fit.itb mcopy -i $@.boot \ - $(BIN_DIR)/u-boot-$(DEVICE_DTS:at91-%=%)_mmc/u-boot.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_DTS:at91-%=%)_mmc-u-boot.bin \ ::u-boot.bin $(if $(findstring sama5d4-xplained,$@), \ diff --git a/target/linux/at91/image/sama7.mk b/target/linux/at91/image/sama7.mk index 8d6f67d80e..29043050ed 100644 --- a/target/linux/at91/image/sama7.mk +++ b/target/linux/at91/image/sama7.mk @@ -16,7 +16,7 @@ define Build/at91-sdcard ::$(DEVICE_NAME)-fit.itb mcopy -i $@.boot \ - $(BIN_DIR)/u-boot-$(DEVICE_DTS:at91-%=%)_mmc1/u-boot.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_DTS:at91-%=%)_mmc1-u-boot.bin \ ::u-boot.bin mcopy -i $@.boot \ From debc420622f9ed56fd2f23d455f831a22cf5a256 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 4 Apr 2025 12:25:21 +0200 Subject: [PATCH 013/128] at91bootstrap: put at91bootstrap images into image staging directory Currently, building at91 subtargets via image builder will fail as the required built at91bootstrap is not present in the image builder at all since its presumed to be in the binary directory which obviously does not exist yet. So, lets install the at91bootstrap binary into image staging directory and use that instead Link: https://github.com/openwrt/openwrt/pull/18414 Signed-off-by: Robert Marko (cherry picked from commit a947be41b721a7c521d23981adaf06ebd1ef5dfe) --- package/boot/at91bootstrap/Makefile | 5 +++++ target/linux/at91/image/sam9x.mk | 2 +- target/linux/at91/image/sama5.mk | 4 ++-- target/linux/at91/image/sama7.mk | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/package/boot/at91bootstrap/Makefile b/package/boot/at91bootstrap/Makefile index 1b145c8a8b..bf47e6aeab 100644 --- a/package/boot/at91bootstrap/Makefile +++ b/package/boot/at91bootstrap/Makefile @@ -201,4 +201,9 @@ define Build/Compile CROSS_COMPILE=$(TARGET_CROSS) endef +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(BINARIES_DIR)/at91bootstrap.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-at91bootstrap.bin +endef + $(eval $(call BuildPackage/AT91Bootstrap)) diff --git a/target/linux/at91/image/sam9x.mk b/target/linux/at91/image/sam9x.mk index 009a41b303..6f2ba19d9f 100644 --- a/target/linux/at91/image/sam9x.mk +++ b/target/linux/at91/image/sam9x.mk @@ -20,7 +20,7 @@ define Build/at91-sdcard ::u-boot.bin mcopy -i $@.boot \ - $(BIN_DIR)/at91bootstrap-$(if $(findstring sam9x60,$@),$(DEVICE_DTS:at91-%=%),at91sam9x5ek)sd_uboot/at91bootstrap.bin \ + $(STAGING_DIR_IMAGE)/$(if $(findstring sam9x60,$@),$(DEVICE_DTS:at91-%=%),at91sam9x5ek)sd_uboot-at91bootstrap.bin \ ::BOOT.bin $(CP) uboot-env.txt $@-uboot-env.txt diff --git a/target/linux/at91/image/sama5.mk b/target/linux/at91/image/sama5.mk index 036cac4de9..268af5999c 100644 --- a/target/linux/at91/image/sama5.mk +++ b/target/linux/at91/image/sama5.mk @@ -21,10 +21,10 @@ define Build/at91-sdcard $(if $(findstring sama5d4-xplained,$@), \ mcopy -i $@.boot \ - $(BIN_DIR)/at91bootstrap-$(DEVICE_DTS:at91-%=%)sd_uboot_secure/at91bootstrap.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_DTS:at91-%=%)sd_uboot_secure-at91bootstrap.bin \ ::BOOT.bin, mcopy -i $@.boot \ - $(BIN_DIR)/at91bootstrap-$(DEVICE_DTS:at91-%=%)sd_uboot/at91bootstrap.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_DTS:at91-%=%)sd_uboot-at91bootstrap.bin \ ::BOOT.bin) $(CP) uboot-env.txt $@-uboot-env.txt diff --git a/target/linux/at91/image/sama7.mk b/target/linux/at91/image/sama7.mk index 29043050ed..924d950e22 100644 --- a/target/linux/at91/image/sama7.mk +++ b/target/linux/at91/image/sama7.mk @@ -20,7 +20,7 @@ define Build/at91-sdcard ::u-boot.bin mcopy -i $@.boot \ - $(BIN_DIR)/at91bootstrap-$(DEVICE_DTS:at91-%=%)sd_uboot/at91bootstrap.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_DTS:at91-%=%)sd_uboot-at91bootstrap.bin \ ::BOOT.bin $(CP) uboot-env.txt $@-uboot-env.txt From bdb89ee6dff4742f2d7bcf101077ee6f9f8031f7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 22 Oct 2025 02:17:25 +0200 Subject: [PATCH 014/128] image: fix race between mkits.sh and mkimage in .itb squashfs generation With further investigation it was found a race in generating .itb images that include a RootFS caused by the mkits.sh and the mkimage. Due to the fact that mkits.sh generates a .pagesync image of the passed rootfs, it can happen that, concurrently, mkimage can be called at the same time mkits.sh is creating another .pagesync for the same rootfs. This cause mkimage to use an half made rootfs.pagesync creating a corrupted image. To address this, also protect the mkimage with the same lock used for mkits.sh preventing any kind of concurrent usage/generation of the rootfs.pagesync blob Fixes: 52cc9d82f113 ("kernel: rework Initramfs locking logic") Link: https://github.com/openwrt/openwrt/pull/20492 Signed-off-by: Christian Marangi (cherry picked from commit 3de1bbd5aeb542de9a4b20eff0f6bbf1767fd6b9) --- include/image-commands.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/image-commands.mk b/include/image-commands.mk index a627ffc202..0833650ade 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -391,8 +391,9 @@ define Build/fit $(if $(DEVICE_DTS_OVERLAY),$(foreach dtso,$(DEVICE_DTS_OVERLAY), -O $(dtso):$(KERNEL_BUILD_DIR)/image-$(dtso).dtbo)) \ -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \ -A $(LINUX_KARCH) -v $(LINUX_VERSION), gen-cpio$(if $(TARGET_PER_DEVICE_ROOTFS),.$(ROOTFS_ID/$(DEVICE_NAME)))) - PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ - -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new + $(call locked,PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ + -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new, \ + gen-cpio$(if $(TARGET_PER_DEVICE_ROOTFS),.$(ROOTFS_ID/$(DEVICE_NAME)))) @mv $@.new $@ endef From ef3b14e06c8339a3ef07478fae57c2d002e39ea7 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 22 Oct 2025 11:36:14 +0200 Subject: [PATCH 015/128] ipq-wifi: update to Git HEAD (2025-10-22) c585e435c611 ipq6018: add jdcloud_re-cs-02 BDF 14aef623f3e5 qcn9074: add jdcloud_re-cs-02 BDF ec6831a43ff0 qca9888: replace TP-Link Archer C60 v2 BDF Link: https://github.com/openwrt/openwrt/pull/20497 Signed-off-by: Robert Marko --- package/firmware/ipq-wifi/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index f939f65c89..8d2a928573 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -6,9 +6,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git -PKG_SOURCE_DATE:=2025-10-17 -PKG_SOURCE_VERSION:=a1529e183333e38bdc95dc8d9317b7af2bec0dcd -PKG_MIRROR_HASH:=30ce8f808424602cba556e106cb16080ef29d6d45a9d9018e04664598460eb2f +PKG_SOURCE_DATE:=2025-10-22 +PKG_SOURCE_VERSION:=ec6831a43ff066c9873e7c41fd6f68354bb67b4a +PKG_MIRROR_HASH:=33a26f90fd450e9dc2b2d5ae9c137ffcd57ef62dac277d63c5d5f6f5a1262a2f PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk From dbf2c101edde9d013658309608b37408fbc235e1 Mon Sep 17 00:00:00 2001 From: Christoph Krapp Date: Thu, 25 Sep 2025 12:26:15 +0200 Subject: [PATCH 016/128] ipq-wifi: Add entry for TP-Link Archer C60 v2 Add IPQ Wifi entry for ath79 TP-Link Archer C60 v2. Signed-off-by: Christoph Krapp Link: https://github.com/openwrt/openwrt/pull/20496 Link: https://github.com/openwrt/openwrt/pull/20497 Signed-off-by: Robert Marko --- package/firmware/ipq-wifi/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index 8d2a928573..569bf1b430 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -58,6 +58,7 @@ ALLWIFIBOARDS:= \ tplink_archer-c59-v1 \ tplink_archer-c6-v2 \ tplink_archer-c60-v1 \ + tplink_archer-c60-v2 \ wallys_dr40x9 \ xiaomi_aiot-ac2350 \ xiaomi_ax3600 \ @@ -192,6 +193,7 @@ $(eval $(call generate-ipq-wifi-package,tplink_eap660hd-v1,TP-Link EAP660 HD v1) $(eval $(call generate-ipq-wifi-package,tplink_archer-c59-v1,TP-Link Archer C59 V1)) $(eval $(call generate-ipq-wifi-package,tplink_archer-c6-v2,TP-Link Archer C6 V2)) $(eval $(call generate-ipq-wifi-package,tplink_archer-c60-v1,TP-Link Archer C60 V1)) +$(eval $(call generate-ipq-wifi-package,tplink_archer-c60-v2,TP-Link Archer C60 V2)) $(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9)) $(eval $(call generate-ipq-wifi-package,xiaomi_aiot-ac2350,Xiaomi AIoT AC2350)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600)) From 2d758300e38b3c214a5c63bcfab163b4b1ebd019 Mon Sep 17 00:00:00 2001 From: Christoph Krapp Date: Thu, 25 Sep 2025 12:26:45 +0200 Subject: [PATCH 017/128] ath79: add calibration variant for TP-Link Archer C60 v2 Now that we have a board file, add calibration variant for TP-Link Archer C60 v2 and add ipq-wifi package for it. Tested-by: Semih Baskan Signed-off-by: Christoph Krapp Link: https://github.com/openwrt/openwrt/pull/20496 Link: https://github.com/openwrt/openwrt/pull/20497 Signed-off-by: Robert Marko --- target/linux/ath79/dts/qca9561_tplink_archer-c60-v2.dts | 1 + target/linux/ath79/image/generic-tp-link.mk | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/target/linux/ath79/dts/qca9561_tplink_archer-c60-v2.dts b/target/linux/ath79/dts/qca9561_tplink_archer-c60-v2.dts index 34fe10cb51..f8625f2e7f 100644 --- a/target/linux/ath79/dts/qca9561_tplink_archer-c60-v2.dts +++ b/target/linux/ath79/dts/qca9561_tplink_archer-c60-v2.dts @@ -33,6 +33,7 @@ reg = <0x0000 0 0 0 0>; nvmem-cells = <&precal_art_5000>, <&macaddr_info_8 (-1)>; nvmem-cell-names = "pre-calibration", "mac-address"; + qcom,ath10k-calibration-variant = "TP-Link-Archer-c60-v2"; }; }; diff --git a/target/linux/ath79/image/generic-tp-link.mk b/target/linux/ath79/image/generic-tp-link.mk index b5b2ec8c7c..df6d0036fd 100644 --- a/target/linux/ath79/image/generic-tp-link.mk +++ b/target/linux/ath79/image/generic-tp-link.mk @@ -141,7 +141,7 @@ define Device/tplink_archer-c60-v2 DEVICE_MODEL := Archer C60 DEVICE_VARIANT := v2 TPLINK_BOARD_ID := ARCHER-C60-V2 - DEVICE_PACKAGES := kmod-ath10k-ct-smallbuffers ath10k-firmware-qca9888-ct + DEVICE_PACKAGES := kmod-ath10k-ct-smallbuffers ath10k-firmware-qca9888-ct ipq-wifi-tplink_archer-c60-v2 SUPPORTED_DEVICES += archer-c60-v2 endef TARGET_DEVICES += tplink_archer-c60-v2 From 630354031a0330482c54eba1c089acc65feb13ce Mon Sep 17 00:00:00 2001 From: Zxl hhyccc Date: Sat, 18 Oct 2025 00:24:09 +0800 Subject: [PATCH 018/128] kernel: bump 6.6 to 6.6.111 https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.111 All patches automatically rebased. Build system: bcm4908 Build system: bcm53xx Signed-off-by: Zxl hhyccc Link: https://github.com/openwrt/openwrt/pull/20434 (cherry picked from commit 70df331a8e02e101d4c65a7935072a7e70bbc9de) Link: https://github.com/openwrt/openwrt/pull/20551 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index d6270b06ef..04111e0155 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .110 -LINUX_KERNEL_HASH-6.6.110 = 1bf20daf5543b8759f325e55fb0da4913715e68741627a13380e66aaf219fb1d +LINUX_VERSION-6.6 = .111 +LINUX_KERNEL_HASH-6.6.111 = 04c470e130d659ef05217ac695422c28d817d19daa50643fe28b945e6ab646c7 From 59029175883fb7cb7586eeec2417401719734953 Mon Sep 17 00:00:00 2001 From: Zxl hhyccc Date: Sat, 18 Oct 2025 01:55:10 +0800 Subject: [PATCH 019/128] kernel: bump 6.6 to 6.6.112 https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.112 All patches automatically rebased. Build system: bcm4908 Build system: bcm53xx Signed-off-by: Zxl hhyccc Link: https://github.com/openwrt/openwrt/pull/20434 (cherry picked from commit 32062152a828b8d890ab3321fa93612de7942ac8) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20551 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 ++-- ...41-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch | 4 ++-- .../950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch | 6 +++--- ...0-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch | 2 +- target/linux/generic/hack-6.6/253-ksmbd-config.patch | 2 +- .../generic/pending-6.6/203-kallsyms_uncompressed.patch | 2 +- target/linux/generic/pending-6.6/920-mangle_bootargs.patch | 2 +- .../855-i2c-mt65xx-allow-optional-pmic-clock.patch | 2 +- ...rng-rockchip-add-hwrng-driver-for-Rockchip-RK3568-.patch | 2 +- ...2-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch | 4 ++-- ...rng-rockchip-add-support-for-rk3588-s-standalone-T.patch | 2 +- ...b-xhci-To-improve-performance-usb-using-lowmem-for.patch | 2 +- ...rng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index 04111e0155..a489c9f12d 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .111 -LINUX_KERNEL_HASH-6.6.111 = 04c470e130d659ef05217ac695422c28d817d19daa50643fe28b945e6ab646c7 +LINUX_VERSION-6.6 = .112 +LINUX_KERNEL_HASH-6.6.112 = 6c7d92bf316a56e91de41cb60da1f63d94a4f8aafaef6a13055df0c291138a22 diff --git a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch index 5f532aa9fc..8bcb5cccf2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch @@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4934,6 +4934,7 @@ static const struct { +@@ -4936,6 +4936,7 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { @@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell int ret = 0; bool invalid_bdaddr; size_t i; -@@ -4962,7 +4963,8 @@ static int hci_dev_setup_sync(struct hci +@@ -4964,7 +4965,8 @@ static int hci_dev_setup_sync(struct hci test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); if (!ret) { if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) && diff --git a/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch b/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch index 5bc3e8fda8..35bd56565e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch @@ -75,7 +75,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3736,6 +3736,48 @@ static int xhci_align_td(struct xhci_hcd +@@ -3733,6 +3733,48 @@ static int xhci_align_td(struct xhci_hcd return 1; } @@ -124,7 +124,7 @@ Signed-off-by: Jonathan Bell /* This is very similar to what ehci-q.c qtd_fill() does */ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index) -@@ -3892,6 +3934,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3889,6 +3931,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * } check_trb_math(urb, enqd_len); @@ -133,7 +133,7 @@ Signed-off-by: Jonathan Bell giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, start_cycle, start_trb); return 0; -@@ -4041,6 +4085,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * +@@ -4038,6 +4082,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * /* Event on completion */ field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state); diff --git a/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch index 50b09c744e..a14c5389c0 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4934,7 +4934,8 @@ static const struct { +@@ -4936,7 +4936,8 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { diff --git a/target/linux/generic/hack-6.6/253-ksmbd-config.patch b/target/linux/generic/hack-6.6/253-ksmbd-config.patch index d54b48895e..3d642e2b65 100644 --- a/target/linux/generic/hack-6.6/253-ksmbd-config.patch +++ b/target/linux/generic/hack-6.6/253-ksmbd-config.patch @@ -10,7 +10,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string --- a/init/Kconfig +++ b/init/Kconfig -@@ -2002,7 +2002,7 @@ config PADATA +@@ -2003,7 +2003,7 @@ config PADATA bool config ASN1 diff --git a/target/linux/generic/pending-6.6/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-6.6/203-kallsyms_uncompressed.patch index 94b22603d8..b067d57362 100644 --- a/target/linux/generic/pending-6.6/203-kallsyms_uncompressed.patch +++ b/target/linux/generic/pending-6.6/203-kallsyms_uncompressed.patch @@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau --- a/init/Kconfig +++ b/init/Kconfig -@@ -1460,6 +1460,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW +@@ -1461,6 +1461,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW the unaligned access emulation. see arch/parisc/kernel/unaligned.c for reference diff --git a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch index 36e7c18324..8bf6183044 100644 --- a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch @@ -13,7 +13,7 @@ Signed-off-by: Imre Kaloz --- a/init/Kconfig +++ b/init/Kconfig -@@ -1820,6 +1820,15 @@ config DEBUG_RSEQ +@@ -1821,6 +1821,15 @@ config DEBUG_RSEQ If unsure, say N. diff --git a/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch b/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch index 544bd4cce0..ba46b8671a 100644 --- a/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch +++ b/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch @@ -19,7 +19,7 @@ Signed-off-by: Daniel Golle --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c -@@ -1442,15 +1442,19 @@ static int mtk_i2c_probe(struct platform +@@ -1445,15 +1445,19 @@ static int mtk_i2c_probe(struct platform if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk)) return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk); diff --git a/target/linux/rockchip/patches-6.6/016-v6.12-hwrng-rockchip-add-hwrng-driver-for-Rockchip-RK3568-.patch b/target/linux/rockchip/patches-6.6/016-v6.12-hwrng-rockchip-add-hwrng-driver-for-Rockchip-RK3568-.patch index 7eed8cc877..94b76b18ec 100644 --- a/target/linux/rockchip/patches-6.6/016-v6.12-hwrng-rockchip-add-hwrng-driver-for-Rockchip-RK3568-.patch +++ b/target/linux/rockchip/patches-6.6/016-v6.12-hwrng-rockchip-add-hwrng-driver-for-Rockchip-RK3568-.patch @@ -30,7 +30,7 @@ Signed-off-by: Herbert Xu --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig -@@ -573,6 +573,20 @@ config HW_RANDOM_JH7110 +@@ -574,6 +574,20 @@ config HW_RANDOM_JH7110 To compile this driver as a module, choose M here. The module will be called jh7110-trng. diff --git a/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch index 08620d66ec..b2f5460d01 100644 --- a/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch +++ b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch @@ -17,7 +17,7 @@ Signed-off-by: Vinod Koul --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -@@ -248,7 +248,7 @@ static int rockchip_combphy_exit(struct +@@ -250,7 +250,7 @@ static int rockchip_combphy_exit(struct return 0; } @@ -26,7 +26,7 @@ Signed-off-by: Vinod Koul .init = rockchip_combphy_init, .exit = rockchip_combphy_exit, .owner = THIS_MODULE, -@@ -367,7 +367,7 @@ static int rockchip_combphy_probe(struct +@@ -369,7 +369,7 @@ static int rockchip_combphy_probe(struct return ret; } diff --git a/target/linux/rockchip/patches-6.6/033-05-v6.15-hwrng-rockchip-add-support-for-rk3588-s-standalone-T.patch b/target/linux/rockchip/patches-6.6/033-05-v6.15-hwrng-rockchip-add-support-for-rk3588-s-standalone-T.patch index 9ae621a54a..1ad406cd6f 100644 --- a/target/linux/rockchip/patches-6.6/033-05-v6.15-hwrng-rockchip-add-support-for-rk3588-s-standalone-T.patch +++ b/target/linux/rockchip/patches-6.6/033-05-v6.15-hwrng-rockchip-add-support-for-rk3588-s-standalone-T.patch @@ -52,7 +52,7 @@ Signed-off-by: Herbert Xu --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig -@@ -580,7 +580,8 @@ config HW_RANDOM_ROCKCHIP +@@ -581,7 +581,8 @@ config HW_RANDOM_ROCKCHIP default HW_RANDOM help This driver provides kernel-side support for the True Random Number diff --git a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch index e514e4e47b..95d83d46bb 100644 --- a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch +++ b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch @@ -160,7 +160,7 @@ Signed-off-by: minda.chen } --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3729,7 +3729,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3726,7 +3726,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * full_len = urb->transfer_buffer_length; /* If we have scatter/gather list, we use it. */ diff --git a/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch index b625014dd9..47c1237bf8 100644 --- a/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch +++ b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch @@ -16,7 +16,7 @@ Signed-off-by: Emil Renner Berthing --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig -@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV +@@ -323,6 +323,19 @@ config HW_RANDOM_POWERNV If unsure, say Y. From 8d90e178b1e7ee9a4954dcbfa21bf0913ba400c4 Mon Sep 17 00:00:00 2001 From: Zxl hhyccc Date: Mon, 20 Oct 2025 22:57:35 +0800 Subject: [PATCH 020/128] kernel: bump 6.6 to 6.6.113 https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.113 Manually rebased: /target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch Dropped patch /target/linux/generic/backport-6.6/541-v6.18-ksmbd-add-max-ip-connections-parameter.patch merged upstream with commit: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.6.y&id=bc718d0bd87e372f7786c0239e340f3577ac94fa All other patches automatically rebased. Build system: bcm4908 Build system: bcm53xx Signed-off-by: Zxl hhyccc Link: https://github.com/openwrt/openwrt/pull/20434 (cherry picked from commit d1d8febc42e06a171ddb4d502379052f769f2717) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20551 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 +- ...s-list-on-FSCTL_QUERY_INTERFACE_INFO.patch | 9 +- ...mbd-add-max-ip-connections-parameter.patch | 119 ------------------ ...-a-separate-timeout-parameter-for-wa.patch | 2 +- ...ow_offload-handle-netdevice-events-f.patch | 2 +- ...les-ignore-EOPNOTSUPP-on-flowtable-d.patch | 2 +- .../pending-6.6/920-mangle_bootargs.patch | 4 +- ...-support-for-ATAGs-rootblock-parsing.patch | 2 +- ...Mangle-bootloader-s-kernel-arguments.patch | 2 +- 9 files changed, 14 insertions(+), 132 deletions(-) delete mode 100644 target/linux/generic/backport-6.6/541-v6.18-ksmbd-add-max-ip-connections-parameter.patch diff --git a/include/kernel-6.6 b/include/kernel-6.6 index a489c9f12d..9affd5932c 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .112 -LINUX_KERNEL_HASH-6.6.112 = 6c7d92bf316a56e91de41cb60da1f63d94a4f8aafaef6a13055df0c291138a22 +LINUX_VERSION-6.6 = .113 +LINUX_KERNEL_HASH-6.6.113 = 1f95cfd2e461d192dd9c6130e47aefc9856529a74ace4191ad8e56ba1849c41e diff --git a/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch b/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch index 3c24f6315c..f81362f906 100644 --- a/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch +++ b/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch @@ -23,13 +23,14 @@ Signed-off-by: Sasha Levin --- a/fs/smb/server/ksmbd_netlink.h +++ b/fs/smb/server/ksmbd_netlink.h -@@ -108,7 +108,8 @@ struct ksmbd_startup_request { +@@ -108,8 +108,9 @@ struct ksmbd_startup_request { __u32 smb2_max_credits; /* MAX credits */ __u32 smbd_max_io_size; /* smbd read write size */ __u32 max_connections; /* Number of maximum simultaneous connections */ -- __u32 reserved[126]; /* Reserved room */ + __s8 bind_interfaces_only; -+ __s8 reserved[503]; /* Reserved room */ + __u32 max_ip_connections; /* Number of maximum connection per ip address */ +- __u32 reserved[125]; /* Reserved room */ ++ __s8 reserved[499]; /* Reserved room */ __u32 ifc_list_sz; /* interfaces list size */ __s8 ____payload[]; - }; + } __packed; diff --git a/target/linux/generic/backport-6.6/541-v6.18-ksmbd-add-max-ip-connections-parameter.patch b/target/linux/generic/backport-6.6/541-v6.18-ksmbd-add-max-ip-connections-parameter.patch deleted file mode 100644 index 473bfd2f15..0000000000 --- a/target/linux/generic/backport-6.6/541-v6.18-ksmbd-add-max-ip-connections-parameter.patch +++ /dev/null @@ -1,119 +0,0 @@ -From d8b6dc9256762293048bf122fc11c4e612d0ef5d Mon Sep 17 00:00:00 2001 -From: Namjae Jeon -Date: Wed, 1 Oct 2025 09:25:35 +0900 -Subject: ksmbd: add max ip connections parameter - -This parameter set the maximum number of connections per ip address. -The default is 8. - -Cc: stable@vger.kernel.org -Fixes: c0d41112f1a5 ("ksmbd: extend the connection limiting mechanism to support IPv6") -Signed-off-by: Namjae Jeon -Signed-off-by: Steve French ---- - fs/smb/server/ksmbd_netlink.h | 5 +++-- - fs/smb/server/server.h | 1 + - fs/smb/server/transport_ipc.c | 3 +++ - fs/smb/server/transport_tcp.c | 27 ++++++++++++++++----------- - 4 files changed, 23 insertions(+), 13 deletions(-) - -(limited to 'fs/smb') - ---- a/fs/smb/server/ksmbd_netlink.h -+++ b/fs/smb/server/ksmbd_netlink.h -@@ -109,10 +109,11 @@ struct ksmbd_startup_request { - __u32 smbd_max_io_size; /* smbd read write size */ - __u32 max_connections; /* Number of maximum simultaneous connections */ - __s8 bind_interfaces_only; -- __s8 reserved[503]; /* Reserved room */ -+ __u32 max_ip_connections; /* Number of maximum connection per ip address */ -+ __s8 reserved[499]; /* Reserved room */ - __u32 ifc_list_sz; /* interfaces list size */ - __s8 ____payload[]; --}; -+} __packed; - - #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) - ---- a/fs/smb/server/server.h -+++ b/fs/smb/server/server.h -@@ -43,6 +43,7 @@ struct ksmbd_server_config { - unsigned int auth_mechs; - unsigned int max_connections; - unsigned int max_inflight_req; -+ unsigned int max_ip_connections; - - char *conf[SERVER_CONF_WORK_GROUP + 1]; - }; ---- a/fs/smb/server/transport_ipc.c -+++ b/fs/smb/server/transport_ipc.c -@@ -321,6 +321,9 @@ static int ipc_server_config_on_startup( - if (req->max_connections) - server_conf.max_connections = req->max_connections; - -+ if (req->max_ip_connections) -+ server_conf.max_ip_connections = req->max_ip_connections; -+ - ret = ksmbd_set_netbios_name(req->netbios_name); - ret |= ksmbd_set_server_string(req->server_string); - ret |= ksmbd_set_work_group(req->work_group); ---- a/fs/smb/server/transport_tcp.c -+++ b/fs/smb/server/transport_tcp.c -@@ -240,6 +240,7 @@ static int ksmbd_kthread_fn(void *p) - struct interface *iface = (struct interface *)p; - struct ksmbd_conn *conn; - int ret; -+ unsigned int max_ip_conns; - - while (!kthread_should_stop()) { - mutex_lock(&iface->sock_release_lock); -@@ -257,34 +258,38 @@ static int ksmbd_kthread_fn(void *p) - continue; - } - -+ if (!server_conf.max_ip_connections) -+ goto skip_max_ip_conns_limit; -+ - /* - * Limits repeated connections from clients with the same IP. - */ -+ max_ip_conns = 0; - down_read(&conn_list_lock); -- list_for_each_entry(conn, &conn_list, conns_list) -+ list_for_each_entry(conn, &conn_list, conns_list) { - #if IS_ENABLED(CONFIG_IPV6) - if (client_sk->sk->sk_family == AF_INET6) { - if (memcmp(&client_sk->sk->sk_v6_daddr, -- &conn->inet6_addr, 16) == 0) { -- ret = -EAGAIN; -- break; -- } -+ &conn->inet6_addr, 16) == 0) -+ max_ip_conns++; - } else if (inet_sk(client_sk->sk)->inet_daddr == -- conn->inet_addr) { -- ret = -EAGAIN; -- break; -- } -+ conn->inet_addr) -+ max_ip_conns++; - #else - if (inet_sk(client_sk->sk)->inet_daddr == -- conn->inet_addr) { -+ conn->inet_addr) -+ max_ip_conns++; -+#endif -+ if (server_conf.max_ip_connections <= max_ip_conns) { - ret = -EAGAIN; - break; - } --#endif -+ } - up_read(&conn_list_lock); - if (ret == -EAGAIN) - continue; - -+skip_max_ip_conns_limit: - if (server_conf.max_connections && - atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { - pr_info_ratelimited("Limit the maximum number of connections(%u)\n", diff --git a/target/linux/generic/backport-6.6/850-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch b/target/linux/generic/backport-6.6/850-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch index 4aad22248a..ddde0118e8 100644 --- a/target/linux/generic/backport-6.6/850-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch +++ b/target/linux/generic/backport-6.6/850-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch @@ -23,7 +23,7 @@ Signed-off-by: Manivannan Sadhasivam --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c -@@ -882,6 +882,7 @@ static int parse_config(struct mhi_contr +@@ -881,6 +881,7 @@ static int parse_config(struct mhi_contr if (!mhi_cntrl->timeout_ms) mhi_cntrl->timeout_ms = MHI_TIMEOUT_MS; diff --git a/target/linux/generic/pending-6.6/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-6.6/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch index c69be593f9..a538687b25 100644 --- a/target/linux/generic/pending-6.6/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +++ b/target/linux/generic/pending-6.6/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch @@ -59,7 +59,7 @@ Signed-off-by: Pablo Neira Ayuso } --- a/net/netfilter/nft_flow_offload.c +++ b/net/netfilter/nft_flow_offload.c -@@ -486,47 +486,14 @@ static struct nft_expr_type nft_flow_off +@@ -485,47 +485,14 @@ static struct nft_expr_type nft_flow_off .owner = THIS_MODULE, }; diff --git a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch index 7a5413700a..e0c3e206da 100644 --- a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c -@@ -8449,7 +8449,7 @@ static int nft_register_flowtable_net_ho +@@ -8448,7 +8448,7 @@ static int nft_register_flowtable_net_ho err = flowtable->data.type->setup(&flowtable->data, hook->ops.dev, FLOW_BLOCK_BIND); diff --git a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch index 8bf6183044..af3653d676 100644 --- a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch @@ -31,7 +31,7 @@ Signed-off-by: Imre Kaloz help --- a/init/main.c +++ b/init/main.c -@@ -608,6 +608,29 @@ static inline void setup_nr_cpu_ids(void +@@ -620,6 +620,29 @@ static inline void setup_nr_cpu_ids(void static inline void smp_prepare_cpus(unsigned int maxcpus) { } #endif @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -897,6 +920,7 @@ void start_kernel(void) +@@ -909,6 +932,7 @@ void start_kernel(void) pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/ipq806x/patches-6.6/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch b/target/linux/ipq806x/patches-6.6/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch index f501514e0b..dee6f044d0 100644 --- a/target/linux/ipq806x/patches-6.6/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch +++ b/target/linux/ipq806x/patches-6.6/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch @@ -177,7 +177,7 @@ Signed-off-by: Christian Marangi #include #include #include -@@ -931,6 +932,17 @@ void start_kernel(void) +@@ -943,6 +944,17 @@ void start_kernel(void) pr_notice("Kernel command line: %s\n", saved_command_line); /* parameters may set static keys */ jump_label_init(); diff --git a/target/linux/mvebu/patches-6.6/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-6.6/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch index 8f5b9dee40..c44930a3f7 100644 --- a/target/linux/mvebu/patches-6.6/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/mvebu/patches-6.6/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch @@ -258,7 +258,7 @@ Signed-off-by: Michael Gray static int kernel_init(void *); /* -@@ -929,6 +933,18 @@ void start_kernel(void) +@@ -941,6 +945,18 @@ void start_kernel(void) boot_cpu_hotplug_init(); pr_notice("Kernel command line: %s\n", saved_command_line); From 984a2197817e7c6e7266ebfa5cde305029d18b1b Mon Sep 17 00:00:00 2001 From: Zxl hhyccc Date: Fri, 24 Oct 2025 23:56:59 +0800 Subject: [PATCH 021/128] kernel: bump 6.6 to 6.6.114 https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.114 Removed upstreamed: /target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch merged upstream with commit: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.6.114&id=499089376206f3f7f09d6852b3ec92f2674d24bb All other patches automatically rebased. Build system: bcm4908 Build system: bcm53xx Signed-off-by: Zxl hhyccc Link: https://github.com/openwrt/openwrt/pull/20434 (cherry picked from commit 8103b7977613b9712420296aba872efc519ce5c3) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20551 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 +-- ...8xx-Enable-LEDs-and-auto-negotiation.patch | 6 ++-- ...all-the-downstream-rpi-sound-card-dr.patch | 2 +- ...78xx-Read-initial-EEE-status-from-DT.patch | 2 +- ...Disable-TCP-Segmentation-Offload-TSO.patch | 2 +- ...e-enabling-of-EEE-into-PHY-init-code.patch | 4 +-- ...e-link-events-to-minimize-poll-storm.patch | 2 +- ...xx-EEE-support-is-now-a-PHY-property.patch | 2 +- ...-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch | 2 +- ...64-numa-Add-NUMA-emulation-for-ARM64.patch | 2 +- ...s-list-on-FSCTL_QUERY_INTERFACE_INFO.patch | 36 ------------------- ...support-for-LED-s-on-RTL8168-RTL8101.patch | 4 +-- ...ix-building-with-CONFIG_LEDS_CLASS-m.patch | 2 +- ...-07-v6.9-r8169-simplify-EEE-handling.patch | 4 +-- ...-v6.9-r8169-add-support-for-RTL8126A.patch | 2 +- ...ode-by-using-core-provided-pcpu-stat.patch | 4 +-- ...-add-LED-support-for-RTL8125-RTL8126.patch | 2 +- ...D-related-deadlock-on-module-removal.patch | 4 +-- ...g-conditional-compiling-for-call-to-.patch | 2 +- ...-disable-interrupt-source-RxOverflow.patch | 2 +- ...r8169-add-support-for-RTL8126A-rev.b.patch | 2 +- ...TSO-on-selected-chip-versions-per-de.patch | 4 +-- ...leftover-locks-after-reverted-change.patch | 2 +- ...r-driver-2.5G-5G-EEE-advertisement-c.patch | 2 +- ...9-remove-support-for-chip-version-11.patch | 4 +-- ...adjust-version-numbering-for-RTL8126.patch | 2 +- ...5-ops-for-MDIO_MMD_VENDOR2-registers.patch | 4 +-- ...ax-jumbo-packet-size-on-RTL8125-RTL8.patch | 2 +- ...8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch | 2 +- ...8169-refactor-chip-version-detection.patch | 8 ++--- ...GA_MAC_VER_LAST-to-facilitate-adding.patch | 4 +-- ...pci_prepare_to_sleep-in-rtl_shutdown.patch | 2 +- ...erge-chip-versions-52-and-53-RTL8117.patch | 2 +- ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 22 ++++++------ ...Fix-DMA-allocations-on-57766-devices.patch | 2 +- .../0001-MIPS-lantiq-add-pcie-driver.patch | 2 +- .../901-arm-add-cmdline-override.patch | 2 +- ...-Rockchip-3568002-erratum-workaround.patch | 4 +-- 38 files changed, 63 insertions(+), 99 deletions(-) delete mode 100644 target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch diff --git a/include/kernel-6.6 b/include/kernel-6.6 index 9affd5932c..fac976bfec 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .113 -LINUX_KERNEL_HASH-6.6.113 = 1f95cfd2e461d192dd9c6130e47aefc9856529a74ace4191ad8e56ba1849c41e +LINUX_VERSION-6.6 = .114 +LINUX_KERNEL_HASH-6.6.114 = ca4175a03ce2943ae192d77ad91e37ee292f1f1bb7b2954b062b0ef7eb0cb97c diff --git a/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch b/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch index fb248b0889..3c06a9783e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2884,6 +2884,11 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2902,6 +2902,11 @@ static int lan78xx_reset(struct lan78xx_ int ret; u32 buf; u8 sig; @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_read_reg(dev, HW_CFG, &buf); if (ret < 0) -@@ -2948,6 +2953,10 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2968,6 +2973,10 @@ static int lan78xx_reset(struct lan78xx_ buf |= HW_CFG_MEF_; @@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_write_reg(dev, HW_CFG, buf); if (ret < 0) return ret; -@@ -3047,6 +3056,9 @@ static int lan78xx_reset(struct lan78xx_ +@@ -3067,6 +3076,9 @@ static int lan78xx_reset(struct lan78xx_ buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; } } diff --git a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch index e3ca201449..09ad4d0ac7 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch @@ -17565,7 +17565,7 @@ Signed-off-by: Phil Elwell } --- a/sound/usb/card.c +++ b/sound/usb/card.c -@@ -863,8 +863,14 @@ static int usb_audio_probe(struct usb_in +@@ -869,8 +869,14 @@ static int usb_audio_probe(struct usb_in if (ignore_ctl_error) chip->quirk_flags |= QUIRK_FLAG_IGNORE_CTL_ERROR; diff --git a/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch b/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch index 7aa05b0abc..36d8bb9d4f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -3112,6 +3112,22 @@ static int lan78xx_open(struct net_devic +@@ -3132,6 +3132,22 @@ static int lan78xx_open(struct net_devic netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch b/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch index 1b6643508b..555d7f9471 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch @@ -38,7 +38,7 @@ Signed-off-by: Dave Stevenson static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -3472,8 +3481,14 @@ static int lan78xx_bind(struct lan78xx_n +@@ -3492,8 +3501,14 @@ static int lan78xx_bind(struct lan78xx_n if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM; diff --git a/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch b/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch index f98d2c7dd6..7cccfd5986 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2420,6 +2420,22 @@ static int lan78xx_phy_init(struct lan78 +@@ -2438,6 +2438,22 @@ static int lan78xx_phy_init(struct lan78 mii_adv_to_linkmode_adv_t(fc, mii_adv); linkmode_or(phydev->advertising, fc, phydev->advertising); @@ -39,7 +39,7 @@ Signed-off-by: Phil Elwell if (phydev->mdio.dev.of_node) { u32 reg; int len; -@@ -3121,22 +3137,6 @@ static int lan78xx_open(struct net_devic +@@ -3141,22 +3157,6 @@ static int lan78xx_open(struct net_devic netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch b/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch index 46bfe50f1a..e0cdc65652 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch @@ -29,7 +29,7 @@ See: https://github.com/raspberrypi/linux/issues/2447 static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -4456,7 +4461,13 @@ static int lan78xx_probe(struct usb_inte +@@ -4476,7 +4481,13 @@ static int lan78xx_probe(struct usb_inte if (ret < 0) goto out4; diff --git a/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch index b5e0095d97..e1cdc17b90 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2425,7 +2425,7 @@ static int lan78xx_phy_init(struct lan78 +@@ -2443,7 +2443,7 @@ static int lan78xx_phy_init(struct lan78 mii_adv_to_linkmode_adv_t(fc, mii_adv); linkmode_or(phydev->advertising, fc, phydev->advertising); diff --git a/target/linux/bcm27xx/patches-6.6/950-0339-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch b/target/linux/bcm27xx/patches-6.6/950-0339-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch index 085e063598..7525a18e0c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0339-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0339-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch @@ -17,4 +17,4 @@ Subject: [PATCH 0339/1085] Patching lan78xx for SOF_TIMESTAMPING_TX_SOFTWARE + .get_ts_info = ethtool_op_get_ts_info, }; - static void lan78xx_init_mac_address(struct lan78xx_net *dev) + static int lan78xx_init_mac_address(struct lan78xx_net *dev) diff --git a/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch b/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch index 169706de8c..93fbbfc47f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch @@ -20,7 +20,7 @@ Cc: “Rafael J. Wysocki" --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -1500,6 +1500,16 @@ config NODES_SHIFT +@@ -1501,6 +1501,16 @@ config NODES_SHIFT Specify the maximum number of NUMA Nodes available on the target system. Increases memory reserved to accommodate various tables. diff --git a/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch b/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch deleted file mode 100644 index f81362f906..0000000000 --- a/target/linux/generic/backport-6.6/540-v6.12-ksmbd-browse-interfaces-list-on-FSCTL_QUERY_INTERFACE_INFO.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0fc403192dcc8def1f6284959141608ac4c86699 Mon Sep 17 00:00:00 2001 -From: Namjae Jeon -Date: Fri, 10 Jan 2025 13:37:05 +0900 -Subject: ksmbd: browse interfaces list on FSCTL_QUERY_INTERFACE_INFO IOCTL - -[ Upstream commit b2d99376c5d61eb60ffdb6c503e4b6c8f9712ddd ] - -ksmbd.mount will give each interfaces list and bind_interfaces_only flags -to ksmbd server. Previously, the interfaces list was sent only -when bind_interfaces_only was enabled. -ksmbd server browse only interfaces list given from ksmbd.conf on -FSCTL_QUERY_INTERFACE_INFO IOCTL. - -Signed-off-by: Namjae Jeon -Signed-off-by: Steve French -Stable-dep-of: 21a4e47578d4 ("ksmbd: fix use-after-free in __smb2_lease_break_noti()") -Signed-off-by: Sasha Levin ---- - fs/smb/server/ksmbd_netlink.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -(limited to 'fs/smb/server/ksmbd_netlink.h') - ---- a/fs/smb/server/ksmbd_netlink.h -+++ b/fs/smb/server/ksmbd_netlink.h -@@ -108,8 +108,9 @@ struct ksmbd_startup_request { - __u32 smb2_max_credits; /* MAX credits */ - __u32 smbd_max_io_size; /* smbd read write size */ - __u32 max_connections; /* Number of maximum simultaneous connections */ -+ __s8 bind_interfaces_only; - __u32 max_ip_connections; /* Number of maximum connection per ip address */ -- __u32 reserved[125]; /* Reserved room */ -+ __s8 reserved[499]; /* Reserved room */ - __u32 ifc_list_sz; /* interfaces list size */ - __s8 ____payload[]; - } __packed; diff --git a/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch index 8bb543b9d6..eb896deed1 100644 --- a/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch +++ b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch @@ -296,7 +296,7 @@ Signed-off-by: David S. Miller static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) { /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ -@@ -5204,6 +5262,7 @@ static int rtl_init_one(struct pci_dev * +@@ -5205,6 +5263,7 @@ static int rtl_init_one(struct pci_dev * raw_spin_lock_init(&tp->cfg9346_usage_lock); raw_spin_lock_init(&tp->config25_lock); raw_spin_lock_init(&tp->mac_ocp_lock); @@ -304,7 +304,7 @@ Signed-off-by: David S. Miller dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev, struct pcpu_sw_netstats); -@@ -5360,6 +5419,12 @@ static int rtl_init_one(struct pci_dev * +@@ -5361,6 +5420,12 @@ static int rtl_init_one(struct pci_dev * if (rc) return rc; diff --git a/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch index fa79d91129..5255689a7a 100644 --- a/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch +++ b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch @@ -59,7 +59,7 @@ Signed-off-by: Jakub Kicinski obj-$(CONFIG_R8169) += r8169.o --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5419,11 +5419,10 @@ static int rtl_init_one(struct pci_dev * +@@ -5420,11 +5420,10 @@ static int rtl_init_one(struct pci_dev * if (rc) return rc; diff --git a/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch index e1fcb00b1d..4a6965346f 100644 --- a/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch +++ b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch @@ -75,7 +75,7 @@ Signed-off-by: Jakub Kicinski genphy_soft_reset(tp->phydev); } -@@ -5121,7 +5096,9 @@ static int r8169_mdio_register(struct rt +@@ -5122,7 +5097,9 @@ static int r8169_mdio_register(struct rt } tp->phydev->mac_managed_pm = true; @@ -86,7 +86,7 @@ Signed-off-by: Jakub Kicinski phy_support_asym_pause(tp->phydev); /* PHY will be woken up in rtl_open() */ -@@ -5256,7 +5233,6 @@ static int rtl_init_one(struct pci_dev * +@@ -5257,7 +5234,6 @@ static int rtl_init_one(struct pci_dev * tp->dev = dev; tp->pci_dev = pdev; tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; diff --git a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch index 80b64d3bed..27f9637f1b 100644 --- a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch +++ b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch @@ -321,7 +321,7 @@ Signed-off-by: David S. Miller padto = max_t(unsigned int, padto, ETH_ZLEN); break; default: -@@ -5148,7 +5205,7 @@ static void rtl_hw_initialize(struct rtl +@@ -5149,7 +5206,7 @@ static void rtl_hw_initialize(struct rtl case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: rtl_hw_init_8168g(tp); break; diff --git a/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch index 60f0cbf06c..19f1963ee1 100644 --- a/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch +++ b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch @@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5297,11 +5297,6 @@ static int rtl_init_one(struct pci_dev * +@@ -5298,11 +5298,6 @@ static int rtl_init_one(struct pci_dev * raw_spin_lock_init(&tp->mac_ocp_lock); mutex_init(&tp->led_lock); @@ -28,7 +28,7 @@ Signed-off-by: Paolo Abeni /* Get the *optional* external "ether_clk" used on some boards */ tp->clk = devm_clk_get_optional_enabled(&pdev->dev, "ether_clk"); if (IS_ERR(tp->clk)) -@@ -5416,6 +5411,8 @@ static int rtl_init_one(struct pci_dev * +@@ -5417,6 +5412,8 @@ static int rtl_init_one(struct pci_dev * dev->hw_features |= NETIF_F_RXALL; dev->hw_features |= NETIF_F_RXFCS; diff --git a/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch index cd33fc1d75..0ca92ba791 100644 --- a/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch +++ b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch @@ -225,7 +225,7 @@ Signed-off-by: Jakub Kicinski void r8169_get_led_name(struct rtl8169_private *tp, int idx, char *buf, int buf_len) { -@@ -5449,10 +5500,12 @@ static int rtl_init_one(struct pci_dev * +@@ -5450,10 +5501,12 @@ static int rtl_init_one(struct pci_dev * if (rc) return rc; diff --git a/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch index 857c2171d5..bdc799354b 100644 --- a/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch +++ b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch @@ -124,7 +124,7 @@ Signed-off-by: David S. Miller u32 ocp_base; }; -@@ -5075,6 +5077,8 @@ static void rtl_remove_one(struct pci_de +@@ -5076,6 +5078,8 @@ static void rtl_remove_one(struct pci_de cancel_work_sync(&tp->wk.work); @@ -133,7 +133,7 @@ Signed-off-by: David S. Miller unregister_netdev(tp->dev); if (tp->dash_type != RTL_DASH_NONE) -@@ -5534,9 +5538,9 @@ static int rtl_init_one(struct pci_dev * +@@ -5535,9 +5539,9 @@ static int rtl_init_one(struct pci_dev * if (IS_ENABLED(CONFIG_R8169_LEDS)) { if (rtl_is_8125(tp)) diff --git a/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch index 265c715f5e..2967b57e30 100644 --- a/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch +++ b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5077,7 +5077,8 @@ static void rtl_remove_one(struct pci_de +@@ -5078,7 +5078,8 @@ static void rtl_remove_one(struct pci_de cancel_work_sync(&tp->wk.work); diff --git a/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch index 9ded598665..fca73b7fd3 100644 --- a/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch +++ b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch @@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5118,12 +5118,10 @@ static void rtl_set_irq_mask(struct rtl8 +@@ -5119,12 +5119,10 @@ static void rtl_set_irq_mask(struct rtl8 tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; if (tp->mac_version <= RTL_GIGA_MAC_VER_06) diff --git a/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch index 628664b2f0..bbe6928885 100644 --- a/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch +++ b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch @@ -224,7 +224,7 @@ Signed-off-by: Jakub Kicinski padto = max_t(unsigned int, padto, ETH_ZLEN); break; default: -@@ -5295,7 +5307,7 @@ static void rtl_hw_initialize(struct rtl +@@ -5296,7 +5308,7 @@ static void rtl_hw_initialize(struct rtl case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: rtl_hw_init_8168g(tp); break; diff --git a/target/linux/generic/backport-6.6/780-26-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch b/target/linux/generic/backport-6.6/780-26-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch index 15bdb43356..739b8e3a23 100644 --- a/target/linux/generic/backport-6.6/780-26-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch +++ b/target/linux/generic/backport-6.6/780-26-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch @@ -20,7 +20,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5492,11 +5492,6 @@ static int rtl_init_one(struct pci_dev * +@@ -5493,11 +5493,6 @@ static int rtl_init_one(struct pci_dev * dev->features |= dev->hw_features; @@ -32,7 +32,7 @@ Signed-off-by: David S. Miller if (rtl_chip_supports_csum_v2(tp)) { dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2); -@@ -5507,6 +5502,17 @@ static int rtl_init_one(struct pci_dev * +@@ -5508,6 +5503,17 @@ static int rtl_init_one(struct pci_dev * netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1); } diff --git a/target/linux/generic/backport-6.6/780-39-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch b/target/linux/generic/backport-6.6/780-39-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch index 90b7c8c767..81c0ac251e 100644 --- a/target/linux/generic/backport-6.6/780-39-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch +++ b/target/linux/generic/backport-6.6/780-39-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch @@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski switch (tp->mac_version) { case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: -@@ -5461,8 +5438,6 @@ static int rtl_init_one(struct pci_dev * +@@ -5462,8 +5439,6 @@ static int rtl_init_one(struct pci_dev * tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->ocp_base = OCP_STD_PHY_BASE; diff --git a/target/linux/generic/backport-6.6/780-44-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch b/target/linux/generic/backport-6.6/780-44-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch index 6da3bf59a8..0de30ceed5 100644 --- a/target/linux/generic/backport-6.6/780-44-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch +++ b/target/linux/generic/backport-6.6/780-44-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch @@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5237,6 +5237,11 @@ static int r8169_mdio_register(struct rt +@@ -5238,6 +5238,11 @@ static int r8169_mdio_register(struct rt tp->phydev->supported_eee); phy_support_asym_pause(tp->phydev); diff --git a/target/linux/generic/backport-6.6/780-46-v6.14-r8169-remove-support-for-chip-version-11.patch b/target/linux/generic/backport-6.6/780-46-v6.14-r8169-remove-support-for-chip-version-11.patch index e4af737edc..6f2a538893 100644 --- a/target/linux/generic/backport-6.6/780-46-v6.14-r8169-remove-support-for-chip-version-11.patch +++ b/target/linux/generic/backport-6.6/780-46-v6.14-r8169-remove-support-for-chip-version-11.patch @@ -68,7 +68,7 @@ Signed-off-by: Jakub Kicinski rtl_irq_disable(tp); napi_schedule(&tp->napi); out: -@@ -5107,9 +5099,6 @@ static void rtl_set_irq_mask(struct rtl8 +@@ -5108,9 +5100,6 @@ static void rtl_set_irq_mask(struct rtl8 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) tp->irq_mask |= SYSErr | RxFIFOOver; @@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski } static int rtl_alloc_irq(struct rtl8169_private *tp) -@@ -5305,7 +5294,6 @@ static int rtl_jumbo_max(struct rtl8169_ +@@ -5306,7 +5295,6 @@ static int rtl_jumbo_max(struct rtl8169_ case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: return JUMBO_7K; /* RTL8168b */ diff --git a/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch b/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch index 8c30506904..6f1f9c177a 100644 --- a/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch +++ b/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch @@ -233,7 +233,7 @@ Signed-off-by: Jakub Kicinski padto = max_t(unsigned int, padto, ETH_ZLEN); break; default: -@@ -5275,7 +5275,7 @@ static void rtl_hw_initialize(struct rtl +@@ -5276,7 +5276,7 @@ static void rtl_hw_initialize(struct rtl case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: rtl_hw_init_8168g(tp); break; diff --git a/target/linux/generic/backport-6.6/780-53-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch b/target/linux/generic/backport-6.6/780-53-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch index 010a8abc02..34de78536e 100644 --- a/target/linux/generic/backport-6.6/780-53-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch +++ b/target/linux/generic/backport-6.6/780-53-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5208,6 +5208,33 @@ static int r8169_mdio_write_reg(struct m +@@ -5209,6 +5209,33 @@ static int r8169_mdio_write_reg(struct m return 0; } @@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski static int r8169_mdio_register(struct rtl8169_private *tp) { struct pci_dev *pdev = tp->pci_dev; -@@ -5238,6 +5265,11 @@ static int r8169_mdio_register(struct rt +@@ -5239,6 +5266,11 @@ static int r8169_mdio_register(struct rt new_bus->read = r8169_mdio_read_reg; new_bus->write = r8169_mdio_write_reg; diff --git a/target/linux/generic/backport-6.6/780-54-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch b/target/linux/generic/backport-6.6/780-54-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch index f8d7e8008a..a25bf9e8eb 100644 --- a/target/linux/generic/backport-6.6/780-54-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch +++ b/target/linux/generic/backport-6.6/780-54-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch @@ -28,7 +28,7 @@ Signed-off-by: Jakub Kicinski static const struct { const char *name; -@@ -5368,6 +5369,9 @@ static int rtl_jumbo_max(struct rtl8169_ +@@ -5369,6 +5370,9 @@ static int rtl_jumbo_max(struct rtl8169_ /* RTL8168c */ case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: return JUMBO_6K; diff --git a/target/linux/generic/backport-6.6/780-55-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch b/target/linux/generic/backport-6.6/780-55-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch index 32623e2358..385c390cb8 100644 --- a/target/linux/generic/backport-6.6/780-55-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch +++ b/target/linux/generic/backport-6.6/780-55-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch @@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5406,7 +5406,7 @@ done: +@@ -5407,7 +5407,7 @@ done: /* register is set if system vendor successfully tested ASPM 1.2 */ static bool rtl_aspm_is_safe(struct rtl8169_private *tp) { diff --git a/target/linux/generic/backport-6.6/780-59-v6.16-r8169-refactor-chip-version-detection.patch b/target/linux/generic/backport-6.6/780-59-v6.16-r8169-refactor-chip-version-detection.patch index 7ffff5dc9b..1bf6e10db2 100644 --- a/target/linux/generic/backport-6.6/780-59-v6.16-r8169-refactor-chip-version-detection.patch +++ b/target/linux/generic/backport-6.6/780-59-v6.16-r8169-refactor-chip-version-detection.patch @@ -353,7 +353,7 @@ Signed-off-by: Jakub Kicinski } static void rtl_release_firmware(struct rtl8169_private *tp) -@@ -5448,9 +5380,9 @@ static bool rtl_aspm_is_safe(struct rtl8 +@@ -5449,9 +5381,9 @@ static bool rtl_aspm_is_safe(struct rtl8 static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -364,7 +364,7 @@ Signed-off-by: Jakub Kicinski struct net_device *dev; u32 txconfig; u16 xid; -@@ -5501,12 +5433,13 @@ static int rtl_init_one(struct pci_dev * +@@ -5502,12 +5434,13 @@ static int rtl_init_one(struct pci_dev * xid = (txconfig >> 20) & 0xfcf; /* Identify chip attached to board */ @@ -381,7 +381,7 @@ Signed-off-by: Jakub Kicinski /* Disable ASPM L1 as that cause random device stop working * problems as well as full system hangs for some PCIe devices users. -@@ -5610,8 +5543,6 @@ static int rtl_init_one(struct pci_dev * +@@ -5611,8 +5544,6 @@ static int rtl_init_one(struct pci_dev * rtl_set_irq_mask(tp); @@ -390,7 +390,7 @@ Signed-off-by: Jakub Kicinski tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters), &tp->counters_phys_addr, GFP_KERNEL); -@@ -5636,7 +5567,7 @@ static int rtl_init_one(struct pci_dev * +@@ -5637,7 +5568,7 @@ static int rtl_init_one(struct pci_dev * } netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n", diff --git a/target/linux/generic/backport-6.6/780-60-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch b/target/linux/generic/backport-6.6/780-60-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch index b46d331a3c..eb05db30e7 100644 --- a/target/linux/generic/backport-6.6/780-60-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch +++ b/target/linux/generic/backport-6.6/780-60-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch @@ -139,7 +139,7 @@ Signed-off-by: Jakub Kicinski padto = max_t(unsigned int, padto, ETH_ZLEN); break; default: -@@ -5310,7 +5310,7 @@ static void rtl_hw_initialize(struct rtl +@@ -5311,7 +5311,7 @@ static void rtl_hw_initialize(struct rtl case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: rtl_hw_init_8168g(tp); break; @@ -148,7 +148,7 @@ Signed-off-by: Jakub Kicinski rtl_hw_init_8125(tp); break; default: -@@ -5335,7 +5335,7 @@ static int rtl_jumbo_max(struct rtl8169_ +@@ -5336,7 +5336,7 @@ static int rtl_jumbo_max(struct rtl8169_ case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: return JUMBO_6K; /* RTL8125/8126 */ diff --git a/target/linux/generic/backport-6.6/780-61-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch b/target/linux/generic/backport-6.6/780-61-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch index 21fdca1031..d04bb0b611 100644 --- a/target/linux/generic/backport-6.6/780-61-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch +++ b/target/linux/generic/backport-6.6/780-61-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch @@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5047,10 +5047,8 @@ static void rtl_shutdown(struct pci_dev +@@ -5048,10 +5048,8 @@ static void rtl_shutdown(struct pci_dev /* Restore original MAC address */ rtl_rar_set(tp, tp->dev->perm_addr); diff --git a/target/linux/generic/backport-6.6/780-64-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch b/target/linux/generic/backport-6.6/780-64-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch index a03eb9f208..2fcf13573c 100644 --- a/target/linux/generic/backport-6.6/780-64-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch +++ b/target/linux/generic/backport-6.6/780-64-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch @@ -92,7 +92,7 @@ Signed-off-by: Jakub Kicinski [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2, [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, -@@ -5293,7 +5290,7 @@ static void rtl_hw_init_8125(struct rtl8 +@@ -5294,7 +5291,7 @@ static void rtl_hw_init_8125(struct rtl8 static void rtl_hw_initialize(struct rtl8169_private *tp) { switch (tp->mac_version) { diff --git a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch index 863372ea87..53b78b70da 100644 --- a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +++ b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch @@ -311,7 +311,7 @@ Signed-off-by: Steven Barth /** * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own * @t: the outgoing tunnel device -@@ -1292,6 +1440,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str +@@ -1291,6 +1439,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str u8 protocol) { struct ip6_tnl *t = netdev_priv(dev); @@ -319,7 +319,7 @@ Signed-off-by: Steven Barth struct ipv6hdr *ipv6h; const struct iphdr *iph; int encap_limit = -1; -@@ -1391,6 +1540,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str +@@ -1390,6 +1539,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield); @@ -338,7 +338,7 @@ Signed-off-by: Steven Barth if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) return -1; -@@ -1544,6 +1705,14 @@ ip6_tnl_change(struct ip6_tnl *t, const +@@ -1543,6 +1704,14 @@ ip6_tnl_change(struct ip6_tnl *t, const t->parms.link = p->link; t->parms.proto = p->proto; t->parms.fwmark = p->fwmark; @@ -353,7 +353,7 @@ Signed-off-by: Steven Barth dst_cache_reset(&t->dst_cache); ip6_tnl_link_config(t); } -@@ -1578,6 +1747,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ +@@ -1577,6 +1746,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ p->flowinfo = u->flowinfo; p->link = u->link; p->proto = u->proto; @@ -361,7 +361,7 @@ Signed-off-by: Steven Barth memcpy(p->name, u->name, sizeof(u->name)); } -@@ -1966,6 +2136,15 @@ static int ip6_tnl_validate(struct nlatt +@@ -1965,6 +2135,15 @@ static int ip6_tnl_validate(struct nlatt return 0; } @@ -377,7 +377,7 @@ Signed-off-by: Steven Barth static void ip6_tnl_netlink_parms(struct nlattr *data[], struct __ip6_tnl_parm *parms) { -@@ -2003,6 +2182,46 @@ static void ip6_tnl_netlink_parms(struct +@@ -2002,6 +2181,46 @@ static void ip6_tnl_netlink_parms(struct if (data[IFLA_IPTUN_FWMARK]) parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); @@ -424,7 +424,7 @@ Signed-off-by: Steven Barth } static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, -@@ -2086,6 +2305,12 @@ static void ip6_tnl_dellink(struct net_d +@@ -2085,6 +2304,12 @@ static void ip6_tnl_dellink(struct net_d static size_t ip6_tnl_get_size(const struct net_device *dev) { @@ -437,7 +437,7 @@ Signed-off-by: Steven Barth return /* IFLA_IPTUN_LINK */ nla_total_size(4) + -@@ -2115,6 +2340,24 @@ static size_t ip6_tnl_get_size(const str +@@ -2114,6 +2339,24 @@ static size_t ip6_tnl_get_size(const str nla_total_size(0) + /* IFLA_IPTUN_FWMARK */ nla_total_size(4) + @@ -462,7 +462,7 @@ Signed-off-by: Steven Barth 0; } -@@ -2122,6 +2365,9 @@ static int ip6_tnl_fill_info(struct sk_b +@@ -2121,6 +2364,9 @@ static int ip6_tnl_fill_info(struct sk_b { struct ip6_tnl *tunnel = netdev_priv(dev); struct __ip6_tnl_parm *parm = &tunnel->parms; @@ -472,7 +472,7 @@ Signed-off-by: Steven Barth if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -@@ -2131,9 +2377,27 @@ static int ip6_tnl_fill_info(struct sk_b +@@ -2130,9 +2376,27 @@ static int ip6_tnl_fill_info(struct sk_b nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || @@ -501,7 +501,7 @@ Signed-off-by: Steven Barth if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -@@ -2173,6 +2437,7 @@ static const struct nla_policy ip6_tnl_p +@@ -2172,6 +2436,7 @@ static const struct nla_policy ip6_tnl_p [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, diff --git a/target/linux/generic/pending-6.6/791-tg3-Fix-DMA-allocations-on-57766-devices.patch b/target/linux/generic/pending-6.6/791-tg3-Fix-DMA-allocations-on-57766-devices.patch index 9d219d13e5..f2302432cb 100644 --- a/target/linux/generic/pending-6.6/791-tg3-Fix-DMA-allocations-on-57766-devices.patch +++ b/target/linux/generic/pending-6.6/791-tg3-Fix-DMA-allocations-on-57766-devices.patch @@ -17,7 +17,7 @@ Signed-off-by: Pavan Chebbi --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -17732,8 +17732,10 @@ static int tg3_init_one(struct pci_dev * +@@ -17729,8 +17729,10 @@ static int tg3_init_one(struct pci_dev * } else persist_dma_mask = dma_mask = DMA_BIT_MASK(64); diff --git a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch index 4ba92226ac..018960be83 100644 --- a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch +++ b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch @@ -5524,7 +5524,7 @@ Signed-off-by: John Crispin (transaction layer end-to-end CRC checking). --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -1612,6 +1612,8 @@ void pci_walk_bus_locked(struct pci_bus +@@ -1626,6 +1626,8 @@ void pci_walk_bus_locked(struct pci_bus void *userdata); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); diff --git a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch index 7b7c905a0f..2c1ff1c994 100644 --- a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch +++ b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch @@ -37,7 +37,7 @@ * CONFIG_CMDLINE is meant to be a default in case nothing else --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -2309,6 +2309,14 @@ config CMDLINE_FORCE +@@ -2310,6 +2310,14 @@ config CMDLINE_FORCE endchoice diff --git a/target/linux/rockchip/patches-6.6/022-v6.15-irqchip-gic-v3-Add-Rockchip-3568002-erratum-workaround.patch b/target/linux/rockchip/patches-6.6/022-v6.15-irqchip-gic-v3-Add-Rockchip-3568002-erratum-workaround.patch index 9c9e643ff9..b5c548ecce 100644 --- a/target/linux/rockchip/patches-6.6/022-v6.15-irqchip-gic-v3-Add-Rockchip-3568002-erratum-workaround.patch +++ b/target/linux/rockchip/patches-6.6/022-v6.15-irqchip-gic-v3-Add-Rockchip-3568002-erratum-workaround.patch @@ -24,7 +24,7 @@ Link: https://lore.kernel.org/all/20250216221634.364158-2-dmitry.osipenko@collab --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst -@@ -270,6 +270,8 @@ stable kernels. +@@ -272,6 +272,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Rockchip | RK3588 | #3588001 | ROCKCHIP_ERRATUM_3588001 | +----------------+-----------------+-----------------+-----------------------------+ @@ -35,7 +35,7 @@ Link: https://lore.kernel.org/all/20250216221634.364158-2-dmitry.osipenko@collab | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -1267,6 +1267,15 @@ config NVIDIA_CARMEL_CNP_ERRATUM +@@ -1268,6 +1268,15 @@ config NVIDIA_CARMEL_CNP_ERRATUM If unsure, say Y. From 99e62c21c6eaf1bc68e56d279d3aad005f52e113 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 23 Apr 2025 14:18:48 +0200 Subject: [PATCH 022/128] mold: dont allow on MacOS Mold does not really work on MacOS, when attempting to use it for example for ubus: mold: get_self_path is not supportedcollect2: error: ld returned 1 exit status Which was introduced by [1] so it seems that MacOS is not supported, so lets make it non selectable when MacOS is the host. [1] https://github.com/rui314/mold/commit/f9a37e9dd43681758bbc5647ba9e596ec4ea9f33 Link: https://github.com/openwrt/openwrt/pull/18575 (cherry picked from commit 3c65dc367827bc06bd45f7eb375c59192deb0a75) Link: https://github.com/openwrt/openwrt/pull/20621 Signed-off-by: Robert Marko --- config/Config-build.in | 1 + 1 file changed, 1 insertion(+) diff --git a/config/Config-build.in b/config/Config-build.in index a9e968f944..1bcd2a711d 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -176,6 +176,7 @@ menu "Global build settings" config MOLD depends on (aarch64 || arm || i386 || i686 || m68k || powerpc || powerpc64 || sh4 || x86_64) depends on !GCC_USE_VERSION_11 + depends on !HOST_OS_MACOS def_bool $(shell, ./config/check-hostcxx.sh 10 2 12) config USE_MOLD From a38b0c94dd02a03ab14f55bc98b2aa24561aed5a Mon Sep 17 00:00:00 2001 From: Andreas Gnau Date: Fri, 3 Oct 2025 10:59:42 +0200 Subject: [PATCH 023/128] tools/ccache: same behaviour for local and CI builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the environment variable `CI` is set, ccache will enable the CMake option CCACHE_DEV_MODE by default. This leads to differing behaviour between local and CI builds which takes quite some time to debug. 🤯 Achieve consistent behaviour between local builds and CI builds by setting CCACHE_DEV_MODE. Set it to OFF, because CCACHE_DEV_MODE amongst other settings like linker choice, enables -Werror, which will lead to potential compilation failures when the host compiler is updated. Using -Werror for host utils is not desirable, because the compiler version used is not controlled by the OpenWrt build system and host utils should compile successfully on an as wide range of host OSes as possible. Reported-by: Roman Azarenko Signed-off-by: Andreas Gnau Link: https://github.com/openwrt/openwrt/pull/20290 (cherry picked from commit 6f32c657db55a2e34f659d81d56aa385aaa7d69d) Link: https://github.com/openwrt/openwrt/pull/20334 Signed-off-by: Christian Marangi --- tools/ccache/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile index 447bc3ea43..fde96be8c1 100644 --- a/tools/ccache/Makefile +++ b/tools/ccache/Makefile @@ -17,6 +17,7 @@ include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/cmake.mk CMAKE_HOST_OPTIONS += \ + -DCCACHE_DEV_MODE=OFF \ -DCMAKE_C_COMPILER_LAUNCHER="" \ -DCMAKE_CXX_COMPILER_LAUNCHER="" \ -DCMAKE_SKIP_RPATH=FALSE \ From aa03dfeb96cfe6a7f4d00cfe03529d8a06d4568e Mon Sep 17 00:00:00 2001 From: Hang Zhou <929513338@qq.com> Date: Fri, 24 Oct 2025 07:21:21 +1100 Subject: [PATCH 024/128] bmips: fix leds on f@st3864op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gpio-leds were not working on F@ST3864OP before https://github.com/openwrt/openwrt/pull/17527 was merged. This pull request adds definitions for all LEDs, including the previously non-working WAN LEDs. Signed-off-by: Hang Zhou <929513338@qq.com> Link: https://github.com/openwrt/openwrt/pull/20533 Signed-off-by: Álvaro Fernández Rojas (cherry picked from commit 6de96914e5cb57687588a77dab08afe3149c21f5) --- .../bcm63268/base-files/etc/board.d/01_leds | 4 + .../bmips/dts/bcm63168-sagem-fast-3864-op.dts | 92 +++++++++++-------- target/linux/bmips/image/bcm63268.mk | 1 + 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/target/linux/bmips/bcm63268/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm63268/base-files/etc/board.d/01_leds index 8af1b77504..8606a49c6f 100644 --- a/target/linux/bmips/bcm63268/base-files/etc/board.d/01_leds +++ b/target/linux/bmips/bcm63268/base-files/etc/board.d/01_leds @@ -23,6 +23,10 @@ sercomm,shg2500) ucidef_set_led_usbport "usb1" "USB1" "blue:modem" "usb1-port1" "usb2-port1" ucidef_set_led_usbport "usb2" "USB2" "green:modem" "usb1-port2" "usb2-port2" ;; +sagem,fast-3864-op) + ucidef_set_led_netdev "wan_link" "WAN_LINK" "amber:wan" "wan" "link" + ucidef_set_led_netdev "wan_act" "WAN_ACT" "green:wan" "wan" "rx tx" + ;; esac board_config_flush diff --git a/target/linux/bmips/dts/bcm63168-sagem-fast-3864-op.dts b/target/linux/bmips/dts/bcm63168-sagem-fast-3864-op.dts index d4c76cdf7c..292376f24e 100644 --- a/target/linux/bmips/dts/bcm63168-sagem-fast-3864-op.dts +++ b/target/linux/bmips/dts/bcm63168-sagem-fast-3864-op.dts @@ -11,6 +11,10 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; + + led-dsl = &led_dsl_green; + led-internet = &led_internet_green; + led-usb = &led_usb_green; }; keys { @@ -38,6 +42,56 @@ debounce-interval = <60>; }; }; + + leds { + compatible = "gpio-leds"; + + led_internet_green: led@8 { + label = "green:internet"; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + }; + + led_usb_green: led@9 { + label = "green:dsl_bonding"; + gpios = <&gpio 9 GPIO_ACTIVE_LOW>; + }; + + led_power_red: led@15 { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led_power_green: led@20 { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio 20 GPIO_ACTIVE_LOW>; + }; + + led@36 { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio 36 GPIO_ACTIVE_LOW>; + }; + + led@37 { + label = "green:wlan_pull_up"; + default-state = "on"; + gpios = <&gpio 37 GPIO_ACTIVE_HIGH>; + }; + + led@38 { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&gpio 38 GPIO_ACTIVE_LOW>; + }; + + led@39 { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&gpio 39 GPIO_ACTIVE_LOW>; + }; + }; }; &ehci { @@ -59,7 +113,7 @@ brcm,serial-mux; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_leds &pinctrl_serial_led>; + pinctrl-0 = <&pinctrl_serial_led>; led@0 { reg = <0>; @@ -81,7 +135,7 @@ label = "red:internet"; }; - led@3 { + led_dsl_green: led@3 { reg = <3>; active-low; label = "green:dsl"; @@ -98,32 +152,6 @@ active-low; label = "red:fxs"; }; - - led@8 { - reg = <8>; - active-low; - label = "green:internet"; - }; - - led@9 { - reg = <9>; - active-low; - label = "green:dsl_bonding"; - }; - - led_power_red: led@15 { - reg = <15>; - active-low; - function = LED_FUNCTION_POWER; - color = ; - }; - - led_power_green: led@20 { - reg = <20>; - active-low; - function = LED_FUNCTION_POWER; - color = ; - }; }; &mdio_ext { @@ -241,14 +269,6 @@ status = "okay"; }; -&pinctrl { - pinctrl_leds: leds { - function = "led"; - pins = "gpio8", "gpio9", "gpio15", - "gpio20"; - }; -}; - &switch0 { dsa,member = <0 0>; diff --git a/target/linux/bmips/image/bcm63268.mk b/target/linux/bmips/image/bcm63268.mk index 3f98acc56f..49fc8626cd 100644 --- a/target/linux/bmips/image/bcm63268.mk +++ b/target/linux/bmips/image/bcm63268.mk @@ -71,6 +71,7 @@ define Device/sagem_fast-3864-op SUBPAGESIZE := 512 VID_HDR_OFFSET := 2048 DEVICE_PACKAGES += $(USB2_PACKAGES) \ + kmod-leds-gpio \ kmod-leds-bcm6328 CFE_WFI_FLASH_TYPE := 3 CFE_WFI_VERSION := 0x5732 From 597598baa96f504482d780fa6b21a34497770dec Mon Sep 17 00:00:00 2001 From: Goetz Goerisch Date: Thu, 30 Oct 2025 12:42:23 +0100 Subject: [PATCH 025/128] kernel: bump 6.6 to 6.6.115 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.115 Patch manual updated: - starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch [1] All patches auto-refreshed. [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.6.115&id=f354f7510ff0efaa1735093625749fc788ec67d1 Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20598 (cherry picked from commit 6526d6d057edb3456420296c5640a63e95198d92) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20701 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 ++-- .../950-0420-hwmon-sht3x-Add-DT-compatible-string.patch | 2 +- .../hack-6.6/780-usb-net-MeigLink_modem_support.patch | 4 ++-- .../710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch | 2 +- .../0067-driver-uart-fix-up-uart-communicate-fail.patch | 6 +++--- .../0068-uart-8250-add-reset-operation-in-runtime-PM.patch | 4 ++-- ...rial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index fac976bfec..706c50ef7b 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .114 -LINUX_KERNEL_HASH-6.6.114 = ca4175a03ce2943ae192d77ad91e37ee292f1f1bb7b2954b062b0ef7eb0cb97c +LINUX_VERSION-6.6 = .115 +LINUX_KERNEL_HASH-6.6.115 = 0a98c05e8d0f6b49fad71b8d779410a0811ea5ae17d81744fe30718633fd9047 diff --git a/target/linux/bcm27xx/patches-6.6/950-0420-hwmon-sht3x-Add-DT-compatible-string.patch b/target/linux/bcm27xx/patches-6.6/950-0420-hwmon-sht3x-Add-DT-compatible-string.patch index c559e39fab..758a5d19bc 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0420-hwmon-sht3x-Add-DT-compatible-string.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0420-hwmon-sht3x-Add-DT-compatible-string.patch @@ -10,7 +10,7 @@ Signed-off-by: Phil Elwell --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c -@@ -911,8 +911,18 @@ static int sht3x_probe(struct i2c_client +@@ -918,8 +918,18 @@ static int sht3x_probe(struct i2c_client return PTR_ERR_OR_ZERO(hwmon_dev); } diff --git a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch index e0d5789947..9d389dd3fc 100644 --- a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch @@ -44,7 +44,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support #define QUECTEL_VENDOR_ID 0x2c7c /* These Quectel products use Quectel's vendor ID */ -@@ -1154,6 +1159,11 @@ static const struct usb_device_id option +@@ -1156,6 +1161,11 @@ static const struct usb_device_id option { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, @@ -56,7 +56,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support /* Quectel products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1195,6 +1205,11 @@ static const struct usb_device_id option +@@ -1197,6 +1207,11 @@ static const struct usb_device_id option .driver_info = ZLP }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = RSVD(4) }, diff --git a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index d62ccc571c..31e29c447e 100644 --- a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau struct rtnl_link { rtnl_doit_func doit; -@@ -4981,7 +4981,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu +@@ -4978,7 +4978,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || brport_nla_put_flag(skb, flags, mask, diff --git a/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch index 18d735b92d..e36b8fd57e 100644 --- a/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch +++ b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch @@ -24,6 +24,6 @@ Signed-off-by: shanlong.li + if (IS_ERR(data->rst)) { + err = PTR_ERR(data->rst); + } - reset_control_deassert(data->rst); - - err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); + err = reset_control_deassert(data->rst); + if (err) + return dev_err_probe(dev, err, "failed to deassert resets\n"); diff --git a/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch index 56efebda6c..8f27dba5aa 100644 --- a/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch +++ b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch @@ -12,7 +12,7 @@ Signed-off-by: William Qiu --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c -@@ -745,6 +745,8 @@ static int dw8250_runtime_suspend(struct +@@ -747,6 +747,8 @@ static int dw8250_runtime_suspend(struct { struct dw8250_data *data = dev_get_drvdata(dev); @@ -21,7 +21,7 @@ Signed-off-by: William Qiu clk_disable_unprepare(data->clk); clk_disable_unprepare(data->pclk); -@@ -760,6 +762,8 @@ static int dw8250_runtime_resume(struct +@@ -762,6 +764,8 @@ static int dw8250_runtime_resume(struct clk_prepare_enable(data->clk); diff --git a/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch index a094e4b5d6..eec64fb6fe 100644 --- a/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch +++ b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch @@ -15,7 +15,7 @@ Signed-off-by: Emil Renner Berthing --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c -@@ -803,6 +803,7 @@ static const struct of_device_id dw8250_ +@@ -805,6 +805,7 @@ static const struct of_device_id dw8250_ { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data }, { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data }, { .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data }, From 9837ae40023b22bcbd03ae823a5b3ce5c41005fa Mon Sep 17 00:00:00 2001 From: Goetz Goerisch Date: Wed, 5 Nov 2025 12:17:27 +0100 Subject: [PATCH 026/128] kernel: bump 6.6 to 6.6.116 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.116 All patches auto-refreshed. Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20598 (cherry picked from commit 099633be82ee8a75a2f271b90f3a07e6e2c01ffc) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20701 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 ++-- ...0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch | 2 +- ...75-serial-sc16is7xx-Read-modem-line-state-at-startup.patch | 2 +- ...serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch | 2 +- .../880-v6.14-gpio-regmap-Use-generic-request-free-ops.patch | 2 +- .../800-gpio-regmap-Bypass-cache-for-shadowed-outputs.patch | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index 706c50ef7b..6bedc40098 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .115 -LINUX_KERNEL_HASH-6.6.115 = 0a98c05e8d0f6b49fad71b8d779410a0811ea5ae17d81744fe30718633fd9047 +LINUX_VERSION-6.6 = .116 +LINUX_KERNEL_HASH-6.6.116 = a9a59742c29be284c205dc87cbe9b065f9688488132c8f5a6057a5539230a51d diff --git a/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch b/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch index 4ef34aeffc..45f65cd475 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -777,6 +777,8 @@ static bool sc16is7xx_port_irq(struct sc +@@ -820,6 +820,8 @@ static bool sc16is7xx_port_irq(struct sc if (rxlen) sc16is7xx_handle_rx(port, rxlen, iir); diff --git a/target/linux/bcm27xx/patches-6.6/950-0475-serial-sc16is7xx-Read-modem-line-state-at-startup.patch b/target/linux/bcm27xx/patches-6.6/950-0475-serial-sc16is7xx-Read-modem-line-state-at-startup.patch index 932e4264b0..2921ca4816 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0475-serial-sc16is7xx-Read-modem-line-state-at-startup.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0475-serial-sc16is7xx-Read-modem-line-state-at-startup.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -1200,6 +1200,9 @@ static int sc16is7xx_startup(struct uart +@@ -1197,6 +1197,9 @@ static int sc16is7xx_startup(struct uart SC16IS7XX_IER_MSI_BIT; sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); diff --git a/target/linux/bcm27xx/patches-6.6/950-1464-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch b/target/linux/bcm27xx/patches-6.6/950-1464-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch index 2d408eddfd..24072ba888 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1464-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1464-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch @@ -31,7 +31,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -1470,7 +1470,7 @@ static int sc16is7xx_setup_mctrl_ports(s +@@ -1467,7 +1467,7 @@ static int sc16is7xx_setup_mctrl_ports(s } static const struct serial_rs485 sc16is7xx_rs485_supported = { diff --git a/target/linux/generic/backport-6.6/880-v6.14-gpio-regmap-Use-generic-request-free-ops.patch b/target/linux/generic/backport-6.6/880-v6.14-gpio-regmap-Use-generic-request-free-ops.patch index f9299f9733..d696acfea4 100644 --- a/target/linux/generic/backport-6.6/880-v6.14-gpio-regmap-Use-generic-request-free-ops.patch +++ b/target/linux/generic/backport-6.6/880-v6.14-gpio-regmap-Use-generic-request-free-ops.patch @@ -19,7 +19,7 @@ Signed-off-by: Bartosz Golaszewski --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c -@@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register +@@ -276,6 +276,8 @@ struct gpio_regmap *gpio_regmap_register chip->label = config->label ?: dev_name(config->parent); chip->can_sleep = regmap_might_sleep(config->regmap); diff --git a/target/linux/realtek/patches-6.6/800-gpio-regmap-Bypass-cache-for-shadowed-outputs.patch b/target/linux/realtek/patches-6.6/800-gpio-regmap-Bypass-cache-for-shadowed-outputs.patch index b4dbf320b2..fd73b162f8 100644 --- a/target/linux/realtek/patches-6.6/800-gpio-regmap-Bypass-cache-for-shadowed-outputs.patch +++ b/target/linux/realtek/patches-6.6/800-gpio-regmap-Bypass-cache-for-shadowed-outputs.patch @@ -37,7 +37,7 @@ Signed-off-by: Sander Vanheule --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c -@@ -74,7 +74,15 @@ static int gpio_regmap_get(struct gpio_c +@@ -80,7 +80,15 @@ static int gpio_regmap_get(struct gpio_c if (ret) return ret; From 550fa37533ad7b089bdeac40da2ea9abefa53383 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Tue, 20 May 2025 07:50:56 +0800 Subject: [PATCH 027/128] ramips: dts: adjust the power regulators of MMC controller - Fix MMC bus IO voltage. The GPIO voltage of mt762x series SoCs is fixed 3.3V. There are no visible registers that can control the voltage level. Also add "no-1-8-v" property to indicate that MMC controller doesn't support 1.8V IO. - Drop useless property "enable-active-high". These dummy fixed voltage regulators are not controlled by the GPIO. We don't need to set the GPIO polarity. Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18886 (cherry picked from commit afdf88b9a165710e6132fab6ec245a61f4394d6e) [rebased upon 24.10 branch] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20258 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/dts/mt7620a.dtsi | 36 ++++++++----------- .../ramips/dts/mt7620a_hiwifi_hc5861.dts | 10 +++--- target/linux/ramips/dts/mt7621.dtsi | 36 ++++++++----------- target/linux/ramips/dts/mt7628an.dtsi | 36 ++++++++----------- 4 files changed, 46 insertions(+), 72 deletions(-) diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi index 0555674802..7542d43bae 100644 --- a/target/linux/ramips/dts/mt7620a.dtsi +++ b/target/linux/ramips/dts/mt7620a.dtsi @@ -32,28 +32,22 @@ compatible = "mti,cpu-interrupt-controller"; }; - mmc_reg_1v8: regulator-1v8 { + reg_vmmc: regulator-vmmc { compatible = "regulator-fixed"; - - enable-active-high; - - regulator-always-on; - regulator-max-microvolt = <1800000>; - regulator-min-microvolt = <1800000>; - regulator-name = "mmc_io"; - }; - - mmc_reg_3v3: regulator-3v3 { - compatible = "regulator-fixed"; - - enable-active-high; - regulator-always-on; regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "mmc_power"; }; + reg_vqmmc: regulator-vqmmc { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "mmc_io"; + }; + palmbus: palmbus@10000000 { compatible = "palmbus"; reg = <0x10000000 0x200000>; @@ -528,20 +522,18 @@ reg = <0x10130000 0x4000>; bus-width = <4>; - + max-frequency = <24000000>; cap-mmc-highspeed; cap-sd-highspeed; + disable-wp; + no-1-8-v; clocks = <&sysc 15>, <&sysc 15>; clock-names = "source", "hclk"; - disable-wp; - interrupt-parent = <&intc>; interrupts = <14>; - max-frequency = <24000000>; - pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&sdhci_pins>; pinctrl-1 = <&sdhci_pins>; @@ -549,8 +541,8 @@ resets = <&sysc 30>; reset-names = "hrst"; - vmmc-supply = <&mmc_reg_3v3>; - vqmmc-supply = <&mmc_reg_1v8>; + vmmc-supply = <®_vmmc>; + vqmmc-supply = <®_vqmmc>; status = "disabled"; }; diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts index 2cb7017972..a279ae3eb5 100644 --- a/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts +++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts @@ -88,12 +88,6 @@ mediatek,ephy-base = /bits/ 8 <12>; }; -&mmc_reg_3v3 { - /delete-property/ enable-active-high; - - gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; -}; - &pcie { status = "okay"; }; @@ -108,6 +102,10 @@ }; }; +®_vmmc { + gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; +}; + &wmac { pinctrl-names = "default", "pa_gpio"; pinctrl-0 = <&pa_pins>; diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi index da03d47ff6..5730e83464 100644 --- a/target/linux/ramips/dts/mt7621.dtsi +++ b/target/linux/ramips/dts/mt7621.dtsi @@ -42,28 +42,22 @@ bootargs = "console=ttyS0,57600"; }; - mmc_reg_1v8: regulator-1v8 { + reg_vmmc: regulator-vmmc { compatible = "regulator-fixed"; - - enable-active-high; - - regulator-always-on; - regulator-max-microvolt = <1800000>; - regulator-min-microvolt = <1800000>; - regulator-name = "mmc_io"; - }; - - mmc_reg_3v3: regulator-3v3 { - compatible = "regulator-fixed"; - - enable-active-high; - regulator-always-on; regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "mmc_power"; }; + reg_vqmmc: regulator-vqmmc { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "mmc_io"; + }; + palmbus: palmbus@1e000000 { compatible = "palmbus"; reg = <0x1e000000 0x100000>; @@ -353,20 +347,18 @@ reg = <0x1e130000 0x4000>; bus-width = <4>; - + max-frequency = <48000000>; cap-mmc-highspeed; cap-sd-highspeed; + disable-wp; + no-1-8-v; clocks = <&sysc MT7621_CLK_SHXC>, <&sysc MT7621_CLK_SHXC>; clock-names = "source", "hclk"; - disable-wp; - interrupt-parent = <&gic>; interrupts = ; - max-frequency = <48000000>; - pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&sdhci_pins>; pinctrl-1 = <&sdhci_pins>; @@ -374,8 +366,8 @@ resets = <&sysc MT7621_RST_SDXC>; reset-names = "hrst"; - vmmc-supply = <&mmc_reg_3v3>; - vqmmc-supply = <&mmc_reg_1v8>; + vmmc-supply = <®_vmmc>; + vqmmc-supply = <®_vqmmc>; status = "disabled"; }; diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi index 79763332b8..e705d46b1e 100644 --- a/target/linux/ramips/dts/mt7628an.dtsi +++ b/target/linux/ramips/dts/mt7628an.dtsi @@ -30,28 +30,22 @@ compatible = "mti,cpu-interrupt-controller"; }; - mmc_reg_1v8: regulator-1v8 { + reg_vmmc: regulator-vmmc { compatible = "regulator-fixed"; - - enable-active-high; - - regulator-always-on; - regulator-max-microvolt = <1800000>; - regulator-min-microvolt = <1800000>; - regulator-name = "mmc_io"; - }; - - mmc_reg_3v3: regulator-3v3 { - compatible = "regulator-fixed"; - - enable-active-high; - regulator-always-on; regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>; regulator-name = "mmc_power"; }; + reg_vqmmc: regulator-vqmmc { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "mmc_io"; + }; + palmbus: palmbus@10000000 { compatible = "palmbus"; reg = <0x10000000 0x200000>; @@ -382,20 +376,18 @@ reg = <0x10130000 0x4000>; bus-width = <4>; - + max-frequency = <24000000>; cap-mmc-highspeed; cap-sd-highspeed; + disable-wp; + no-1-8-v; clocks = <&sysc 16>, <&sysc 16>; clock-names = "source", "hclk"; - disable-wp; - interrupt-parent = <&intc>; interrupts = <14>; - max-frequency = <24000000>; - pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&sdxc_pins>; pinctrl-1 = <&sdxc_pins>; @@ -403,8 +395,8 @@ resets = <&sysc 30>; reset-names = "hrst"; - vmmc-supply = <&mmc_reg_3v3>; - vqmmc-supply = <&mmc_reg_1v8>; + vmmc-supply = <®_vmmc>; + vqmmc-supply = <®_vqmmc>; status = "disabled"; }; From 0ed371472cc3b6ab38cec88c073ca84c15938c4a Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sat, 24 May 2025 16:31:07 +0800 Subject: [PATCH 028/128] ramips: mtk-mmc: fix data timeout value The MT7628 programing guide shows that the correct DTOC unit is 1048576 clocks instead of 65536 clocks. This value is also used by linux upstream mtk-sd driver. Correct the DTOC register and also round up its value. Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18896 (cherry picked from commit e69c867cdf62623613c9026b577b290edae780a1) Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20258 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c index a9c242bfd3..7cfa469242 100644 --- a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c +++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c @@ -84,7 +84,7 @@ #endif /* end of --- */ #define DEFAULT_DEBOUNCE (8) /* 8 cycles */ -#define DEFAULT_DTOC (40) /* data timeout counter. 65536x40 sclk. */ +#define DEFAULT_DTOC (40) /* data timeout counter. 1048576x40 sclk. */ #define CMD_TIMEOUT (HZ / 10) /* 100ms */ #define DAT_TIMEOUT (HZ / 2 * 5) /* 500ms x5 */ @@ -414,13 +414,13 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) clk_ns = 1000000000UL / host->sclk; timeout = ns / clk_ns + clks; - timeout = timeout >> 16; /* in 65536 sclk cycle unit */ + timeout = DIV_ROUND_UP(timeout, BIT(20)); /* in 1048576 sclk cycle unit */ timeout = timeout > 1 ? timeout - 1 : 0; timeout = timeout > 255 ? 255 : timeout; sdr_set_field(SDC_CFG, SDC_CFG_DTOC, timeout); - N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles", + N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 1048576 cycles", ns, clks, timeout + 1); } @@ -2276,7 +2276,7 @@ static int msdc_drv_probe(struct platform_device *pdev) host->power_mode = MMC_POWER_OFF; // host->card_inserted = hw->flags & MSDC_REMOVABLE ? 0 : 1; host->timeout_ns = 0; - host->timeout_clks = DEFAULT_DTOC * 65536; + host->timeout_clks = DEFAULT_DTOC * 1048576; host->mrq = NULL; //init_MUTEX(&host->sem); /* we don't need to support multiple threads access */ From 0be05cdf72cc19d8b1121817b23d1b96d040e610 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Fri, 13 Jun 2025 21:05:31 +0800 Subject: [PATCH 029/128] ramips: mtk-sd: backport Host Software Queue support This new feature has some improvements for random RW performance. Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18896 (cherry picked from commit db76fe6a02ed5bf3b545a8a09d6112ed4039edaf) [removed kernel 6.12 patches] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20258 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/modules.mk | 8 +- ...plement-Host-Software-Queue-for-eMMC.patch | 188 ++++++++++++++++++ ...IPS-ralink-add-sdhci-for-mt7620a-SoC.patch | 2 +- ...tialize-pad-delay-and-drive-strength.patch | 10 +- 4 files changed, 199 insertions(+), 9 deletions(-) create mode 100644 target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk index 22a9660b0f..286457c25e 100644 --- a/target/linux/ramips/modules.mk +++ b/target/linux/ramips/modules.mk @@ -10,12 +10,14 @@ define KernelPackage/mmc-mtk DEPENDS:=@(TARGET_ramips_mt7620||TARGET_ramips_mt76x8||TARGET_ramips_mt7621) +kmod-mmc KCONFIG:= \ CONFIG_MMC \ - CONFIG_MMC_MTK \ - CONFIG_MMC_CQHCI + CONFIG_MMC_CQHCI \ + CONFIG_MMC_HSQ \ + CONFIG_MMC_MTK FILES:= \ $(LINUX_DIR)/drivers/mmc/host/cqhci.ko \ + $(LINUX_DIR)/drivers/mmc/host/mmc_hsq.ko \ $(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko - AUTOLOAD:=$(call AutoProbe,cqhci mtk-sd,1) + AUTOLOAD:=$(call AutoProbe,cqhci mmc_hsq mtk-sd,1) endef define KernelPackage/mmc-mtk/description diff --git a/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch b/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch new file mode 100644 index 0000000000..f14f79fa05 --- /dev/null +++ b/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch @@ -0,0 +1,188 @@ +From 7e9ddd7d45897b15a64c4a3c88f2f7909bf49749 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Mon, 30 Sep 2024 11:01:56 +0200 +Subject: [PATCH] mmc: mtk-sd: Implement Host Software Queue for eMMC and SD + Card + +Add support for Host Software Queue (HSQ) and enable it when the +controller instance does not have Command Queue Engine HW support. + +It was chosen to enable HSQ only for eMMC and SD/MicroSD cards +and not for SDIO as performance improvements are seen only for +the former. + +Performance was measured with a SanDisk Extreme Ultra A2 MicroSD +card in a MediaTek MT8195T Acer Chromebook Spin 513 (CP513-2H), +by running FIO (bs=4k) on an ArchLinux userspace. + +.... Summarizing .... +Random read: +24.28% IOPS, +24.29% BW +Sequential read: +3.14% IOPS, +3.49% BW +Random RW (avg): +50.53% IOPS, +50.68% BW + +Below, more data from the benchmarks. + +Before: + - Random read: IOPS=1643, BW=6574KiB/s + bw ( KiB/s): min= 4578, max= 7440, per=99.95%, avg=6571.55, stdev=74.16, samples=953 + iops : min= 1144, max= 1860, avg=1642.14, stdev=18.54, samples=953 + lat (msec) : 100=0.01%, 250=0.12%, 500=0.38%, 750=97.89%, 1000=1.44%, 2000=0.16% + - Sequential read: IOPS=19.1k, BW=74.4MiB/s + bw ( KiB/s): min=12288, max=118483, per=100.00%, avg=76293.38, stdev=1971.42, samples=956 + iops : min= 3072, max=29620, avg=19072.14, stdev=492.87, samples=956 + lat (msec) : 4=0.01%, 10=0.01%, 20=0.21%, 50=23.95%, 100=75.67%, 250=0.05%, 500=0.03%, 750=0.08% + - Random R/W: read: IOPS=282, BW=1129KiB/s (1156kB/s) write: IOPS=284, BW=1136KiB/s + read bw ( KiB/s): min= 31, max= 3496, per=100.00%, avg=1703.67, stdev=155.42, samples=630 + read iops : min= 7, max= 873, avg=425.22, stdev=38.85, samples=630 + wri bw ( KiB/s): min= 31, max= 3443, per=100.00%, avg=1674.27, stdev=164.23, samples=644 + wri iops : min= 7, max= 860, avg=417.87, stdev=41.03, samples=644 + lat (msec) : 250=0.13%, 500=0.44%, 750=0.84%, 1000=22.29%, 2000=74.01%, >=2000=2.30% + +After: + - Random read: IOPS=2042, BW=8171KiB/s + bw ( KiB/s): min= 4907, max= 9072, per=99.94%, avg=8166.80, stdev=93.77, samples=954 + iops : min= 1226, max= 2268, avg=2040.78, stdev=23.41, samples=954 + lat (msec) : 100=0.03%, 250=0.13%, 500=52.88%, 750=46.64%, 1000=0.32% + - Sequential read: IOPS=19.7k, BW=77.0MiB/s + bw ( KiB/s): min=67980, max=94248, per=100.00%, avg=78894.27, stdev=1475.07, samples=956 + iops : min=16994, max=23562, avg=19722.45, stdev=368.76, samples=956 + lat (msec) : 4=0.01%, 10=0.01%, 20=0.05%, 50=28.78%, 100=71.14%, 250=0.01%, 500=0.02% + - Random R/W: read: IOPS=424, BW=1699KiB/s write: IOPS=428, BW=1714KiB/s + read bw ( KiB/s): min= 228, max= 2856, per=100.00%, avg=1796.60, stdev=112.59, samples=901 + read iops : min= 54, max= 712, avg=447.81, stdev=28.21, samples=901 + wri bw ( KiB/s): min= 28, max= 2904, per=100.00%, avg=1780.11, stdev=128.27, samples=916 + wri iops : min= 4, max= 724, avg=443.69, stdev=32.14, samples=916 + +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20240930090156.33537-1-angelogioacchino.delregno@collabora.com +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/Kconfig | 1 + + drivers/mmc/host/mtk-sd.c | 49 +++++++++++++++++++++++++++++++++++++-- + 2 files changed, 48 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -979,6 +979,7 @@ config MMC_MTK + depends on COMMON_CLK + select REGULATOR + select MMC_CQHCI ++ select MMC_HSQ + help + This selects the MediaTek(R) Secure digital and Multimedia card Interface. + If you have a machine with a integrated SD/MMC card reader, say Y or M here. +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -34,6 +34,7 @@ + #include + + #include "cqhci.h" ++#include "mmc_hsq.h" + + #define MAX_BD_NUM 1024 + #define MSDC_NR_CLOCKS 3 +@@ -469,6 +470,7 @@ struct msdc_host { + bool hs400_tuning; /* hs400 mode online tuning */ + bool internal_cd; /* Use internal card-detect logic */ + bool cqhci; /* support eMMC hw cmdq */ ++ bool hsq_en; /* Host Software Queue is enabled */ + struct msdc_save_para save_para; /* used when gate HCLK */ + struct msdc_tune_para def_tune_para; /* default tune setting */ + struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */ +@@ -1164,7 +1166,9 @@ static void msdc_track_cmd_data(struct m + + static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) + { ++ struct mmc_host *mmc = mmc_from_priv(host); + unsigned long flags; ++ bool hsq_req_done; + + /* + * No need check the return value of cancel_delayed_work, as only ONE +@@ -1172,6 +1176,27 @@ static void msdc_request_done(struct msd + */ + cancel_delayed_work(&host->req_timeout); + ++ /* ++ * If the request was handled from Host Software Queue, there's almost ++ * nothing to do here, and we also don't need to reset mrq as any race ++ * condition would not have any room to happen, since HSQ stores the ++ * "scheduled" mrqs in an internal array of mrq slots anyway. ++ * However, if the controller experienced an error, we still want to ++ * reset it as soon as possible. ++ * ++ * Note that non-HSQ requests will still be happening at times, even ++ * though it is enabled, and that's what is going to reset host->mrq. ++ * Also, msdc_unprepare_data() is going to be called by HSQ when needed ++ * as HSQ request finalization will eventually call the .post_req() ++ * callback of this driver which, in turn, unprepares the data. ++ */ ++ hsq_req_done = host->hsq_en ? mmc_hsq_finalize_request(mmc, mrq) : false; ++ if (hsq_req_done) { ++ if (host->error) ++ msdc_reset_hw(host); ++ return; ++ } ++ + spin_lock_irqsave(&host->lock, flags); + host->mrq = NULL; + spin_unlock_irqrestore(&host->lock, flags); +@@ -1181,7 +1206,7 @@ static void msdc_request_done(struct msd + msdc_unprepare_data(host, mrq->data); + if (host->error) + msdc_reset_hw(host); +- mmc_request_done(mmc_from_priv(host), mrq); ++ mmc_request_done(mmc, mrq); + if (host->dev_comp->recheck_sdio_irq) + msdc_recheck_sdio_irq(host); + } +@@ -1341,7 +1366,7 @@ static void msdc_ops_request(struct mmc_ + struct msdc_host *host = mmc_priv(mmc); + + host->error = 0; +- WARN_ON(host->mrq); ++ WARN_ON(!host->hsq_en && host->mrq); + host->mrq = mrq; + + if (mrq->data) { +@@ -2863,6 +2888,19 @@ static int msdc_drv_probe(struct platfor + mmc->max_seg_size = 64 * 1024; + /* Reduce CIT to 0x40 that corresponds to 2.35us */ + msdc_cqe_cit_cal(host, 2350); ++ } else if (mmc->caps2 & MMC_CAP2_NO_SDIO) { ++ /* Use HSQ on eMMC/SD (but not on SDIO) if HW CQE not supported */ ++ struct mmc_hsq *hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL); ++ if (!hsq) { ++ ret = -ENOMEM; ++ goto release; ++ } ++ ++ ret = mmc_hsq_init(hsq, mmc); ++ if (ret) ++ goto release; ++ ++ host->hsq_en = true; + } + + ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, +@@ -2988,6 +3026,9 @@ static int __maybe_unused msdc_runtime_s + struct mmc_host *mmc = dev_get_drvdata(dev); + struct msdc_host *host = mmc_priv(mmc); + ++ if (host->hsq_en) ++ mmc_hsq_suspend(mmc); ++ + msdc_save_reg(host); + + if (sdio_irq_claimed(mmc)) { +@@ -3018,6 +3059,10 @@ static int __maybe_unused msdc_runtime_r + pinctrl_select_state(host->pinctrl, host->pins_uhs); + enable_irq(host->irq); + } ++ ++ if (host->hsq_en) ++ mmc_hsq_resume(mmc); ++ + return 0; + } + diff --git a/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch index c19b0606a1..e80b988234 100644 --- a/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch +++ b/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch @@ -25,7 +25,7 @@ Signed-off-by: John Crispin --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig -@@ -1059,6 +1059,8 @@ config MMC_OWL +@@ -1060,6 +1060,8 @@ config MMC_OWL config MMC_SDHCI_EXTERNAL_DMA bool diff --git a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch index 1e9b8d173b..bb858a3773 100644 --- a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch +++ b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch @@ -9,7 +9,7 @@ Signed-off-by: Shiji Yang --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c -@@ -75,8 +75,12 @@ +@@ -76,8 +76,12 @@ #define MSDC_PATCH_BIT 0xb0 #define MSDC_PATCH_BIT1 0xb4 #define MSDC_PATCH_BIT2 0xb8 @@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang #define PAD_DS_TUNE 0x188 #define PAD_CMD_TUNE 0x18c #define EMMC51_CFG0 0x204 -@@ -402,6 +406,7 @@ struct mtk_mmc_compatible { +@@ -403,6 +407,7 @@ struct mtk_mmc_compatible { bool enhance_rx; bool support_64g; bool use_internal_cd; @@ -30,7 +30,7 @@ Signed-off-by: Shiji Yang }; struct msdc_tune_para { -@@ -539,6 +544,7 @@ static const struct mtk_mmc_compatible m +@@ -541,6 +546,7 @@ static const struct mtk_mmc_compatible m .stop_clk_fix = false, .enhance_rx = false, .use_internal_cd = true, @@ -38,7 +38,7 @@ Signed-off-by: Shiji Yang }; static const struct mtk_mmc_compatible mt7622_compat = { -@@ -1748,9 +1754,11 @@ static void msdc_init_hw(struct msdc_hos +@@ -1773,9 +1779,11 @@ static void msdc_init_hw(struct msdc_hos } writel(0, host->base + MSDC_IOCON); sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0); @@ -53,7 +53,7 @@ Signed-off-by: Shiji Yang sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL); if (host->dev_comp->stop_clk_fix) { -@@ -1814,6 +1822,18 @@ static void msdc_init_hw(struct msdc_hos +@@ -1839,6 +1847,18 @@ static void msdc_init_hw(struct msdc_hos MSDC_PAD_TUNE_RXDLYSEL); } From 43c1a0440f642ab004ffa7adadf6b87df7634a42 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Fri, 13 Jun 2025 21:36:16 +0800 Subject: [PATCH 030/128] ramips: mtk-sd: stability improvements for MIPS mt762x SoCs * Add tuning parameters to improve the stability of 48~50 MHz High-Speed SD mode. * Fix I/O errors on EMMC mode by disabling unsupported auto CMD23 feature. Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18896 (cherry picked from commit 3f78e5c918000faeef2f827333680a708df94ca9) [removed kernel 6.12 patches] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20258 Signed-off-by: Hauke Mehrtens --- ...uning-parameters-for-legacy-MIPS-MT7.patch | 81 +++++++++++ ...isable-auto-CMD23-support-for-mt7620.patch | 137 ++++++++++++++++++ ...efault-PATCH_BIT1-2-values-for-mt762.patch | 30 ++++ ...tialize-pad-delay-and-drive-strength.patch | 74 ---------- 4 files changed, 248 insertions(+), 74 deletions(-) create mode 100644 target/linux/ramips/patches-6.6/831-01-mmc-mtk-sd-add-tuning-parameters-for-legacy-MIPS-MT7.patch create mode 100644 target/linux/ramips/patches-6.6/831-02-mmc-mtk-sd-disable-auto-CMD23-support-for-mt7620.patch create mode 100644 target/linux/ramips/patches-6.6/831-03-mmc-mtk-sd-use-default-PATCH_BIT1-2-values-for-mt762.patch delete mode 100644 target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch diff --git a/target/linux/ramips/patches-6.6/831-01-mmc-mtk-sd-add-tuning-parameters-for-legacy-MIPS-MT7.patch b/target/linux/ramips/patches-6.6/831-01-mmc-mtk-sd-add-tuning-parameters-for-legacy-MIPS-MT7.patch new file mode 100644 index 0000000000..069d493ee7 --- /dev/null +++ b/target/linux/ramips/patches-6.6/831-01-mmc-mtk-sd-add-tuning-parameters-for-legacy-MIPS-MT7.patch @@ -0,0 +1,81 @@ +From: Shiji Yang +Date: Sat, 24 May 2025 15:53:26 +0800 +Subject: [PATCH 1/3] mmc: mtk-sd: add tuning parameters for legacy MIPS MT762x + SoCs + +The MIPS MT762x SoCs require some specific tuning parameters at +different clock frequencies. These legacy SoCs only support max +48~50 MHz High-Speed SD mode. Therefore, the standard tuning step +is not available. We have to hard code these tuning parameters +to make them work properly. + +Signed-off-by: Shiji Yang +--- + drivers/mmc/host/mtk-sd.c | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -76,8 +76,13 @@ + #define MSDC_PATCH_BIT 0xb0 + #define MSDC_PATCH_BIT1 0xb4 + #define MSDC_PATCH_BIT2 0xb8 ++#define MSDC_PAD_CTRL0 0xe0 ++#define MSDC_PAD_CTRL1 0xe4 ++#define MSDC_PAD_CTRL2 0xe8 + #define MSDC_PAD_TUNE 0xec + #define MSDC_PAD_TUNE0 0xf0 ++#define MSDC_DAT_RDDLY0 0xf0 ++#define MSDC_DAT_RDDLY1 0xf4 + #define PAD_DS_TUNE 0x188 + #define PAD_CMD_TUNE 0x18c + #define EMMC51_CFG0 0x204 +@@ -403,6 +408,7 @@ struct mtk_mmc_compatible { + bool enhance_rx; + bool support_64g; + bool use_internal_cd; ++ bool mips_mt762x; + }; + + struct msdc_tune_para { +@@ -541,6 +547,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = false, + .enhance_rx = false, + .use_internal_cd = true, ++ .mips_mt762x = true, + }; + + static const struct mtk_mmc_compatible mt7622_compat = { +@@ -970,7 +977,12 @@ static void msdc_set_mclk(struct msdc_ho + * mmc_select_hs400() will drop to 50Mhz and High speed mode, + * tune result of hs200/200Mhz is not suitable for 50Mhz + */ +- if (mmc->actual_clock <= 52000000) { ++ if (host->dev_comp->mips_mt762x && ++ mmc->actual_clock > 25000000) { ++ sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); ++ sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); ++ sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); ++ } else if (mmc->actual_clock <= 52000000) { + writel(host->def_tune_para.iocon, host->base + MSDC_IOCON); + if (host->top_base) { + writel(host->def_tune_para.emmc_top_control, +@@ -1839,6 +1851,18 @@ static void msdc_init_hw(struct msdc_hos + MSDC_PAD_TUNE_RXDLYSEL); + } + ++ if (host->dev_comp->mips_mt762x) { ++ /* Set pins drive strength */ ++ writel(0x000d0044, host->base + MSDC_PAD_CTRL0); ++ writel(0x000e0044, host->base + MSDC_PAD_CTRL1); ++ writel(0x000e0044, host->base + MSDC_PAD_CTRL2); ++ ++ /* Set tuning parameters */ ++ writel(0x84101010, host->base + tune_reg); ++ writel(0x10101010, host->base + MSDC_DAT_RDDLY0); ++ writel(0x10101010, host->base + MSDC_DAT_RDDLY1); ++ } ++ + if (mmc->caps2 & MMC_CAP2_NO_SDIO) { + sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIO); + sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ); diff --git a/target/linux/ramips/patches-6.6/831-02-mmc-mtk-sd-disable-auto-CMD23-support-for-mt7620.patch b/target/linux/ramips/patches-6.6/831-02-mmc-mtk-sd-disable-auto-CMD23-support-for-mt7620.patch new file mode 100644 index 0000000000..e61c609bdc --- /dev/null +++ b/target/linux/ramips/patches-6.6/831-02-mmc-mtk-sd-disable-auto-CMD23-support-for-mt7620.patch @@ -0,0 +1,137 @@ +From: Shiji Yang +Date: Fri, 13 Jun 2025 20:12:55 +0800 +Subject: [PATCH 2/3] mmc: mtk-sd: disable auto CMD23 support for mt7620 + +MT7628 ProgrammingGuide indicates that the host controller version +3.0 and later support auto CMD23 function. However, it doesn't +define SD command register BIT[29](Auto CMD23 enable bit). I guess +the legacy MIPS MT762x series SoCs don't support this feature at +all. The experiment on JDCloud RE-SP-01B(MT7621 + 128 GiB EMMC) +shows that disabling auto CMD23 can fix the following IO errors: + +[ 143.344604] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.353661] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.362662] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.371684] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.380684] I/O error, dev mmcblk0boot0, sector 0 op 0x0:(READ) flags 0x80700 phys_seg 4 prio class 0 +[ 143.390414] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.399468] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.408516] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.417556] mtk-msdc 1e130000.mmc: msdc_track_cmd_data: cmd=6 arg=03B30101; host->error=0x00000002 +[ 143.426590] I/O error, dev mmcblk0boot0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0 +[ 143.435585] Buffer I/O error on dev mmcblk0boot0, logical block 0, async page read + +Signed-off-by: Shiji Yang +--- + drivers/mmc/host/mtk-sd.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -407,6 +407,7 @@ struct mtk_mmc_compatible { + bool stop_clk_fix; + bool enhance_rx; + bool support_64g; ++ bool support_cmd23; + bool use_internal_cd; + bool mips_mt762x; + }; +@@ -495,6 +496,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = false, + .enhance_rx = false, + .support_64g = false, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt2712_compat = { +@@ -508,6 +510,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = true, + .enhance_rx = true, + .support_64g = true, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt6779_compat = { +@@ -521,6 +524,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = true, + .enhance_rx = true, + .support_64g = true, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt6795_compat = { +@@ -534,6 +538,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = false, + .enhance_rx = false, + .support_64g = false, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt7620_compat = { +@@ -546,6 +551,7 @@ static const struct mtk_mmc_compatible m + .busy_check = false, + .stop_clk_fix = false, + .enhance_rx = false, ++ .support_cmd23 = false, + .use_internal_cd = true, + .mips_mt762x = true, + }; +@@ -561,6 +567,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = true, + .enhance_rx = true, + .support_64g = false, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt7986_compat = { +@@ -574,6 +581,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = true, + .enhance_rx = true, + .support_64g = true, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt8135_compat = { +@@ -587,6 +595,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = false, + .enhance_rx = false, + .support_64g = false, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt8173_compat = { +@@ -600,6 +609,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = false, + .enhance_rx = false, + .support_64g = false, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt8183_compat = { +@@ -613,6 +623,7 @@ static const struct mtk_mmc_compatible m + .stop_clk_fix = true, + .enhance_rx = true, + .support_64g = true, ++ .support_cmd23 = true, + }; + + static const struct mtk_mmc_compatible mt8516_compat = { +@@ -624,6 +635,7 @@ static const struct mtk_mmc_compatible m + .data_tune = true, + .busy_check = true, + .stop_clk_fix = true, ++ .support_cmd23 = true, + }; + + static const struct of_device_id msdc_of_ids[] = { +@@ -2851,7 +2863,9 @@ static int msdc_drv_probe(struct platfor + if (mmc->caps & MMC_CAP_SDIO_IRQ) + mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; + +- mmc->caps |= MMC_CAP_CMD23; ++ if (host->dev_comp->support_cmd23) ++ mmc->caps |= MMC_CAP_CMD23; ++ + if (host->cqhci) + mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; + /* MMC core transfer sizes tunable parameters */ diff --git a/target/linux/ramips/patches-6.6/831-03-mmc-mtk-sd-use-default-PATCH_BIT1-2-values-for-mt762.patch b/target/linux/ramips/patches-6.6/831-03-mmc-mtk-sd-use-default-PATCH_BIT1-2-values-for-mt762.patch new file mode 100644 index 0000000000..0891d362fc --- /dev/null +++ b/target/linux/ramips/patches-6.6/831-03-mmc-mtk-sd-use-default-PATCH_BIT1-2-values-for-mt762.patch @@ -0,0 +1,30 @@ +From: Shiji Yang +Date: Sat, 24 May 2025 15:53:26 +0800 +Subject: [PATCH 3/3] mmc: mtk-sd: use default PATCH_BIT1/2 values for mt7620 + +The definitions of these two registers seem to be slightly different +from other variants. Use their default values to follow the vendor +SDK driver behaviors. + +Signed-off-by: Shiji Yang +--- + drivers/mmc/host/mtk-sd.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -1797,9 +1797,11 @@ static void msdc_init_hw(struct msdc_hos + } + writel(0, host->base + MSDC_IOCON); + sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0); +- writel(0x403c0046, host->base + MSDC_PATCH_BIT); +- sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); +- writel(0xffff4089, host->base + MSDC_PATCH_BIT1); ++ if (!host->dev_comp->mips_mt762x) { ++ writel(0x403c0046, host->base + MSDC_PATCH_BIT); ++ sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); ++ writel(0xffff4089, host->base + MSDC_PATCH_BIT1); ++ } + sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL); + + if (host->dev_comp->stop_clk_fix) { diff --git a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch deleted file mode 100644 index bb858a3773..0000000000 --- a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Shiji Yang -Date: Wed, 10 Jul 2024 12:18:52 +0800 -Subject: [PATCH] mmc: mtk-sd: initialize the pad and tune registers - -Signed-off-by: Shiji Yang ---- - drivers/mmc/host/mtk-sd.c | 26 +++++++++++++++++++++++--- - 1 file changed, 23 insertions(+), 3 deletions(-) - ---- a/drivers/mmc/host/mtk-sd.c -+++ b/drivers/mmc/host/mtk-sd.c -@@ -76,8 +76,12 @@ - #define MSDC_PATCH_BIT 0xb0 - #define MSDC_PATCH_BIT1 0xb4 - #define MSDC_PATCH_BIT2 0xb8 -+#define MSDC_PAD_CTRL0 0xe0 -+#define MSDC_PAD_CTRL1 0xe4 -+#define MSDC_PAD_CTRL2 0xe8 - #define MSDC_PAD_TUNE 0xec - #define MSDC_PAD_TUNE0 0xf0 -+#define MSDC_PAD_TUNE1 0xf4 - #define PAD_DS_TUNE 0x188 - #define PAD_CMD_TUNE 0x18c - #define EMMC51_CFG0 0x204 -@@ -403,6 +407,7 @@ struct mtk_mmc_compatible { - bool enhance_rx; - bool support_64g; - bool use_internal_cd; -+ bool legacy_mt762x; /* for mt7620, mt7621 and mt76x8 */ - }; - - struct msdc_tune_para { -@@ -541,6 +546,7 @@ static const struct mtk_mmc_compatible m - .stop_clk_fix = false, - .enhance_rx = false, - .use_internal_cd = true, -+ .legacy_mt762x = true, - }; - - static const struct mtk_mmc_compatible mt7622_compat = { -@@ -1773,9 +1779,11 @@ static void msdc_init_hw(struct msdc_hos - } - writel(0, host->base + MSDC_IOCON); - sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0); -- writel(0x403c0046, host->base + MSDC_PATCH_BIT); -- sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); -- writel(0xffff4089, host->base + MSDC_PATCH_BIT1); -+ if(!host->dev_comp->legacy_mt762x) { -+ writel(0x403c0046, host->base + MSDC_PATCH_BIT); -+ sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); -+ writel(0xffff4089, host->base + MSDC_PATCH_BIT1); -+ } - sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL); - - if (host->dev_comp->stop_clk_fix) { -@@ -1839,6 +1847,18 @@ static void msdc_init_hw(struct msdc_hos - MSDC_PAD_TUNE_RXDLYSEL); - } - -+ if (host->dev_comp->legacy_mt762x) { -+ /* Set pins drive strength */ -+ writel(0x000d0044, host->base + MSDC_PAD_CTRL0); -+ writel(0x000e0044, host->base + MSDC_PAD_CTRL1); -+ writel(0x000e0044, host->base + MSDC_PAD_CTRL2); -+ -+ /* Set pad delay */ -+ writel(0x84101010, host->base + MSDC_PAD_TUNE); -+ writel(0x10101010, host->base + MSDC_PAD_TUNE0); -+ writel(0x10101010, host->base + MSDC_PAD_TUNE1); -+ } -+ - if (mmc->caps2 & MMC_CAP2_NO_SDIO) { - sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIO); - sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ); From a902c0d02037ada89e39df1483fe4e4bd8bb7296 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sat, 24 May 2025 16:32:26 +0800 Subject: [PATCH 031/128] ramips: dts: increase maximum MMC clock frequency The High-Speed SD mode stability issue should have been fixed. Increase the MMC max-frequency to improve the IO speed. We can still use the sysfs to limit the clock frequency, e.g. root@OpenWrt:~# echo 25000000 > /sys/kernel/debug/mmc0/clock Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18896 (cherry picked from commit 143cfd6113231c61f38d1b9f5a0ea9ce3cc986c5) Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20258 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/dts/mt7620a.dtsi | 2 +- target/linux/ramips/dts/mt7621.dtsi | 2 +- target/linux/ramips/dts/mt7628an.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi index 7542d43bae..ef430b1b9f 100644 --- a/target/linux/ramips/dts/mt7620a.dtsi +++ b/target/linux/ramips/dts/mt7620a.dtsi @@ -522,7 +522,7 @@ reg = <0x10130000 0x4000>; bus-width = <4>; - max-frequency = <24000000>; + max-frequency = <48000000>; cap-mmc-highspeed; cap-sd-highspeed; disable-wp; diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi index 5730e83464..dc82120350 100644 --- a/target/linux/ramips/dts/mt7621.dtsi +++ b/target/linux/ramips/dts/mt7621.dtsi @@ -347,7 +347,7 @@ reg = <0x1e130000 0x4000>; bus-width = <4>; - max-frequency = <48000000>; + max-frequency = <50000000>; cap-mmc-highspeed; cap-sd-highspeed; disable-wp; diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi index e705d46b1e..47dd4df276 100644 --- a/target/linux/ramips/dts/mt7628an.dtsi +++ b/target/linux/ramips/dts/mt7628an.dtsi @@ -376,7 +376,7 @@ reg = <0x10130000 0x4000>; bus-width = <4>; - max-frequency = <24000000>; + max-frequency = <48000000>; cap-mmc-highspeed; cap-sd-highspeed; disable-wp; From 32a2193a4877fffeb255c90b1f3c38667ed8bf53 Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Mon, 8 Sep 2025 21:50:33 +0800 Subject: [PATCH 032/128] uboot-rockchip: add Fastrhino R66S support Add support for the Lunzn FastRhino R66S board. Tested-by: Francisco G Luna Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/19990 (cherry picked from commit 678536740ed58495e654f638f77decb8af18d768) [rebase patches upon 24.10 branch] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20618 Signed-off-by: Hauke Mehrtens --- package/boot/uboot-rockchip/Makefile | 8 ++ ...rd-rockchip-add-Lunzn-FastRhino-R66S.patch | 132 ++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 package/boot/uboot-rockchip/patches/003-board-rockchip-add-Lunzn-FastRhino-R66S.patch diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 7bb95d3b61..4f688396c3 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -219,6 +219,13 @@ define U-Boot/bpi-r2-pro-rk3568 sinovoip_bpi-r2-pro endef +define U-Boot/fastrhino-r66s-rk3568 + $(U-Boot/rk3568/Default) + NAME:=FastRhino R66S + BUILD_DEVICES:= \ + lunzn_fastrhino-r66s +endef + define U-Boot/nanopi-r5c-rk3568 $(U-Boot/rk3568/Default) NAME:=NanoPi R5C @@ -333,6 +340,7 @@ UBOOT_TARGETS := \ radxa-zero-3-rk3566 \ rock-3c-rk3566 \ bpi-r2-pro-rk3568 \ + fastrhino-r66s-rk3568 \ nanopi-r5c-rk3568 \ nanopi-r5s-rk3568 \ radxa-e25-rk3568 \ diff --git a/package/boot/uboot-rockchip/patches/003-board-rockchip-add-Lunzn-FastRhino-R66S.patch b/package/boot/uboot-rockchip/patches/003-board-rockchip-add-Lunzn-FastRhino-R66S.patch new file mode 100644 index 0000000000..99ad66638d --- /dev/null +++ b/package/boot/uboot-rockchip/patches/003-board-rockchip-add-Lunzn-FastRhino-R66S.patch @@ -0,0 +1,132 @@ +From 37a5383059d0c3d8a72394cbffef775042a40acd Mon Sep 17 00:00:00 2001 +From: Tianling Shen +Date: Mon, 8 Sep 2025 19:32:18 +0800 +Subject: [PATCH] board: rockchip: add Lunzn FastRhino R66S + +Lunzn Fastrhino R66S is a high-performance mini router. + +Specification: +- Rockchip RK3568 +- 1/2GB LPDDR4 RAM +- SD card slot +- 2x USB 3.0 Port +- 2x 2500 Base-T (PCIe, r8125b) +- 12v DC Jack + +Signed-off-by: Tianling Shen +Reviewed-by: Kever Yang +--- + .../arm/dts/rk3568-fastrhino-r66s-u-boot.dtsi | 3 + + board/rockchip/evb_rk3568/MAINTAINERS | 7 ++ + configs/fastrhino-r66s-rk3568_defconfig | 64 +++++++++++++++++++ + doc/board/rockchip/rockchip.rst | 1 + + 4 files changed, 75 insertions(+) + create mode 100644 arch/arm/dts/rk3568-fastrhino-r66s-u-boot.dtsi + create mode 100644 configs/fastrhino-r66s-rk3568_defconfig + +--- /dev/null ++++ b/arch/arm/dts/rk3568-fastrhino-r66s-u-boot.dtsi +@@ -0,0 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++#include "rk356x-u-boot.dtsi" ++ ++/ { ++ chosen { ++ stdout-path = &uart2; ++ }; ++}; +--- a/board/rockchip/evb_rk3568/MAINTAINERS ++++ b/board/rockchip/evb_rk3568/MAINTAINERS +@@ -14,6 +14,13 @@ F: configs/evb-rk3568_defconfig + F: arch/arm/dts/rk3568-evb-u-boot.dtsi + F: arch/arm/dts/rk3568-evb.dts + ++FASTRHINO-R66S-RK3568 ++M: Tianling Shen ++R: Jonas Karlman ++S: Maintained ++F: configs/fastrhino-r66s-rk3568_defconfig ++F: arch/arm/dts/rk3568-fastrhino-r66s-u-boot.dtsi ++ + GENERIC-RK3568 + M: Jonas Karlman + S: Maintained +--- /dev/null ++++ b/configs/fastrhino-r66s-rk3568_defconfig +@@ -0,0 +1,65 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3568-fastrhino-r66s" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_SPL_SERIAL=y ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-fastrhino-r66s.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_ATF=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_SPL_DM_SEQ_ALIAS=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_SPL_CLK=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_RTL8169=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_ERRNO_STR=y +--- a/doc/board/rockchip/rockchip.rst ++++ b/doc/board/rockchip/rockchip.rst +@@ -118,6 +118,7 @@ List of mainline supported Rockchip boar + - FriendlyElec NanoPi R5S (nanopi-r5s-rk3568) + - Generic RK3566/RK3568 (generic-rk3568) + - Hardkernel ODROID-M1 (odroid-m1-rk3568) ++ - Lunzn FastRhino R66S (fastrhino-r66s-rk3568) + - Radxa E25 Carrier Board (radxa-e25-rk3568) + - Radxa ROCK 3A (rock-3a-rk3568) + - Radxa ROCK 3B (rock-3b-rk3568) From c3b4e8e531b5ae1dbacc5aa74fca520abf33c3e4 Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Mon, 8 Sep 2025 21:54:55 +0800 Subject: [PATCH 033/128] rockchip: add Lunzn FastRhino R66S support Hardware -------- RockChip RK3568 ARM64 (4 cores) 1/2GB LPDDR4 RAM 2x 2500 Base-T (PCIe, r8125b) 1 LED (Power) 1 Button (Reset) Micro-SD Slot 2x USB 3.0 Port 12V DC Jack Installation ------------ Uncompress the OpenWrt sysupgrade and write it to a micro SD card using dd. Tested-by: Francisco G Luna Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/19990 (cherry picked from commit d76a77427017ee6356d3d0f9be61927c03748a09) Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20618 Signed-off-by: Hauke Mehrtens --- .../armv8/base-files/etc/board.d/02_network | 4 +++- .../etc/hotplug.d/net/40-net-smp-affinity | 1 + target/linux/rockchip/image/armv8.mk | 8 +++++++ ...date-LED-properties-for-Lunzn-Fastrh.patch | 24 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 target/linux/rockchip/patches-6.6/134-arm64-dts-rockchip-Update-LED-properties-for-Lunzn-Fastrh.patch diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network index 9a6e479323..56e0cc2408 100644 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network @@ -22,6 +22,7 @@ rockchip_setup_interfaces() ;; friendlyarm,nanopc-t6|\ friendlyarm,nanopi-r5c|\ + lunzn,fastrhino-r66s|\ radxa,e25|\ radxa,rock-3b) ucidef_set_interfaces_lan_wan 'eth0' 'eth1' @@ -52,7 +53,8 @@ rockchip_setup_macs() armsom,sige7|\ friendlyarm,nanopc-t6|\ friendlyarm,nanopi-r2c|\ - friendlyarm,nanopi-r2s) + friendlyarm,nanopi-r2s|\ + lunzn,fastrhino-r66s) wan_mac=$(macaddr_generate_from_mmc_cid mmcblk0) lan_mac=$(macaddr_add "$wan_mac" 1) ;; diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity index f5cdd9be8a..d9ca53b7e1 100644 --- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity +++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity @@ -32,6 +32,7 @@ case "$(board_name)" in armsom,sige7|\ friendlyarm,nanopi-r3s|\ friendlyarm,nanopi-r5c|\ +lunzn,fastrhino-r66s|\ radxa,e25|\ sinovoip,rk3568-bpi-r2pro) set_interface_core 2 "eth0" diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index 54ce6f771e..af224bb608 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -124,6 +124,14 @@ define Device/friendlyarm_nanopi-r6s endef TARGET_DEVICES += friendlyarm_nanopi-r6s +define Device/lunzn_fastrhino-r66s + DEVICE_VENDOR := Lunzn + DEVICE_MODEL := FastRhino R66S + SOC := rk3568 + DEVICE_PACKAGES := kmod-r8169 +endef +TARGET_DEVICES += lunzn_fastrhino-r66s + define Device/pine64_rock64 DEVICE_VENDOR := Pine64 DEVICE_MODEL := Rock64 diff --git a/target/linux/rockchip/patches-6.6/134-arm64-dts-rockchip-Update-LED-properties-for-Lunzn-Fastrh.patch b/target/linux/rockchip/patches-6.6/134-arm64-dts-rockchip-Update-LED-properties-for-Lunzn-Fastrh.patch new file mode 100644 index 0000000000..dfc850d629 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/134-arm64-dts-rockchip-Update-LED-properties-for-Lunzn-Fastrh.patch @@ -0,0 +1,24 @@ +--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi +@@ -9,6 +9,13 @@ + #include "rk3568.dtsi" + + / { ++ aliases { ++ led-boot = &status_led; ++ led-failsafe = &status_led; ++ led-running = &status_led; ++ led-upgrade = &status_led; ++ }; ++ + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; +@@ -35,7 +42,6 @@ + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "heartbeat"; + }; + }; + From d414ed185eeb72e6c705bd4bc986fba48ca76e85 Mon Sep 17 00:00:00 2001 From: Luis Mita Date: Sat, 11 Oct 2025 10:48:46 -0400 Subject: [PATCH 034/128] ramips: mt76x8: add support for Cudy RE1200 Outdoor v1 Hardware: - SoC: MediaTek MT7628DAN - Flash: 8 MiB XMC 25QH64CHIQ - RAM: 64 MiB (integrated on SoC) - WLAN: 2.4 GHz (MT7603E, 11n), 5 GHz (MediaTek MT7613BEN, 11ac) - Ethernet: 1x10/100 Mbps LAN - Buttons: 1 Reset button, 1 WPS button - LEDs: 5x Green - Serial Console: unpopulated header 115200 8n1 - Power: 24v Passive POE MAC addresses: +---------+-------------------+-----------+ | | MAC | Algorithm | +---------+-------------------+-----------+ | LAN | 80:af:ca:xx:xx:x0 | label | | WLAN 2g | 80:af:ca:xx:xx:x0 | label | | WLAN 5g | 80:af:ca:xx:xx:x2 | +2 | +---------+-------------------+-----------+ Installation: Please check the Wiki for this device for a more convenient solution than the one below. 1. Disassemble the device, desolder and dump the flash chip with a SPI programmer. 2. Separate the partitions with dd: dd if=spi_dump.bin of=u-boot.bin bs=1 skip=0 count=196608 status=progress dd if=spi_dump.bin of=u-boot-env.bin bs=1 skip=196608 count=65536 status=progress dd if=spi_dump.bin of=factory.bin bs=1 skip=262144 count=65536 status=progress dd if=spi_dump.bin of=firmware.bin bs=1 skip=327680 count=7995392 status=progress dd if=spi_dump.bin of=bdinfo.bin bs=1 skip=8323072 count=65536 status=progress 3. Download the sysupgrade firmware at openwrt.bin. 4. The firmware size should be 7995392 bytes. Fix the size of your firmware putting zeros to the end, with: truncate -s 7995392 firmware.bin 5. Combine all the parititions: cat u-boot.bin u-boot-env.bin factory.bin openwrt.bin bdinfo.bin > spi_new.bin 6. Erase and flash the SPI chip with the new file. Solder the chip and boot the router. Signed-off-by: Luis Mita Link: https://github.com/openwrt/openwrt/pull/20381 (cherry picked from commit 65215e6d465eeec76e025fca3ec9f15474435b6f) Link: https://github.com/openwrt/openwrt/pull/20463 Signed-off-by: Hauke Mehrtens --- .../dts/mt7628an_cudy_re1200-outdoor-v1.dts | 186 ++++++++++++++++++ target/linux/ramips/image/mt76x8.mk | 11 ++ .../mt76x8/base-files/etc/board.d/01_leds | 1 + .../mt76x8/base-files/etc/board.d/02_network | 1 + 4 files changed, 199 insertions(+) create mode 100644 target/linux/ramips/dts/mt7628an_cudy_re1200-outdoor-v1.dts diff --git a/target/linux/ramips/dts/mt7628an_cudy_re1200-outdoor-v1.dts b/target/linux/ramips/dts/mt7628an_cudy_re1200-outdoor-v1.dts new file mode 100644 index 0000000000..95dab752f4 --- /dev/null +++ b/target/linux/ramips/dts/mt7628an_cudy_re1200-outdoor-v1.dts @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7628an.dtsi" + +#include +#include +#include + +/ { + compatible = "cudy,re1200-outdoor-v1", "mediatek,mt7628an-soc"; + model = "Cudy RE1200 Outdoor v1"; + + aliases { + led-boot = &led_status; + led-running = &led_status; + led-failsafe = &led_status; + led-upgrade = &led_status; + label-mac-device = ðernet; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_status:status { + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_STATUS; + }; + + internet { + gpios = <&gpio 40 GPIO_ACTIVE_HIGH>; + color = ; + function = LED_FUNCTION_WAN_ONLINE; + }; + + lan { + gpios = <&gpio 43 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_LAN; + }; + + wifi2g { + gpios = <&gpio 0 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WLAN_2GHZ; + linux,default-trigger = "phy0tpt"; + }; + + wifi5g { + gpios = <&gpio 42 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WLAN_5GHZ; + linux,default-trigger = "phy1tpt"; + }; + }; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x400>; + }; + + eeprom_factory_8000: eeprom@8000 { + reg = <0x8000 0x4da8>; + }; + }; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0x7a0000>; + }; + + partition@ff0000 { + label = "bdinfo"; + reg = <0x7f0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_bdinfo_de00: macaddr@de00 { + compatible = "mac-base"; + reg = <0xde00 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "i2c", "gpio", "wdt", "p0led_an", "wled_an"; + function = "gpio"; + }; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_8000>, <&macaddr_bdinfo_de00 2>; + nvmem-cell-names = "eeprom", "mac-address"; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&eeprom_factory_0>, <&macaddr_bdinfo_de00 0>; + nvmem-cell-names = "eeprom", "mac-address"; +}; + +ðernet { + nvmem-cells = <&macaddr_bdinfo_de00 0>; + nvmem-cell-names = "mac-address"; +}; + +&esw { + mediatek,portmap = <0x3d>; + mediatek,portdisable = <0x3e>; +}; diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk index 3573d16a45..94cccab743 100644 --- a/target/linux/ramips/image/mt76x8.mk +++ b/target/linux/ramips/image/mt76x8.mk @@ -184,6 +184,17 @@ define Device/cudy_m1200-v1 endef TARGET_DEVICES += cudy_m1200-v1 +define Device/cudy_re1200-outdoor-v1 + IMAGE_SIZE := 7808k + DEVICE_VENDOR := Cudy + DEVICE_MODEL := RE1200 Outdoor + DEVICE_VARIANT := v1 + DEVICE_PACKAGES := kmod-mt7615e kmod-mt7663-firmware-ap + UIMAGE_NAME := R56 + SUPPORTED_DEVICES += R56 +endef +TARGET_DEVICES += cudy_re1200-outdoor-v1 + define Device/cudy_tr1200-v1 IMAGE_SIZE := 15872k DEVICE_VENDOR := Cudy diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds index 00e5086bb3..e1612ec74b 100644 --- a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds @@ -92,6 +92,7 @@ tplink,archer-mr200-v5) ucidef_set_led_netdev "lan" "lan" "white:lan" "eth0" ucidef_set_led_netdev "wan" "wan" "white:wan" "wwan0" ;; +cudy,re1200-outdoor-v1|\ tplink,re200-v2|\ tplink,re200-v3|\ tplink,re200-v4|\ diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network index 31cb38091b..92168d1fcf 100644 --- a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network @@ -169,6 +169,7 @@ ramips_setup_interfaces() "0:lan" "1:lan" "2:lan" "3:lan" "6t@eth0" ucidef_set_interface "wan" device "/dev/cdc-wdm0" protocol "qmi" ;; + cudy,re1200-outdoor-v1|\ tplink,tl-mr3020-v3) ucidef_add_switch "switch0" \ "0:lan" "6@eth0" From a167e68c76444c8510e10aeaafa21f986098164e Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Thu, 9 Oct 2025 21:31:22 +0800 Subject: [PATCH 035/128] mediatek: add Konka KOMI A31 support This board is also as known as E-Life ETR631-T/ETR635-U. Hardware specification: SoC: MediaTek MT7981B 2x A53 Flash: 128 MB SPI-NAND RAM: 256MB DDR3 Ethernet: 4x 10/100/1000 Mbps Switch: MediaTek MT7531AE WiFi: MediaTek MT7976C Button: Reset, Mesh Power: DC 12V 1A Gain telnet access: 1. Login into web interface, and download the configuration. 2. Uncompress the configuration: * Enter fakeroot if you are not login as root. tar -zxf .tar.gz 3. Edit 'etc/passwd', remove root password: 'root::1:0:99999:7:::'. 4. Edit 'etc/rc.local', insert telnetd command before 'exit 0': ( sleep 3s; telnetd; ) & 5. Repack the configuration: tar -zcf backup.tar.gz etc/ 6. Upload new configuration via web interface, now you can connect to KOMI A31 via telnet. Flash instructions: 1. Connect to KOMI A31, backup everything, especially 'Factory' part. 2. Write new BL2: mtd write openwrt-mediatek-filogic-konka_komi-a31-preloader.bin BL2 3. Write new FIP: mtd write openwrt-mediatek-filogic-konka_komi-a31-bl31-uboot.fip FIP 4. Set static IP on your PC: IP 192.168.1.254/24, GW 192.168.1.1 5. Serve OpenWrt initramfs image using TFTP server. 6. Cut off the power and re-engage, wait for TFTP recovery to complete. 7. After OpenWrt has booted, perform sysupgrade. Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20357 (cherry picked from commit 8a7de107d89fe33c811603ce997a09ea7394a478) [rebase uboot patches upon 24.10 branch] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20595 Signed-off-by: Hauke Mehrtens --- .../uboot-envtools/files/mediatek_filogic | 1 + package/boot/uboot-mediatek/Makefile | 13 + .../patches/447-add-konka_komi-a31.patch | 328 ++++++++++++++++++ .../mediatek/dts/mt7981b-konka-komi-a31.dts | 279 +++++++++++++++ .../filogic/base-files/etc/board.d/02_network | 1 + .../base-files/lib/upgrade/platform.sh | 1 + target/linux/mediatek/image/filogic.mk | 28 ++ 7 files changed, 651 insertions(+) create mode 100644 package/boot/uboot-mediatek/patches/447-add-konka_komi-a31.patch create mode 100644 target/linux/mediatek/dts/mt7981b-konka-komi-a31.dts diff --git a/package/boot/uboot-envtools/files/mediatek_filogic b/package/boot/uboot-envtools/files/mediatek_filogic index 3f8fa0d543..1bf63d3061 100644 --- a/package/boot/uboot-envtools/files/mediatek_filogic +++ b/package/boot/uboot-envtools/files/mediatek_filogic @@ -38,6 +38,7 @@ cmcc,a10-ubootmod|\ cudy,tr3000-v1-ubootmod|\ h3c,magic-nx30-pro|\ jcg,q30-pro|\ +konka,komi-a31|\ mercusys,mr90x-v1-ubi|\ netcore,n60|\ netis,nx31|\ diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index f68a5d6ff5..eb54526397 100644 --- a/package/boot/uboot-mediatek/Makefile +++ b/package/boot/uboot-mediatek/Makefile @@ -326,6 +326,18 @@ define U-Boot/mt7981_jcg_q30-pro DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 endef +define U-Boot/mt7981_konka_komi-a31 + NAME:=Konka KOMI A31 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=konka_komi-a31 + UBOOT_CONFIG:=mt7981_konka_komi-a31 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand + BL2_SOC:=mt7981 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 +endef + define U-Boot/mt7981_netis_nx31 NAME:=netis NX31 BUILD_SUBTARGET:=filogic @@ -876,6 +888,7 @@ UBOOT_TARGETS := \ mt7981_glinet_gl-xe3000 \ mt7981_h3c_magic-nx30-pro \ mt7981_jcg_q30-pro \ + mt7981_konka_komi-a31 \ mt7981_netis_nx31 \ mt7981_nokia_ea0326gmp \ mt7981_openwrt_one-snand \ diff --git a/package/boot/uboot-mediatek/patches/447-add-konka_komi-a31.patch b/package/boot/uboot-mediatek/patches/447-add-konka_komi-a31.patch new file mode 100644 index 0000000000..79e554a3f7 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/447-add-konka_komi-a31.patch @@ -0,0 +1,328 @@ +--- /dev/null ++++ b/configs/mt7981_konka_komi-a31_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-konka-komi-a31" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-konka-komi-a31.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="konka_komi-a31_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7981-konka-komi-a31.dts +@@ -0,0 +1,158 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "Konka KOMI A31"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x10000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ button-mesh { ++ label = "mesh"; ++ linux,code = ; ++ linux,input-type = ; ++ gpios = <&gpio 0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ button-reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ green_led: led-0 { ++ label = "green:status"; ++ gpios = <&gpio 8 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-1 { ++ label = "blue:status"; ++ gpios = <&gpio 13 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ red_led: led-2 { ++ label = "red:status"; ++ gpios = <&gpio 34 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "u-boot-env"; ++ reg = <0x100000 0x80000>; ++ }; ++ ++ partition@180000 { ++ label = "factory"; ++ reg = <0x180000 0x200000>; ++ }; ++ ++ partition@380000 { ++ label = "fip"; ++ reg = <0x380000 0x200000>; ++ }; ++ ++ partition@580000 { ++ label = "ubi"; ++ reg = <0x580000 0x7a80000>; ++ compatible = "linux,ubi"; ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ mediatek,force-highspeed; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/konka_komi-a31_env +@@ -0,0 +1,54 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootcmd=if pstore check ; then run boot_recovery ; else run boot_ubi ; fi ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-konka_komi-a31-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-konka_komi-a31-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-konka_komi-a31-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-konka_komi-a31-squashfs-sysupgrade.itb ++bootled_pwr=red:status ++bootled_rec=blue:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_rec off ++boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2 ++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800 ++mtd_write_fip=mtd erase fip && mtd write fip $loadaddr ++mtd_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format ++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/target/linux/mediatek/dts/mt7981b-konka-komi-a31.dts b/target/linux/mediatek/dts/mt7981b-konka-komi-a31.dts new file mode 100644 index 0000000000..0a3a1b35c0 --- /dev/null +++ b/target/linux/mediatek/dts/mt7981b-konka-komi-a31.dts @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; +#include +#include +#include +#include + +#include "mt7981.dtsi" + +/ { + model = "Konka KOMI A31"; + compatible = "konka,komi-a31", "mediatek,mt7981"; + + aliases { + led-boot = &red_led; + led-failsafe = &red_led; + led-running = &green_led; + led-upgrade = &green_led; + label-mac-device = &gmac1; + serial0 = &uart0; + }; + + chosen { + bootargs = "root=/dev/fit0 rootwait"; + rootdisk = <&ubi_rootdisk>; + stdout-path = "serial0:115200n8"; + }; + + memory@40000000 { + reg = <0 0x40000000 0 0x10000000>; + device_type = "memory"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-mesh { + label = "mesh"; + linux,code = ; + linux,input-type = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + button-reset { + label = "reset"; + linux,code = ; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + green_led: led-0 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 8 GPIO_ACTIVE_LOW>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 13 GPIO_ACTIVE_LOW>; + }; + + red_led: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 34 GPIO_ACTIVE_LOW>; + }; + }; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + nvmem-cells = <&macaddr_factory_2a 0>; + nvmem-cell-names = "mac-address"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "gmii"; + phy-handle = <&int_gbe_phy>; + + nvmem-cells = <&macaddr_factory_24 0>; + nvmem-cell-names = "mac-address"; + }; +}; + +&mdio_bus { + switch: switch@1f { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&pio>; + interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; + }; +}; + +&pio { + spi0_flash_pins: spi0-pins { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-disable; /* bias-disable */ + }; + + conf-pd { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-disable; /* bias-disable */ + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_flash_pins>; + status = "okay"; + + spi_nand: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bl2"; + reg = <0x0 0x100000>; + read-only; + }; + + partition@100000 { + label = "u-boot-env"; + reg = <0x100000 0x80000>; + }; + + partition@180000 { + label = "factory"; + reg = <0x180000 0x200000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + macaddr_factory_24: macaddr@24 { + compatible = "mac-base"; + reg = <0x24 0x6>; + #nvmem-cell-cells = <1>; + }; + + macaddr_factory_2a: macaddr@2a { + compatible = "mac-base"; + reg = <0x2a 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + + partition@380000 { + label = "fip"; + reg = <0x380000 0x200000>; + read-only; + }; + + partition@580000 { + compatible = "linux,ubi"; + label = "ubi"; + reg = <0x580000 0x7a80000>; + + volumes { + ubi_rootdisk: ubi-volume-fit { + volname = "fit"; + }; + }; + }; + }; + }; +}; + +&switch { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan1"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&wifi { + #address-cells = <1>; + #size-cells = <0>; + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + status = "okay"; + + band@0 { + reg = <0>; + nvmem-cells = <&macaddr_factory_2a 1>; + nvmem-cell-names = "mac-address"; + }; + + band@1 { + reg = <1>; + nvmem-cells = <&macaddr_factory_2a 2>; + nvmem-cell-names = "mac-address"; + }; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index 59a7a720f3..e876ef75ed 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -11,6 +11,7 @@ mediatek_setup_interfaces() abt,asr3000|\ cmcc,rax3000m|\ h3c,magic-nx30-pro|\ + konka,komi-a31|\ netis,nx31|\ nokia,ea0326gmp|\ mercusys,mr80x-v3|\ diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index 64b6d4b60b..bd66551198 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -78,6 +78,7 @@ platform_do_upgrade() { h3c,magic-nx30-pro|\ jcg,q30-pro|\ jdcloud,re-cp-03|\ + konka,komi-a31|\ mediatek,mt7981-rfb|\ mediatek,mt7988a-rfb|\ mercusys,mr90x-v1-ubi|\ diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 186099ad8c..2cf44bee14 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1204,6 +1204,34 @@ define Device/keenetic_kn-3911 endef TARGET_DEVICES += keenetic_kn-3911 +define Device/konka_komi-a31 + DEVICE_VENDOR := Konka + DEVICE_MODEL := KOMI A31 + DEVICE_ALT0_VENDOR := E-Life + DEVICE_ALT0_MODEL := ETR631-T + DEVICE_ALT1_VENDOR := E-Life + DEVICE_ALT1_MODEL := ETR635-U + DEVICE_DTS := mt7981b-konka-komi-a31 + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_IN_UBI := 1 + UBOOTENV_IN_UBI := 1 + IMAGES := sysupgrade.itb + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + KERNEL := kernel-bin | gzip + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k + IMAGE/sysupgrade.itb := append-kernel | \ + fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-static-with-rootfs | append-metadata + ARTIFACTS := preloader.bin bl31-uboot.fip + ARTIFACT/preloader.bin := mt7981-bl2 spim-nand-ddr3 + ARTIFACT/bl31-uboot.fip := mt7981-bl31-uboot konka_komi-a31 +endef +TARGET_DEVICES += konka_komi-a31 + define Device/mediatek_mt7981-rfb DEVICE_VENDOR := MediaTek DEVICE_MODEL := MT7981 rfb From a6e8cbdf533d049d0d769784f2d8f07f78707323 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 5 Jul 2025 12:44:03 +0200 Subject: [PATCH 036/128] airoha: replace thermal patch with upstream version Replace thermal patch with upstream version. The thermal maintainer reported that the sysfs entry are considered deprecated and that slope and offset should be handled internally to the driver. Link: https://github.com/openwrt/openwrt/pull/19816 Signed-off-by: Christian Marangi (cherry picked from commit a713260966003f2941e1327a7158d542689967dc) --- ...dd-support-for-Airoha-EN7581-therma.patch} | 127 ++++++----- ...-drivers-airoha-Fix-spelling-mistake.patch | 44 ++++ ...evm_thermal_of_zone_register_with_pa.patch | 210 ------------------ 3 files changed, 115 insertions(+), 266 deletions(-) rename target/linux/airoha/patches-6.6/{101-02-thermal-Add-support-for-Airoha-EN7581-thermal-sensor.patch => 049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch} (84%) create mode 100644 target/linux/airoha/patches-6.6/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch delete mode 100644 target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch diff --git a/target/linux/airoha/patches-6.6/101-02-thermal-Add-support-for-Airoha-EN7581-thermal-sensor.patch b/target/linux/airoha/patches-6.6/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch similarity index 84% rename from target/linux/airoha/patches-6.6/101-02-thermal-Add-support-for-Airoha-EN7581-thermal-sensor.patch rename to target/linux/airoha/patches-6.6/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch index ffacbba693..e168cda324 100644 --- a/target/linux/airoha/patches-6.6/101-02-thermal-Add-support-for-Airoha-EN7581-thermal-sensor.patch +++ b/target/linux/airoha/patches-6.6/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch @@ -1,7 +1,7 @@ -From bc6a6a4ec6c28467683121cc165e5681b4acdf8d Mon Sep 17 00:00:00 2001 +From 42de37f40e1bc818df216dfa0918c114cfb5941d Mon Sep 17 00:00:00 2001 From: Christian Marangi -Date: Tue, 27 Aug 2024 23:04:53 +0200 -Subject: [PATCH 3/3] thermal: Add support for Airoha EN7581 thermal sensor +Date: Sun, 11 May 2025 20:49:55 +0200 +Subject: [PATCH] thermal/drivers: Add support for Airoha EN7581 thermal sensor Add support for Airoha EN7581 thermal sensor. This provide support for reading the CPU or SoC Package sensor and to setup trip points for hot @@ -12,12 +12,20 @@ The thermal regs provide a way to read the ADC value from an external register placed in the Chip SCU regs. Monitor will read this value and fire an interrupt if the trip condition configured is reached. +The Thermal Trip and Interrupt logic is conceptually similar to Mediatek +LVTS Thermal but differ in register mapping and actual function/bug +workaround. The implementation only share some register names but from +functionality observation it's very different and used only for the +basic function of periodically poll the temp and trip the interrupt. + Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20250511185003.3754495-2-ansuelsmth@gmail.com +Signed-off-by: Daniel Lezcano --- drivers/thermal/Kconfig | 9 + drivers/thermal/Makefile | 1 + - drivers/thermal/airoha_thermal.c | 482 +++++++++++++++++++++++++++++++ - 3 files changed, 492 insertions(+) + drivers/thermal/airoha_thermal.c | 489 +++++++++++++++++++++++++++++++ + 3 files changed, 499 insertions(+) create mode 100644 drivers/thermal/airoha_thermal.c --- a/drivers/thermal/Kconfig @@ -50,7 +58,7 @@ Signed-off-by: Christian Marangi obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o --- /dev/null +++ b/drivers/thermal/airoha_thermal.c -@@ -0,0 +1,482 @@ +@@ -0,0 +1,489 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include @@ -235,15 +243,17 @@ Signed-off-by: Christian Marangi +#define EN7581_SCU_THERMAL_MUX_DIODE1 0x7 + +/* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */ -+#define TEMP_TO_RAW(priv, tz, temp) ((((((temp) / 100) - (priv)->init_temp) * \ -+ thermal_zone_get_slope(tz)) / 1000) + \ -+ thermal_zone_get_offset(tz)) ++#define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \ ++ (priv)->default_slope) / 1000) + \ ++ (priv)->default_offset) + +/* Convert raw to temp ((((temp - offset) * 1000) / slope + init) * 100) */ -+#define RAW_TO_TEMP(priv, tz, raw) (((((raw) - thermal_zone_get_offset(tz)) * 1000) / \ -+ thermal_zone_get_slope(tz) + \ ++#define RAW_TO_TEMP(priv, raw) (((((raw) - (priv)->default_offset) * 1000) / \ ++ (priv)->default_slope + \ + (priv)->init_temp) * 100) + ++#define AIROHA_MAX_SAMPLES 6 ++ +struct airoha_thermal_priv { + void __iomem *base; + struct regmap *chip_scu; @@ -251,6 +261,8 @@ Signed-off-by: Christian Marangi + + struct thermal_zone_device *tz; + int init_temp; ++ int default_slope; ++ int default_offset; +}; + +static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) @@ -280,28 +292,25 @@ Signed-off-by: Christian Marangi +static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); -+ int min, max, avg_temp, temp_adc; ++ int min_value, max_value, avg_value, value; + int i; + -+ /* Get the starting temp */ -+ temp_adc = airoha_get_thermal_ADC(priv); -+ min = temp_adc; -+ max = temp_adc; -+ avg_temp = temp_adc; ++ avg_value = 0; ++ min_value = INT_MAX; ++ max_value = INT_MIN; + -+ /* Make 5 more measurement and average the temp ADC difference */ -+ for (i = 0; i < 5; i++) { -+ temp_adc = airoha_get_thermal_ADC(priv); -+ avg_temp += temp_adc; -+ if (temp_adc > max) -+ max = temp_adc; -+ if (temp_adc < min) -+ min = temp_adc; ++ for (i = 0; i < AIROHA_MAX_SAMPLES; i++) { ++ value = airoha_get_thermal_ADC(priv); ++ min_value = min(value, min_value); ++ max_value = max(value, max_value); ++ avg_value += value; + } -+ avg_temp = avg_temp - max - min; -+ avg_temp /= 4; + -+ *temp = RAW_TO_TEMP(priv, tz, avg_temp); ++ /* Drop min and max and average for the remaining sample */ ++ avg_value -= (min_value + max_value); ++ avg_value /= AIROHA_MAX_SAMPLES - 2; ++ ++ *temp = RAW_TO_TEMP(priv, avg_value); + return 0; +} + @@ -309,29 +318,35 @@ Signed-off-by: Christian Marangi + int high) +{ + struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); ++ bool enable_monitor = false; + + if (high != INT_MAX) { -+ /* Validate high and clamp them a sane value */ -+ if (high > RAW_TO_TEMP(priv, tz, FIELD_MAX(EN7581_DOUT_TADC_MASK))) -+ high = 110000; ++ /* Validate high and clamp it a supported value */ ++ high = clamp_t(int, high, RAW_TO_TEMP(priv, 0), ++ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); + + /* We offset the high temp of 1°C to trigger correct event */ -+ writel(TEMP_TO_RAW(priv, tz, high) >> 4, ++ writel(TEMP_TO_RAW(priv, high) >> 4, + priv->base + EN7581_TEMPOFFSETH); ++ ++ enable_monitor = true; + } + + if (low != -INT_MAX) { -+ /* Validate low and clamp them to a sane value */ -+ if (low < RAW_TO_TEMP(priv, tz, 0)) -+ low = -33000; ++ /* Validate low and clamp it to a supported value */ ++ low = clamp_t(int, high, RAW_TO_TEMP(priv, 0), ++ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); + + /* We offset the low temp of 1°C to trigger correct event */ -+ writel(TEMP_TO_RAW(priv, tz, low) >> 4, ++ writel(TEMP_TO_RAW(priv, low) >> 4, + priv->base + EN7581_TEMPOFFSETL); ++ ++ enable_monitor = true; + } + -+ /* Enable sensor 0 monitor */ -+ writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); ++ /* Enable sensor 0 monitor after trip are set */ ++ if (enable_monitor) ++ writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); + + return 0; +} @@ -345,32 +360,35 @@ Signed-off-by: Christian Marangi +{ + struct airoha_thermal_priv *priv = data; + enum thermal_notify_event event; ++ bool update = false; + u32 status; + + status = readl(priv->base + EN7581_TEMPMONINTSTS); + switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) { + case EN7581_HOFSINTSTS0: + event = THERMAL_TRIP_VIOLATED; ++ update = true; + break; + case EN7581_LOFSINTSTS0: + event = THERMAL_EVENT_UNSPECIFIED; ++ update = true; + break; + default: -+ goto exit; ++ /* Should be impossible as we enable only these Interrupt */ ++ break; + } + -+ thermal_zone_device_update(priv->tz, event); -+ -+exit: -+ /* reset interrupt */ ++ /* Reset Interrupt */ + writel(status, priv->base + EN7581_TEMPMONINTSTS); + ++ if (update) ++ thermal_zone_device_update(priv->tz, event); ++ + return IRQ_HANDLED; +} + +static void airoha_thermal_setup_adc_val(struct device *dev, -+ struct airoha_thermal_priv *priv, -+ struct thermal_zone_params *tzp) ++ struct airoha_thermal_priv *priv) +{ + u32 efuse_calib_info, cpu_sensor; + @@ -381,19 +399,19 @@ Signed-off-by: Christian Marangi + + efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG); + if (efuse_calib_info) { -+ tzp->offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); ++ priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); + /* Different slope are applied if the sensor is used for CPU or for package */ + cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG); + if (cpu_sensor) { -+ tzp->slope = EN7581_SLOPE_X100_DIO_DEFAULT; ++ priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; + priv->init_temp = EN7581_INIT_TEMP_FTK_X10; + } else { -+ tzp->slope = EN7581_SLOPE_X100_DIO_AVS; ++ priv->default_slope = EN7581_SLOPE_X100_DIO_AVS; + priv->init_temp = EN7581_INIT_TEMP_CPK_X10; + } + } else { -+ tzp->offset = airoha_get_thermal_ADC(priv); -+ tzp->slope = EN7581_SLOPE_X100_DIO_DEFAULT; ++ priv->default_offset = airoha_get_thermal_ADC(priv); ++ priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; + priv->init_temp = EN7581_INIT_TEMP_NONK_X10; + dev_info(dev, "missing thermal calibrarion EFUSE, using non calibrated value\n"); + } @@ -456,7 +474,6 @@ Signed-off-by: Christian Marangi + +static int airoha_thermal_probe(struct platform_device *pdev) +{ -+ struct thermal_zone_params tzp = { }; + struct airoha_thermal_priv *priv; + struct device_node *chip_scu_np; + struct device *dev = &pdev->dev; @@ -487,19 +504,17 @@ Signed-off-by: Christian Marangi + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + airoha_thermal_irq, IRQF_ONESHOT, -+ pdev->name, (void *)priv); ++ pdev->name, priv); + if (ret) { + dev_err(dev, "Can't get interrupt working.\n"); + return ret; + } + + airoha_thermal_setup_monitor(priv); -+ airoha_thermal_setup_adc_val(dev, priv, &tzp); ++ airoha_thermal_setup_adc_val(dev, priv); + + /* register of thermal sensor and get info from DT */ -+ priv->tz = devm_thermal_of_zone_register_with_params(dev, 0, priv, -+ &thdev_ops, -+ &tzp); ++ priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops); + if (IS_ERR(priv->tz)) { + dev_err(dev, "register thermal zone sensor failed\n"); + return PTR_ERR(priv->tz); diff --git a/target/linux/airoha/patches-6.6/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch b/target/linux/airoha/patches-6.6/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch new file mode 100644 index 0000000000..7b1b9478c3 --- /dev/null +++ b/target/linux/airoha/patches-6.6/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch @@ -0,0 +1,44 @@ +From e23cba0ab49a9cf95e9bc3a86cfbf336b0e285f6 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 14 May 2025 23:39:12 +0200 +Subject: [PATCH] thermal/drivers/airoha: Fix spelling mistake + +Fix various spelling mistake in airoha_thermal_setup_monitor() and +define. + +Reported-by: Alok Tiwari +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20250514213919.2321490-1-ansuelsmth@gmail.com +Signed-off-by: Daniel Lezcano +--- + drivers/thermal/airoha_thermal.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/thermal/airoha_thermal.c ++++ b/drivers/thermal/airoha_thermal.c +@@ -155,7 +155,7 @@ + * Can operate in: + * - 1 sample + * - 2 sample and make average of them +- * - 4,6,10,16 sample, drop max and min and make avgerage of them ++ * - 4,6,10,16 sample, drop max and min and make average of them + */ + #define EN7581_MSRCTL_1SAMPLE 0x0 + #define EN7581_MSRCTL_AVG2SAMPLE 0x1 +@@ -365,12 +365,12 @@ static void airoha_thermal_setup_monitor + /* + * Configure ADC valid reading addr + * The AHB temp monitor system doesn't have direct access to the +- * thermal sensor. It does instead work by providing all kind of +- * address to configure how to access and setup an ADC for the ++ * thermal sensor. It does instead work by providing various ++ * addresses to configure how to access and setup an ADC for the + * sensor. EN7581 supports only one sensor hence the + * implementation is greatly simplified but the AHB supports +- * up to 4 different sensor from the same ADC that can be +- * switched by tuning the ADC mux or wiriting address. ++ * up to 4 different sensors from the same ADC that can be ++ * switched by tuning the ADC mux or writing address. + * + * We set valid instead of volt as we don't enable valid/volt + * split reading and AHB read valid addr in such case. diff --git a/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch b/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch deleted file mode 100644 index d646e05170..0000000000 --- a/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 1f194995c3648e20da53137d4c9110b39e779f41 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 18 Oct 2024 11:34:35 +0200 -Subject: [PATCH 2/3] thermal: of: Add - devm_thermal_of_zone_register_with_params() variant - -Commit b1ae92dcfa8e ("thermal: core: Make struct thermal_zone_device -definition internal") moved the thermal_zone_device struct from global -thermal.h to internal thermal_core.h making the internal variables of -the struct not accessible from the user drivers (without inclusing -thermal_core.h). - -One case where the internal variables might be needed is for the -thermal_zone_params in the context of OF probe. - -In such case a thermal driver might have default params that can only be -parsed at runtime (example present in EFUSE or derived from other values) -and wants to update the values in the thermal_zone_params for the -thermal device. (to use the helper like get_slope() or get_offset()) - -To account for this scenario, introduce a variant of -devm_thermal_of_zone_register(), -devm_thermal_of_zone_register_with_params(), that takes and additional -variable and permits to register the thermal device with default -thermal_zone_params. - -To follow OF implementation, these params are only treated as default -params and are ignored if a related one is defined in DT. (example a -slope or offset value defined in DT have priority to the default one -passed in a thermal_device_params struct) - -This permits to support both implementation, use the helpers and expose -these values in sysfs. - -Signed-off-by: Christian Marangi ---- - drivers/thermal/thermal_of.c | 67 +++++++++++++++++++++++++++++------- - include/linux/thermal.h | 13 +++++++ - 2 files changed, 68 insertions(+), 12 deletions(-) - ---- a/drivers/thermal/thermal_of.c -+++ b/drivers/thermal/thermal_of.c -@@ -246,7 +246,7 @@ static void thermal_of_parameters_init(s - { - int coef[2]; - int ncoef = ARRAY_SIZE(coef); -- int prop, ret; -+ int prop; - - tzp->no_hwmon = true; - -@@ -258,14 +258,11 @@ static void thermal_of_parameters_init(s - * thermal zone. Thus, we are considering only the first two - * values as slope and offset. - */ -- ret = of_property_read_u32_array(np, "coefficients", coef, ncoef); -- if (ret) { -- coef[0] = 1; -- coef[1] = 0; -+ if (!of_property_read_u32_array(np, "coefficients", coef, ncoef)) { -+ tzp->slope = coef[0]; -+ tzp->offset = coef[1]; - } - -- tzp->slope = coef[0]; -- tzp->offset = coef[1]; - } - - static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz) -@@ -459,10 +456,15 @@ static void thermal_of_zone_unregister(s - * zone properties and registers new thermal zone with those - * properties. - * -+ * The passed thermal zone params are treated as default values and ignored if -+ * the related property is found in DT. (DT params have priority to -+ * default values) -+ * - * @sensor: A device node pointer corresponding to the sensor in the device tree - * @id: An integer as sensor identifier - * @data: A private data to be stored in the thermal zone dedicated private area - * @ops: A set of thermal sensor ops -+ * @tzp: a pointer to the default thermal zone params structure associated with the sensor - * - * Return: a valid thermal zone structure pointer on success. - * - EINVAL: if the device tree thermal description is malformed -@@ -470,11 +472,11 @@ static void thermal_of_zone_unregister(s - * - Other negative errors are returned by the underlying called functions - */ - static struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, -- const struct thermal_zone_device_ops *ops) -+ const struct thermal_zone_device_ops *ops, -+ struct thermal_zone_params *tzp) - { - struct thermal_zone_device *tz; - struct thermal_trip *trips; -- struct thermal_zone_params tzp = {}; - struct thermal_zone_device_ops *of_ops; - struct device_node *np; - int delay, pdelay; -@@ -509,7 +511,7 @@ static struct thermal_zone_device *therm - goto out_kfree_trips; - } - -- thermal_of_parameters_init(np, &tzp); -+ thermal_of_parameters_init(np, tzp); - - of_ops->bind = thermal_of_bind; - of_ops->unbind = thermal_of_unbind; -@@ -517,7 +519,7 @@ static struct thermal_zone_device *therm - mask = GENMASK_ULL((ntrips) - 1, 0); - - tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips, -- mask, data, of_ops, &tzp, -+ mask, data, of_ops, tzp, - pdelay, delay); - if (IS_ERR(tz)) { - ret = PTR_ERR(tz); -@@ -572,6 +574,7 @@ static int devm_thermal_of_zone_match(st - struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int sensor_id, void *data, - const struct thermal_zone_device_ops *ops) - { -+ struct thermal_zone_params tzp = { .slope = 1 }; - struct thermal_zone_device **ptr, *tzd; - - ptr = devres_alloc(devm_thermal_of_zone_release, sizeof(*ptr), -@@ -579,7 +582,7 @@ struct thermal_zone_device *devm_thermal - if (!ptr) - return ERR_PTR(-ENOMEM); - -- tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops); -+ tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops, &tzp); - if (IS_ERR(tzd)) { - devres_free(ptr); - return tzd; -@@ -593,6 +596,46 @@ struct thermal_zone_device *devm_thermal - EXPORT_SYMBOL_GPL(devm_thermal_of_zone_register); - - /** -+ * devm_thermal_of_zone_register_with_params - register a thermal tied with the sensor life cycle -+ * with default params -+ * -+ * This function is the device version of the thermal_of_zone_register() function. -+ * -+ * @dev: a device structure pointer to sensor to be tied with the thermal zone OF life cycle -+ * @sensor_id: the sensor identifier -+ * @data: a pointer to a private data to be stored in the thermal zone 'devdata' field -+ * @ops: a pointer to the ops structure associated with the sensor -+ * @tzp: a pointer to the default thermal zone params structure associated with the sensor -+ * -+ * The thermal zone params are treated as default values and ignored if the related property is -+ * found in DT. (DT params have priority to default values) -+ */ -+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int sensor_id, -+ void *data, -+ const struct thermal_zone_device_ops *ops, -+ struct thermal_zone_params *tzp) -+{ -+ struct thermal_zone_device **ptr, *tzd; -+ -+ ptr = devres_alloc(devm_thermal_of_zone_release, sizeof(*ptr), -+ GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops, tzp); -+ if (IS_ERR(tzd)) { -+ devres_free(ptr); -+ return tzd; -+ } -+ -+ *ptr = tzd; -+ devres_add(dev, ptr); -+ -+ return tzd; -+} -+EXPORT_SYMBOL_GPL(devm_thermal_of_zone_register_with_params); -+ -+/** - * devm_thermal_of_zone_unregister - Resource managed version of - * thermal_of_zone_unregister(). - * @dev: Device for which which resource was allocated. ---- a/include/linux/thermal.h -+++ b/include/linux/thermal.h -@@ -263,6 +263,10 @@ struct thermal_zone_params { - #ifdef CONFIG_THERMAL_OF - struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data, - const struct thermal_zone_device_ops *ops); -+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int id, -+ void *data, -+ const struct thermal_zone_device_ops *ops, -+ struct thermal_zone_params *tzp); - - void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz); - -@@ -274,6 +278,15 @@ struct thermal_zone_device *devm_thermal - { - return ERR_PTR(-ENOTSUPP); - } -+ -+static inline -+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int id, -+ void *data, -+ const struct thermal_zone_device_ops *ops, -+ struct thermal_zone_params *tzp) -+{ -+ return ERR_PTR(-ENOTSUPP); -+} - - static inline void devm_thermal_of_zone_unregister(struct device *dev, - struct thermal_zone_device *tz) From 3b1fc6661a995fd02f1fc05bc83e6c1aeea1cf00 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 1 Sep 2025 18:19:57 +0200 Subject: [PATCH 037/128] airoha: backport patch adding support for AN7581 Ethernet PHY Backport patch adding support for AN7581 Ethernet PHY based on the same Mediatek embedded Switch PHY. Link: https://github.com/openwrt/openwrt/pull/19816 (cherry picked from commit 0adaeff5eea122891d255e9ed743c617e91d716e) [ rework backported patch ] Signed-off-by: Christian Marangi --- ...atek-add-Airoha-PHY-ID-to-SoC-driver.patch | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch diff --git a/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch b/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch new file mode 100644 index 0000000000..5d8e14aeea --- /dev/null +++ b/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch @@ -0,0 +1,130 @@ +From 6a325aed130bb68790e765f923e76ec5669d2da7 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 10 Apr 2025 12:04:04 +0200 +Subject: [PATCH 2/2] net: phy: mediatek: add Airoha PHY ID to SoC driver + +Airoha AN7581 SoC ship with a Switch based on the MT753x Switch embedded +in other SoC like the MT7581 and the MT7988. Similar to these they +require configuring some pin to enable LED PHYs. + +Add support for the PHY ID for the Airoha embedded Switch and define a +simple probe function to toggle these pins. Also fill the LED functions +and add dedicated function to define LED polarity. + +Reviewed-by: Andrew Lunn +Signed-off-by: Christian Marangi +Link: https://patch.msgid.link/20250410100410.348-2-ansuelsmth@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/Kconfig | 4 +- + drivers/net/phy/mediatek-ge-soc.c | 62 +++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -15,8 +15,9 @@ config MEDIATEK_GE_PHY + + config MEDIATEK_GE_SOC_PHY + tristate "MediaTek SoC Ethernet PHYs" +- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST +- depends on NVMEM_MTK_EFUSE ++ depends on ARM64 || COMPILE_TEST ++ depends on ARCH_AIROHA || (ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || \ ++ COMPILE_TEST + help + Supports MediaTek SoC built-in Gigabit Ethernet PHYs. + +--- a/drivers/net/phy/mediatek-ge-soc.c ++++ b/drivers/net/phy/mediatek-ge-soc.c +@@ -10,8 +10,11 @@ + + #include "mtk.h" + ++#define MTK_PHY_MAX_LEDS 2 ++ + #define MTK_GPHY_ID_MT7981 0x03a29461 + #define MTK_GPHY_ID_MT7988 0x03a29481 ++#define MTK_GPHY_ID_AN7581 0x03a294c1 + + #define MTK_EXT_PAGE_ACCESS 0x1f + #define MTK_PHY_PAGE_STANDARD 0x0000 +@@ -1405,6 +1408,53 @@ static int mt7981_phy_probe(struct phy_d + return mt798x_phy_calibration(phydev); + } + ++static int an7581_phy_probe(struct phy_device *phydev) ++{ ++ struct mtk_socphy_priv *priv; ++ struct pinctrl *pinctrl; ++ ++ /* Toggle pinctrl to enable PHY LED */ ++ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); ++ if (IS_ERR(pinctrl)) ++ dev_err(&phydev->mdio.bus->dev, ++ "Failed to setup PHY LED pinctrl\n"); ++ ++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ phydev->priv = priv; ++ ++ return 0; ++} ++ ++static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index, ++ unsigned long modes) ++{ ++ u32 mode; ++ u16 val; ++ ++ if (index >= MTK_PHY_MAX_LEDS) ++ return -EINVAL; ++ ++ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { ++ switch (mode) { ++ case PHY_LED_ACTIVE_LOW: ++ val = MTK_PHY_LED_ON_POLARITY; ++ break; ++ case PHY_LED_ACTIVE_HIGH: ++ val = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? ++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, ++ MTK_PHY_LED_ON_POLARITY, val); ++} ++ + static struct phy_driver mtk_socphy_driver[] = { + { + PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), +@@ -1440,6 +1490,17 @@ static struct phy_driver mtk_socphy_driv + .led_hw_control_set = mt798x_phy_led_hw_control_set, + .led_hw_control_get = mt798x_phy_led_hw_control_get, + }, ++ { ++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581), ++ .name = "Airoha AN7581 PHY", ++ .probe = an7581_phy_probe, ++ .led_blink_set = mt798x_phy_led_blink_set, ++ .led_brightness_set = mt798x_phy_led_brightness_set, ++ .led_hw_is_supported = mt798x_phy_led_hw_is_supported, ++ .led_hw_control_set = mt798x_phy_led_hw_control_set, ++ .led_hw_control_get = mt798x_phy_led_hw_control_get, ++ .led_polarity_set = an7581_phy_led_polarity_set, ++ }, + }; + + module_phy_driver(mtk_socphy_driver); +@@ -1447,6 +1508,7 @@ module_phy_driver(mtk_socphy_driver); + static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { + { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) }, + { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) }, ++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581) }, + { } + }; + From bac7ee02f93bec5886e2eb73e383442509c6a828 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 1 Sep 2025 18:23:58 +0200 Subject: [PATCH 038/128] airoha: backport trivial fixes for pinctrl and ethernet driver Backport trivial fixes from upstream related to pinctrl and ethernet driver. Link: https://github.com/openwrt/openwrt/pull/19816 Signed-off-by: Christian Marangi (cherry picked from commit 354d7472d5c6b06e0c11606e1b9104a5f7d24374) --- ...ix-wrong-PHY-LED-mapping-and-PHY2-LE.patch | 435 ++++++++++++++++++ ...ix-return-value-in-pinconf-callbacks.patch | 50 ++ ...-channel-configuration-for-ETS-Qdisc.patch | 36 ++ ...-channel-configuration-for-ETS-Qdisc.patch | 104 ----- 4 files changed, 521 insertions(+), 104 deletions(-) create mode 100644 target/linux/airoha/patches-6.6/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch create mode 100644 target/linux/airoha/patches-6.6/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch create mode 100644 target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch delete mode 100644 target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch diff --git a/target/linux/airoha/patches-6.6/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch b/target/linux/airoha/patches-6.6/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch new file mode 100644 index 0000000000..386532781f --- /dev/null +++ b/target/linux/airoha/patches-6.6/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch @@ -0,0 +1,435 @@ +From 457d9772e8a5cdae64f66b5f7d5b0247365191ec Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 1 Apr 2025 15:50:21 +0200 +Subject: [PATCH] pinctrl: airoha: fix wrong PHY LED mapping and PHY2 LED + defines + +The current PHY2 LED define are wrong and actually set BITs outside the +related mask. Fix it and set the correct value. While at it, also use +FIELD_PREP_CONST macro to make it simple to understand what values are +actually applied for the mask. + +Also fix wrong PHY LED mapping. The SoC Switch supports up to 4 port but +the register define mapping for 5 PHY port, starting from 0. The mapping +was wrongly defined starting from PHY1. Reorder the function group to +start from PHY0. PHY4 is actually never supported as we don't have a +GPIO pin to assign. + +Cc: stable@vger.kernel.org +Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") +Reviewed-by: Benjamin Larsson +Signed-off-by: Christian Marangi +Acked-by: Lorenzo Bianconi +Link: https://lore.kernel.org/20250401135026.18018-1-ansuelsmth@gmail.com +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 159 ++++++++++------------ + 1 file changed, 70 insertions(+), 89 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -106,39 +107,19 @@ + #define REG_LAN_LED1_MAPPING 0x0280 + + #define LAN4_LED_MAPPING_MASK GENMASK(18, 16) +-#define LAN4_PHY4_LED_MAP BIT(18) +-#define LAN4_PHY2_LED_MAP BIT(17) +-#define LAN4_PHY1_LED_MAP BIT(16) +-#define LAN4_PHY0_LED_MAP 0 +-#define LAN4_PHY3_LED_MAP GENMASK(17, 16) ++#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n)) + + #define LAN3_LED_MAPPING_MASK GENMASK(14, 12) +-#define LAN3_PHY4_LED_MAP BIT(14) +-#define LAN3_PHY2_LED_MAP BIT(13) +-#define LAN3_PHY1_LED_MAP BIT(12) +-#define LAN3_PHY0_LED_MAP 0 +-#define LAN3_PHY3_LED_MAP GENMASK(13, 12) ++#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n)) + + #define LAN2_LED_MAPPING_MASK GENMASK(10, 8) +-#define LAN2_PHY4_LED_MAP BIT(12) +-#define LAN2_PHY2_LED_MAP BIT(11) +-#define LAN2_PHY1_LED_MAP BIT(10) +-#define LAN2_PHY0_LED_MAP 0 +-#define LAN2_PHY3_LED_MAP GENMASK(11, 10) ++#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n)) + + #define LAN1_LED_MAPPING_MASK GENMASK(6, 4) +-#define LAN1_PHY4_LED_MAP BIT(6) +-#define LAN1_PHY2_LED_MAP BIT(5) +-#define LAN1_PHY1_LED_MAP BIT(4) +-#define LAN1_PHY0_LED_MAP 0 +-#define LAN1_PHY3_LED_MAP GENMASK(5, 4) ++#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n)) + + #define LAN0_LED_MAPPING_MASK GENMASK(2, 0) +-#define LAN0_PHY4_LED_MAP BIT(3) +-#define LAN0_PHY2_LED_MAP BIT(2) +-#define LAN0_PHY1_LED_MAP BIT(1) +-#define LAN0_PHY0_LED_MAP 0 +-#define LAN0_PHY3_LED_MAP GENMASK(2, 1) ++#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n)) + + /* CONF */ + #define REG_I2C_SDA_E2 0x001c +@@ -1470,8 +1451,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY1_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1485,8 +1466,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY1_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1500,8 +1481,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY1_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1515,8 +1496,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY1_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, +@@ -1534,8 +1515,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY2_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1549,8 +1530,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY2_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1564,8 +1545,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY2_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1579,8 +1560,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY2_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, +@@ -1598,8 +1579,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY3_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1613,8 +1594,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY3_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1628,8 +1609,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY3_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1643,8 +1624,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY3_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, +@@ -1662,8 +1643,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY4_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1677,8 +1658,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY4_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1692,8 +1673,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY4_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1707,8 +1688,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED0_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY4_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, +@@ -1726,8 +1707,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY1_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1741,8 +1722,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY1_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1756,8 +1737,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY1_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, { +@@ -1771,8 +1752,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY1_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(0) + }, + .regmap_size = 2, + }, +@@ -1790,8 +1771,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY2_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1805,8 +1786,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY2_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1820,8 +1801,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY2_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, { +@@ -1835,8 +1816,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY2_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(1) + }, + .regmap_size = 2, + }, +@@ -1854,8 +1835,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY3_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1869,8 +1850,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY3_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1884,8 +1865,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY3_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, { +@@ -1899,8 +1880,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY3_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(2) + }, + .regmap_size = 2, + }, +@@ -1918,8 +1899,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY4_LED_MAP ++ LAN0_LED_MAPPING_MASK, ++ LAN0_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1933,8 +1914,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY4_LED_MAP ++ LAN1_LED_MAPPING_MASK, ++ LAN1_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1948,8 +1929,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY4_LED_MAP ++ LAN2_LED_MAPPING_MASK, ++ LAN2_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, { +@@ -1963,8 +1944,8 @@ static const struct airoha_pinctrl_func_ + .regmap[1] = { + AIROHA_FUNC_MUX, + REG_LAN_LED1_MAPPING, +- LAN4_LED_MAPPING_MASK, +- LAN4_PHY4_LED_MAP ++ LAN3_LED_MAPPING_MASK, ++ LAN3_PHY_LED_MAP(3) + }, + .regmap_size = 2, + }, diff --git a/target/linux/airoha/patches-6.6/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch b/target/linux/airoha/patches-6.6/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch new file mode 100644 index 0000000000..f12b941e74 --- /dev/null +++ b/target/linux/airoha/patches-6.6/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch @@ -0,0 +1,50 @@ +From 563fcd6475931c5c8c652a4dd548256314cc87ed Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Aug 2025 14:14:18 +0200 +Subject: [PATCH] pinctrl: airoha: Fix return value in pinconf callbacks + +Pinctrl stack requires ENOTSUPP error code if the parameter is not +supported by the pinctrl driver. Fix the returned error code in pinconf +callbacks if the operation is not supported. + +Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/20250822-airoha-pinconf-err-val-fix-v1-1-87b4f264ced2@kernel.org +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -2696,7 +2696,7 @@ static int airoha_pinconf_get(struct pin + arg = 1; + break; + default: +- return -EOPNOTSUPP; ++ return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); +@@ -2790,7 +2790,7 @@ static int airoha_pinconf_set(struct pin + break; + } + default: +- return -EOPNOTSUPP; ++ return -ENOTSUPP; + } + } + +@@ -2807,10 +2807,10 @@ static int airoha_pinconf_group_get(stru + if (airoha_pinconf_get(pctrl_dev, + airoha_pinctrl_groups[group].pins[i], + config)) +- return -EOPNOTSUPP; ++ return -ENOTSUPP; + + if (i && cur_config != *config) +- return -EOPNOTSUPP; ++ return -ENOTSUPP; + + cur_config = *config; + } diff --git a/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch b/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch new file mode 100644 index 0000000000..42873cf004 --- /dev/null +++ b/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch @@ -0,0 +1,36 @@ +From 7d0da8f862340c5f42f0062b8560b8d0971a6ac4 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 7 Jan 2025 23:26:28 +0100 +Subject: [PATCH] net: airoha: Fix channel configuration for ETS Qdisc + +Limit ETS QoS channel to AIROHA_NUM_QOS_CHANNELS in +airoha_tc_setup_qdisc_ets() in order to align the configured channel to +the value set in airoha_dev_select_queue(). + +Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250107-airoha-ets-fix-chan-v1-1-97f66ed3a068@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2064,11 +2064,14 @@ static int airoha_qdma_get_tx_ets_stats( + static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, + struct tc_ets_qopt_offload *opt) + { +- int channel = TC_H_MAJ(opt->handle) >> 16; ++ int channel; + + if (opt->parent == TC_H_ROOT) + return -EINVAL; + ++ channel = TC_H_MAJ(opt->handle) >> 16; ++ channel = channel % AIROHA_NUM_QOS_CHANNELS; ++ + switch (opt->command) { + case TC_ETS_REPLACE: + return airoha_qdma_set_tx_ets_sched(port, channel, opt); diff --git a/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch b/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch deleted file mode 100644 index 21896d7fa9..0000000000 --- a/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch +++ /dev/null @@ -1,104 +0,0 @@ -From patchwork Tue Jan 7 22:26:28 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Lorenzo Bianconi -X-Patchwork-Id: 13929634 -X-Patchwork-Delegate: kuba@kernel.org -Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org - [10.30.226.201]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.subspace.kernel.org (Postfix) with ESMTPS id A82271A3035 - for ; Tue, 7 Jan 2025 22:27:02 +0000 (UTC) -Authentication-Results: smtp.subspace.kernel.org; - arc=none smtp.client-ip=10.30.226.201 -ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; - t=1736288822; cv=none; - b=XZhiaYPBxLiUvOxWeE7zfuFI3fOmu5SLoHdLPFXNXBtvmZWWIohKA8AeGI37v/l+0Du9JwGRKMkb19v/IxDJtMXkyTJXHHKYhXWaNFpj/pFRk9C4WsIa29OCqanfA+yXUQLJyGVopMLsxfcbzznozIANWbaO0NVBHyZZSH9eaYU= -ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; - s=arc-20240116; t=1736288822; c=relaxed/simple; - bh=/BuvRwLGk+7by7QeOu7n+QgJ5Sk03TO9WCsGbgTs3sE=; - h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; - b=jHXwJfD+6o5WvM5xaeL35BI6hshOViNtg+mSqf5q8jH9l3k6FctngCkEYdxJzcYaw9aEEigC8/FZiHoPrIXGyJA29kTWkYSjj7rtagL1aSIWPGAuSJaaAUv2Bj8jxUmIlJxb23wTleEv/Pwnz+1oSf3yZ7g46h9gv4RZaU8yySg= -ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; - dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org - header.b=Gx3FMrdJ; arc=none smtp.client-ip=10.30.226.201 -Authentication-Results: smtp.subspace.kernel.org; - dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org - header.b="Gx3FMrdJ" -Received: by smtp.kernel.org (Postfix) with ESMTPSA id E1A57C4CED6; - Tue, 7 Jan 2025 22:27:01 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; - s=k20201202; t=1736288822; - bh=/BuvRwLGk+7by7QeOu7n+QgJ5Sk03TO9WCsGbgTs3sE=; - h=From:Date:Subject:To:Cc:From; - b=Gx3FMrdJH+xaen2jSRnu523A40ZOBBFaj896IwBv1PeosUm+eiUCx+K3Qz9CAisX0 - Bj4ohheTiHZDQHZelhKF3ZFTfVQUyYiLiard4x5QdylW2YZA0cpwJe64TMf7CsHbrT - NHCF7nrJPJUwOhDoS/YVdeTw/bb9DlM95aKGSfyH0cy7Kdmjz55No3Im9bCSKcgyaX - Y/lcRZglFjbLyiC3LS06AtM0KOyhUxQKrH+ZWpx5E/sdOEj3SRTJ/I+K8o3m75Kzsn - wKRft5pBwfhGEIrJXrFR4f73QwnxJ6eSUrfjYV8k4mFQpH3nB0hKLi2DpvYPim5dj/ - ADsdcP6QPwokg== -From: Lorenzo Bianconi -Date: Tue, 07 Jan 2025 23:26:28 +0100 -Subject: [PATCH net-next] net: airoha: Fix channel configuration for ETS - Qdisc -Precedence: bulk -X-Mailing-List: netdev@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -MIME-Version: 1.0 -Message-Id: <20250107-airoha-ets-fix-chan-v1-1-97f66ed3a068@kernel.org> -X-B4-Tracking: v=1; b=H4sIABOqfWcC/x2MSwqAMAwFryJZG6ifVvAq4qLUaLNRaUSE0rsbX - Q5v3mQQSkwCY5Uh0c3Cx67Q1BWE6PeNkBdlaE1rTWMG9JyO6JEuwZUf/CSkzobgw+AW14M+z0S - 6/dVpLuUFNrlCSGUAAAA= -X-Change-ID: 20250107-airoha-ets-fix-chan-e35ccac76d64 -To: Felix Fietkau , Sean Wang , - Mark Lee , Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Matthias Brugger , - AngeloGioacchino Del Regno -Cc: linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, netdev@vger.kernel.org, - Lorenzo Bianconi -X-Mailer: b4 0.14.2 -X-Patchwork-Delegate: kuba@kernel.org - -Limit ETS QoS channel to AIROHA_NUM_QOS_CHANNELS in -airoha_tc_setup_qdisc_ets() in order to align the configured channel to -the value set in airoha_dev_select_queue(). - -Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Michal Swiatkowski ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - - ---- -base-commit: a1942da8a38717ddd9b4c132f59e1657c85c1432 -change-id: 20250107-airoha-ets-fix-chan-e35ccac76d64 - -Best regards, - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2064,11 +2064,14 @@ static int airoha_qdma_get_tx_ets_stats( - static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, - struct tc_ets_qopt_offload *opt) - { -- int channel = TC_H_MAJ(opt->handle) >> 16; -+ int channel; - - if (opt->parent == TC_H_ROOT) - return -EINVAL; - -+ channel = TC_H_MAJ(opt->handle) >> 16; -+ channel = channel % AIROHA_NUM_QOS_CHANNELS; -+ - switch (opt->command) { - case TC_ETS_REPLACE: - return airoha_qdma_set_tx_ets_sched(port, channel, opt); From 671f4d53acf183af80641362f5b6af0295083277 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 1 Sep 2025 18:24:57 +0200 Subject: [PATCH 039/128] airoha: major backport of Airoha Ethernet driver feature support Major backport of upstream patch for support of multiple feature of the Airoha Ethernet driver. Feature backported are TSO, Jumbo packet, Offload and initial Wlan Offload support. Link: https://github.com/openwrt/openwrt/pull/19816 (cherry picked from commit 9d3009f426d5b5ca4eb120989d7d5776175a97d3) [ add missing kconfig flag ] Signed-off-by: Christian Marangi --- target/linux/airoha/an7581/config-6.6 | 1 + ...min-max-packet-len-configuration-in-.patch | 59 ++ ...-net-airoha-Enable-Rx-Scatter-Gather.patch | 170 +++++ ...oduce-airoha_dev_change_mtu-callback.patch | 47 ++ ...15-net-airoha-Increase-max-mtu-to-9k.patch | 26 + ...an4-support-in-airoha_qdma_get_gdm_p.patch | 29 + ...able-TSO-Scatter-Gather-for-LAN-port.patch | 27 + ...ev-dsa_ptr-check-in-airoha_get_dsa_t.patch | 47 ++ ...net-airoha-fix-CONFIG_DEBUG_FS-check.patch | 35 + ...id-report-in-airoha_tc_get_htb_get_l.patch | 77 +++ ...et-airoha-Fix-ETS-priomap-validation.patch | 58 ++ ...ate-egress-gdm-port-in-airoha_ppe_fo.patch | 100 +++ ...6-net-airoha-Add-l2_flows-rhashtable.patch | 207 ++++++ ...iroha-Add-L2-hw-acceleration-support.patch | 253 +++++++ ...-Add-matchall-filter-offload-support.patch | 405 +++++++++++ ...oha-Introduce-airoha_irq_bank-struct.patch | 292 ++++++++ ...e-multiple-IRQ-lines-support-in-airo.patch | 379 +++++++++++ ...issing-field-to-ppe_mbox_data-struct.patch | 48 ++ ...age-recycling-in-airoha_qdma_rx_proc.patch | 72 ++ ...ove-memory-allocation-in-airoha_npu_.patch | 196 ++++++ ...-Add-FLOW_CLS_STATS-callback-support.patch | 633 ++++++++++++++++++ ...-airoha-ppe-Disable-packet-keepalive.patch | 28 + ...t-store-hfwd-references-in-airoha_qd.patch | 57 ++ ...he-capability-to-allocate-hwfd-buffe.patch | 79 +++ ...he-capability-to-allocate-hfwd-descr.patch | 82 +++ ...n-error-handling-path-in-airoha_allo.patch | 42 ++ ...itialize-PPE-UPDMEM-source-mac-table.patch | 122 ++++ ...-IPv6-hw-acceleration-in-bridge-mode.patch | 64 ++ ...smac_id-configuration-in-bridge-mode.patch | 32 + ...net-airoha-Add-PPPoE-offload-support.patch | 87 +++ ...16-net-airoha-Enable-RX-queues-16-31.patch | 28 + ...s-check-return-value-from-airoha_ppe.patch | 32 + ...te-number-of-descriptors-according-t.patch | 77 +++ ...rentiate-hwfd-buffer-size-for-QDMA0-.patch | 64 ++ ...PE-table-access-in-airoha_ppe_debugf.patch | 92 +++ ...o-not-invalid-PPE-entries-in-case-of.patch | 42 ++ ...-resource-set-range-and-size-helpers.patch | 73 ++ ...Add-functions-to-parse-memory-region.patch | 163 +++++ ...dd-NPU-wlan-memory-initialization-co.patch | 179 +++++ ...dd-wlan_-send-get-_msg-NPU-callbacks.patch | 139 ++++ ...pu-Add-wlan-irq-management-callbacks.patch | 74 ++ ...ead-NPU-wlan-interrupt-lines-from-th.patch | 58 ++ ...pu-Enable-core-3-for-WiFi-offloading.patch | 28 + ...t-airoha-Add-airoha_offload.h-header.patch | 416 ++++++++++++ ...airoha-Add-wlan-flowtable-TX-offload.patch | 198 ++++++ ...on-airoha_eth-struct-in-airoha_ppe_f.patch | 95 +++ ...Add-airoha_ppe_dev-struct-definition.patch | 223 ++++++ ...duce-check_skb-callback-in-ppe_dev-o.patch | 207 ++++++ ...-channel-configuration-for-ETS-Qdisc.patch | 2 +- 49 files changed, 5943 insertions(+), 1 deletion(-) create mode 100644 target/linux/airoha/patches-6.6/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch create mode 100644 target/linux/airoha/patches-6.6/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch create mode 100644 target/linux/airoha/patches-6.6/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch create mode 100644 target/linux/airoha/patches-6.6/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch create mode 100644 target/linux/airoha/patches-6.6/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch create mode 100644 target/linux/airoha/patches-6.6/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch create mode 100644 target/linux/airoha/patches-6.6/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch create mode 100644 target/linux/airoha/patches-6.6/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch create mode 100644 target/linux/airoha/patches-6.6/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch create mode 100644 target/linux/airoha/patches-6.6/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch create mode 100644 target/linux/airoha/patches-6.6/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch create mode 100644 target/linux/airoha/patches-6.6/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch create mode 100644 target/linux/airoha/patches-6.6/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch create mode 100644 target/linux/airoha/patches-6.6/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch create mode 100644 target/linux/airoha/patches-6.6/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch create mode 100644 target/linux/airoha/patches-6.6/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch create mode 100644 target/linux/airoha/patches-6.6/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch create mode 100644 target/linux/airoha/patches-6.6/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch create mode 100644 target/linux/airoha/patches-6.6/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch create mode 100644 target/linux/airoha/patches-6.6/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch create mode 100644 target/linux/airoha/patches-6.6/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch create mode 100644 target/linux/airoha/patches-6.6/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch create mode 100644 target/linux/airoha/patches-6.6/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch create mode 100644 target/linux/airoha/patches-6.6/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch create mode 100644 target/linux/airoha/patches-6.6/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch create mode 100644 target/linux/airoha/patches-6.6/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch create mode 100644 target/linux/airoha/patches-6.6/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch create mode 100644 target/linux/airoha/patches-6.6/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch create mode 100644 target/linux/airoha/patches-6.6/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch create mode 100644 target/linux/airoha/patches-6.6/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch create mode 100644 target/linux/airoha/patches-6.6/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch create mode 100644 target/linux/airoha/patches-6.6/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch create mode 100644 target/linux/airoha/patches-6.6/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch create mode 100644 target/linux/airoha/patches-6.6/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch create mode 100644 target/linux/airoha/patches-6.6/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch create mode 100644 target/linux/airoha/patches-6.6/083-01-v6.13-resource-Add-resource-set-range-and-size-helpers.patch create mode 100644 target/linux/airoha/patches-6.6/083-02-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch create mode 100644 target/linux/airoha/patches-6.6/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch create mode 100644 target/linux/airoha/patches-6.6/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch create mode 100644 target/linux/airoha/patches-6.6/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch create mode 100644 target/linux/airoha/patches-6.6/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch create mode 100644 target/linux/airoha/patches-6.6/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch create mode 100644 target/linux/airoha/patches-6.6/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch create mode 100644 target/linux/airoha/patches-6.6/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch create mode 100644 target/linux/airoha/patches-6.6/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch create mode 100644 target/linux/airoha/patches-6.6/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch create mode 100644 target/linux/airoha/patches-6.6/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 44f86a3b39..358a953393 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -388,6 +388,7 @@ CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_FLAGS=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NET_AIROHA=y +# CONFIG_NET_AIROHA_FLOW_STATS is not set CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_MT7530=y diff --git a/target/linux/airoha/patches-6.6/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch b/target/linux/airoha/patches-6.6/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch new file mode 100644 index 0000000000..03654f4450 --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch @@ -0,0 +1,59 @@ +From 54d989d58d2ac87c8504c2306ba8b4957c60e8dc Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 15:21:08 +0100 +Subject: [PATCH 1/6] net: airoha: Move min/max packet len configuration in + airoha_dev_open() + +In order to align max allowed packet size to the configured mtu, move +REG_GDM_LEN_CFG configuration in airoha_dev_open routine. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-1-283ebc61120e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -138,15 +138,10 @@ static void airoha_fe_maccr_init(struct + { + int p; + +- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { ++ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) + airoha_fe_set(eth, REG_GDM_FWD_CFG(p), + GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | + GDM_DROP_CRC_ERR); +- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), +- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, +- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | +- FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); +- } + + airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, + FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); +@@ -1521,9 +1516,9 @@ static void airoha_update_hw_stats(struc + + static int airoha_dev_open(struct net_device *dev) + { ++ int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN; + struct airoha_gdm_port *port = netdev_priv(dev); + struct airoha_qdma *qdma = port->qdma; +- int err; + + netif_tx_start_all_queues(dev); + err = airoha_set_vip_for_gdm_port(port, true); +@@ -1537,6 +1532,11 @@ static int airoha_dev_open(struct net_de + airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), + GDM_STAG_EN_MASK); + ++ airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), ++ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, ++ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | ++ FIELD_PREP(GDM_LONG_LEN_MASK, len)); ++ + airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, + GLOBAL_CFG_TX_DMA_EN_MASK | + GLOBAL_CFG_RX_DMA_EN_MASK); diff --git a/target/linux/airoha/patches-6.6/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch b/target/linux/airoha/patches-6.6/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch new file mode 100644 index 0000000000..cea179c274 --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch @@ -0,0 +1,170 @@ +From e12182ddb6e712951d21a50e2c8ccd700e41a40c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 15:21:09 +0100 +Subject: [PATCH 2/6] net: airoha: Enable Rx Scatter-Gather + +EN7581 SoC can receive 9k frames. Enable the reception of Scatter-Gather +(SG) frames. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-2-283ebc61120e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 68 ++++++++++++++--------- + drivers/net/ethernet/airoha/airoha_eth.h | 1 + + drivers/net/ethernet/airoha/airoha_regs.h | 5 ++ + 3 files changed, 48 insertions(+), 26 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -615,10 +615,10 @@ static int airoha_qdma_rx_process(struct + struct airoha_qdma_desc *desc = &q->desc[q->tail]; + u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); + dma_addr_t dma_addr = le32_to_cpu(desc->addr); ++ struct page *page = virt_to_head_page(e->buf); + u32 desc_ctrl = le32_to_cpu(desc->ctrl); + struct airoha_gdm_port *port; +- struct sk_buff *skb; +- int len, p; ++ int data_len, len, p; + + if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) + break; +@@ -636,30 +636,41 @@ static int airoha_qdma_rx_process(struct + dma_sync_single_for_cpu(eth->dev, dma_addr, + SKB_WITH_OVERHEAD(q->buf_size), dir); + ++ data_len = q->skb ? q->buf_size ++ : SKB_WITH_OVERHEAD(q->buf_size); ++ if (data_len < len) ++ goto free_frag; ++ + p = airoha_qdma_get_gdm_port(eth, desc); +- if (p < 0 || !eth->ports[p]) { +- page_pool_put_full_page(q->page_pool, +- virt_to_head_page(e->buf), +- true); +- continue; +- } ++ if (p < 0 || !eth->ports[p]) ++ goto free_frag; + + port = eth->ports[p]; +- skb = napi_build_skb(e->buf, q->buf_size); +- if (!skb) { +- page_pool_put_full_page(q->page_pool, +- virt_to_head_page(e->buf), +- true); +- break; ++ if (!q->skb) { /* first buffer */ ++ q->skb = napi_build_skb(e->buf, q->buf_size); ++ if (!q->skb) ++ goto free_frag; ++ ++ __skb_put(q->skb, len); ++ skb_mark_for_recycle(q->skb); ++ q->skb->dev = port->dev; ++ q->skb->protocol = eth_type_trans(q->skb, port->dev); ++ q->skb->ip_summed = CHECKSUM_UNNECESSARY; ++ skb_record_rx_queue(q->skb, qid); ++ } else { /* scattered frame */ ++ struct skb_shared_info *shinfo = skb_shinfo(q->skb); ++ int nr_frags = shinfo->nr_frags; ++ ++ if (nr_frags >= ARRAY_SIZE(shinfo->frags)) ++ goto free_frag; ++ ++ skb_add_rx_frag(q->skb, nr_frags, page, ++ e->buf - page_address(page), len, ++ q->buf_size); + } + +- skb_reserve(skb, 2); +- __skb_put(skb, len); +- skb_mark_for_recycle(skb); +- skb->dev = port->dev; +- skb->protocol = eth_type_trans(skb, skb->dev); +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- skb_record_rx_queue(skb, qid); ++ if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl)) ++ continue; + + if (netdev_uses_dsa(port->dev)) { + /* PPE module requires untagged packets to work +@@ -672,22 +683,27 @@ static int airoha_qdma_rx_process(struct + + if (sptag < ARRAY_SIZE(port->dsa_meta) && + port->dsa_meta[sptag]) +- skb_dst_set_noref(skb, ++ skb_dst_set_noref(q->skb, + &port->dsa_meta[sptag]->dst); + } + + hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); + if (hash != AIROHA_RXD4_FOE_ENTRY) +- skb_set_hash(skb, jhash_1word(hash, 0), ++ skb_set_hash(q->skb, jhash_1word(hash, 0), + PKT_HASH_TYPE_L4); + + reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); + if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) + airoha_ppe_check_skb(eth->ppe, hash); + +- napi_gro_receive(&q->napi, skb); +- + done++; ++ napi_gro_receive(&q->napi, q->skb); ++ q->skb = NULL; ++ continue; ++free_frag: ++ page_pool_put_full_page(q->page_pool, page, true); ++ dev_kfree_skb(q->skb); ++ q->skb = NULL; + } + airoha_qdma_fill_rx_queue(q); + +@@ -763,6 +779,7 @@ static int airoha_qdma_init_rx_queue(str + FIELD_PREP(RX_RING_THR_MASK, thr)); + airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, + FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); ++ airoha_qdma_set(qdma, REG_RX_SCATTER_CFG(qid), RX_RING_SG_EN_MASK); + + airoha_qdma_fill_rx_queue(q); + +@@ -1162,7 +1179,6 @@ static int airoha_qdma_hw_init(struct ai + } + + airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, +- GLOBAL_CFG_RX_2B_OFFSET_MASK | + FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | + GLOBAL_CFG_CPU_TXR_RR_MASK | + GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -176,6 +176,7 @@ struct airoha_queue { + + struct napi_struct napi; + struct page_pool *page_pool; ++ struct sk_buff *skb; + }; + + struct airoha_tx_irq_queue { +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -626,10 +626,15 @@ + #define REG_RX_DELAY_INT_IDX(_n) \ + (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) + ++#define REG_RX_SCATTER_CFG(_n) \ ++ (((_n) < 16) ? 0x0214 + ((_n) << 5) : 0x0e14 + (((_n) - 16) << 5)) ++ + #define RX_DELAY_INT_MASK GENMASK(15, 0) + + #define RX_RING_DMA_IDX_MASK GENMASK(15, 0) + ++#define RX_RING_SG_EN_MASK BIT(0) ++ + #define REG_INGRESS_TRTCM_CFG 0x0070 + #define INGRESS_TRTCM_EN_MASK BIT(31) + #define INGRESS_TRTCM_MODE_MASK BIT(30) diff --git a/target/linux/airoha/patches-6.6/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch b/target/linux/airoha/patches-6.6/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch new file mode 100644 index 0000000000..2a4aa08880 --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch @@ -0,0 +1,47 @@ +From 03b1b69f0662c46f258a45e4a7d7837351c11692 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 15:21:10 +0100 +Subject: [PATCH 3/6] net: airoha: Introduce airoha_dev_change_mtu callback + +Add airoha_dev_change_mtu callback to update the MTU of a running +device. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-3-283ebc61120e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1706,6 +1706,20 @@ static void airoha_dev_get_stats64(struc + } while (u64_stats_fetch_retry(&port->stats.syncp, start)); + } + ++static int airoha_dev_change_mtu(struct net_device *dev, int mtu) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_eth *eth = port->qdma->eth; ++ u32 len = ETH_HLEN + mtu + ETH_FCS_LEN; ++ ++ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), ++ GDM_LONG_LEN_MASK, ++ FIELD_PREP(GDM_LONG_LEN_MASK, len)); ++ WRITE_ONCE(dev->mtu, mtu); ++ ++ return 0; ++} ++ + static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) + { +@@ -2398,6 +2412,7 @@ static const struct net_device_ops airoh + .ndo_init = airoha_dev_init, + .ndo_open = airoha_dev_open, + .ndo_stop = airoha_dev_stop, ++ .ndo_change_mtu = airoha_dev_change_mtu, + .ndo_select_queue = airoha_dev_select_queue, + .ndo_start_xmit = airoha_dev_xmit, + .ndo_get_stats64 = airoha_dev_get_stats64, diff --git a/target/linux/airoha/patches-6.6/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch b/target/linux/airoha/patches-6.6/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch new file mode 100644 index 0000000000..8771ff22db --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch @@ -0,0 +1,26 @@ +From 168ef0c1dee83c401896a0bca680e9f97b1ebd64 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 15:21:11 +0100 +Subject: [PATCH 4/6] net: airoha: Increase max mtu to 9k + +EN7581 SoC supports 9k maximum MTU. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-4-283ebc61120e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -20,7 +20,7 @@ + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 + #define AIROHA_MAX_NUM_XSI_RSTS 5 +-#define AIROHA_MAX_MTU 2000 ++#define AIROHA_MAX_MTU 9216 + #define AIROHA_MAX_PACKET_SIZE 2048 + #define AIROHA_NUM_QOS_CHANNELS 4 + #define AIROHA_NUM_QOS_QUEUES 8 diff --git a/target/linux/airoha/patches-6.6/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch b/target/linux/airoha/patches-6.6/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch new file mode 100644 index 0000000000..1c3030afd0 --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch @@ -0,0 +1,29 @@ +From 35ea4f06fd33fc32f556a0c26d1d8340497fa7f8 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 15:38:05 +0100 +Subject: [PATCH 5/6] net: airoha: Fix lan4 support in + airoha_qdma_get_gdm_port() + +EN7581 SoC supports lan{1,4} ports on MT7530 DSA switch. Fix lan4 +reported value in airoha_qdma_get_gdm_port routine. + +Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-airoha-eth-fix-lan4-v1-1-832417da4bb5@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -589,7 +589,7 @@ static int airoha_qdma_get_gdm_port(stru + + sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); + switch (sport) { +- case 0x10 ... 0x13: ++ case 0x10 ... 0x14: + port = 0; + break; + case 0x2 ... 0x4: diff --git a/target/linux/airoha/patches-6.6/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch b/target/linux/airoha/patches-6.6/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch new file mode 100644 index 0000000000..28a85e67ad --- /dev/null +++ b/target/linux/airoha/patches-6.6/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch @@ -0,0 +1,27 @@ +From a202dfe31cae2f2120297a7142385d80a5577d42 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 4 Mar 2025 16:46:40 +0100 +Subject: [PATCH 6/6] net: airoha: Enable TSO/Scatter Gather for LAN port + +Set net_device vlan_features in order to enable TSO and Scatter Gather +for DSA user ports. + +Reviewed-by: Mateusz Polchlopek +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250304-lan-enable-tso-v1-1-b398eb9976ba@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2503,6 +2503,7 @@ static int airoha_alloc_gdm_port(struct + NETIF_F_SG | NETIF_F_TSO | + NETIF_F_HW_TC; + dev->features |= dev->hw_features; ++ dev->vlan_features = dev->hw_features; + dev->dev.of_node = np; + dev->irq = qdma->irq; + SET_NETDEV_DEV(dev, eth->dev); diff --git a/target/linux/airoha/patches-6.6/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch b/target/linux/airoha/patches-6.6/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch new file mode 100644 index 0000000000..7134de9173 --- /dev/null +++ b/target/linux/airoha/patches-6.6/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch @@ -0,0 +1,47 @@ +From e368d2a1e8b6f0926e4e76a56b484249905192f5 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 6 Mar 2025 11:52:20 +0100 +Subject: [PATCH] net: airoha: Fix dev->dsa_ptr check in airoha_get_dsa_tag() + +Fix the following warning reported by Smatch static checker in +airoha_get_dsa_tag routine: + +drivers/net/ethernet/airoha/airoha_eth.c:1722 airoha_get_dsa_tag() +warn: 'dp' isn't an ERR_PTR + +dev->dsa_ptr can't be set to an error pointer, it can just be NULL. +Remove this check since it is already performed in netdev_uses_dsa(). + +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/netdev/Z8l3E0lGOcrel07C@lore-desk/T/#m54adc113fcdd8c5e6c5f65ffd60d8e8b1d483d90 +Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250306-airoha-flowtable-fixes-v1-1-68d3c1296cdd@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1742,18 +1742,13 @@ static u32 airoha_get_dsa_tag(struct sk_ + { + #if IS_ENABLED(CONFIG_NET_DSA) + struct ethhdr *ehdr; +- struct dsa_port *dp; + u8 xmit_tpid; + u16 tag; + + if (!netdev_uses_dsa(dev)) + return 0; + +- dp = dev->dsa_ptr; +- if (IS_ERR(dp)) +- return 0; +- +- if (dp->tag_ops->proto != DSA_TAG_PROTO_MTK) ++ if (dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) + return 0; + + if (skb_cow_head(skb, 0)) diff --git a/target/linux/airoha/patches-6.6/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch b/target/linux/airoha/patches-6.6/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch new file mode 100644 index 0000000000..a8467408ed --- /dev/null +++ b/target/linux/airoha/patches-6.6/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch @@ -0,0 +1,35 @@ +From 08d0185e36ad8bb5902a73711bf114765d282161 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 14 Mar 2025 16:49:59 +0100 +Subject: [PATCH] net: airoha: fix CONFIG_DEBUG_FS check + +The #if check causes a build failure when CONFIG_DEBUG_FS is turned +off: + +In file included from drivers/net/ethernet/airoha/airoha_eth.c:17: +drivers/net/ethernet/airoha/airoha_eth.h:543:5: error: "CONFIG_DEBUG_FS" is not defined, evaluates to 0 [-Werror=undef] + 543 | #if CONFIG_DEBUG_FS + | ^~~~~~~~~~~~~~~ + +Replace it with the correct #ifdef. + +Fixes: 3fe15c640f38 ("net: airoha: Introduce PPE debugfs support") +Signed-off-by: Arnd Bergmann +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250314155009.4114308-1-arnd@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -540,7 +540,7 @@ void airoha_ppe_deinit(struct airoha_eth + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash); + +-#if CONFIG_DEBUG_FS ++#ifdef CONFIG_DEBUG_FS + int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); + #else + static inline int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) diff --git a/target/linux/airoha/patches-6.6/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch b/target/linux/airoha/patches-6.6/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch new file mode 100644 index 0000000000..0a815c17b6 --- /dev/null +++ b/target/linux/airoha/patches-6.6/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch @@ -0,0 +1,77 @@ +From 57b290d97c6150774bf929117ca737a26d8fc33d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 31 Mar 2025 08:52:53 +0200 +Subject: [PATCH 1/2] net: airoha: Fix qid report in + airoha_tc_get_htb_get_leaf_queue() + +Fix the following kernel warning deleting HTB offloaded leafs and/or root +HTB qdisc in airoha_eth driver properly reporting qid in +airoha_tc_get_htb_get_leaf_queue routine. + +$tc qdisc replace dev eth1 root handle 10: htb offload +$tc class add dev eth1 arent 10: classid 10:4 htb rate 100mbit ceil 100mbit +$tc qdisc replace dev eth1 parent 10:4 handle 4: ets bands 8 \ + quanta 1514 3028 4542 6056 7570 9084 10598 12112 +$tc qdisc del dev eth1 root + +[ 55.827864] ------------[ cut here ]------------ +[ 55.832493] WARNING: CPU: 3 PID: 2678 at 0xffffffc0798695a4 +[ 55.956510] CPU: 3 PID: 2678 Comm: tc Tainted: G O 6.6.71 #0 +[ 55.963557] Hardware name: Airoha AN7581 Evaluation Board (DT) +[ 55.969383] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 55.976344] pc : 0xffffffc0798695a4 +[ 55.979851] lr : 0xffffffc079869a20 +[ 55.983358] sp : ffffffc0850536a0 +[ 55.986665] x29: ffffffc0850536a0 x28: 0000000000000024 x27: 0000000000000001 +[ 55.993800] x26: 0000000000000000 x25: ffffff8008b19000 x24: ffffff800222e800 +[ 56.000935] x23: 0000000000000001 x22: 0000000000000000 x21: ffffff8008b19000 +[ 56.008071] x20: ffffff8002225800 x19: ffffff800379d000 x18: 0000000000000000 +[ 56.015206] x17: ffffffbf9ea59000 x16: ffffffc080018000 x15: 0000000000000000 +[ 56.022342] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000001 +[ 56.029478] x11: ffffffc081471008 x10: ffffffc081575a98 x9 : 0000000000000000 +[ 56.036614] x8 : ffffffc08167fd40 x7 : ffffffc08069e104 x6 : ffffff8007f86000 +[ 56.043748] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000001 +[ 56.050884] x2 : 0000000000000000 x1 : 0000000000000250 x0 : ffffff800222c000 +[ 56.058020] Call trace: +[ 56.060459] 0xffffffc0798695a4 +[ 56.063618] 0xffffffc079869a20 +[ 56.066777] __qdisc_destroy+0x40/0xa0 +[ 56.070528] qdisc_put+0x54/0x6c +[ 56.073748] qdisc_graft+0x41c/0x648 +[ 56.077324] tc_get_qdisc+0x168/0x2f8 +[ 56.080978] rtnetlink_rcv_msg+0x230/0x330 +[ 56.085076] netlink_rcv_skb+0x5c/0x128 +[ 56.088913] rtnetlink_rcv+0x14/0x1c +[ 56.092490] netlink_unicast+0x1e0/0x2c8 +[ 56.096413] netlink_sendmsg+0x198/0x3c8 +[ 56.100337] ____sys_sendmsg+0x1c4/0x274 +[ 56.104261] ___sys_sendmsg+0x7c/0xc0 +[ 56.107924] __sys_sendmsg+0x44/0x98 +[ 56.111492] __arm64_sys_sendmsg+0x20/0x28 +[ 56.115580] invoke_syscall.constprop.0+0x58/0xfc +[ 56.120285] do_el0_svc+0x3c/0xbc +[ 56.123592] el0_svc+0x18/0x4c +[ 56.126647] el0t_64_sync_handler+0x118/0x124 +[ 56.131005] el0t_64_sync+0x150/0x154 +[ 56.134660] ---[ end trace 0000000000000000 ]--- + +Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support") +Signed-off-by: Lorenzo Bianconi +Acked-by: Paolo Abeni +Link: https://patch.msgid.link/20250331-airoha-htb-qdisc-offload-del-fix-v1-1-4ea429c2c968@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2356,7 +2356,7 @@ static int airoha_tc_get_htb_get_leaf_qu + return -EINVAL; + } + +- opt->qid = channel; ++ opt->qid = AIROHA_NUM_TX_RING + channel; + + return 0; + } diff --git a/target/linux/airoha/patches-6.6/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch b/target/linux/airoha/patches-6.6/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch new file mode 100644 index 0000000000..118047e43d --- /dev/null +++ b/target/linux/airoha/patches-6.6/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch @@ -0,0 +1,58 @@ +From 367579274f60cb23c570ae5348966ab51e1509a4 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 31 Mar 2025 18:17:31 +0200 +Subject: [PATCH 2/2] net: airoha: Fix ETS priomap validation + +ETS Qdisc schedules SP bands in a priority order assigning band-0 the +highest priority (band-0 > band-1 > .. > band-n) while EN7581 arranges +SP bands in a priority order assigning band-7 the highest priority +(band-7 > band-6, .. > band-n). +Fix priomap check in airoha_qdma_set_tx_ets_sched routine in order to +align ETS Qdisc and airoha_eth driver SP priority ordering. + +Fixes: b56e4d660a96 ("net: airoha: Enforce ETS Qdisc priomap") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Reviewed-by: Davide Caratti +Link: https://patch.msgid.link/20250331-airoha-ets-validate-priomap-v1-1-60a524488672@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2029,7 +2029,7 @@ static int airoha_qdma_set_tx_ets_sched( + struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; + enum tx_sched_mode mode = TC_SCH_SP; + u16 w[AIROHA_NUM_QOS_QUEUES] = {}; +- int i, nstrict = 0, nwrr, qidx; ++ int i, nstrict = 0; + + if (p->bands > AIROHA_NUM_QOS_QUEUES) + return -EINVAL; +@@ -2047,17 +2047,17 @@ static int airoha_qdma_set_tx_ets_sched( + * lowest priorities with respect to SP ones. + * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn + */ +- nwrr = p->bands - nstrict; +- qidx = nstrict && nwrr ? nstrict : 0; +- for (i = 1; i <= p->bands; i++) { +- if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) ++ for (i = 0; i < nstrict; i++) { ++ if (p->priomap[p->bands - i - 1] != i) + return -EINVAL; +- +- qidx = i == nwrr ? 0 : qidx + 1; + } + +- for (i = 0; i < nwrr; i++) ++ for (i = 0; i < p->bands - nstrict; i++) { ++ if (p->priomap[i] != nstrict + i) ++ return -EINVAL; ++ + w[i] = p->weights[nstrict + i]; ++ } + + if (!nstrict) + mode = TC_SCH_WRR8; diff --git a/target/linux/airoha/patches-6.6/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch b/target/linux/airoha/patches-6.6/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch new file mode 100644 index 0000000000..c6ddbde692 --- /dev/null +++ b/target/linux/airoha/patches-6.6/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch @@ -0,0 +1,100 @@ +From 09bccf56db36501ccb1935d921dc24451e9f57dd Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 1 Apr 2025 11:42:30 +0200 +Subject: [PATCH] net: airoha: Validate egress gdm port in + airoha_ppe_foe_entry_prepare() + +Dev pointer in airoha_ppe_foe_entry_prepare routine is not strictly +a device allocated by airoha_eth driver since it is an egress device +and the flowtable can contain even wlan, pppoe or vlan devices. E.g: + +flowtable ft { + hook ingress priority filter + devices = { eth1, lan1, lan2, lan3, lan4, wlan0 } + flags offload ^ + | + "not allocated by airoha_eth" -- +} + +In this case airoha_get_dsa_port() will just return the original device +pointer and we can't assume netdev priv pointer points to an +airoha_gdm_port struct. +Fix the issue validating egress gdm port in airoha_ppe_foe_entry_prepare +routine before accessing net_device priv pointer. + +Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250401-airoha-validate-egress-gdm-port-v4-1-c7315d33ce10@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 13 +++++++++++++ + drivers/net/ethernet/airoha/airoha_eth.h | 3 +++ + drivers/net/ethernet/airoha/airoha_ppe.c | 8 ++++++-- + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2452,6 +2452,19 @@ static void airoha_metadata_dst_free(str + } + } + ++bool airoha_is_valid_gdm_port(struct airoha_eth *eth, ++ struct airoha_gdm_port *port) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { ++ if (eth->ports[i] == port) ++ return true; ++ } ++ ++ return false; ++} ++ + static int airoha_alloc_gdm_port(struct airoha_eth *eth, + struct device_node *np, int index) + { +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -532,6 +532,9 @@ u32 airoha_rmw(void __iomem *base, u32 o + #define airoha_qdma_clear(qdma, offset, val) \ + airoha_rmw((qdma)->regs, (offset), (val), 0) + ++bool airoha_is_valid_gdm_port(struct airoha_eth *eth, ++ struct airoha_gdm_port *port); ++ + void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); + int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, + void *cb_priv); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -197,7 +197,8 @@ static int airoha_get_dsa_port(struct ne + #endif + } + +-static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, ++static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, ++ struct airoha_foe_entry *hwe, + struct net_device *dev, int type, + struct airoha_flow_data *data, + int l4proto) +@@ -225,6 +226,9 @@ static int airoha_ppe_foe_entry_prepare( + struct airoha_gdm_port *port = netdev_priv(dev); + u8 pse_port; + ++ if (!airoha_is_valid_gdm_port(eth, port)) ++ return -EINVAL; ++ + if (dsa_port >= 0) + pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; + else +@@ -633,7 +637,7 @@ static int airoha_ppe_flow_offload_repla + !is_valid_ether_addr(data.eth.h_dest)) + return -EINVAL; + +- err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, ++ err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type, + &data, l4proto); + if (err) + return err; diff --git a/target/linux/airoha/patches-6.6/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch b/target/linux/airoha/patches-6.6/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch new file mode 100644 index 0000000000..95f83f53bd --- /dev/null +++ b/target/linux/airoha/patches-6.6/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch @@ -0,0 +1,207 @@ +From b4916f67902e2ae1dc8e37dfa45e8894ad2f8921 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 9 Apr 2025 11:47:14 +0200 +Subject: [PATCH 1/2] net: airoha: Add l2_flows rhashtable + +Introduce l2_flows rhashtable in airoha_ppe struct in order to +store L2 flows committed by upper layers of the kernel. This is a +preliminary patch in order to offload L2 traffic rules. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Michal Kubiak +Link: https://patch.msgid.link/20250409-airoha-flowtable-l2b-v2-1-4a1e3935ea92@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.h | 15 +++- + drivers/net/ethernet/airoha/airoha_ppe.c | 103 ++++++++++++++++++----- + 2 files changed, 98 insertions(+), 20 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -422,12 +422,23 @@ struct airoha_flow_data { + } pppoe; + }; + ++enum airoha_flow_entry_type { ++ FLOW_TYPE_L4, ++ FLOW_TYPE_L2, ++ FLOW_TYPE_L2_SUBFLOW, ++}; ++ + struct airoha_flow_table_entry { +- struct hlist_node list; ++ union { ++ struct hlist_node list; /* PPE L3 flow entry */ ++ struct rhash_head l2_node; /* L2 flow entry */ ++ }; + + struct airoha_foe_entry data; + u32 hash; + ++ enum airoha_flow_entry_type type; ++ + struct rhash_head node; + unsigned long cookie; + }; +@@ -480,6 +491,8 @@ struct airoha_ppe { + void *foe; + dma_addr_t foe_dma; + ++ struct rhashtable l2_flows; ++ + struct hlist_head *foe_flow; + u16 foe_check_time[PPE_NUM_ENTRIES]; + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -24,6 +24,13 @@ static const struct rhashtable_params ai + .automatic_shrinking = true, + }; + ++static const struct rhashtable_params airoha_l2_flow_table_params = { ++ .head_offset = offsetof(struct airoha_flow_table_entry, l2_node), ++ .key_offset = offsetof(struct airoha_flow_table_entry, data.bridge), ++ .key_len = 2 * ETH_ALEN, ++ .automatic_shrinking = true, ++}; ++ + static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) + { + return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; +@@ -476,6 +483,43 @@ static int airoha_ppe_foe_commit_entry(s + return 0; + } + ++static void airoha_ppe_foe_remove_flow(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ lockdep_assert_held(&ppe_lock); ++ ++ hlist_del_init(&e->list); ++ if (e->hash != 0xffff) { ++ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; ++ e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, ++ AIROHA_FOE_STATE_INVALID); ++ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); ++ e->hash = 0xffff; ++ } ++} ++ ++static void airoha_ppe_foe_remove_l2_flow(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ lockdep_assert_held(&ppe_lock); ++ ++ rhashtable_remove_fast(&ppe->l2_flows, &e->l2_node, ++ airoha_l2_flow_table_params); ++} ++ ++static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ spin_lock_bh(&ppe_lock); ++ ++ if (e->type == FLOW_TYPE_L2) ++ airoha_ppe_foe_remove_l2_flow(ppe, e); ++ else ++ airoha_ppe_foe_remove_flow(ppe, e); ++ ++ spin_unlock_bh(&ppe_lock); ++} ++ + static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) + { + struct airoha_flow_table_entry *e; +@@ -505,11 +549,37 @@ unlock: + spin_unlock_bh(&ppe_lock); + } + ++static int ++airoha_ppe_foe_l2_flow_commit_entry(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ struct airoha_flow_table_entry *prev; ++ ++ e->type = FLOW_TYPE_L2; ++ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &e->l2_node, ++ airoha_l2_flow_table_params); ++ if (!prev) ++ return 0; ++ ++ if (IS_ERR(prev)) ++ return PTR_ERR(prev); ++ ++ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, ++ &e->l2_node, ++ airoha_l2_flow_table_params); ++} ++ + static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe, + struct airoha_flow_table_entry *e) + { +- u32 hash = airoha_ppe_foe_get_entry_hash(&e->data); ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, e->data.ib1); ++ u32 hash; + ++ if (type == PPE_PKT_TYPE_BRIDGE) ++ return airoha_ppe_foe_l2_flow_commit_entry(ppe, e); ++ ++ hash = airoha_ppe_foe_get_entry_hash(&e->data); ++ e->type = FLOW_TYPE_L4; + e->hash = 0xffff; + + spin_lock_bh(&ppe_lock); +@@ -519,23 +589,6 @@ static int airoha_ppe_foe_flow_commit_en + return 0; + } + +-static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, +- struct airoha_flow_table_entry *e) +-{ +- spin_lock_bh(&ppe_lock); +- +- hlist_del_init(&e->list); +- if (e->hash != 0xffff) { +- e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; +- e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, +- AIROHA_FOE_STATE_INVALID); +- airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); +- e->hash = 0xffff; +- } +- +- spin_unlock_bh(&ppe_lock); +-} +- + static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, + struct flow_cls_offload *f) + { +@@ -890,9 +943,20 @@ int airoha_ppe_init(struct airoha_eth *e + if (err) + return err; + ++ err = rhashtable_init(&ppe->l2_flows, &airoha_l2_flow_table_params); ++ if (err) ++ goto error_flow_table_destroy; ++ + err = airoha_ppe_debugfs_init(ppe); + if (err) +- rhashtable_destroy(ð->flow_table); ++ goto error_l2_flow_table_destroy; ++ ++ return 0; ++ ++error_l2_flow_table_destroy: ++ rhashtable_destroy(&ppe->l2_flows); ++error_flow_table_destroy: ++ rhashtable_destroy(ð->flow_table); + + return err; + } +@@ -909,6 +973,7 @@ void airoha_ppe_deinit(struct airoha_eth + } + rcu_read_unlock(); + ++ rhashtable_destroy(ð->ppe->l2_flows); + rhashtable_destroy(ð->flow_table); + debugfs_remove(eth->ppe->debugfs_dir); + } diff --git a/target/linux/airoha/patches-6.6/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch b/target/linux/airoha/patches-6.6/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch new file mode 100644 index 0000000000..2375962338 --- /dev/null +++ b/target/linux/airoha/patches-6.6/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch @@ -0,0 +1,253 @@ +From cd53f622611f9a6dd83b858c85448dd3568b67ec Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 9 Apr 2025 11:47:15 +0200 +Subject: [PATCH 2/2] net: airoha: Add L2 hw acceleration support + +Similar to mtk driver, introduce the capability to offload L2 traffic +defining flower rules in the PSE/PPE engine available on EN7581 SoC. +Since the hw always reports L2/L3/L4 flower rules, link all L2 rules +sharing the same L2 info (with different L3/L4 info) in the L2 subflows +list of a given L2 PPE entry. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Michal Kubiak +Link: https://patch.msgid.link/20250409-airoha-flowtable-l2b-v2-2-4a1e3935ea92@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 2 +- + drivers/net/ethernet/airoha/airoha_eth.h | 9 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 121 ++++++++++++++++++++--- + 3 files changed, 115 insertions(+), 17 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -694,7 +694,7 @@ static int airoha_qdma_rx_process(struct + + reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); + if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) +- airoha_ppe_check_skb(eth->ppe, hash); ++ airoha_ppe_check_skb(eth->ppe, q->skb, hash); + + done++; + napi_gro_receive(&q->napi, q->skb); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -431,10 +431,14 @@ enum airoha_flow_entry_type { + struct airoha_flow_table_entry { + union { + struct hlist_node list; /* PPE L3 flow entry */ +- struct rhash_head l2_node; /* L2 flow entry */ ++ struct { ++ struct rhash_head l2_node; /* L2 flow entry */ ++ struct hlist_head l2_flows; /* PPE L2 subflows list */ ++ }; + }; + + struct airoha_foe_entry data; ++ struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ + u32 hash; + + enum airoha_flow_entry_type type; +@@ -548,7 +552,8 @@ u32 airoha_rmw(void __iomem *base, u32 o + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + +-void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); ++void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, ++ u16 hash); + int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, + void *cb_priv); + int airoha_ppe_init(struct airoha_eth *eth); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -204,6 +204,15 @@ static int airoha_get_dsa_port(struct ne + #endif + } + ++static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br, ++ struct ethhdr *eh) ++{ ++ br->dest_mac_hi = get_unaligned_be32(eh->h_dest); ++ br->dest_mac_lo = get_unaligned_be16(eh->h_dest + 4); ++ br->src_mac_hi = get_unaligned_be16(eh->h_source); ++ br->src_mac_lo = get_unaligned_be32(eh->h_source + 2); ++} ++ + static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, + struct airoha_foe_entry *hwe, + struct net_device *dev, int type, +@@ -254,13 +263,7 @@ static int airoha_ppe_foe_entry_prepare( + + qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); + if (type == PPE_PKT_TYPE_BRIDGE) { +- hwe->bridge.dest_mac_hi = get_unaligned_be32(data->eth.h_dest); +- hwe->bridge.dest_mac_lo = +- get_unaligned_be16(data->eth.h_dest + 4); +- hwe->bridge.src_mac_hi = +- get_unaligned_be16(data->eth.h_source); +- hwe->bridge.src_mac_lo = +- get_unaligned_be32(data->eth.h_source + 2); ++ airoha_ppe_foe_set_bridge_addrs(&hwe->bridge, &data->eth); + hwe->bridge.data = qdata; + hwe->bridge.ib2 = val; + l2 = &hwe->bridge.l2.common; +@@ -385,6 +388,19 @@ static u32 airoha_ppe_foe_get_entry_hash + hv3 = hwe->ipv6.src_ip[1] ^ hwe->ipv6.dest_ip[1]; + hv3 ^= hwe->ipv6.src_ip[0]; + break; ++ case PPE_PKT_TYPE_BRIDGE: { ++ struct airoha_foe_mac_info *l2 = &hwe->bridge.l2; ++ ++ hv1 = l2->common.src_mac_hi & 0xffff; ++ hv1 = hv1 << 16 | l2->src_mac_lo; ++ ++ hv2 = l2->common.dest_mac_lo; ++ hv2 = hv2 << 16; ++ hv2 = hv2 | ((l2->common.src_mac_hi & 0xffff0000) >> 16); ++ ++ hv3 = l2->common.dest_mac_hi; ++ break; ++ } + case PPE_PKT_TYPE_IPV4_DSLITE: + case PPE_PKT_TYPE_IPV6_6RD: + default: +@@ -496,15 +512,24 @@ static void airoha_ppe_foe_remove_flow(s + airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); + e->hash = 0xffff; + } ++ if (e->type == FLOW_TYPE_L2_SUBFLOW) { ++ hlist_del_init(&e->l2_subflow_node); ++ kfree(e); ++ } + } + + static void airoha_ppe_foe_remove_l2_flow(struct airoha_ppe *ppe, + struct airoha_flow_table_entry *e) + { ++ struct hlist_head *head = &e->l2_flows; ++ struct hlist_node *n; ++ + lockdep_assert_held(&ppe_lock); + + rhashtable_remove_fast(&ppe->l2_flows, &e->l2_node, + airoha_l2_flow_table_params); ++ hlist_for_each_entry_safe(e, n, head, l2_subflow_node) ++ airoha_ppe_foe_remove_flow(ppe, e); + } + + static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, +@@ -520,10 +545,56 @@ static void airoha_ppe_foe_flow_remove_e + spin_unlock_bh(&ppe_lock); + } + +-static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) ++static int ++airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e, ++ u32 hash) ++{ ++ u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; ++ struct airoha_foe_entry *hwe_p, hwe; ++ struct airoha_flow_table_entry *f; ++ struct airoha_foe_mac_info *l2; ++ int type; ++ ++ hwe_p = airoha_ppe_foe_get_entry(ppe, hash); ++ if (!hwe_p) ++ return -EINVAL; ++ ++ f = kzalloc(sizeof(*f), GFP_ATOMIC); ++ if (!f) ++ return -ENOMEM; ++ ++ hlist_add_head(&f->l2_subflow_node, &e->l2_flows); ++ f->type = FLOW_TYPE_L2_SUBFLOW; ++ f->hash = hash; ++ ++ memcpy(&hwe, hwe_p, sizeof(*hwe_p)); ++ hwe.ib1 = (hwe.ib1 & mask) | (e->data.ib1 & ~mask); ++ l2 = &hwe.bridge.l2; ++ memcpy(l2, &e->data.bridge.l2, sizeof(*l2)); ++ ++ type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe.ib1); ++ if (type == PPE_PKT_TYPE_IPV4_HNAPT) ++ memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, ++ sizeof(hwe.ipv4.new_tuple)); ++ else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T && ++ l2->common.etype == ETH_P_IP) ++ l2->common.etype = ETH_P_IPV6; ++ ++ hwe.bridge.ib2 = e->data.bridge.ib2; ++ airoha_ppe_foe_commit_entry(ppe, &hwe, hash); ++ ++ return 0; ++} ++ ++static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, ++ struct sk_buff *skb, ++ u32 hash) + { + struct airoha_flow_table_entry *e; ++ struct airoha_foe_bridge br = {}; + struct airoha_foe_entry *hwe; ++ bool commit_done = false; + struct hlist_node *n; + u32 index, state; + +@@ -539,12 +610,33 @@ static void airoha_ppe_foe_insert_entry( + + index = airoha_ppe_foe_get_entry_hash(hwe); + hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { +- if (airoha_ppe_foe_compare_entry(e, hwe)) { +- airoha_ppe_foe_commit_entry(ppe, &e->data, hash); +- e->hash = hash; +- break; ++ if (e->type == FLOW_TYPE_L2_SUBFLOW) { ++ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); ++ if (state != AIROHA_FOE_STATE_BIND) { ++ e->hash = 0xffff; ++ airoha_ppe_foe_remove_flow(ppe, e); ++ } ++ continue; ++ } ++ ++ if (commit_done || !airoha_ppe_foe_compare_entry(e, hwe)) { ++ e->hash = 0xffff; ++ continue; + } ++ ++ airoha_ppe_foe_commit_entry(ppe, &e->data, hash); ++ commit_done = true; ++ e->hash = hash; + } ++ ++ if (commit_done) ++ goto unlock; ++ ++ airoha_ppe_foe_set_bridge_addrs(&br, eth_hdr(skb)); ++ e = rhashtable_lookup_fast(&ppe->l2_flows, &br, ++ airoha_l2_flow_table_params); ++ if (e) ++ airoha_ppe_foe_commit_subflow_entry(ppe, e, hash); + unlock: + spin_unlock_bh(&ppe_lock); + } +@@ -899,7 +991,8 @@ int airoha_ppe_setup_tc_block_cb(enum tc + return err; + } + +-void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash) ++void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, ++ u16 hash) + { + u16 now, diff; + +@@ -912,7 +1005,7 @@ void airoha_ppe_check_skb(struct airoha_ + return; + + ppe->foe_check_time[hash] = now; +- airoha_ppe_foe_insert_entry(ppe, hash); ++ airoha_ppe_foe_insert_entry(ppe, skb, hash); + } + + int airoha_ppe_init(struct airoha_eth *eth) diff --git a/target/linux/airoha/patches-6.6/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch b/target/linux/airoha/patches-6.6/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch new file mode 100644 index 0000000000..ba2a2bf2d5 --- /dev/null +++ b/target/linux/airoha/patches-6.6/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch @@ -0,0 +1,405 @@ +From df8398fb7bb7a0e509200af56b79343aa133b7d6 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 15 Apr 2025 09:14:34 +0200 +Subject: [PATCH] net: airoha: Add matchall filter offload support + +Introduce tc matchall filter offload support in airoha_eth driver. +Matchall hw filter is used to implement hw rate policing via tc action +police: + +$tc qdisc add dev eth0 handle ffff: ingress +$tc filter add dev eth0 parent ffff: matchall action police \ + rate 100mbit burst 1000k drop + +The current implementation supports just drop/accept as exceed/notexceed +actions. Moreover, rate and burst are the only supported configuration +parameters. + +Reviewed-by: Davide Caratti +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250415-airoha-hw-rx-ratelimit-v4-1-03458784fbc3@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 273 +++++++++++++++++++++- + drivers/net/ethernet/airoha/airoha_eth.h | 8 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 9 +- + drivers/net/ethernet/airoha/airoha_regs.h | 7 + + 4 files changed, 286 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -527,6 +527,25 @@ static int airoha_fe_init(struct airoha_ + /* disable IFC by default */ + airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); + ++ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), ++ FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) | ++ FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1)); ++ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1), ++ FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) | ++ FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2)); ++ + /* enable 1:N vlan action, init vlan table */ + airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); + +@@ -1632,7 +1651,6 @@ static void airhoha_set_gdm2_loopback(st + + if (port->id == 3) { + /* FIXME: handle XSI_PCE1_PORT */ +- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500); + airoha_fe_rmw(eth, REG_FE_WAN_PORT, + WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, + FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); +@@ -2107,6 +2125,125 @@ static int airoha_tc_setup_qdisc_ets(str + } + } + ++static int airoha_qdma_get_rl_param(struct airoha_qdma *qdma, int queue_id, ++ u32 addr, enum trtcm_param_type param, ++ u32 *val_low, u32 *val_high) ++{ ++ u32 idx = QDMA_METER_IDX(queue_id), group = QDMA_METER_GROUP(queue_id); ++ u32 val, config = FIELD_PREP(RATE_LIMIT_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(RATE_LIMIT_METER_GROUP_MASK, group) | ++ FIELD_PREP(RATE_LIMIT_PARAM_INDEX_MASK, idx); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ if (read_poll_timeout(airoha_qdma_rr, val, ++ val & RATE_LIMIT_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, qdma, ++ REG_TRTCM_CFG_PARAM(addr))) ++ return -ETIMEDOUT; ++ ++ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); ++ if (val_high) ++ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); ++ ++ return 0; ++} ++ ++static int airoha_qdma_set_rl_param(struct airoha_qdma *qdma, int queue_id, ++ u32 addr, enum trtcm_param_type param, ++ u32 val) ++{ ++ u32 idx = QDMA_METER_IDX(queue_id), group = QDMA_METER_GROUP(queue_id); ++ u32 config = RATE_LIMIT_PARAM_RW_MASK | ++ FIELD_PREP(RATE_LIMIT_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(RATE_LIMIT_METER_GROUP_MASK, group) | ++ FIELD_PREP(RATE_LIMIT_PARAM_INDEX_MASK, idx); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ ++ return read_poll_timeout(airoha_qdma_rr, val, ++ val & RATE_LIMIT_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, ++ qdma, REG_TRTCM_CFG_PARAM(addr)); ++} ++ ++static int airoha_qdma_set_rl_config(struct airoha_qdma *qdma, int queue_id, ++ u32 addr, bool enable, u32 enable_mask) ++{ ++ u32 val; ++ int err; ++ ++ err = airoha_qdma_get_rl_param(qdma, queue_id, addr, TRTCM_MISC_MODE, ++ &val, NULL); ++ if (err) ++ return err; ++ ++ val = enable ? val | enable_mask : val & ~enable_mask; ++ ++ return airoha_qdma_set_rl_param(qdma, queue_id, addr, TRTCM_MISC_MODE, ++ val); ++} ++ ++static int airoha_qdma_set_rl_token_bucket(struct airoha_qdma *qdma, ++ int queue_id, u32 rate_val, ++ u32 bucket_size) ++{ ++ u32 val, config, tick, unit, rate, rate_frac; ++ int err; ++ ++ err = airoha_qdma_get_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, ++ TRTCM_MISC_MODE, &config, NULL); ++ if (err) ++ return err; ++ ++ val = airoha_qdma_rr(qdma, REG_INGRESS_TRTCM_CFG); ++ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); ++ if (config & TRTCM_TICK_SEL) ++ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); ++ if (!tick) ++ return -EINVAL; ++ ++ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; ++ if (!unit) ++ return -EINVAL; ++ ++ rate = rate_val / unit; ++ rate_frac = rate_val % unit; ++ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; ++ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | ++ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); ++ ++ err = airoha_qdma_set_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, ++ TRTCM_TOKEN_RATE_MODE, rate); ++ if (err) ++ return err; ++ ++ val = bucket_size; ++ if (!(config & TRTCM_PKT_MODE)) ++ val = max_t(u32, val, MIN_TOKEN_SIZE); ++ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); ++ ++ return airoha_qdma_set_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, val); ++} ++ ++static int airoha_qdma_init_rl_config(struct airoha_qdma *qdma, int queue_id, ++ bool enable, enum trtcm_unit_type unit) ++{ ++ bool tick_sel = queue_id == 0 || queue_id == 2 || queue_id == 8; ++ enum trtcm_param mode = TRTCM_METER_MODE; ++ int err; ++ ++ mode |= unit == TRTCM_PACKET_UNIT ? TRTCM_PKT_MODE : 0; ++ err = airoha_qdma_set_rl_config(qdma, queue_id, REG_INGRESS_TRTCM_CFG, ++ enable, mode); ++ if (err) ++ return err; ++ ++ return airoha_qdma_set_rl_config(qdma, queue_id, REG_INGRESS_TRTCM_CFG, ++ tick_sel, TRTCM_TICK_SEL); ++} ++ + static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, + u32 addr, enum trtcm_param_type param, + enum trtcm_mode_type mode, +@@ -2271,10 +2408,142 @@ static int airoha_tc_htb_alloc_leaf_queu + return 0; + } + ++static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port, ++ u32 rate, u32 bucket_size, ++ enum trtcm_unit_type unit_type) ++{ ++ struct airoha_qdma *qdma = port->qdma; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ int err; ++ ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ err = airoha_qdma_init_rl_config(qdma, i, !!rate, unit_type); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_set_rl_token_bucket(qdma, i, rate, ++ bucket_size); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static int airoha_tc_matchall_act_validate(struct tc_cls_matchall_offload *f) ++{ ++ const struct flow_action *actions = &f->rule->action; ++ const struct flow_action_entry *act; ++ ++ if (!flow_action_has_entries(actions)) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "filter run with no actions"); ++ return -EINVAL; ++ } ++ ++ if (!flow_offload_has_one_action(actions)) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "only once action per filter is supported"); ++ return -EOPNOTSUPP; ++ } ++ ++ act = &actions->entries[0]; ++ if (act->id != FLOW_ACTION_POLICE) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, "unsupported action"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (act->police.exceed.act_id != FLOW_ACTION_DROP) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "invalid exceed action id"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "invalid notexceed action id"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT && ++ !flow_action_is_last_entry(actions, act)) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "action accept must be last"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (act->police.peakrate_bytes_ps || act->police.avrate || ++ act->police.overhead || act->police.mtu) { ++ NL_SET_ERR_MSG_MOD(f->common.extack, ++ "peakrate/avrate/overhead/mtu unsupported"); ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int airoha_dev_tc_matchall(struct net_device *dev, ++ struct tc_cls_matchall_offload *f) ++{ ++ enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT; ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ u32 rate = 0, bucket_size = 0; ++ ++ switch (f->command) { ++ case TC_CLSMATCHALL_REPLACE: { ++ const struct flow_action_entry *act; ++ int err; ++ ++ err = airoha_tc_matchall_act_validate(f); ++ if (err) ++ return err; ++ ++ act = &f->rule->action.entries[0]; ++ if (act->police.rate_pkt_ps) { ++ rate = act->police.rate_pkt_ps; ++ bucket_size = act->police.burst_pkt; ++ unit_type = TRTCM_PACKET_UNIT; ++ } else { ++ rate = div_u64(act->police.rate_bytes_ps, 1000); ++ rate = rate << 3; /* Kbps */ ++ bucket_size = act->police.burst; ++ } ++ fallthrough; ++ } ++ case TC_CLSMATCHALL_DESTROY: ++ return airoha_qdma_set_rx_meter(port, rate, bucket_size, ++ unit_type); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type, ++ void *type_data, void *cb_priv) ++{ ++ struct net_device *dev = cb_priv; ++ ++ if (!tc_can_offload(dev)) ++ return -EOPNOTSUPP; ++ ++ switch (type) { ++ case TC_SETUP_CLSFLOWER: ++ return airoha_ppe_setup_tc_block_cb(dev, type_data); ++ case TC_SETUP_CLSMATCHALL: ++ return airoha_dev_tc_matchall(dev, type_data); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, + struct flow_block_offload *f) + { +- flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb; ++ flow_setup_cb_t *cb = airoha_dev_setup_tc_block_cb; + static LIST_HEAD(block_cb_list); + struct flow_block_cb *block_cb; + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -127,6 +127,11 @@ enum tx_sched_mode { + TC_SCH_WRR2, + }; + ++enum trtcm_unit_type { ++ TRTCM_BYTE_UNIT, ++ TRTCM_PACKET_UNIT, ++}; ++ + enum trtcm_param_type { + TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ + TRTCM_TOKEN_RATE_MODE, +@@ -554,8 +559,7 @@ bool airoha_is_valid_gdm_port(struct air + + void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, + u16 hash); +-int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, +- void *cb_priv); ++int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -967,18 +967,13 @@ error_npu_put: + return err; + } + +-int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, +- void *cb_priv) ++int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) + { +- struct flow_cls_offload *cls = type_data; +- struct net_device *dev = cb_priv; + struct airoha_gdm_port *port = netdev_priv(dev); ++ struct flow_cls_offload *cls = type_data; + struct airoha_eth *eth = port->qdma->eth; + int err = 0; + +- if (!tc_can_offload(dev) || type != TC_SETUP_CLSFLOWER) +- return -EOPNOTSUPP; +- + mutex_lock(&flow_offload_mutex); + + if (!eth->npu) +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -283,6 +283,7 @@ + #define PPE_HASH_SEED 0x12345678 + + #define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) ++#define DFT_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) + + #define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) + +@@ -691,6 +692,12 @@ + #define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) + #define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) + ++#define RATE_LIMIT_PARAM_RW_MASK BIT(31) ++#define RATE_LIMIT_PARAM_RW_DONE_MASK BIT(30) ++#define RATE_LIMIT_PARAM_TYPE_MASK GENMASK(29, 28) ++#define RATE_LIMIT_METER_GROUP_MASK GENMASK(27, 26) ++#define RATE_LIMIT_PARAM_INDEX_MASK GENMASK(23, 16) ++ + #define REG_TXWRR_MODE_CFG 0x1020 + #define TWRR_WEIGHT_SCALE_MASK BIT(31) + #define TWRR_WEIGHT_BASE_MASK BIT(3) diff --git a/target/linux/airoha/patches-6.6/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch b/target/linux/airoha/patches-6.6/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch new file mode 100644 index 0000000000..dd5dc16458 --- /dev/null +++ b/target/linux/airoha/patches-6.6/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch @@ -0,0 +1,292 @@ +From 9439db26d3ee4a897e5cd108864172531f31ce07 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 18 Apr 2025 12:40:49 +0200 +Subject: [PATCH 1/2] net: airoha: Introduce airoha_irq_bank struct + +EN7581 ethernet SoC supports 4 programmable IRQ lines each one composed +by 4 IRQ configuration registers. Add airoha_irq_bank struct as a +container for independent IRQ lines info (e.g. IRQ number, enabled source +interrupts, ecc). This is a preliminary patch to support multiple IRQ lines +in airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250418-airoha-eth-multi-irq-v1-1-1ab0083ca3c1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 106 ++++++++++++++-------- + drivers/net/ethernet/airoha/airoha_eth.h | 13 ++- + drivers/net/ethernet/airoha/airoha_regs.h | 11 ++- + 3 files changed, 86 insertions(+), 44 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -34,37 +34,40 @@ u32 airoha_rmw(void __iomem *base, u32 o + return val; + } + +-static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, +- u32 clear, u32 set) ++static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank, ++ int index, u32 clear, u32 set) + { ++ struct airoha_qdma *qdma = irq_bank->qdma; ++ int bank = irq_bank - &qdma->irq_banks[0]; + unsigned long flags; + +- if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) ++ if (WARN_ON_ONCE(index >= ARRAY_SIZE(irq_bank->irqmask))) + return; + +- spin_lock_irqsave(&qdma->irq_lock, flags); ++ spin_lock_irqsave(&irq_bank->irq_lock, flags); + +- qdma->irqmask[index] &= ~clear; +- qdma->irqmask[index] |= set; +- airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); ++ irq_bank->irqmask[index] &= ~clear; ++ irq_bank->irqmask[index] |= set; ++ airoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index), ++ irq_bank->irqmask[index]); + /* Read irq_enable register in order to guarantee the update above + * completes in the spinlock critical section. + */ +- airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); ++ airoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index)); + +- spin_unlock_irqrestore(&qdma->irq_lock, flags); ++ spin_unlock_irqrestore(&irq_bank->irq_lock, flags); + } + +-static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, +- u32 mask) ++static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank, ++ int index, u32 mask) + { +- airoha_qdma_set_irqmask(qdma, index, 0, mask); ++ airoha_qdma_set_irqmask(irq_bank, index, 0, mask); + } + +-static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, +- u32 mask) ++static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank, ++ int index, u32 mask) + { +- airoha_qdma_set_irqmask(qdma, index, mask, 0); ++ airoha_qdma_set_irqmask(irq_bank, index, mask, 0); + } + + static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) +@@ -732,6 +735,7 @@ free_frag: + static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) + { + struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); ++ struct airoha_irq_bank *irq_bank = &q->qdma->irq_banks[0]; + int cur, done = 0; + + do { +@@ -740,7 +744,7 @@ static int airoha_qdma_rx_napi_poll(stru + } while (cur && done < budget); + + if (done < budget && napi_complete(napi)) +- airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, ++ airoha_qdma_irq_enable(irq_bank, QDMA_INT_REG_IDX1, + RX_DONE_INT_MASK); + + return done; +@@ -945,7 +949,7 @@ unlock: + } + + if (done < budget && napi_complete(napi)) +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, ++ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, + TX_DONE_INT_MASK(id)); + + return done; +@@ -1176,13 +1180,16 @@ static int airoha_qdma_hw_init(struct ai + int i; + + /* clear pending irqs */ +- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) ++ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks[0].irqmask); i++) + airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); + + /* setup irqs */ +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); ++ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, ++ INT_IDX0_MASK); ++ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX1, ++ INT_IDX1_MASK); ++ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4, ++ INT_IDX4_MASK); + + /* setup irq binding */ + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +@@ -1227,13 +1234,14 @@ static int airoha_qdma_hw_init(struct ai + + static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) + { +- struct airoha_qdma *qdma = dev_instance; +- u32 intr[ARRAY_SIZE(qdma->irqmask)]; ++ struct airoha_irq_bank *irq_bank = dev_instance; ++ struct airoha_qdma *qdma = irq_bank->qdma; ++ u32 intr[ARRAY_SIZE(irq_bank->irqmask)]; + int i; + +- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { ++ for (i = 0; i < ARRAY_SIZE(intr); i++) { + intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); +- intr[i] &= qdma->irqmask[i]; ++ intr[i] &= irq_bank->irqmask[i]; + airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); + } + +@@ -1241,7 +1249,7 @@ static irqreturn_t airoha_irq_handler(in + return IRQ_NONE; + + if (intr[1] & RX_DONE_INT_MASK) { +- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, ++ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, + RX_DONE_INT_MASK); + + for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +@@ -1258,7 +1266,7 @@ static irqreturn_t airoha_irq_handler(in + if (!(intr[0] & TX_DONE_INT_MASK(i))) + continue; + +- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, ++ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX0, + TX_DONE_INT_MASK(i)); + napi_schedule(&qdma->q_tx_irq[i].napi); + } +@@ -1267,6 +1275,39 @@ static irqreturn_t airoha_irq_handler(in + return IRQ_HANDLED; + } + ++static int airoha_qdma_init_irq_banks(struct platform_device *pdev, ++ struct airoha_qdma *qdma) ++{ ++ struct airoha_eth *eth = qdma->eth; ++ int i, id = qdma - ð->qdma[0]; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { ++ struct airoha_irq_bank *irq_bank = &qdma->irq_banks[i]; ++ int err, irq_index = 4 * id + i; ++ const char *name; ++ ++ spin_lock_init(&irq_bank->irq_lock); ++ irq_bank->qdma = qdma; ++ ++ irq_bank->irq = platform_get_irq(pdev, irq_index); ++ if (irq_bank->irq < 0) ++ return irq_bank->irq; ++ ++ name = devm_kasprintf(eth->dev, GFP_KERNEL, ++ KBUILD_MODNAME ".%d", irq_index); ++ if (!name) ++ return -ENOMEM; ++ ++ err = devm_request_irq(eth->dev, irq_bank->irq, ++ airoha_irq_handler, IRQF_SHARED, name, ++ irq_bank); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ + static int airoha_qdma_init(struct platform_device *pdev, + struct airoha_eth *eth, + struct airoha_qdma *qdma) +@@ -1274,9 +1315,7 @@ static int airoha_qdma_init(struct platf + int err, id = qdma - ð->qdma[0]; + const char *res; + +- spin_lock_init(&qdma->irq_lock); + qdma->eth = eth; +- + res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); + if (!res) + return -ENOMEM; +@@ -1286,12 +1325,7 @@ static int airoha_qdma_init(struct platf + return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), + "failed to iomap qdma%d regs\n", id); + +- qdma->irq = platform_get_irq(pdev, 4 * id); +- if (qdma->irq < 0) +- return qdma->irq; +- +- err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, +- IRQF_SHARED, KBUILD_MODNAME, qdma); ++ err = airoha_qdma_init_irq_banks(pdev, qdma); + if (err) + return err; + +@@ -2782,7 +2816,7 @@ static int airoha_alloc_gdm_port(struct + dev->features |= dev->hw_features; + dev->vlan_features = dev->hw_features; + dev->dev.of_node = np; +- dev->irq = qdma->irq; ++ dev->irq = qdma->irq_banks[0].irq; + SET_NETDEV_DEV(dev, eth->dev); + + /* reserve hw queues for HTB offloading */ +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -17,6 +17,7 @@ + + #define AIROHA_MAX_NUM_GDM_PORTS 4 + #define AIROHA_MAX_NUM_QDMA 2 ++#define AIROHA_MAX_NUM_IRQ_BANKS 1 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 + #define AIROHA_MAX_NUM_XSI_RSTS 5 +@@ -452,17 +453,23 @@ struct airoha_flow_table_entry { + unsigned long cookie; + }; + +-struct airoha_qdma { +- struct airoha_eth *eth; +- void __iomem *regs; ++struct airoha_irq_bank { ++ struct airoha_qdma *qdma; + + /* protect concurrent irqmask accesses */ + spinlock_t irq_lock; + u32 irqmask[QDMA_INT_REG_MAX]; + int irq; ++}; ++ ++struct airoha_qdma { ++ struct airoha_eth *eth; ++ void __iomem *regs; + + atomic_t users; + ++ struct airoha_irq_bank irq_banks[AIROHA_MAX_NUM_IRQ_BANKS]; ++ + struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; + + struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -423,11 +423,12 @@ + ((_n) == 2) ? 0x0720 : \ + ((_n) == 1) ? 0x0024 : 0x0020) + +-#define REG_INT_ENABLE(_n) \ +- (((_n) == 4) ? 0x0750 : \ +- ((_n) == 3) ? 0x0744 : \ +- ((_n) == 2) ? 0x0740 : \ +- ((_n) == 1) ? 0x002c : 0x0028) ++#define REG_INT_ENABLE(_b, _n) \ ++ (((_n) == 4) ? 0x0750 + ((_b) << 5) : \ ++ ((_n) == 3) ? 0x0744 + ((_b) << 5) : \ ++ ((_n) == 2) ? 0x0740 + ((_b) << 5) : \ ++ ((_n) == 1) ? 0x002c + ((_b) << 3) : \ ++ 0x0028 + ((_b) << 3)) + + /* QDMA_CSR_INT_ENABLE1 */ + #define RX15_COHERENT_INT_MASK BIT(31) diff --git a/target/linux/airoha/patches-6.6/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch b/target/linux/airoha/patches-6.6/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch new file mode 100644 index 0000000000..db4494e12f --- /dev/null +++ b/target/linux/airoha/patches-6.6/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch @@ -0,0 +1,379 @@ +From f252493e1835366fc25ce631c3056f900977dd11 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 18 Apr 2025 12:40:50 +0200 +Subject: [PATCH 2/2] net: airoha: Enable multiple IRQ lines support in + airoha_eth driver. + +EN7581 ethernet SoC supports 4 programmable IRQ lines for Tx and Rx +interrupts. Enable multiple IRQ lines support. Map Rx/Tx queues to the +available IRQ lines using the default scheme used in the vendor SDK: + +- IRQ0: rx queues [0-4],[7-9],15 +- IRQ1: rx queues [21-30] +- IRQ2: rx queues 5 +- IRQ3: rx queues 6 + +Tx queues interrupts are managed by IRQ0. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250418-airoha-eth-multi-irq-v1-2-1ab0083ca3c1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 67 +++++--- + drivers/net/ethernet/airoha/airoha_eth.h | 13 +- + drivers/net/ethernet/airoha/airoha_regs.h | 185 +++++++++++++++++----- + 3 files changed, 206 insertions(+), 59 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -735,7 +735,6 @@ free_frag: + static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) + { + struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); +- struct airoha_irq_bank *irq_bank = &q->qdma->irq_banks[0]; + int cur, done = 0; + + do { +@@ -743,9 +742,20 @@ static int airoha_qdma_rx_napi_poll(stru + done += cur; + } while (cur && done < budget); + +- if (done < budget && napi_complete(napi)) +- airoha_qdma_irq_enable(irq_bank, QDMA_INT_REG_IDX1, +- RX_DONE_INT_MASK); ++ if (done < budget && napi_complete(napi)) { ++ struct airoha_qdma *qdma = q->qdma; ++ int i, qid = q - &qdma->q_rx[0]; ++ int intr_reg = qid < RX_DONE_HIGH_OFFSET ? QDMA_INT_REG_IDX1 ++ : QDMA_INT_REG_IDX2; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { ++ if (!(BIT(qid) & RX_IRQ_BANK_PIN_MASK(i))) ++ continue; ++ ++ airoha_qdma_irq_enable(&qdma->irq_banks[i], intr_reg, ++ BIT(qid % RX_DONE_HIGH_OFFSET)); ++ } ++ } + + return done; + } +@@ -1179,17 +1189,24 @@ static int airoha_qdma_hw_init(struct ai + { + int i; + +- /* clear pending irqs */ +- for (i = 0; i < ARRAY_SIZE(qdma->irq_banks[0].irqmask); i++) ++ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { ++ /* clear pending irqs */ + airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); +- +- /* setup irqs */ ++ /* setup rx irqs */ ++ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX0, ++ INT_RX0_MASK(RX_IRQ_BANK_PIN_MASK(i))); ++ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX1, ++ INT_RX1_MASK(RX_IRQ_BANK_PIN_MASK(i))); ++ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX2, ++ INT_RX2_MASK(RX_IRQ_BANK_PIN_MASK(i))); ++ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX3, ++ INT_RX3_MASK(RX_IRQ_BANK_PIN_MASK(i))); ++ } ++ /* setup tx irqs */ + airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, +- INT_IDX0_MASK); +- airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX1, +- INT_IDX1_MASK); ++ TX_COHERENT_LOW_INT_MASK | INT_TX_MASK); + airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4, +- INT_IDX4_MASK); ++ TX_COHERENT_HIGH_INT_MASK); + + /* setup irq binding */ + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +@@ -1236,6 +1253,7 @@ static irqreturn_t airoha_irq_handler(in + { + struct airoha_irq_bank *irq_bank = dev_instance; + struct airoha_qdma *qdma = irq_bank->qdma; ++ u32 rx_intr_mask = 0, rx_intr1, rx_intr2; + u32 intr[ARRAY_SIZE(irq_bank->irqmask)]; + int i; + +@@ -1248,17 +1266,24 @@ static irqreturn_t airoha_irq_handler(in + if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) + return IRQ_NONE; + +- if (intr[1] & RX_DONE_INT_MASK) { +- airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, +- RX_DONE_INT_MASK); ++ rx_intr1 = intr[1] & RX_DONE_LOW_INT_MASK; ++ if (rx_intr1) { ++ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, rx_intr1); ++ rx_intr_mask |= rx_intr1; ++ } + +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; ++ rx_intr2 = intr[2] & RX_DONE_HIGH_INT_MASK; ++ if (rx_intr2) { ++ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX2, rx_intr2); ++ rx_intr_mask |= (rx_intr2 << 16); ++ } + +- if (intr[1] & BIT(i)) +- napi_schedule(&qdma->q_rx[i].napi); +- } ++ for (i = 0; rx_intr_mask && i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ if (rx_intr_mask & BIT(i)) ++ napi_schedule(&qdma->q_rx[i].napi); + } + + if (intr[0] & INT_TX_MASK) { +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -17,7 +17,7 @@ + + #define AIROHA_MAX_NUM_GDM_PORTS 4 + #define AIROHA_MAX_NUM_QDMA 2 +-#define AIROHA_MAX_NUM_IRQ_BANKS 1 ++#define AIROHA_MAX_NUM_IRQ_BANKS 4 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 + #define AIROHA_MAX_NUM_XSI_RSTS 5 +@@ -453,6 +453,17 @@ struct airoha_flow_table_entry { + unsigned long cookie; + }; + ++/* RX queue to IRQ mapping: BIT(q) in IRQ(n) */ ++#define RX_IRQ0_BANK_PIN_MASK 0x839f ++#define RX_IRQ1_BANK_PIN_MASK 0x7fe00000 ++#define RX_IRQ2_BANK_PIN_MASK 0x20 ++#define RX_IRQ3_BANK_PIN_MASK 0x40 ++#define RX_IRQ_BANK_PIN_MASK(_n) \ ++ (((_n) == 3) ? RX_IRQ3_BANK_PIN_MASK : \ ++ ((_n) == 2) ? RX_IRQ2_BANK_PIN_MASK : \ ++ ((_n) == 1) ? RX_IRQ1_BANK_PIN_MASK : \ ++ RX_IRQ0_BANK_PIN_MASK) ++ + struct airoha_irq_bank { + struct airoha_qdma *qdma; + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -463,6 +463,26 @@ + #define IRQ0_FULL_INT_MASK BIT(1) + #define IRQ0_INT_MASK BIT(0) + ++#define RX_COHERENT_LOW_INT_MASK \ ++ (RX15_COHERENT_INT_MASK | RX14_COHERENT_INT_MASK | \ ++ RX13_COHERENT_INT_MASK | RX12_COHERENT_INT_MASK | \ ++ RX11_COHERENT_INT_MASK | RX10_COHERENT_INT_MASK | \ ++ RX9_COHERENT_INT_MASK | RX8_COHERENT_INT_MASK | \ ++ RX7_COHERENT_INT_MASK | RX6_COHERENT_INT_MASK | \ ++ RX5_COHERENT_INT_MASK | RX4_COHERENT_INT_MASK | \ ++ RX3_COHERENT_INT_MASK | RX2_COHERENT_INT_MASK | \ ++ RX1_COHERENT_INT_MASK | RX0_COHERENT_INT_MASK) ++ ++#define RX_COHERENT_LOW_OFFSET __ffs(RX_COHERENT_LOW_INT_MASK) ++#define INT_RX0_MASK(_n) \ ++ (((_n) << RX_COHERENT_LOW_OFFSET) & RX_COHERENT_LOW_INT_MASK) ++ ++#define TX_COHERENT_LOW_INT_MASK \ ++ (TX7_COHERENT_INT_MASK | TX6_COHERENT_INT_MASK | \ ++ TX5_COHERENT_INT_MASK | TX4_COHERENT_INT_MASK | \ ++ TX3_COHERENT_INT_MASK | TX2_COHERENT_INT_MASK | \ ++ TX1_COHERENT_INT_MASK | TX0_COHERENT_INT_MASK) ++ + #define TX_DONE_INT_MASK(_n) \ + ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ + : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) +@@ -471,17 +491,6 @@ + (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ + IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) + +-#define INT_IDX0_MASK \ +- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ +- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ +- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ +- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ +- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ +- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ +- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ +- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ +- RX15_COHERENT_INT_MASK | INT_TX_MASK) +- + /* QDMA_CSR_INT_ENABLE2 */ + #define RX15_NO_CPU_DSCP_INT_MASK BIT(31) + #define RX14_NO_CPU_DSCP_INT_MASK BIT(30) +@@ -516,19 +525,121 @@ + #define RX1_DONE_INT_MASK BIT(1) + #define RX0_DONE_INT_MASK BIT(0) + +-#define RX_DONE_INT_MASK \ +- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ +- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ +- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ +- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ +- RX15_DONE_INT_MASK) +-#define INT_IDX1_MASK \ +- (RX_DONE_INT_MASK | \ +- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ +- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ +- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ +- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ +- RX15_NO_CPU_DSCP_INT_MASK) ++#define RX_NO_CPU_DSCP_LOW_INT_MASK \ ++ (RX15_NO_CPU_DSCP_INT_MASK | RX14_NO_CPU_DSCP_INT_MASK | \ ++ RX13_NO_CPU_DSCP_INT_MASK | RX12_NO_CPU_DSCP_INT_MASK | \ ++ RX11_NO_CPU_DSCP_INT_MASK | RX10_NO_CPU_DSCP_INT_MASK | \ ++ RX9_NO_CPU_DSCP_INT_MASK | RX8_NO_CPU_DSCP_INT_MASK | \ ++ RX7_NO_CPU_DSCP_INT_MASK | RX6_NO_CPU_DSCP_INT_MASK | \ ++ RX5_NO_CPU_DSCP_INT_MASK | RX4_NO_CPU_DSCP_INT_MASK | \ ++ RX3_NO_CPU_DSCP_INT_MASK | RX2_NO_CPU_DSCP_INT_MASK | \ ++ RX1_NO_CPU_DSCP_INT_MASK | RX0_NO_CPU_DSCP_INT_MASK) ++ ++#define RX_DONE_LOW_INT_MASK \ ++ (RX15_DONE_INT_MASK | RX14_DONE_INT_MASK | \ ++ RX13_DONE_INT_MASK | RX12_DONE_INT_MASK | \ ++ RX11_DONE_INT_MASK | RX10_DONE_INT_MASK | \ ++ RX9_DONE_INT_MASK | RX8_DONE_INT_MASK | \ ++ RX7_DONE_INT_MASK | RX6_DONE_INT_MASK | \ ++ RX5_DONE_INT_MASK | RX4_DONE_INT_MASK | \ ++ RX3_DONE_INT_MASK | RX2_DONE_INT_MASK | \ ++ RX1_DONE_INT_MASK | RX0_DONE_INT_MASK) ++ ++#define RX_NO_CPU_DSCP_LOW_OFFSET __ffs(RX_NO_CPU_DSCP_LOW_INT_MASK) ++#define INT_RX1_MASK(_n) \ ++ ((((_n) << RX_NO_CPU_DSCP_LOW_OFFSET) & RX_NO_CPU_DSCP_LOW_INT_MASK) | \ ++ (RX_DONE_LOW_INT_MASK & (_n))) ++ ++/* QDMA_CSR_INT_ENABLE3 */ ++#define RX31_NO_CPU_DSCP_INT_MASK BIT(31) ++#define RX30_NO_CPU_DSCP_INT_MASK BIT(30) ++#define RX29_NO_CPU_DSCP_INT_MASK BIT(29) ++#define RX28_NO_CPU_DSCP_INT_MASK BIT(28) ++#define RX27_NO_CPU_DSCP_INT_MASK BIT(27) ++#define RX26_NO_CPU_DSCP_INT_MASK BIT(26) ++#define RX25_NO_CPU_DSCP_INT_MASK BIT(25) ++#define RX24_NO_CPU_DSCP_INT_MASK BIT(24) ++#define RX23_NO_CPU_DSCP_INT_MASK BIT(23) ++#define RX22_NO_CPU_DSCP_INT_MASK BIT(22) ++#define RX21_NO_CPU_DSCP_INT_MASK BIT(21) ++#define RX20_NO_CPU_DSCP_INT_MASK BIT(20) ++#define RX19_NO_CPU_DSCP_INT_MASK BIT(19) ++#define RX18_NO_CPU_DSCP_INT_MASK BIT(18) ++#define RX17_NO_CPU_DSCP_INT_MASK BIT(17) ++#define RX16_NO_CPU_DSCP_INT_MASK BIT(16) ++#define RX31_DONE_INT_MASK BIT(15) ++#define RX30_DONE_INT_MASK BIT(14) ++#define RX29_DONE_INT_MASK BIT(13) ++#define RX28_DONE_INT_MASK BIT(12) ++#define RX27_DONE_INT_MASK BIT(11) ++#define RX26_DONE_INT_MASK BIT(10) ++#define RX25_DONE_INT_MASK BIT(9) ++#define RX24_DONE_INT_MASK BIT(8) ++#define RX23_DONE_INT_MASK BIT(7) ++#define RX22_DONE_INT_MASK BIT(6) ++#define RX21_DONE_INT_MASK BIT(5) ++#define RX20_DONE_INT_MASK BIT(4) ++#define RX19_DONE_INT_MASK BIT(3) ++#define RX18_DONE_INT_MASK BIT(2) ++#define RX17_DONE_INT_MASK BIT(1) ++#define RX16_DONE_INT_MASK BIT(0) ++ ++#define RX_NO_CPU_DSCP_HIGH_INT_MASK \ ++ (RX31_NO_CPU_DSCP_INT_MASK | RX30_NO_CPU_DSCP_INT_MASK | \ ++ RX29_NO_CPU_DSCP_INT_MASK | RX28_NO_CPU_DSCP_INT_MASK | \ ++ RX27_NO_CPU_DSCP_INT_MASK | RX26_NO_CPU_DSCP_INT_MASK | \ ++ RX25_NO_CPU_DSCP_INT_MASK | RX24_NO_CPU_DSCP_INT_MASK | \ ++ RX23_NO_CPU_DSCP_INT_MASK | RX22_NO_CPU_DSCP_INT_MASK | \ ++ RX21_NO_CPU_DSCP_INT_MASK | RX20_NO_CPU_DSCP_INT_MASK | \ ++ RX19_NO_CPU_DSCP_INT_MASK | RX18_NO_CPU_DSCP_INT_MASK | \ ++ RX17_NO_CPU_DSCP_INT_MASK | RX16_NO_CPU_DSCP_INT_MASK) ++ ++#define RX_DONE_HIGH_INT_MASK \ ++ (RX31_DONE_INT_MASK | RX30_DONE_INT_MASK | \ ++ RX29_DONE_INT_MASK | RX28_DONE_INT_MASK | \ ++ RX27_DONE_INT_MASK | RX26_DONE_INT_MASK | \ ++ RX25_DONE_INT_MASK | RX24_DONE_INT_MASK | \ ++ RX23_DONE_INT_MASK | RX22_DONE_INT_MASK | \ ++ RX21_DONE_INT_MASK | RX20_DONE_INT_MASK | \ ++ RX19_DONE_INT_MASK | RX18_DONE_INT_MASK | \ ++ RX17_DONE_INT_MASK | RX16_DONE_INT_MASK) ++ ++#define RX_DONE_INT_MASK (RX_DONE_HIGH_INT_MASK | RX_DONE_LOW_INT_MASK) ++#define RX_DONE_HIGH_OFFSET fls(RX_DONE_HIGH_INT_MASK) ++ ++#define INT_RX2_MASK(_n) \ ++ ((RX_NO_CPU_DSCP_HIGH_INT_MASK & (_n)) | \ ++ (((_n) >> RX_DONE_HIGH_OFFSET) & RX_DONE_HIGH_INT_MASK)) ++ ++/* QDMA_CSR_INT_ENABLE4 */ ++#define RX31_COHERENT_INT_MASK BIT(31) ++#define RX30_COHERENT_INT_MASK BIT(30) ++#define RX29_COHERENT_INT_MASK BIT(29) ++#define RX28_COHERENT_INT_MASK BIT(28) ++#define RX27_COHERENT_INT_MASK BIT(27) ++#define RX26_COHERENT_INT_MASK BIT(26) ++#define RX25_COHERENT_INT_MASK BIT(25) ++#define RX24_COHERENT_INT_MASK BIT(24) ++#define RX23_COHERENT_INT_MASK BIT(23) ++#define RX22_COHERENT_INT_MASK BIT(22) ++#define RX21_COHERENT_INT_MASK BIT(21) ++#define RX20_COHERENT_INT_MASK BIT(20) ++#define RX19_COHERENT_INT_MASK BIT(19) ++#define RX18_COHERENT_INT_MASK BIT(18) ++#define RX17_COHERENT_INT_MASK BIT(17) ++#define RX16_COHERENT_INT_MASK BIT(16) ++ ++#define RX_COHERENT_HIGH_INT_MASK \ ++ (RX31_COHERENT_INT_MASK | RX30_COHERENT_INT_MASK | \ ++ RX29_COHERENT_INT_MASK | RX28_COHERENT_INT_MASK | \ ++ RX27_COHERENT_INT_MASK | RX26_COHERENT_INT_MASK | \ ++ RX25_COHERENT_INT_MASK | RX24_COHERENT_INT_MASK | \ ++ RX23_COHERENT_INT_MASK | RX22_COHERENT_INT_MASK | \ ++ RX21_COHERENT_INT_MASK | RX20_COHERENT_INT_MASK | \ ++ RX19_COHERENT_INT_MASK | RX18_COHERENT_INT_MASK | \ ++ RX17_COHERENT_INT_MASK | RX16_COHERENT_INT_MASK) ++ ++#define INT_RX3_MASK(_n) (RX_COHERENT_HIGH_INT_MASK & (_n)) + + /* QDMA_CSR_INT_ENABLE5 */ + #define TX31_COHERENT_INT_MASK BIT(31) +@@ -556,19 +667,19 @@ + #define TX9_COHERENT_INT_MASK BIT(9) + #define TX8_COHERENT_INT_MASK BIT(8) + +-#define INT_IDX4_MASK \ +- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ +- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ +- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ +- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ +- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ +- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ +- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ +- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ +- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ +- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ +- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ +- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) ++#define TX_COHERENT_HIGH_INT_MASK \ ++ (TX31_COHERENT_INT_MASK | TX30_COHERENT_INT_MASK | \ ++ TX29_COHERENT_INT_MASK | TX28_COHERENT_INT_MASK | \ ++ TX27_COHERENT_INT_MASK | TX26_COHERENT_INT_MASK | \ ++ TX25_COHERENT_INT_MASK | TX24_COHERENT_INT_MASK | \ ++ TX23_COHERENT_INT_MASK | TX22_COHERENT_INT_MASK | \ ++ TX21_COHERENT_INT_MASK | TX20_COHERENT_INT_MASK | \ ++ TX19_COHERENT_INT_MASK | TX18_COHERENT_INT_MASK | \ ++ TX17_COHERENT_INT_MASK | TX16_COHERENT_INT_MASK | \ ++ TX15_COHERENT_INT_MASK | TX14_COHERENT_INT_MASK | \ ++ TX13_COHERENT_INT_MASK | TX12_COHERENT_INT_MASK | \ ++ TX11_COHERENT_INT_MASK | TX10_COHERENT_INT_MASK | \ ++ TX9_COHERENT_INT_MASK | TX8_COHERENT_INT_MASK) + + #define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) + diff --git a/target/linux/airoha/patches-6.6/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch b/target/linux/airoha/patches-6.6/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch new file mode 100644 index 0000000000..2fb90b6c3b --- /dev/null +++ b/target/linux/airoha/patches-6.6/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch @@ -0,0 +1,48 @@ +From 4a7843cc8a41b9612becccc07715ed017770eb89 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 6 May 2025 18:56:47 +0200 +Subject: [PATCH] net: airoha: Add missing field to ppe_mbox_data struct + +The official Airoha EN7581 firmware requires adding max_packet field in +ppe_mbox_data struct while the unofficial one used to develop the Airoha +EN7581 flowtable support does not require this field. +This patch does not introduce any real backwards compatible issue since +EN7581 fw is not publicly available in linux-firmware or other +repositories (e.g. OpenWrt) yet and the official fw version will use this +new layout. For this reason this change needs to be backported. +Moreover, make explicit the padding added by the compiler introducing +the rsv array in init_info struct. +At the same time use u32 instead of int for init_info and set_info +struct definitions in ppe_mbox_data struct. + +Fixes: 23290c7bc190d ("net: airoha: Introduce Airoha NPU support") +Reviewed-by: Simon Horman +Reviewed-by: Jacob Keller +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250506-airoha-en7581-fix-ppe_mbox_data-v5-1-29cabed6864d@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -104,12 +104,14 @@ struct ppe_mbox_data { + u8 xpon_hal_api; + u8 wan_xsi; + u8 ct_joyme4; +- int ppe_type; +- int wan_mode; +- int wan_sel; ++ u8 max_packet; ++ u8 rsv[3]; ++ u32 ppe_type; ++ u32 wan_mode; ++ u32 wan_sel; + } init_info; + struct { +- int func_id; ++ u32 func_id; + u32 size; + u32 data; + } set_info; diff --git a/target/linux/airoha/patches-6.6/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch b/target/linux/airoha/patches-6.6/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch new file mode 100644 index 0000000000..bcf60ce8dd --- /dev/null +++ b/target/linux/airoha/patches-6.6/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch @@ -0,0 +1,72 @@ +From d6d2b0e1538d5c381ec0ca95afaf772c096ea5dc Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 15 May 2025 08:33:06 +0200 +Subject: [PATCH] net: airoha: Fix page recycling in airoha_qdma_rx_process() + +Do not recycle the page twice in airoha_qdma_rx_process routine in case +of error. Just run dev_kfree_skb() if the skb has been allocated and marked +for recycling. Run page_pool_put_full_page() directly if the skb has not +been allocated yet. +Moreover, rely on DMA address from queue entry element instead of reading +it from the DMA descriptor for DMA syncing in airoha_qdma_rx_process(). + +Fixes: e12182ddb6e71 ("net: airoha: Enable Rx Scatter-Gather") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250515-airoha-fix-rx-process-error-condition-v2-1-657e92c894b9@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -636,7 +636,6 @@ static int airoha_qdma_rx_process(struct + struct airoha_queue_entry *e = &q->entry[q->tail]; + struct airoha_qdma_desc *desc = &q->desc[q->tail]; + u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); +- dma_addr_t dma_addr = le32_to_cpu(desc->addr); + struct page *page = virt_to_head_page(e->buf); + u32 desc_ctrl = le32_to_cpu(desc->ctrl); + struct airoha_gdm_port *port; +@@ -645,22 +644,16 @@ static int airoha_qdma_rx_process(struct + if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) + break; + +- if (!dma_addr) +- break; +- +- len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); +- if (!len) +- break; +- + q->tail = (q->tail + 1) % q->ndesc; + q->queued--; + +- dma_sync_single_for_cpu(eth->dev, dma_addr, ++ dma_sync_single_for_cpu(eth->dev, e->dma_addr, + SKB_WITH_OVERHEAD(q->buf_size), dir); + ++ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); + data_len = q->skb ? q->buf_size + : SKB_WITH_OVERHEAD(q->buf_size); +- if (data_len < len) ++ if (!len || data_len < len) + goto free_frag; + + p = airoha_qdma_get_gdm_port(eth, desc); +@@ -723,9 +716,12 @@ static int airoha_qdma_rx_process(struct + q->skb = NULL; + continue; + free_frag: +- page_pool_put_full_page(q->page_pool, page, true); +- dev_kfree_skb(q->skb); +- q->skb = NULL; ++ if (q->skb) { ++ dev_kfree_skb(q->skb); ++ q->skb = NULL; ++ } else { ++ page_pool_put_full_page(q->page_pool, page, true); ++ } + } + airoha_qdma_fill_rx_queue(q); + diff --git a/target/linux/airoha/patches-6.6/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch b/target/linux/airoha/patches-6.6/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch new file mode 100644 index 0000000000..f0c41d5dc4 --- /dev/null +++ b/target/linux/airoha/patches-6.6/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch @@ -0,0 +1,196 @@ +From c52918744ee1e49cea86622a2633b9782446428f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 16 May 2025 09:59:59 +0200 +Subject: [PATCH 1/3] net: airoha: npu: Move memory allocation in + airoha_npu_send_msg() caller + +Move ppe_mbox_data struct memory allocation from airoha_npu_send_msg +routine to the caller one. This is a preliminary patch to enable wlan NPU +offloading and flow counter stats support. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-1-06d5fbf28984@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 126 +++++++++++++---------- + 1 file changed, 72 insertions(+), 54 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -124,17 +124,12 @@ static int airoha_npu_send_msg(struct ai + u16 core = 0; /* FIXME */ + u32 val, offset = core << 4; + dma_addr_t dma_addr; +- void *addr; + int ret; + +- addr = kmemdup(p, size, GFP_ATOMIC); +- if (!addr) +- return -ENOMEM; +- +- dma_addr = dma_map_single(npu->dev, addr, size, DMA_TO_DEVICE); ++ dma_addr = dma_map_single(npu->dev, p, size, DMA_TO_DEVICE); + ret = dma_mapping_error(npu->dev, dma_addr); + if (ret) +- goto out; ++ return ret; + + spin_lock_bh(&npu->cores[core].lock); + +@@ -155,8 +150,6 @@ static int airoha_npu_send_msg(struct ai + spin_unlock_bh(&npu->cores[core].lock); + + dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); +-out: +- kfree(addr); + + return ret; + } +@@ -261,76 +254,101 @@ static irqreturn_t airoha_npu_wdt_handle + + static int airoha_npu_ppe_init(struct airoha_npu *npu) + { +- struct ppe_mbox_data ppe_data = { +- .func_type = NPU_OP_SET, +- .func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT, +- .init_info = { +- .ppe_type = PPE_TYPE_L2B_IPV4_IPV6, +- .wan_mode = QDMA_WAN_ETHER, +- }, +- }; ++ struct ppe_mbox_data *ppe_data; ++ int err; + +- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, +- sizeof(struct ppe_mbox_data)); ++ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); ++ if (!ppe_data) ++ return -ENOMEM; ++ ++ ppe_data->func_type = NPU_OP_SET; ++ ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT; ++ ppe_data->init_info.ppe_type = PPE_TYPE_L2B_IPV4_IPV6; ++ ppe_data->init_info.wan_mode = QDMA_WAN_ETHER; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); ++ kfree(ppe_data); ++ ++ return err; + } + + static int airoha_npu_ppe_deinit(struct airoha_npu *npu) + { +- struct ppe_mbox_data ppe_data = { +- .func_type = NPU_OP_SET, +- .func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT, +- }; ++ struct ppe_mbox_data *ppe_data; ++ int err; ++ ++ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); ++ if (!ppe_data) ++ return -ENOMEM; + +- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, +- sizeof(struct ppe_mbox_data)); ++ ppe_data->func_type = NPU_OP_SET; ++ ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); ++ kfree(ppe_data); ++ ++ return err; + } + + static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, + dma_addr_t foe_addr, + int sram_num_entries) + { +- struct ppe_mbox_data ppe_data = { +- .func_type = NPU_OP_SET, +- .func_id = PPE_FUNC_SET_WAIT_API, +- .set_info = { +- .func_id = PPE_SRAM_RESET_VAL, +- .data = foe_addr, +- .size = sram_num_entries, +- }, +- }; ++ struct ppe_mbox_data *ppe_data; ++ int err; ++ ++ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); ++ if (!ppe_data) ++ return -ENOMEM; ++ ++ ppe_data->func_type = NPU_OP_SET; ++ ppe_data->func_id = PPE_FUNC_SET_WAIT_API; ++ ppe_data->set_info.func_id = PPE_SRAM_RESET_VAL; ++ ppe_data->set_info.data = foe_addr; ++ ppe_data->set_info.size = sram_num_entries; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); ++ kfree(ppe_data); + +- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, +- sizeof(struct ppe_mbox_data)); ++ return err; + } + + static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, + dma_addr_t foe_addr, + u32 entry_size, u32 hash, bool ppe2) + { +- struct ppe_mbox_data ppe_data = { +- .func_type = NPU_OP_SET, +- .func_id = PPE_FUNC_SET_WAIT_API, +- .set_info = { +- .data = foe_addr, +- .size = entry_size, +- }, +- }; ++ struct ppe_mbox_data *ppe_data; + int err; + +- ppe_data.set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY +- : PPE_SRAM_SET_ENTRY; ++ ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); ++ if (!ppe_data) ++ return -ENOMEM; ++ ++ ppe_data->func_type = NPU_OP_SET; ++ ppe_data->func_id = PPE_FUNC_SET_WAIT_API; ++ ppe_data->set_info.data = foe_addr; ++ ppe_data->set_info.size = entry_size; ++ ppe_data->set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY ++ : PPE_SRAM_SET_ENTRY; + +- err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, +- sizeof(struct ppe_mbox_data)); ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); + if (err) +- return err; ++ goto out; + +- ppe_data.set_info.func_id = PPE_SRAM_SET_VAL; +- ppe_data.set_info.data = hash; +- ppe_data.set_info.size = sizeof(u32); ++ ppe_data->set_info.func_id = PPE_SRAM_SET_VAL; ++ ppe_data->set_info.data = hash; ++ ppe_data->set_info.size = sizeof(u32); ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); ++out: ++ kfree(ppe_data); + +- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, +- sizeof(struct ppe_mbox_data)); ++ return err; + } + + struct airoha_npu *airoha_npu_get(struct device *dev) diff --git a/target/linux/airoha/patches-6.6/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch b/target/linux/airoha/patches-6.6/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch new file mode 100644 index 0000000000..584ddb1da8 --- /dev/null +++ b/target/linux/airoha/patches-6.6/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch @@ -0,0 +1,633 @@ +From b81e0f2b58be37628b2e12f8dffdd63c84573e75 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 16 May 2025 10:00:00 +0200 +Subject: [PATCH 2/3] net: airoha: Add FLOW_CLS_STATS callback support + +Introduce per-flow stats accounting to the flowtable hw offload in +the airoha_eth driver. Flow stats are split in the PPE and NPU modules: +- PPE: accounts for high 32bit of per-flow stats +- NPU: accounts for low 32bit of per-flow stats + +FLOW_CLS_STATS can be enabled or disabled at compile time. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-2-06d5fbf28984@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/Kconfig | 7 + + drivers/net/ethernet/airoha/airoha_eth.h | 33 +++ + drivers/net/ethernet/airoha/airoha_npu.c | 52 +++- + drivers/net/ethernet/airoha/airoha_npu.h | 4 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 269 ++++++++++++++++-- + .../net/ethernet/airoha/airoha_ppe_debugfs.c | 9 +- + 6 files changed, 354 insertions(+), 20 deletions(-) + +--- a/drivers/net/ethernet/airoha/Kconfig ++++ b/drivers/net/ethernet/airoha/Kconfig +@@ -24,4 +24,11 @@ config NET_AIROHA + This driver supports the gigabit ethernet MACs in the + Airoha SoC family. + ++config NET_AIROHA_FLOW_STATS ++ default y ++ bool "Airoha flow stats" ++ depends on NET_AIROHA && NET_AIROHA_NPU ++ help ++ Enable Aiorha flowtable statistic counters. ++ + endif #NET_VENDOR_AIROHA +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -50,6 +50,14 @@ + #define PPE_NUM 2 + #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) + #define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) ++#ifdef CONFIG_NET_AIROHA_FLOW_STATS ++#define PPE1_STATS_NUM_ENTRIES (4 * 1024) ++#else ++#define PPE1_STATS_NUM_ENTRIES 0 ++#endif /* CONFIG_NET_AIROHA_FLOW_STATS */ ++#define PPE_STATS_NUM_ENTRIES (2 * PPE1_STATS_NUM_ENTRIES) ++#define PPE1_SRAM_NUM_DATA_ENTRIES (PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES) ++#define PPE_SRAM_NUM_DATA_ENTRIES (2 * PPE1_SRAM_NUM_DATA_ENTRIES) + #define PPE_DRAM_NUM_ENTRIES (16 * 1024) + #define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) + #define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) +@@ -261,6 +269,8 @@ struct airoha_foe_mac_info { + + u16 pppoe_id; + u16 src_mac_lo; ++ ++ u32 meter; + }; + + #define AIROHA_FOE_IB1_UNBIND_PREBIND BIT(24) +@@ -296,6 +306,11 @@ struct airoha_foe_mac_info { + #define AIROHA_FOE_TUNNEL BIT(6) + #define AIROHA_FOE_TUNNEL_ID GENMASK(5, 0) + ++#define AIROHA_FOE_TUNNEL_MTU GENMASK(31, 16) ++#define AIROHA_FOE_ACNT_GRP3 GENMASK(15, 9) ++#define AIROHA_FOE_METER_GRP3 GENMASK(8, 5) ++#define AIROHA_FOE_METER_GRP2 GENMASK(4, 0) ++ + struct airoha_foe_bridge { + u32 dest_mac_hi; + +@@ -379,6 +394,8 @@ struct airoha_foe_ipv6 { + u32 ib2; + + struct airoha_foe_mac_info_common l2; ++ ++ u32 meter; + }; + + struct airoha_foe_entry { +@@ -397,6 +414,16 @@ struct airoha_foe_entry { + }; + }; + ++struct airoha_foe_stats { ++ u32 bytes; ++ u32 packets; ++}; ++ ++struct airoha_foe_stats64 { ++ u64 bytes; ++ u64 packets; ++}; ++ + struct airoha_flow_data { + struct ethhdr eth; + +@@ -447,6 +474,7 @@ struct airoha_flow_table_entry { + struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ + u32 hash; + ++ struct airoha_foe_stats64 stats; + enum airoha_flow_entry_type type; + + struct rhash_head node; +@@ -523,6 +551,9 @@ struct airoha_ppe { + struct hlist_head *foe_flow; + u16 foe_check_time[PPE_NUM_ENTRIES]; + ++ struct airoha_foe_stats *foe_stats; ++ dma_addr_t foe_stats_dma; ++ + struct dentry *debugfs_dir; + }; + +@@ -582,6 +613,8 @@ int airoha_ppe_init(struct airoha_eth *e + void airoha_ppe_deinit(struct airoha_eth *eth); + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash); ++void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, ++ struct airoha_foe_stats64 *stats); + + #ifdef CONFIG_DEBUG_FS + int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include "airoha_eth.h" + #include "airoha_npu.h" + + #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" +@@ -72,6 +73,7 @@ enum { + PPE_FUNC_SET_WAIT_HWNAT_INIT, + PPE_FUNC_SET_WAIT_HWNAT_DEINIT, + PPE_FUNC_SET_WAIT_API, ++ PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP, + }; + + enum { +@@ -115,6 +117,10 @@ struct ppe_mbox_data { + u32 size; + u32 data; + } set_info; ++ struct { ++ u32 npu_stats_addr; ++ u32 foe_stats_addr; ++ } stats_info; + }; + }; + +@@ -351,7 +357,40 @@ out: + return err; + } + +-struct airoha_npu *airoha_npu_get(struct device *dev) ++static int airoha_npu_stats_setup(struct airoha_npu *npu, ++ dma_addr_t foe_stats_addr) ++{ ++ int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); ++ struct ppe_mbox_data *ppe_data; ++ ++ if (!size) /* flow stats are disabled */ ++ return 0; ++ ++ ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); ++ if (!ppe_data) ++ return -ENOMEM; ++ ++ ppe_data->func_type = NPU_OP_SET; ++ ppe_data->func_id = PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP; ++ ppe_data->stats_info.foe_stats_addr = foe_stats_addr; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, ++ sizeof(*ppe_data)); ++ if (err) ++ goto out; ++ ++ npu->stats = devm_ioremap(npu->dev, ++ ppe_data->stats_info.npu_stats_addr, ++ size); ++ if (!npu->stats) ++ err = -ENOMEM; ++out: ++ kfree(ppe_data); ++ ++ return err; ++} ++ ++struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) + { + struct platform_device *pdev; + struct device_node *np; +@@ -389,6 +428,17 @@ struct airoha_npu *airoha_npu_get(struct + goto error_module_put; + } + ++ if (stats_addr) { ++ int err; ++ ++ err = airoha_npu_stats_setup(npu, *stats_addr); ++ if (err) { ++ dev_err(dev, "failed to allocate npu stats buffer\n"); ++ npu = ERR_PTR(err); ++ goto error_module_put; ++ } ++ } ++ + return npu; + + error_module_put: +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -17,6 +17,8 @@ struct airoha_npu { + struct work_struct wdt_work; + } cores[NPU_NUM_CORES]; + ++ struct airoha_foe_stats __iomem *stats; ++ + struct { + int (*ppe_init)(struct airoha_npu *npu); + int (*ppe_deinit)(struct airoha_npu *npu); +@@ -30,5 +32,5 @@ struct airoha_npu { + } ops; + }; + +-struct airoha_npu *airoha_npu_get(struct device *dev); ++struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); + void airoha_npu_put(struct airoha_npu *npu); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -102,7 +102,7 @@ static void airoha_ppe_hw_init(struct ai + + if (airoha_ppe2_is_enabled(eth)) { + sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_ENTRIES); ++ PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -119,7 +119,7 @@ static void airoha_ppe_hw_init(struct ai + dram_num_entries)); + } else { + sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_ENTRIES); ++ PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES); + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -417,6 +417,77 @@ static u32 airoha_ppe_foe_get_entry_hash + return hash; + } + ++static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) ++{ ++ if (!airoha_ppe2_is_enabled(ppe->eth)) ++ return hash; ++ ++ return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES ++ : hash; ++} ++ ++static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, ++ struct airoha_npu *npu, ++ int index) ++{ ++ memset_io(&npu->stats[index], 0, sizeof(*npu->stats)); ++ memset(&ppe->foe_stats[index], 0, sizeof(*ppe->foe_stats)); ++} ++ ++static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, ++ struct airoha_npu *npu) ++{ ++ int i; ++ ++ for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) ++ airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); ++} ++ ++static void airoha_ppe_foe_flow_stats_update(struct airoha_ppe *ppe, ++ struct airoha_npu *npu, ++ struct airoha_foe_entry *hwe, ++ u32 hash) ++{ ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ u32 index, pse_port, val, *data, *ib2, *meter; ++ u8 nbq; ++ ++ index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); ++ if (index >= PPE_STATS_NUM_ENTRIES) ++ return; ++ ++ if (type == PPE_PKT_TYPE_BRIDGE) { ++ data = &hwe->bridge.data; ++ ib2 = &hwe->bridge.ib2; ++ meter = &hwe->bridge.l2.meter; ++ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { ++ data = &hwe->ipv6.data; ++ ib2 = &hwe->ipv6.ib2; ++ meter = &hwe->ipv6.meter; ++ } else { ++ data = &hwe->ipv4.data; ++ ib2 = &hwe->ipv4.ib2; ++ meter = &hwe->ipv4.l2.meter; ++ } ++ ++ airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, index); ++ ++ val = FIELD_GET(AIROHA_FOE_CHANNEL | AIROHA_FOE_QID, *data); ++ *data = (*data & ~AIROHA_FOE_ACTDP) | ++ FIELD_PREP(AIROHA_FOE_ACTDP, val); ++ ++ val = *ib2 & (AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | ++ AIROHA_FOE_IB2_PSE_QOS | AIROHA_FOE_IB2_FAST_PATH); ++ *meter |= FIELD_PREP(AIROHA_FOE_TUNNEL_MTU, val); ++ ++ pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); ++ nbq = pse_port == 1 ? 6 : 5; ++ *ib2 &= ~(AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | ++ AIROHA_FOE_IB2_PSE_QOS); ++ *ib2 |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, 6) | ++ FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); ++} ++ + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash) + { +@@ -470,6 +541,8 @@ static int airoha_ppe_foe_commit_entry(s + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); + u32 ts = airoha_ppe_get_timestamp(ppe); + struct airoha_eth *eth = ppe->eth; ++ struct airoha_npu *npu; ++ int err = 0; + + memcpy(&hwe->d, &e->d, sizeof(*hwe) - sizeof(hwe->ib1)); + wmb(); +@@ -478,25 +551,28 @@ static int airoha_ppe_foe_commit_entry(s + e->ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_TIMESTAMP, ts); + hwe->ib1 = e->ib1; + ++ rcu_read_lock(); ++ ++ npu = rcu_dereference(eth->npu); ++ if (!npu) { ++ err = -ENODEV; ++ goto unlock; ++ } ++ ++ airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); ++ + if (hash < PPE_SRAM_NUM_ENTRIES) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); + bool ppe2 = airoha_ppe2_is_enabled(eth) && + hash >= PPE1_SRAM_NUM_ENTRIES; +- struct airoha_npu *npu; +- int err = -ENODEV; +- +- rcu_read_lock(); +- npu = rcu_dereference(eth->npu); +- if (npu) +- err = npu->ops.ppe_foe_commit_entry(npu, addr, +- sizeof(*hwe), hash, +- ppe2); +- rcu_read_unlock(); + +- return err; ++ err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), ++ hash, ppe2); + } ++unlock: ++ rcu_read_unlock(); + +- return 0; ++ return err; + } + + static void airoha_ppe_foe_remove_flow(struct airoha_ppe *ppe, +@@ -582,6 +658,7 @@ airoha_ppe_foe_commit_subflow_entry(stru + l2->common.etype = ETH_P_IPV6; + + hwe.bridge.ib2 = e->data.bridge.ib2; ++ hwe.bridge.data = e->data.bridge.data; + airoha_ppe_foe_commit_entry(ppe, &hwe, hash); + + return 0; +@@ -681,6 +758,98 @@ static int airoha_ppe_foe_flow_commit_en + return 0; + } + ++static int airoha_ppe_get_entry_idle_time(struct airoha_ppe *ppe, u32 ib1) ++{ ++ u32 state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); ++ u32 ts, ts_mask, now = airoha_ppe_get_timestamp(ppe); ++ int idle; ++ ++ if (state == AIROHA_FOE_STATE_BIND) { ++ ts = FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, ib1); ++ ts_mask = AIROHA_FOE_IB1_BIND_TIMESTAMP; ++ } else { ++ ts = FIELD_GET(AIROHA_FOE_IB1_UNBIND_TIMESTAMP, ib1); ++ now = FIELD_GET(AIROHA_FOE_IB1_UNBIND_TIMESTAMP, now); ++ ts_mask = AIROHA_FOE_IB1_UNBIND_TIMESTAMP; ++ } ++ idle = now - ts; ++ ++ return idle < 0 ? idle + ts_mask + 1 : idle; ++} ++ ++static void ++airoha_ppe_foe_flow_l2_entry_update(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ int min_idle = airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); ++ struct airoha_flow_table_entry *iter; ++ struct hlist_node *n; ++ ++ lockdep_assert_held(&ppe_lock); ++ ++ hlist_for_each_entry_safe(iter, n, &e->l2_flows, l2_subflow_node) { ++ struct airoha_foe_entry *hwe; ++ u32 ib1, state; ++ int idle; ++ ++ hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); ++ ib1 = READ_ONCE(hwe->ib1); ++ ++ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); ++ if (state != AIROHA_FOE_STATE_BIND) { ++ iter->hash = 0xffff; ++ airoha_ppe_foe_remove_flow(ppe, iter); ++ continue; ++ } ++ ++ idle = airoha_ppe_get_entry_idle_time(ppe, ib1); ++ if (idle >= min_idle) ++ continue; ++ ++ min_idle = idle; ++ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_TIMESTAMP; ++ e->data.ib1 |= ib1 & AIROHA_FOE_IB1_BIND_TIMESTAMP; ++ } ++} ++ ++static void airoha_ppe_foe_flow_entry_update(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ struct airoha_foe_entry *hwe_p, hwe = {}; ++ ++ spin_lock_bh(&ppe_lock); ++ ++ if (e->type == FLOW_TYPE_L2) { ++ airoha_ppe_foe_flow_l2_entry_update(ppe, e); ++ goto unlock; ++ } ++ ++ if (e->hash == 0xffff) ++ goto unlock; ++ ++ hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); ++ if (!hwe_p) ++ goto unlock; ++ ++ memcpy(&hwe, hwe_p, sizeof(*hwe_p)); ++ if (!airoha_ppe_foe_compare_entry(e, &hwe)) { ++ e->hash = 0xffff; ++ goto unlock; ++ } ++ ++ e->data.ib1 = hwe.ib1; ++unlock: ++ spin_unlock_bh(&ppe_lock); ++} ++ ++static int airoha_ppe_entry_idle_time(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ airoha_ppe_foe_flow_entry_update(ppe, e); ++ ++ return airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); ++} ++ + static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, + struct flow_cls_offload *f) + { +@@ -896,6 +1065,60 @@ static int airoha_ppe_flow_offload_destr + return 0; + } + ++void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, ++ struct airoha_foe_stats64 *stats) ++{ ++ u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); ++ struct airoha_eth *eth = ppe->eth; ++ struct airoha_npu *npu; ++ ++ if (index >= PPE_STATS_NUM_ENTRIES) ++ return; ++ ++ rcu_read_lock(); ++ ++ npu = rcu_dereference(eth->npu); ++ if (npu) { ++ u64 packets = ppe->foe_stats[index].packets; ++ u64 bytes = ppe->foe_stats[index].bytes; ++ struct airoha_foe_stats npu_stats; ++ ++ memcpy_fromio(&npu_stats, &npu->stats[index], ++ sizeof(*npu->stats)); ++ stats->packets = packets << 32 | npu_stats.packets; ++ stats->bytes = bytes << 32 | npu_stats.bytes; ++ } ++ ++ rcu_read_unlock(); ++} ++ ++static int airoha_ppe_flow_offload_stats(struct airoha_gdm_port *port, ++ struct flow_cls_offload *f) ++{ ++ struct airoha_eth *eth = port->qdma->eth; ++ struct airoha_flow_table_entry *e; ++ u32 idle; ++ ++ e = rhashtable_lookup(ð->flow_table, &f->cookie, ++ airoha_flow_table_params); ++ if (!e) ++ return -ENOENT; ++ ++ idle = airoha_ppe_entry_idle_time(eth->ppe, e); ++ f->stats.lastused = jiffies - idle * HZ; ++ ++ if (e->hash != 0xffff) { ++ struct airoha_foe_stats64 stats = {}; ++ ++ airoha_ppe_foe_entry_get_stats(eth->ppe, e->hash, &stats); ++ f->stats.pkts += (stats.packets - e->stats.packets); ++ f->stats.bytes += (stats.bytes - e->stats.bytes); ++ e->stats = stats; ++ } ++ ++ return 0; ++} ++ + static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, + struct flow_cls_offload *f) + { +@@ -904,6 +1127,8 @@ static int airoha_ppe_flow_offload_cmd(s + return airoha_ppe_flow_offload_replace(port, f); + case FLOW_CLS_DESTROY: + return airoha_ppe_flow_offload_destroy(port, f); ++ case FLOW_CLS_STATS: ++ return airoha_ppe_flow_offload_stats(port, f); + default: + break; + } +@@ -929,11 +1154,12 @@ static int airoha_ppe_flush_sram_entries + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) + { +- struct airoha_npu *npu = airoha_npu_get(eth->dev); ++ struct airoha_npu *npu = airoha_npu_get(eth->dev, ++ ð->ppe->foe_stats_dma); + + if (IS_ERR(npu)) { + request_module("airoha-npu"); +- npu = airoha_npu_get(eth->dev); ++ npu = airoha_npu_get(eth->dev, ð->ppe->foe_stats_dma); + } + + return npu; +@@ -956,6 +1182,8 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + ++ airoha_ppe_foe_flow_stats_reset(eth->ppe, npu); ++ + rcu_assign_pointer(eth->npu, npu); + synchronize_rcu(); + +@@ -1027,6 +1255,15 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_flow) + return -ENOMEM; + ++ foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); ++ if (foe_size) { ++ ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size, ++ &ppe->foe_stats_dma, ++ GFP_KERNEL); ++ if (!ppe->foe_stats) ++ return -ENOMEM; ++ } ++ + err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); + if (err) + return err; +--- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c +@@ -61,6 +61,7 @@ static int airoha_ppe_debugfs_foe_show(s + u16 *src_port = NULL, *dest_port = NULL; + struct airoha_foe_mac_info_common *l2; + unsigned char h_source[ETH_ALEN] = {}; ++ struct airoha_foe_stats64 stats = {}; + unsigned char h_dest[ETH_ALEN]; + struct airoha_foe_entry *hwe; + u32 type, state, ib2, data; +@@ -144,14 +145,18 @@ static int airoha_ppe_debugfs_foe_show(s + cpu_to_be16(hwe->ipv4.l2.src_mac_lo); + } + ++ airoha_ppe_foe_entry_get_stats(ppe, i, &stats); ++ + *((__be32 *)h_dest) = cpu_to_be32(l2->dest_mac_hi); + *((__be16 *)&h_dest[4]) = cpu_to_be16(l2->dest_mac_lo); + *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); + + seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x" +- " vlan=%d,%d ib1=%08x ib2=%08x\n", ++ " vlan=%d,%d ib1=%08x ib2=%08x" ++ " packets=%llu bytes=%llu\n", + h_source, h_dest, l2->etype, data, +- l2->vlan1, l2->vlan2, hwe->ib1, ib2); ++ l2->vlan1, l2->vlan2, hwe->ib1, ib2, ++ stats.packets, stats.bytes); + } + + return 0; diff --git a/target/linux/airoha/patches-6.6/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch b/target/linux/airoha/patches-6.6/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch new file mode 100644 index 0000000000..30c74ddec6 --- /dev/null +++ b/target/linux/airoha/patches-6.6/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch @@ -0,0 +1,28 @@ +From a98326c151ea3d92e9496858cc2dacccd0870941 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 16 May 2025 10:00:01 +0200 +Subject: [PATCH 3/3] net: airoha: ppe: Disable packet keepalive + +Since netfilter flowtable entries are now refreshed by flow-stats +polling, we can disable hw packet keepalive used to periodically send +packets belonging to offloaded flows to the kernel in order to refresh +flowtable entries. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-3-06d5fbf28984@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -84,6 +84,7 @@ static void airoha_ppe_hw_init(struct ai + + airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), + PPE_TB_CFG_SEARCH_MISS_MASK | ++ PPE_TB_CFG_KEEPALIVE_MASK | + PPE_TB_ENTRY_SIZE_MASK, + FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | + FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); diff --git a/target/linux/airoha/patches-6.6/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch b/target/linux/airoha/patches-6.6/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch new file mode 100644 index 0000000000..81d708f8ce --- /dev/null +++ b/target/linux/airoha/patches-6.6/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch @@ -0,0 +1,57 @@ +From 09aa788f98da3e2f41ce158cc691d6d52e808bc9 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 21 May 2025 09:16:37 +0200 +Subject: [PATCH 1/3] net: airoha: Do not store hfwd references in airoha_qdma + struct + +Since hfwd descriptor and buffer queues are allocated via +dmam_alloc_coherent() we do not need to store their references +in airoha_qdma struct. This patch does not introduce any logical changes, +just code clean-up. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-2-a6e9b085b4f0@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 8 ++------ + drivers/net/ethernet/airoha/airoha_eth.h | 6 ------ + 2 files changed, 2 insertions(+), 12 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1078,17 +1078,13 @@ static int airoha_qdma_init_hfwd_queues( + int size; + + size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); +- qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, +- GFP_KERNEL); +- if (!qdma->hfwd.desc) ++ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) + return -ENOMEM; + + airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); + + size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; +- qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, +- GFP_KERNEL); +- if (!qdma->hfwd.q) ++ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) + return -ENOMEM; + + airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -513,12 +513,6 @@ struct airoha_qdma { + + struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; + struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; +- +- /* descriptor and packet buffers for qdma hw forward */ +- struct { +- void *desc; +- void *q; +- } hfwd; + }; + + struct airoha_gdm_port { diff --git a/target/linux/airoha/patches-6.6/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch b/target/linux/airoha/patches-6.6/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch new file mode 100644 index 0000000000..d6f3e94f09 --- /dev/null +++ b/target/linux/airoha/patches-6.6/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch @@ -0,0 +1,79 @@ +From 3a1ce9e3d01bbf3912c3e3f81cb554d558eb715b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 21 May 2025 09:16:38 +0200 +Subject: [PATCH 2/3] net: airoha: Add the capability to allocate hwfd buffers + via reserved-memory + +In some configurations QDMA blocks require a contiguous block of +system memory for hwfd buffers queue. Introduce the capability to allocate +hw buffers forwarding queue via the reserved-memory DTS property instead of +running dmam_alloc_coherent(). + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-3-a6e9b085b4f0@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 33 +++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -5,6 +5,7 @@ + */ + #include + #include ++#include + #include + #include + #include +@@ -1073,9 +1074,11 @@ static void airoha_qdma_cleanup_tx_queue + static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) + { + struct airoha_eth *eth = qdma->eth; ++ int id = qdma - ð->qdma[0]; + dma_addr_t dma_addr; ++ const char *name; ++ int size, index; + u32 status; +- int size; + + size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); + if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) +@@ -1083,10 +1086,34 @@ static int airoha_qdma_init_hfwd_queues( + + airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); + +- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; +- if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) ++ name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); ++ if (!name) + return -ENOMEM; + ++ index = of_property_match_string(eth->dev->of_node, ++ "memory-region-names", name); ++ if (index >= 0) { ++ struct reserved_mem *rmem; ++ struct device_node *np; ++ ++ /* Consume reserved memory for hw forwarding buffers queue if ++ * available in the DTS ++ */ ++ np = of_parse_phandle(eth->dev->of_node, "memory-region", ++ index); ++ if (!np) ++ return -ENODEV; ++ ++ rmem = of_reserved_mem_lookup(np); ++ of_node_put(np); ++ dma_addr = rmem->base; ++ } else { ++ size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; ++ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, ++ GFP_KERNEL)) ++ return -ENOMEM; ++ } ++ + airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); + + airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, diff --git a/target/linux/airoha/patches-6.6/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch b/target/linux/airoha/patches-6.6/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch new file mode 100644 index 0000000000..a380adf3b7 --- /dev/null +++ b/target/linux/airoha/patches-6.6/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch @@ -0,0 +1,82 @@ +From c683e378c0907e66cee939145edf936c254ff1e3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 21 May 2025 09:16:39 +0200 +Subject: [PATCH 3/3] net: airoha: Add the capability to allocate hfwd + descriptors in SRAM + +In order to improve packet processing and packet forwarding +performances, EN7581 SoC supports consuming SRAM instead of DRAM for +hw forwarding descriptors queue. +For downlink hw accelerated traffic request to consume SRAM memory +for hw forwarding descriptors queue. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-4-a6e9b085b4f0@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 11 +---------- + drivers/net/ethernet/airoha/airoha_eth.h | 9 +++++++++ + drivers/net/ethernet/airoha/airoha_ppe.c | 6 ++++++ + 3 files changed, 16 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -71,15 +71,6 @@ static void airoha_qdma_irq_disable(stru + airoha_qdma_set_irqmask(irq_bank, index, mask, 0); + } + +-static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) +-{ +- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. +- * GDM{2,3,4} can be used as wan port connected to an external +- * phy module. +- */ +- return port->id == 1; +-} +- + static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) + { + struct airoha_eth *eth = port->qdma->eth; +@@ -1125,7 +1116,7 @@ static int airoha_qdma_init_hfwd_queues( + LMGR_INIT_START | LMGR_SRAM_MODE_MASK | + HW_FWD_DESC_NUM_MASK, + FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | +- LMGR_INIT_START); ++ LMGR_INIT_START | LMGR_SRAM_MODE_MASK); + + return read_poll_timeout(airoha_qdma_rr, status, + !(status & LMGR_INIT_START), USEC_PER_MSEC, +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -597,6 +597,15 @@ u32 airoha_rmw(void __iomem *base, u32 o + #define airoha_qdma_clear(qdma, offset, val) \ + airoha_rmw((qdma)->regs, (offset), (val), 0) + ++static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) ++{ ++ /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. ++ * GDM{2,3,4} can be used as wan port connected to an external ++ * phy module. ++ */ ++ return port->id == 1; ++} ++ + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -251,6 +251,12 @@ static int airoha_ppe_foe_entry_prepare( + else + pse_port = 2; /* uplink relies on GDM2 loopback */ + val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); ++ ++ /* For downlink traffic consume SRAM memory for hw forwarding ++ * descriptors queue. ++ */ ++ if (airhoa_is_lan_gdm_port(port)) ++ val |= AIROHA_FOE_IB2_FAST_PATH; + } + + if (is_multicast_ether_addr(data->eth.h_dest)) diff --git a/target/linux/airoha/patches-6.6/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch b/target/linux/airoha/patches-6.6/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch new file mode 100644 index 0000000000..8606cfff58 --- /dev/null +++ b/target/linux/airoha/patches-6.6/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch @@ -0,0 +1,42 @@ +From c59783780c8ad66f6076a9a7c74df3e006e29519 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 24 May 2025 09:29:11 +0200 +Subject: [PATCH] net: airoha: Fix an error handling path in + airoha_alloc_gdm_port() + +If register_netdev() fails, the error handling path of the probe will not +free the memory allocated by the previous airoha_metadata_dst_alloc() call +because port->dev->reg_state will not be NETREG_REGISTERED. + +So, an explicit airoha_metadata_dst_free() call is needed in this case to +avoid a memory leak. + +Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor") +Signed-off-by: Christophe JAILLET +Acked-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/1b94b91345017429ed653e2f05d25620dc2823f9.1746715755.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2881,7 +2881,15 @@ static int airoha_alloc_gdm_port(struct + if (err) + return err; + +- return register_netdev(dev); ++ err = register_netdev(dev); ++ if (err) ++ goto free_metadata_dst; ++ ++ return 0; ++ ++free_metadata_dst: ++ airoha_metadata_dst_free(port); ++ return err; + } + + static int airoha_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.6/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch b/target/linux/airoha/patches-6.6/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch new file mode 100644 index 0000000000..334661dd96 --- /dev/null +++ b/target/linux/airoha/patches-6.6/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch @@ -0,0 +1,122 @@ +From a869d3a5eb011a9cf9bd864f31f5cf27362de8c7 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 2 Jun 2025 12:55:37 +0200 +Subject: [PATCH 1/3] net: airoha: Initialize PPE UPDMEM source-mac table + +UPDMEM source-mac table is a key-value map used to store devices mac +addresses according to the port identifier. UPDMEM source mac table is +used during IPv6 traffic hw acceleration since PPE entries, for space +constraints, do not contain the full source mac address but just the +identifier in the UPDMEM source-mac table. +Configure UPDMEM source-mac table with device mac addresses and set +the source-mac ID field for PPE IPv6 entries in order to select the +proper device mac address as source mac for L3 IPv6 hw accelerated traffic. + +Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-1-3287f8b55214@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 2 ++ + drivers/net/ethernet/airoha/airoha_eth.h | 1 + + drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++++++++++++++++++++++- + drivers/net/ethernet/airoha/airoha_regs.h | 10 +++++++++ + 4 files changed, 38 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -84,6 +84,8 @@ static void airoha_set_macaddr(struct ai + val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; + airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); + airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); ++ ++ airoha_ppe_init_upd_mem(port); + } + + static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -614,6 +614,7 @@ void airoha_ppe_check_skb(struct airoha_ + int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); ++void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash); + void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -223,6 +223,7 @@ static int airoha_ppe_foe_entry_prepare( + int dsa_port = airoha_get_dsa_port(&dev); + struct airoha_foe_mac_info_common *l2; + u32 qdata, ports_pad, val; ++ u8 smac_id = 0xf; + + memset(hwe, 0, sizeof(*hwe)); + +@@ -257,6 +258,8 @@ static int airoha_ppe_foe_entry_prepare( + */ + if (airhoa_is_lan_gdm_port(port)) + val |= AIROHA_FOE_IB2_FAST_PATH; ++ ++ smac_id = port->id; + } + + if (is_multicast_ether_addr(data->eth.h_dest)) +@@ -291,7 +294,7 @@ static int airoha_ppe_foe_entry_prepare( + hwe->ipv4.l2.src_mac_lo = + get_unaligned_be16(data->eth.h_source + 4); + } else { +- l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf); ++ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id); + } + + if (data->vlan.num) { +@@ -1238,6 +1241,27 @@ void airoha_ppe_check_skb(struct airoha_ + airoha_ppe_foe_insert_entry(ppe, skb, hash); + } + ++void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) ++{ ++ struct airoha_eth *eth = port->qdma->eth; ++ struct net_device *dev = port->dev; ++ const u8 *addr = dev->dev_addr; ++ u32 val; ++ ++ val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; ++ airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val); ++ airoha_fe_wr(eth, REG_UPDMEM_CTRL(0), ++ FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) | ++ PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); ++ ++ val = (addr[0] << 8) | addr[1]; ++ airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val); ++ airoha_fe_wr(eth, REG_UPDMEM_CTRL(0), ++ FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) | ++ FIELD_PREP(PPE_UPDMEM_OFFSET_MASK, 1) | ++ PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); ++} ++ + int airoha_ppe_init(struct airoha_eth *eth) + { + struct airoha_ppe *ppe; +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -313,6 +313,16 @@ + #define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320) + #define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2)) + ++#define REG_UPDMEM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x370) ++#define PPE_UPDMEM_ACK_MASK BIT(31) ++#define PPE_UPDMEM_ADDR_MASK GENMASK(11, 8) ++#define PPE_UPDMEM_OFFSET_MASK GENMASK(7, 4) ++#define PPE_UPDMEM_SEL_MASK GENMASK(3, 2) ++#define PPE_UPDMEM_WR_MASK BIT(1) ++#define PPE_UPDMEM_REQ_MASK BIT(0) ++ ++#define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374) ++ + #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) + #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) + #define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) diff --git a/target/linux/airoha/patches-6.6/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch b/target/linux/airoha/patches-6.6/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch new file mode 100644 index 0000000000..faa7669e0d --- /dev/null +++ b/target/linux/airoha/patches-6.6/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch @@ -0,0 +1,64 @@ +From 504a577c9b000f9e0e99e1b28616fb4eb369e1ef Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 2 Jun 2025 12:55:38 +0200 +Subject: [PATCH 2/3] net: airoha: Fix IPv6 hw acceleration in bridge mode + +ib2 and airoha_foe_mac_info_common have not the same offsets in +airoha_foe_bridge and airoha_foe_ipv6 structures. Current codebase does +not accelerate IPv6 traffic in bridge mode since ib2 and l2 info are not +set properly copying airoha_foe_bridge struct into airoha_foe_ipv6 one +in airoha_ppe_foe_commit_subflow_entry routine. +Fix IPv6 hw acceleration in bridge mode resolving ib2 and +airoha_foe_mac_info_common overwrite in +airoha_ppe_foe_commit_subflow_entry() and configuring them with proper +values. + +Fixes: cd53f622611f ("net: airoha: Add L2 hw acceleration support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-2-3287f8b55214@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -639,7 +639,6 @@ airoha_ppe_foe_commit_subflow_entry(stru + u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; + struct airoha_foe_entry *hwe_p, hwe; + struct airoha_flow_table_entry *f; +- struct airoha_foe_mac_info *l2; + int type; + + hwe_p = airoha_ppe_foe_get_entry(ppe, hash); +@@ -656,18 +655,20 @@ airoha_ppe_foe_commit_subflow_entry(stru + + memcpy(&hwe, hwe_p, sizeof(*hwe_p)); + hwe.ib1 = (hwe.ib1 & mask) | (e->data.ib1 & ~mask); +- l2 = &hwe.bridge.l2; +- memcpy(l2, &e->data.bridge.l2, sizeof(*l2)); + + type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe.ib1); +- if (type == PPE_PKT_TYPE_IPV4_HNAPT) +- memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, +- sizeof(hwe.ipv4.new_tuple)); +- else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T && +- l2->common.etype == ETH_P_IP) +- l2->common.etype = ETH_P_IPV6; ++ if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { ++ memcpy(&hwe.ipv6.l2, &e->data.bridge.l2, sizeof(hwe.ipv6.l2)); ++ hwe.ipv6.ib2 = e->data.bridge.ib2; ++ } else { ++ memcpy(&hwe.bridge.l2, &e->data.bridge.l2, ++ sizeof(hwe.bridge.l2)); ++ hwe.bridge.ib2 = e->data.bridge.ib2; ++ if (type == PPE_PKT_TYPE_IPV4_HNAPT) ++ memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, ++ sizeof(hwe.ipv4.new_tuple)); ++ } + +- hwe.bridge.ib2 = e->data.bridge.ib2; + hwe.bridge.data = e->data.bridge.data; + airoha_ppe_foe_commit_entry(ppe, &hwe, hash); + diff --git a/target/linux/airoha/patches-6.6/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch b/target/linux/airoha/patches-6.6/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch new file mode 100644 index 0000000000..f790d9d148 --- /dev/null +++ b/target/linux/airoha/patches-6.6/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch @@ -0,0 +1,32 @@ +From c86fac5365d3a068422beeb508f2741f1a2d734d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 2 Jun 2025 12:55:39 +0200 +Subject: [PATCH 3/3] net: airoha: Fix smac_id configuration in bridge mode + +Set PPE entry smac_id field to 0xf in airoha_ppe_foe_commit_subflow_entry +routine for IPv6 traffic in order to instruct the hw to keep original +source mac address for IPv6 hw accelerated traffic in bridge mode. + +Fixes: cd53f622611f ("net: airoha: Add L2 hw acceleration support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-3-3287f8b55214@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -660,6 +660,11 @@ airoha_ppe_foe_commit_subflow_entry(stru + if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { + memcpy(&hwe.ipv6.l2, &e->data.bridge.l2, sizeof(hwe.ipv6.l2)); + hwe.ipv6.ib2 = e->data.bridge.ib2; ++ /* setting smac_id to 0xf instruct the hw to keep original ++ * source mac address ++ */ ++ hwe.ipv6.l2.src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, ++ 0xf); + } else { + memcpy(&hwe.bridge.l2, &e->data.bridge.l2, + sizeof(hwe.bridge.l2)); diff --git a/target/linux/airoha/patches-6.6/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch b/target/linux/airoha/patches-6.6/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch new file mode 100644 index 0000000000..6245f0d218 --- /dev/null +++ b/target/linux/airoha/patches-6.6/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch @@ -0,0 +1,87 @@ +From 0097c4195b1d0ca57d15979626c769c74747b5a0 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 9 Jun 2025 22:28:40 +0200 +Subject: [PATCH] net: airoha: Add PPPoE offload support + +Introduce flowtable hw acceleration for PPPoE traffic. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250609-b4-airoha-flowtable-pppoe-v1-1-1520fa7711b4@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 31 ++++++++++++++++++------ + 1 file changed, 23 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -232,6 +232,7 @@ static int airoha_ppe_foe_entry_prepare( + FIELD_PREP(AIROHA_FOE_IB1_BIND_UDP, l4proto == IPPROTO_UDP) | + FIELD_PREP(AIROHA_FOE_IB1_BIND_VLAN_LAYER, data->vlan.num) | + FIELD_PREP(AIROHA_FOE_IB1_BIND_VPM, data->vlan.num) | ++ FIELD_PREP(AIROHA_FOE_IB1_BIND_PPPOE, data->pppoe.num) | + AIROHA_FOE_IB1_BIND_TTL; + hwe->ib1 = val; + +@@ -281,33 +282,42 @@ static int airoha_ppe_foe_entry_prepare( + hwe->ipv6.data = qdata; + hwe->ipv6.ib2 = val; + l2 = &hwe->ipv6.l2; ++ l2->etype = ETH_P_IPV6; + } else { + hwe->ipv4.data = qdata; + hwe->ipv4.ib2 = val; + l2 = &hwe->ipv4.l2.common; ++ l2->etype = ETH_P_IP; + } + + l2->dest_mac_hi = get_unaligned_be32(data->eth.h_dest); + l2->dest_mac_lo = get_unaligned_be16(data->eth.h_dest + 4); + if (type <= PPE_PKT_TYPE_IPV4_DSLITE) { ++ struct airoha_foe_mac_info *mac_info; ++ + l2->src_mac_hi = get_unaligned_be32(data->eth.h_source); + hwe->ipv4.l2.src_mac_lo = + get_unaligned_be16(data->eth.h_source + 4); ++ ++ mac_info = (struct airoha_foe_mac_info *)l2; ++ mac_info->pppoe_id = data->pppoe.sid; + } else { +- l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id); ++ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id) | ++ FIELD_PREP(AIROHA_FOE_MAC_PPPOE_ID, ++ data->pppoe.sid); + } + + if (data->vlan.num) { +- l2->etype = dsa_port >= 0 ? BIT(dsa_port) : 0; + l2->vlan1 = data->vlan.hdr[0].id; + if (data->vlan.num == 2) + l2->vlan2 = data->vlan.hdr[1].id; +- } else if (dsa_port >= 0) { +- l2->etype = BIT(15) | BIT(dsa_port); +- } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { +- l2->etype = ETH_P_IPV6; +- } else { +- l2->etype = ETH_P_IP; ++ } ++ ++ if (dsa_port >= 0) { ++ l2->etype = BIT(dsa_port); ++ l2->etype |= !data->vlan.num ? BIT(15) : 0; ++ } else if (data->pppoe.num) { ++ l2->etype = ETH_P_PPP_SES; + } + + return 0; +@@ -957,6 +967,11 @@ static int airoha_ppe_flow_offload_repla + case FLOW_ACTION_VLAN_POP: + break; + case FLOW_ACTION_PPPOE_PUSH: ++ if (data.pppoe.num == 1 || data.vlan.num == 2) ++ return -EOPNOTSUPP; ++ ++ data.pppoe.sid = act->pppoe.sid; ++ data.pppoe.num++; + break; + default: + return -EOPNOTSUPP; diff --git a/target/linux/airoha/patches-6.6/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch b/target/linux/airoha/patches-6.6/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch new file mode 100644 index 0000000000..1550c59261 --- /dev/null +++ b/target/linux/airoha/patches-6.6/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch @@ -0,0 +1,28 @@ +From f478d68b653323b691280b40fbd3b8ca1ac75aa2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 9 Jun 2025 22:40:35 +0200 +Subject: [PATCH] net: airoha: Enable RX queues 16-31 + +Fix RX_DONE_INT_MASK definition in order to enable RX queues 16-31. + +Fixes: f252493e18353 ("net: airoha: Enable multiple IRQ lines support in airoha_eth driver.") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250609-aioha-fix-rx-queue-mask-v1-1-f33706a06fa2@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_regs.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -614,8 +614,9 @@ + RX19_DONE_INT_MASK | RX18_DONE_INT_MASK | \ + RX17_DONE_INT_MASK | RX16_DONE_INT_MASK) + +-#define RX_DONE_INT_MASK (RX_DONE_HIGH_INT_MASK | RX_DONE_LOW_INT_MASK) + #define RX_DONE_HIGH_OFFSET fls(RX_DONE_HIGH_INT_MASK) ++#define RX_DONE_INT_MASK \ ++ ((RX_DONE_HIGH_INT_MASK << RX_DONE_HIGH_OFFSET) | RX_DONE_LOW_INT_MASK) + + #define INT_RX2_MASK(_n) \ + ((RX_NO_CPU_DSCP_HIGH_INT_MASK & (_n)) | \ diff --git a/target/linux/airoha/patches-6.6/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch b/target/linux/airoha/patches-6.6/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch new file mode 100644 index 0000000000..551e8e3c9d --- /dev/null +++ b/target/linux/airoha/patches-6.6/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch @@ -0,0 +1,32 @@ +From 78bd03ee1f20a267d2c218884b66041b3508ac9c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 18 Jun 2025 09:37:40 +0200 +Subject: [PATCH] net: airoha: Always check return value from + airoha_ppe_foe_get_entry() + +airoha_ppe_foe_get_entry routine can return NULL, so check the returned +pointer is not NULL in airoha_ppe_foe_flow_l2_entry_update() + +Fixes: b81e0f2b58be3 ("net: airoha: Add FLOW_CLS_STATS callback support") +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250618-check-ret-from-airoha_ppe_foe_get_entry-v2-1-068dcea3cc66@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -819,8 +819,10 @@ airoha_ppe_foe_flow_l2_entry_update(stru + int idle; + + hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); +- ib1 = READ_ONCE(hwe->ib1); ++ if (!hwe) ++ continue; + ++ ib1 = READ_ONCE(hwe->ib1); + state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); + if (state != AIROHA_FOE_STATE_BIND) { + iter->hash = 0xffff; diff --git a/target/linux/airoha/patches-6.6/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch b/target/linux/airoha/patches-6.6/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch new file mode 100644 index 0000000000..9d419c33db --- /dev/null +++ b/target/linux/airoha/patches-6.6/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch @@ -0,0 +1,77 @@ +From edf8afeecfbb0b8c1a2edb8c8892d2f759d35321 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 19 Jun 2025 09:07:24 +0200 +Subject: [PATCH 1/2] net: airoha: Compute number of descriptors according to + reserved memory size + +In order to not exceed the reserved memory size for hwfd buffers, +compute the number of hwfd buffers/descriptors according to the +reserved memory size and the size of each hwfd buffer (2KB). + +Fixes: 3a1ce9e3d01b ("net: airoha: Add the capability to allocate hwfd buffers via reserved-memory") +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250619-airoha-hw-num-desc-v4-1-49600a9b319a@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1066,19 +1066,13 @@ static void airoha_qdma_cleanup_tx_queue + + static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) + { ++ int size, index, num_desc = HW_DSCP_NUM; + struct airoha_eth *eth = qdma->eth; + int id = qdma - ð->qdma[0]; + dma_addr_t dma_addr; + const char *name; +- int size, index; + u32 status; + +- size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); +- if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) +- return -ENOMEM; +- +- airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); +- + name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); + if (!name) + return -ENOMEM; +@@ -1100,8 +1094,12 @@ static int airoha_qdma_init_hfwd_queues( + rmem = of_reserved_mem_lookup(np); + of_node_put(np); + dma_addr = rmem->base; ++ /* Compute the number of hw descriptors according to the ++ * reserved memory size and the payload buffer size ++ */ ++ num_desc = rmem->size / AIROHA_MAX_PACKET_SIZE; + } else { +- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; ++ size = AIROHA_MAX_PACKET_SIZE * num_desc; + if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, + GFP_KERNEL)) + return -ENOMEM; +@@ -1109,6 +1107,11 @@ static int airoha_qdma_init_hfwd_queues( + + airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); + ++ size = num_desc * sizeof(struct airoha_qdma_fwd_desc); ++ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) ++ return -ENOMEM; ++ ++ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); + airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, + HW_FWD_DSCP_PAYLOAD_SIZE_MASK, + FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); +@@ -1117,7 +1120,7 @@ static int airoha_qdma_init_hfwd_queues( + airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, + LMGR_INIT_START | LMGR_SRAM_MODE_MASK | + HW_FWD_DESC_NUM_MASK, +- FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | ++ FIELD_PREP(HW_FWD_DESC_NUM_MASK, num_desc) | + LMGR_INIT_START | LMGR_SRAM_MODE_MASK); + + return read_poll_timeout(airoha_qdma_rr, status, diff --git a/target/linux/airoha/patches-6.6/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch b/target/linux/airoha/patches-6.6/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch new file mode 100644 index 0000000000..d47fc43413 --- /dev/null +++ b/target/linux/airoha/patches-6.6/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch @@ -0,0 +1,64 @@ +From 7b46bdaec00a675f6fac9d0b01a2105b5746ebe9 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 19 Jun 2025 09:07:25 +0200 +Subject: [PATCH 2/2] net: airoha: Differentiate hwfd buffer size for QDMA0 and + QDMA1 + +EN7581 SoC allows configuring the size and the number of buffers in +hwfd payload queue for both QDMA0 and QDMA1. +In order to reduce the required DRAM used for hwfd buffers queues and +decrease the memory footprint, differentiate hwfd buffer size for QDMA0 +and QDMA1 and reduce hwfd buffer size to 1KB for QDMA1 (WAN) while +maintaining 2KB for QDMA0 (LAN). + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250619-airoha-hw-num-desc-v4-2-49600a9b319a@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1069,14 +1069,15 @@ static int airoha_qdma_init_hfwd_queues( + int size, index, num_desc = HW_DSCP_NUM; + struct airoha_eth *eth = qdma->eth; + int id = qdma - ð->qdma[0]; ++ u32 status, buf_size; + dma_addr_t dma_addr; + const char *name; +- u32 status; + + name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); + if (!name) + return -ENOMEM; + ++ buf_size = id ? AIROHA_MAX_PACKET_SIZE / 2 : AIROHA_MAX_PACKET_SIZE; + index = of_property_match_string(eth->dev->of_node, + "memory-region-names", name); + if (index >= 0) { +@@ -1097,9 +1098,9 @@ static int airoha_qdma_init_hfwd_queues( + /* Compute the number of hw descriptors according to the + * reserved memory size and the payload buffer size + */ +- num_desc = rmem->size / AIROHA_MAX_PACKET_SIZE; ++ num_desc = div_u64(rmem->size, buf_size); + } else { +- size = AIROHA_MAX_PACKET_SIZE * num_desc; ++ size = buf_size * num_desc; + if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, + GFP_KERNEL)) + return -ENOMEM; +@@ -1112,9 +1113,10 @@ static int airoha_qdma_init_hfwd_queues( + return -ENOMEM; + + airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); ++ /* QDMA0: 2KB. QDMA1: 1KB */ + airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, + HW_FWD_DSCP_PAYLOAD_SIZE_MASK, +- FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); ++ FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, !!id)); + airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, + FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); + airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, diff --git a/target/linux/airoha/patches-6.6/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch b/target/linux/airoha/patches-6.6/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch new file mode 100644 index 0000000000..919b6b44da --- /dev/null +++ b/target/linux/airoha/patches-6.6/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch @@ -0,0 +1,92 @@ +From 38358fa3cc8e16c6862a3e5c5c233f9f652e3a6d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 31 Jul 2025 12:29:08 +0200 +Subject: [PATCH] net: airoha: Fix PPE table access in + airoha_ppe_debugfs_foe_show() + +In order to avoid any possible race we need to hold the ppe_lock +spinlock accessing the hw PPE table. airoha_ppe_foe_get_entry routine is +always executed holding ppe_lock except in airoha_ppe_debugfs_foe_show +routine. Fix the problem introducing airoha_ppe_foe_get_entry_locked +routine. + +Fixes: 3fe15c640f380 ("net: airoha: Introduce PPE debugfs support") +Reviewed-by: Dawid Osuchowski +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250731-airoha_ppe_foe_get_entry_locked-v2-1-50efbd8c0fd6@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -508,9 +508,11 @@ static void airoha_ppe_foe_flow_stats_up + FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); + } + +-struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, +- u32 hash) ++static struct airoha_foe_entry * ++airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) + { ++ lockdep_assert_held(&ppe_lock); ++ + if (hash < PPE_SRAM_NUM_ENTRIES) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); + struct airoha_eth *eth = ppe->eth; +@@ -537,6 +539,18 @@ struct airoha_foe_entry *airoha_ppe_foe_ + return ppe->foe + hash * sizeof(struct airoha_foe_entry); + } + ++struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, ++ u32 hash) ++{ ++ struct airoha_foe_entry *hwe; ++ ++ spin_lock_bh(&ppe_lock); ++ hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); ++ spin_unlock_bh(&ppe_lock); ++ ++ return hwe; ++} ++ + static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, + struct airoha_foe_entry *hwe) + { +@@ -651,7 +665,7 @@ airoha_ppe_foe_commit_subflow_entry(stru + struct airoha_flow_table_entry *f; + int type; + +- hwe_p = airoha_ppe_foe_get_entry(ppe, hash); ++ hwe_p = airoha_ppe_foe_get_entry_locked(ppe, hash); + if (!hwe_p) + return -EINVAL; + +@@ -703,7 +717,7 @@ static void airoha_ppe_foe_insert_entry( + + spin_lock_bh(&ppe_lock); + +- hwe = airoha_ppe_foe_get_entry(ppe, hash); ++ hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); + if (!hwe) + goto unlock; + +@@ -818,7 +832,7 @@ airoha_ppe_foe_flow_l2_entry_update(stru + u32 ib1, state; + int idle; + +- hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); ++ hwe = airoha_ppe_foe_get_entry_locked(ppe, iter->hash); + if (!hwe) + continue; + +@@ -855,7 +869,7 @@ static void airoha_ppe_foe_flow_entry_up + if (e->hash == 0xffff) + goto unlock; + +- hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); ++ hwe_p = airoha_ppe_foe_get_entry_locked(ppe, e->hash); + if (!hwe_p) + goto unlock; + diff --git a/target/linux/airoha/patches-6.6/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch b/target/linux/airoha/patches-6.6/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch new file mode 100644 index 0000000000..eda914aab7 --- /dev/null +++ b/target/linux/airoha/patches-6.6/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch @@ -0,0 +1,42 @@ +From 9f6b606b6b37e61427412708411e8e04b1a858e8 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 18 Aug 2025 11:58:25 +0200 +Subject: [PATCH] net: airoha: ppe: Do not invalid PPE entries in case of SW + hash collision + +SW hash computed by airoha_ppe_foe_get_entry_hash routine (used for +foe_flow hlist) can theoretically produce collisions between two +different HW PPE entries. +In airoha_ppe_foe_insert_entry() if the collision occurs we will mark +the second PPE entry in the list as stale (setting the hw hash to 0xffff). +Stale entries are no more updated in airoha_ppe_foe_flow_entry_update +routine and so they are removed by Netfilter. +Fix the problem not marking the second entry as stale in +airoha_ppe_foe_insert_entry routine if we have already inserted the +brand new entry in the PPE table and let Netfilter remove real stale +entries according to their timestamp. +Please note this is just a theoretical issue spotted reviewing the code +and not faced running the system. + +Fixes: cd53f622611f9 ("net: airoha: Add L2 hw acceleration support") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250818-airoha-en7581-hash-collision-fix-v1-1-d190c4b53d1c@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -736,10 +736,8 @@ static void airoha_ppe_foe_insert_entry( + continue; + } + +- if (commit_done || !airoha_ppe_foe_compare_entry(e, hwe)) { +- e->hash = 0xffff; ++ if (!airoha_ppe_foe_compare_entry(e, hwe)) + continue; +- } + + airoha_ppe_foe_commit_entry(ppe, &e->data, hash); + commit_done = true; diff --git a/target/linux/airoha/patches-6.6/083-01-v6.13-resource-Add-resource-set-range-and-size-helpers.patch b/target/linux/airoha/patches-6.6/083-01-v6.13-resource-Add-resource-set-range-and-size-helpers.patch new file mode 100644 index 0000000000..36a5300ad0 --- /dev/null +++ b/target/linux/airoha/patches-6.6/083-01-v6.13-resource-Add-resource-set-range-and-size-helpers.patch @@ -0,0 +1,73 @@ +From 9fb6fef0fb49124291837af1da5028f79d53f98e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Fri, 14 Jun 2024 13:06:03 +0300 +Subject: [PATCH] resource: Add resource set range and size helpers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Setting the end address for a resource with a given size lacks a helper and +is therefore coded manually unlike the getter side which has a helper for +resource size calculation. Also, almost all callsites that calculate the +end address for a resource also set the start address right before it like +this: + + res->start = start_addr; + res->end = res->start + size - 1; + +Add resource_set_range(res, start_addr, size) that sets the start address +and calculates the end address to simplify this often repeated fragment. + +Also add resource_set_size() for the cases where setting the start address +of the resource is not necessary but mention in its kerneldoc that +resource_set_range() is preferred when setting both addresses. + +Link: https://lore.kernel.org/r/20240614100606.15830-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +--- + include/linux/ioport.h | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +--- a/include/linux/ioport.h ++++ b/include/linux/ioport.h +@@ -216,6 +216,38 @@ struct resource *lookup_resource(struct + int adjust_resource(struct resource *res, resource_size_t start, + resource_size_t size); + resource_size_t resource_alignment(struct resource *res); ++ ++/** ++ * resource_set_size - Calculate resource end address from size and start ++ * @res: Resource descriptor ++ * @size: Size of the resource ++ * ++ * Calculate the end address for @res based on @size. ++ * ++ * Note: The start address of @res must be set when calling this function. ++ * Prefer resource_set_range() if setting both the start address and @size. ++ */ ++static inline void resource_set_size(struct resource *res, resource_size_t size) ++{ ++ res->end = res->start + size - 1; ++} ++ ++/** ++ * resource_set_range - Set resource start and end addresses ++ * @res: Resource descriptor ++ * @start: Start address for the resource ++ * @size: Size of the resource ++ * ++ * Set @res start address and calculate the end address based on @size. ++ */ ++static inline void resource_set_range(struct resource *res, ++ resource_size_t start, ++ resource_size_t size) ++{ ++ res->start = start; ++ resource_set_size(res, size); ++} ++ + static inline resource_size_t resource_size(const struct resource *res) + { + return res->end - res->start + 1; diff --git a/target/linux/airoha/patches-6.6/083-02-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch b/target/linux/airoha/patches-6.6/083-02-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch new file mode 100644 index 0000000000..cbfec9a391 --- /dev/null +++ b/target/linux/airoha/patches-6.6/083-02-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch @@ -0,0 +1,163 @@ +From f4fcfdda2fd8834c62dcb9bfddcf1f89d190b70e Mon Sep 17 00:00:00 2001 +From: "Rob Herring (Arm)" +Date: Wed, 23 Apr 2025 14:42:13 -0500 +Subject: [PATCH] of: reserved_mem: Add functions to parse "memory-region" + +Drivers with "memory-region" properties currently have to do their own +parsing of "memory-region" properties. The result is all the drivers +have similar patterns of a call to parse "memory-region" and then get +the region's address and size. As this is a standard property, it should +have common functions for drivers to use. Add new functions to count the +number of regions and retrieve the region's address as a resource. + +Reviewed-by: Daniel Baluta +Acked-by: Arnaud Pouliquen +Link: https://lore.kernel.org/r/20250423-dt-memory-region-v2-v2-1-2fbd6ebd3c88@kernel.org +Signed-off-by: Rob Herring (Arm) +--- + drivers/of/of_reserved_mem.c | 80 +++++++++++++++++++++++++++++++++ + include/linux/of_reserved_mem.h | 26 +++++++++++ + 2 files changed, 106 insertions(+) + +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -12,6 +12,7 @@ + #define pr_fmt(fmt) "OF: reserved mem: " fmt + + #include ++#include + #include + #include + #include +@@ -514,3 +515,82 @@ struct reserved_mem *of_reserved_mem_loo + return NULL; + } + EXPORT_SYMBOL_GPL(of_reserved_mem_lookup); ++ ++/** ++ * of_reserved_mem_region_to_resource() - Get a reserved memory region as a resource ++ * @np: node containing 'memory-region' property ++ * @idx: index of 'memory-region' property to lookup ++ * @res: Pointer to a struct resource to fill in with reserved region ++ * ++ * This function allows drivers to lookup a node's 'memory-region' property ++ * entries by index and return a struct resource for the entry. ++ * ++ * Returns 0 on success with @res filled in. Returns -ENODEV if 'memory-region' ++ * is missing or unavailable, -EINVAL for any other error. ++ */ ++int of_reserved_mem_region_to_resource(const struct device_node *np, ++ unsigned int idx, struct resource *res) ++{ ++ struct reserved_mem *rmem; ++ ++ if (!np) ++ return -EINVAL; ++ ++ struct device_node __free(device_node) *target = of_parse_phandle(np, "memory-region", idx); ++ if (!target || !of_device_is_available(target)) ++ return -ENODEV; ++ ++ rmem = of_reserved_mem_lookup(target); ++ if (!rmem) ++ return -EINVAL; ++ ++ resource_set_range(res, rmem->base, rmem->size); ++ res->name = rmem->name; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource); ++ ++/** ++ * of_reserved_mem_region_to_resource_byname() - Get a reserved memory region as a resource ++ * @np: node containing 'memory-region' property ++ * @name: name of 'memory-region' property entry to lookup ++ * @res: Pointer to a struct resource to fill in with reserved region ++ * ++ * This function allows drivers to lookup a node's 'memory-region' property ++ * entries by name and return a struct resource for the entry. ++ * ++ * Returns 0 on success with @res filled in, or a negative error-code on ++ * failure. ++ */ ++int of_reserved_mem_region_to_resource_byname(const struct device_node *np, ++ const char *name, ++ struct resource *res) ++{ ++ int idx; ++ ++ if (!name) ++ return -EINVAL; ++ ++ idx = of_property_match_string(np, "memory-region-names", name); ++ if (idx < 0) ++ return idx; ++ ++ return of_reserved_mem_region_to_resource(np, idx, res); ++} ++EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource_byname); ++ ++/** ++ * of_reserved_mem_region_count() - Return the number of 'memory-region' entries ++ * @np: node containing 'memory-region' property ++ * ++ * This function allows drivers to retrieve the number of entries for a node's ++ * 'memory-region' property. ++ * ++ * Returns the number of entries on success, or negative error code on a ++ * malformed property. ++ */ ++int of_reserved_mem_region_count(const struct device_node *np) ++{ ++ return of_count_phandle_with_args(np, "memory-region", NULL); ++} ++EXPORT_SYMBOL_GPL(of_reserved_mem_region_count); +--- a/include/linux/of_reserved_mem.h ++++ b/include/linux/of_reserved_mem.h +@@ -7,6 +7,7 @@ + + struct of_phandle_args; + struct reserved_mem_ops; ++struct resource; + + struct reserved_mem { + const char *name; +@@ -40,6 +41,12 @@ int of_reserved_mem_device_init_by_name( + void of_reserved_mem_device_release(struct device *dev); + + struct reserved_mem *of_reserved_mem_lookup(struct device_node *np); ++int of_reserved_mem_region_to_resource(const struct device_node *np, ++ unsigned int idx, struct resource *res); ++int of_reserved_mem_region_to_resource_byname(const struct device_node *np, ++ const char *name, struct resource *res); ++int of_reserved_mem_region_count(const struct device_node *np); ++ + #else + + #define RESERVEDMEM_OF_DECLARE(name, compat, init) \ +@@ -64,6 +71,25 @@ static inline struct reserved_mem *of_re + { + return NULL; + } ++ ++static inline int of_reserved_mem_region_to_resource(const struct device_node *np, ++ unsigned int idx, ++ struct resource *res) ++{ ++ return -ENOSYS; ++} ++ ++static inline int of_reserved_mem_region_to_resource_byname(const struct device_node *np, ++ const char *name, ++ struct resource *res) ++{ ++ return -ENOSYS; ++} ++ ++static inline int of_reserved_mem_region_count(const struct device_node *np) ++{ ++ return 0; ++} + #endif + + /** diff --git a/target/linux/airoha/patches-6.6/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch b/target/linux/airoha/patches-6.6/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch new file mode 100644 index 0000000000..7e9e9423ec --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch @@ -0,0 +1,179 @@ +From 564923b02c1d2fe02ee789f9849ff79979b63b9f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:37 +0200 +Subject: [PATCH 1/6] net: airoha: npu: Add NPU wlan memory initialization + commands + +Introduce wlan_init_reserved_memory callback used by MT76 driver during +NPU wlan offloading setup. +This is a preliminary patch to enable wlan flowtable offload for EN7581 +SoC with MT76 driver. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-2-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 82 ++++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_npu.h | 38 +++++++++++ + 2 files changed, 120 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -124,6 +124,13 @@ struct ppe_mbox_data { + }; + }; + ++struct wlan_mbox_data { ++ u32 ifindex:4; ++ u32 func_type:4; ++ u32 func_id; ++ DECLARE_FLEX_ARRAY(u8, d); ++}; ++ + static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, + void *p, int size) + { +@@ -390,6 +397,80 @@ out: + return err; + } + ++static int airoha_npu_wlan_msg_send(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_set_cmd func_id, ++ void *data, int data_len, gfp_t gfp) ++{ ++ struct wlan_mbox_data *wlan_data; ++ int err, len; ++ ++ len = sizeof(*wlan_data) + data_len; ++ wlan_data = kzalloc(len, gfp); ++ if (!wlan_data) ++ return -ENOMEM; ++ ++ wlan_data->ifindex = ifindex; ++ wlan_data->func_type = NPU_OP_SET; ++ wlan_data->func_id = func_id; ++ memcpy(wlan_data->d, data, data_len); ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); ++ kfree(wlan_data); ++ ++ return err; ++} ++ ++static int ++airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, ++ int ifindex, const char *name, ++ enum airoha_npu_wlan_set_cmd func_id) ++{ ++ struct device *dev = npu->dev; ++ struct resource res; ++ int err; ++ u32 val; ++ ++ err = of_reserved_mem_region_to_resource_byname(dev->of_node, name, ++ &res); ++ if (err) ++ return err; ++ ++ val = res.start; ++ return airoha_npu_wlan_msg_send(npu, ifindex, func_id, &val, ++ sizeof(val), GFP_KERNEL); ++} ++ ++static int airoha_npu_wlan_init_memory(struct airoha_npu *npu) ++{ ++ enum airoha_npu_wlan_set_cmd cmd = WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU; ++ u32 val = 0; ++ int err; ++ ++ err = airoha_npu_wlan_msg_send(npu, 1, cmd, &val, sizeof(val), ++ GFP_KERNEL); ++ if (err) ++ return err; ++ ++ cmd = WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR; ++ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-bufid", cmd); ++ if (err) ++ return err; ++ ++ cmd = WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR; ++ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "pkt", cmd); ++ if (err) ++ return err; ++ ++ cmd = WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR; ++ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-pkt", cmd); ++ if (err) ++ return err; ++ ++ cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU; ++ return airoha_npu_wlan_msg_send(npu, 0, cmd, &val, sizeof(val), ++ GFP_KERNEL); ++} ++ + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) + { + struct platform_device *pdev; +@@ -493,6 +574,7 @@ static int airoha_npu_probe(struct platf + npu->ops.ppe_deinit = airoha_npu_ppe_deinit; + npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; + npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; ++ npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; + + npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); + if (IS_ERR(npu->regmap)) +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -6,6 +6,43 @@ + + #define NPU_NUM_CORES 8 + ++enum airoha_npu_wlan_set_cmd { ++ WLAN_FUNC_SET_WAIT_PCIE_ADDR, ++ WLAN_FUNC_SET_WAIT_DESC, ++ WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, ++ WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, ++ WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, ++ WLAN_FUNC_SET_WAIT_DRIVER_MODEL, ++ WLAN_FUNC_SET_WAIT_DEL_STA, ++ WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, ++ WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, ++ WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, ++ WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, ++ WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, ++ WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, ++ WLAN_FUNC_SET_WAIT_PCIE_STATE, ++ WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, ++ WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, ++ WLAN_FUNC_SET_WAIT_BAR_INFO, ++ WLAN_FUNC_SET_WAIT_FAST_FLAG, ++ WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, ++ WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, ++ WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, ++ WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, ++ WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, ++ WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, ++ WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, ++ WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, ++ WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, ++ WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, ++ WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, ++ WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, ++ WLAN_FUNC_SET_WAIT_HWNAT_INIT, ++ WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, ++ WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, ++ WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, ++}; ++ + struct airoha_npu { + struct device *dev; + struct regmap *regmap; +@@ -29,6 +66,7 @@ struct airoha_npu { + dma_addr_t foe_addr, + u32 entry_size, u32 hash, + bool ppe2); ++ int (*wlan_init_reserved_memory)(struct airoha_npu *npu); + } ops; + }; + diff --git a/target/linux/airoha/patches-6.6/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch b/target/linux/airoha/patches-6.6/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch new file mode 100644 index 0000000000..5ff820d0be --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch @@ -0,0 +1,139 @@ +From f97fc66185b2004ad5f393f78b3e645009ddd1d0 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:38 +0200 +Subject: [PATCH 2/6] net: airoha: npu: Add wlan_{send,get}_msg NPU callbacks + +Introduce wlan_send_msg() and wlan_get_msg() NPU wlan callbacks used +by the wlan driver (MT76) to initialize NPU module registers in order to +offload wireless-wired traffic. +This is a preliminary patch to enable wlan flowtable offload for EN7581 +SoC with MT76 driver. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-3-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 52 ++++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_npu.h | 22 ++++++++++ + 2 files changed, 74 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -42,6 +42,22 @@ + #define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) + #define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) + ++#define NPU_WLAN_BASE_ADDR 0x30d000 ++ ++#define REG_IRQ_STATUS (NPU_WLAN_BASE_ADDR + 0x030) ++#define REG_IRQ_RXDONE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 2) + 0x034) ++#define NPU_IRQ_RX_MASK(_n) ((_n) == 1 ? BIT(17) : BIT(16)) ++ ++#define REG_TX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x080) ++#define REG_TX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x084) ++#define REG_TX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x088) ++#define REG_TX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x08c) ++ ++#define REG_RX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x180) ++#define REG_RX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x184) ++#define REG_RX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x188) ++#define REG_RX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x18c) ++ + #define NPU_TIMER_BASE_ADDR 0x310100 + #define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) + #define WDT_EN_MASK BIT(25) +@@ -420,6 +436,30 @@ static int airoha_npu_wlan_msg_send(stru + return err; + } + ++static int airoha_npu_wlan_msg_get(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_get_cmd func_id, ++ void *data, int data_len, gfp_t gfp) ++{ ++ struct wlan_mbox_data *wlan_data; ++ int err, len; ++ ++ len = sizeof(*wlan_data) + data_len; ++ wlan_data = kzalloc(len, gfp); ++ if (!wlan_data) ++ return -ENOMEM; ++ ++ wlan_data->ifindex = ifindex; ++ wlan_data->func_type = NPU_OP_GET; ++ wlan_data->func_id = func_id; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); ++ if (!err) ++ memcpy(data, wlan_data->d, data_len); ++ kfree(wlan_data); ++ ++ return err; ++} ++ + static int + airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, + int ifindex, const char *name, +@@ -471,6 +511,15 @@ static int airoha_npu_wlan_init_memory(s + GFP_KERNEL); + } + ++static u32 airoha_npu_wlan_queue_addr_get(struct airoha_npu *npu, int qid, ++ bool xmit) ++{ ++ if (xmit) ++ return REG_TX_BASE(qid + 2); ++ ++ return REG_RX_BASE(qid); ++} ++ + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) + { + struct platform_device *pdev; +@@ -575,6 +624,9 @@ static int airoha_npu_probe(struct platf + npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; + npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; + npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; ++ npu->ops.wlan_send_msg = airoha_npu_wlan_msg_send; ++ npu->ops.wlan_get_msg = airoha_npu_wlan_msg_get; ++ npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; + + npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); + if (IS_ERR(npu->regmap)) +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -43,6 +43,20 @@ enum airoha_npu_wlan_set_cmd { + WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, + }; + ++enum airoha_npu_wlan_get_cmd { ++ WLAN_FUNC_GET_WAIT_NPU_INFO, ++ WLAN_FUNC_GET_WAIT_LAST_RATE, ++ WLAN_FUNC_GET_WAIT_COUNTER, ++ WLAN_FUNC_GET_WAIT_DBG_COUNTER, ++ WLAN_FUNC_GET_WAIT_RXDESC_BASE, ++ WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, ++ WLAN_FUNC_GET_WAIT_DMA_ADDR, ++ WLAN_FUNC_GET_WAIT_RING_SIZE, ++ WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, ++ WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, ++ WLAN_FUNC_GET_WAIT_NPU_VERSION, ++}; ++ + struct airoha_npu { + struct device *dev; + struct regmap *regmap; +@@ -67,6 +81,14 @@ struct airoha_npu { + u32 entry_size, u32 hash, + bool ppe2); + int (*wlan_init_reserved_memory)(struct airoha_npu *npu); ++ int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_set_cmd func_id, ++ void *data, int data_len, gfp_t gfp); ++ int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_get_cmd func_id, ++ void *data, int data_len, gfp_t gfp); ++ u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, ++ bool xmit); + } ops; + }; + diff --git a/target/linux/airoha/patches-6.6/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch b/target/linux/airoha/patches-6.6/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch new file mode 100644 index 0000000000..f05b947cec --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch @@ -0,0 +1,74 @@ +From 03b7ca3ee5e1b700c462aed5b6cb88f616d6ba7f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:39 +0200 +Subject: [PATCH 3/6] net: airoha: npu: Add wlan irq management callbacks + +Introduce callbacks used by the MT76 driver to configure NPU SoC +interrupts. This is a preliminary patch to enable wlan flowtable +offload for EN7581 SoC with MT76 driver. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-4-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 27 ++++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_npu.h | 4 ++++ + 2 files changed, 31 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -520,6 +520,29 @@ static u32 airoha_npu_wlan_queue_addr_ge + return REG_RX_BASE(qid); + } + ++static void airoha_npu_wlan_irq_status_set(struct airoha_npu *npu, u32 val) ++{ ++ regmap_write(npu->regmap, REG_IRQ_STATUS, val); ++} ++ ++static u32 airoha_npu_wlan_irq_status_get(struct airoha_npu *npu, int q) ++{ ++ u32 val; ++ ++ regmap_read(npu->regmap, REG_IRQ_STATUS, &val); ++ return val; ++} ++ ++static void airoha_npu_wlan_irq_enable(struct airoha_npu *npu, int q) ++{ ++ regmap_set_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); ++} ++ ++static void airoha_npu_wlan_irq_disable(struct airoha_npu *npu, int q) ++{ ++ regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); ++} ++ + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) + { + struct platform_device *pdev; +@@ -627,6 +650,10 @@ static int airoha_npu_probe(struct platf + npu->ops.wlan_send_msg = airoha_npu_wlan_msg_send; + npu->ops.wlan_get_msg = airoha_npu_wlan_msg_get; + npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; ++ npu->ops.wlan_set_irq_status = airoha_npu_wlan_irq_status_set; ++ npu->ops.wlan_get_irq_status = airoha_npu_wlan_irq_status_get; ++ npu->ops.wlan_enable_irq = airoha_npu_wlan_irq_enable; ++ npu->ops.wlan_disable_irq = airoha_npu_wlan_irq_disable; + + npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); + if (IS_ERR(npu->regmap)) +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -89,6 +89,10 @@ struct airoha_npu { + void *data, int data_len, gfp_t gfp); + u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, + bool xmit); ++ void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); ++ u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); ++ void (*wlan_enable_irq)(struct airoha_npu *npu, int q); ++ void (*wlan_disable_irq)(struct airoha_npu *npu, int q); + } ops; + }; + diff --git a/target/linux/airoha/patches-6.6/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch b/target/linux/airoha/patches-6.6/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch new file mode 100644 index 0000000000..234dc8b99a --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch @@ -0,0 +1,58 @@ +From a1740b16c83729d908c760eaa821f27b51e58a13 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:40 +0200 +Subject: [PATCH 4/6] net: airoha: npu: Read NPU wlan interrupt lines from the + DTS + +Read all NPU wlan IRQ lines from the NPU device-tree node. +NPU module fires wlan irq lines when the traffic to/from the WiFi NIC is +not hw accelerated (these interrupts will be consumed by the MT76 driver +in subsequent patches). +This is a preliminary patch to enable wlan flowtable offload for EN7581 +SoC. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-5-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 9 +++++++++ + drivers/net/ethernet/airoha/airoha_npu.h | 3 +++ + 2 files changed, 12 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -696,6 +696,15 @@ static int airoha_npu_probe(struct platf + INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); + } + ++ /* wlan IRQ lines */ ++ for (i = 0; i < ARRAY_SIZE(npu->irqs); i++) { ++ irq = platform_get_irq(pdev, i + ARRAY_SIZE(npu->cores) + 1); ++ if (irq < 0) ++ return irq; ++ ++ npu->irqs[i] = irq; ++ } ++ + err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (err) + return err; +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -5,6 +5,7 @@ + */ + + #define NPU_NUM_CORES 8 ++#define NPU_NUM_IRQ 6 + + enum airoha_npu_wlan_set_cmd { + WLAN_FUNC_SET_WAIT_PCIE_ADDR, +@@ -68,6 +69,8 @@ struct airoha_npu { + struct work_struct wdt_work; + } cores[NPU_NUM_CORES]; + ++ int irqs[NPU_NUM_IRQ]; ++ + struct airoha_foe_stats __iomem *stats; + + struct { diff --git a/target/linux/airoha/patches-6.6/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch b/target/linux/airoha/patches-6.6/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch new file mode 100644 index 0000000000..c285af23c3 --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch @@ -0,0 +1,28 @@ +From 29c4a3ce508961a02d185ead2d52699b16d82c6d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:41 +0200 +Subject: [PATCH 5/6] net: airoha: npu: Enable core 3 for WiFi offloading + +NPU core 3 is responsible for WiFi offloading so enable it during NPU +probe. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-6-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -726,8 +726,7 @@ static int airoha_npu_probe(struct platf + usleep_range(1000, 2000); + + /* enable NPU cores */ +- /* do not start core3 since it is used for WiFi offloading */ +- regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); ++ regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xff); + regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); + msleep(100); + diff --git a/target/linux/airoha/patches-6.6/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch b/target/linux/airoha/patches-6.6/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch new file mode 100644 index 0000000000..ef98c85c36 --- /dev/null +++ b/target/linux/airoha/patches-6.6/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch @@ -0,0 +1,416 @@ +From b3ef7bdec66fb1813e865fd39d179a93cefd2015 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 11 Aug 2025 17:31:42 +0200 +Subject: [PATCH 6/6] net: airoha: Add airoha_offload.h header + +Move NPU definitions to airoha_offload.h in include/linux/soc/airoha/ in +order to allow the MT76 driver to access the callback definitions. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-7-58823603bb4e@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 2 +- + drivers/net/ethernet/airoha/airoha_npu.h | 103 --------- + drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- + include/linux/soc/airoha/airoha_offload.h | 260 ++++++++++++++++++++++ + 4 files changed, 262 insertions(+), 105 deletions(-) + delete mode 100644 drivers/net/ethernet/airoha/airoha_npu.h + create mode 100644 include/linux/soc/airoha/airoha_offload.h + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -11,9 +11,9 @@ + #include + #include + #include ++#include + + #include "airoha_eth.h" +-#include "airoha_npu.h" + + #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" + #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" +--- a/drivers/net/ethernet/airoha/airoha_npu.h ++++ /dev/null +@@ -1,103 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * Copyright (c) 2025 AIROHA Inc +- * Author: Lorenzo Bianconi +- */ +- +-#define NPU_NUM_CORES 8 +-#define NPU_NUM_IRQ 6 +- +-enum airoha_npu_wlan_set_cmd { +- WLAN_FUNC_SET_WAIT_PCIE_ADDR, +- WLAN_FUNC_SET_WAIT_DESC, +- WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, +- WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, +- WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, +- WLAN_FUNC_SET_WAIT_DRIVER_MODEL, +- WLAN_FUNC_SET_WAIT_DEL_STA, +- WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, +- WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, +- WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, +- WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, +- WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, +- WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, +- WLAN_FUNC_SET_WAIT_PCIE_STATE, +- WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, +- WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, +- WLAN_FUNC_SET_WAIT_BAR_INFO, +- WLAN_FUNC_SET_WAIT_FAST_FLAG, +- WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, +- WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, +- WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, +- WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, +- WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, +- WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, +- WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, +- WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, +- WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, +- WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, +- WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, +- WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, +- WLAN_FUNC_SET_WAIT_HWNAT_INIT, +- WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, +- WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, +- WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, +-}; +- +-enum airoha_npu_wlan_get_cmd { +- WLAN_FUNC_GET_WAIT_NPU_INFO, +- WLAN_FUNC_GET_WAIT_LAST_RATE, +- WLAN_FUNC_GET_WAIT_COUNTER, +- WLAN_FUNC_GET_WAIT_DBG_COUNTER, +- WLAN_FUNC_GET_WAIT_RXDESC_BASE, +- WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, +- WLAN_FUNC_GET_WAIT_DMA_ADDR, +- WLAN_FUNC_GET_WAIT_RING_SIZE, +- WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, +- WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, +- WLAN_FUNC_GET_WAIT_NPU_VERSION, +-}; +- +-struct airoha_npu { +- struct device *dev; +- struct regmap *regmap; +- +- struct airoha_npu_core { +- struct airoha_npu *npu; +- /* protect concurrent npu memory accesses */ +- spinlock_t lock; +- struct work_struct wdt_work; +- } cores[NPU_NUM_CORES]; +- +- int irqs[NPU_NUM_IRQ]; +- +- struct airoha_foe_stats __iomem *stats; +- +- struct { +- int (*ppe_init)(struct airoha_npu *npu); +- int (*ppe_deinit)(struct airoha_npu *npu); +- int (*ppe_flush_sram_entries)(struct airoha_npu *npu, +- dma_addr_t foe_addr, +- int sram_num_entries); +- int (*ppe_foe_commit_entry)(struct airoha_npu *npu, +- dma_addr_t foe_addr, +- u32 entry_size, u32 hash, +- bool ppe2); +- int (*wlan_init_reserved_memory)(struct airoha_npu *npu); +- int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, +- enum airoha_npu_wlan_set_cmd func_id, +- void *data, int data_len, gfp_t gfp); +- int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, +- enum airoha_npu_wlan_get_cmd func_id, +- void *data, int data_len, gfp_t gfp); +- u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, +- bool xmit); +- void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); +- u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); +- void (*wlan_enable_irq)(struct airoha_npu *npu, int q); +- void (*wlan_disable_irq)(struct airoha_npu *npu, int q); +- } ops; +-}; +- +-struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); +-void airoha_npu_put(struct airoha_npu *npu); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -7,10 +7,10 @@ + #include + #include + #include ++#include + #include + #include + +-#include "airoha_npu.h" + #include "airoha_regs.h" + #include "airoha_eth.h" + +--- /dev/null ++++ b/include/linux/soc/airoha/airoha_offload.h +@@ -0,0 +1,260 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2025 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++#ifndef AIROHA_OFFLOAD_H ++#define AIROHA_OFFLOAD_H ++ ++#include ++#include ++ ++#define NPU_NUM_CORES 8 ++#define NPU_NUM_IRQ 6 ++#define NPU_RX0_DESC_NUM 512 ++#define NPU_RX1_DESC_NUM 512 ++ ++/* CTRL */ ++#define NPU_RX_DMA_DESC_LAST_MASK BIT(29) ++#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15) ++#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1) ++#define NPU_RX_DMA_DESC_DONE_MASK BIT(0) ++/* INFO */ ++#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28) ++#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26) ++#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21) ++#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16) ++#define NPU_RX_DMA_FOE_ID_MASK GENMASK(15, 0) ++/* DATA */ ++#define NPU_RX_DMA_SID_MASK GENMASK(31, 16) ++#define NPU_RX_DMA_FRAG_TYPE_MASK GENMASK(15, 14) ++#define NPU_RX_DMA_PRIORITY_MASK GENMASK(13, 10) ++#define NPU_RX_DMA_RADIO_ID_MASK GENMASK(9, 6) ++#define NPU_RX_DMA_VAP_ID_MASK GENMASK(5, 2) ++#define NPU_RX_DMA_FRAME_TYPE_MASK GENMASK(1, 0) ++ ++struct airoha_npu_rx_dma_desc { ++ u32 ctrl; ++ u32 info; ++ u32 data; ++ u32 addr; ++ u64 rsv; ++} __packed; ++ ++/* CTRL */ ++#define NPU_TX_DMA_DESC_SCHED_MASK BIT(31) ++#define NPU_TX_DMA_DESC_LEN_MASK GENMASK(30, 18) ++#define NPU_TX_DMA_DESC_VEND_LEN_MASK GENMASK(17, 1) ++#define NPU_TX_DMA_DESC_DONE_MASK BIT(0) ++ ++#define NPU_TXWI_LEN 192 ++ ++struct airoha_npu_tx_dma_desc { ++ u32 ctrl; ++ u32 addr; ++ u64 rsv; ++ u8 txwi[NPU_TXWI_LEN]; ++} __packed; ++ ++enum airoha_npu_wlan_set_cmd { ++ WLAN_FUNC_SET_WAIT_PCIE_ADDR, ++ WLAN_FUNC_SET_WAIT_DESC, ++ WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, ++ WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, ++ WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, ++ WLAN_FUNC_SET_WAIT_DRIVER_MODEL, ++ WLAN_FUNC_SET_WAIT_DEL_STA, ++ WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, ++ WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, ++ WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, ++ WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, ++ WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, ++ WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, ++ WLAN_FUNC_SET_WAIT_PCIE_STATE, ++ WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, ++ WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, ++ WLAN_FUNC_SET_WAIT_BAR_INFO, ++ WLAN_FUNC_SET_WAIT_FAST_FLAG, ++ WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, ++ WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, ++ WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, ++ WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, ++ WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, ++ WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, ++ WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, ++ WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, ++ WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, ++ WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, ++ WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, ++ WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, ++ WLAN_FUNC_SET_WAIT_HWNAT_INIT, ++ WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, ++ WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, ++ WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, ++}; ++ ++enum airoha_npu_wlan_get_cmd { ++ WLAN_FUNC_GET_WAIT_NPU_INFO, ++ WLAN_FUNC_GET_WAIT_LAST_RATE, ++ WLAN_FUNC_GET_WAIT_COUNTER, ++ WLAN_FUNC_GET_WAIT_DBG_COUNTER, ++ WLAN_FUNC_GET_WAIT_RXDESC_BASE, ++ WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, ++ WLAN_FUNC_GET_WAIT_DMA_ADDR, ++ WLAN_FUNC_GET_WAIT_RING_SIZE, ++ WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, ++ WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, ++ WLAN_FUNC_GET_WAIT_NPU_VERSION, ++}; ++ ++struct airoha_npu { ++#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) ++ struct device *dev; ++ struct regmap *regmap; ++ ++ struct airoha_npu_core { ++ struct airoha_npu *npu; ++ /* protect concurrent npu memory accesses */ ++ spinlock_t lock; ++ struct work_struct wdt_work; ++ } cores[NPU_NUM_CORES]; ++ ++ int irqs[NPU_NUM_IRQ]; ++ ++ struct airoha_foe_stats __iomem *stats; ++ ++ struct { ++ int (*ppe_init)(struct airoha_npu *npu); ++ int (*ppe_deinit)(struct airoha_npu *npu); ++ int (*ppe_flush_sram_entries)(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ int sram_num_entries); ++ int (*ppe_foe_commit_entry)(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ u32 entry_size, u32 hash, ++ bool ppe2); ++ int (*wlan_init_reserved_memory)(struct airoha_npu *npu); ++ int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_set_cmd func_id, ++ void *data, int data_len, gfp_t gfp); ++ int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_get_cmd func_id, ++ void *data, int data_len, gfp_t gfp); ++ u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, ++ bool xmit); ++ void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); ++ u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); ++ void (*wlan_enable_irq)(struct airoha_npu *npu, int q); ++ void (*wlan_disable_irq)(struct airoha_npu *npu, int q); ++ } ops; ++#endif ++}; ++ ++#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) ++struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); ++void airoha_npu_put(struct airoha_npu *npu); ++ ++static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) ++{ ++ return npu->ops.wlan_init_reserved_memory(npu); ++} ++ ++static inline int airoha_npu_wlan_send_msg(struct airoha_npu *npu, ++ int ifindex, ++ enum airoha_npu_wlan_set_cmd cmd, ++ void *data, int data_len, gfp_t gfp) ++{ ++ return npu->ops.wlan_send_msg(npu, ifindex, cmd, data, data_len, gfp); ++} ++ ++static inline int airoha_npu_wlan_get_msg(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_get_cmd cmd, ++ void *data, int data_len, gfp_t gfp) ++{ ++ return npu->ops.wlan_get_msg(npu, ifindex, cmd, data, data_len, gfp); ++} ++ ++static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, ++ int qid, bool xmit) ++{ ++ return npu->ops.wlan_get_queue_addr(npu, qid, xmit); ++} ++ ++static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, ++ u32 val) ++{ ++ npu->ops.wlan_set_irq_status(npu, val); ++} ++ ++static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, int q) ++{ ++ return npu->ops.wlan_get_irq_status(npu, q); ++} ++ ++static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) ++{ ++ npu->ops.wlan_enable_irq(npu, q); ++} ++ ++static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) ++{ ++ npu->ops.wlan_disable_irq(npu, q); ++} ++#else ++static inline struct airoha_npu *airoha_npu_get(struct device *dev, ++ dma_addr_t *foe_stats_addr) ++{ ++ return NULL; ++} ++ ++static inline void airoha_npu_put(struct airoha_npu *npu) ++{ ++} ++ ++static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline int airoha_npu_wlan_send_msg(struct airoha_npu *npu, ++ int ifindex, ++ enum airoha_npu_wlan_set_cmd cmd, ++ void *data, int data_len, gfp_t gfp) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline int airoha_npu_wlan_get_msg(struct airoha_npu *npu, int ifindex, ++ enum airoha_npu_wlan_get_cmd cmd, ++ void *data, int data_len, gfp_t gfp) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, ++ int qid, bool xmit) ++{ ++ return 0; ++} ++ ++static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, ++ u32 val) ++{ ++} ++ ++static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, ++ int q) ++{ ++ return 0; ++} ++ ++static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) ++{ ++} ++ ++static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) ++{ ++} ++#endif ++ ++#endif /* AIROHA_OFFLOAD_H */ diff --git a/target/linux/airoha/patches-6.6/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch b/target/linux/airoha/patches-6.6/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch new file mode 100644 index 0000000000..ab9a3761a5 --- /dev/null +++ b/target/linux/airoha/patches-6.6/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch @@ -0,0 +1,198 @@ +From a8bdd935d1ddb7186358fb60ffe84253e85340c8 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 14 Aug 2025 09:51:16 +0200 +Subject: [PATCH] net: airoha: Add wlan flowtable TX offload + +Introduce support to offload the traffic received on the ethernet NIC +and forwarded to the wireless one using HW Packet Processor Engine (PPE) +capabilities. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250814-airoha-en7581-wlan-tx-offload-v1-1-72e0a312003e@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 11 +++ + drivers/net/ethernet/airoha/airoha_ppe.c | 103 ++++++++++++++++------- + 2 files changed, 85 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -252,6 +252,10 @@ enum { + #define AIROHA_FOE_MAC_SMAC_ID GENMASK(20, 16) + #define AIROHA_FOE_MAC_PPPOE_ID GENMASK(15, 0) + ++#define AIROHA_FOE_MAC_WDMA_QOS GENMASK(15, 12) ++#define AIROHA_FOE_MAC_WDMA_BAND BIT(11) ++#define AIROHA_FOE_MAC_WDMA_WCID GENMASK(10, 0) ++ + struct airoha_foe_mac_info_common { + u16 vlan1; + u16 etype; +@@ -481,6 +485,13 @@ struct airoha_flow_table_entry { + unsigned long cookie; + }; + ++struct airoha_wdma_info { ++ u8 idx; ++ u8 queue; ++ u16 wcid; ++ u8 bss; ++}; ++ + /* RX queue to IRQ mapping: BIT(q) in IRQ(n) */ + #define RX_IRQ0_BANK_PIN_MASK 0x839f + #define RX_IRQ1_BANK_PIN_MASK 0x7fe00000 +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -190,6 +190,31 @@ static int airoha_ppe_flow_mangle_ipv4(c + return 0; + } + ++static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr, ++ struct airoha_wdma_info *info) ++{ ++ struct net_device_path_stack stack; ++ struct net_device_path *path; ++ int err; ++ ++ if (!dev) ++ return -ENODEV; ++ ++ err = dev_fill_forward_path(dev, addr, &stack); ++ if (err) ++ return err; ++ ++ path = &stack.path[stack.num_paths - 1]; ++ if (path->type != DEV_PATH_MTK_WDMA) ++ return -1; ++ ++ info->idx = path->mtk_wdma.wdma_idx; ++ info->bss = path->mtk_wdma.bss; ++ info->wcid = path->mtk_wdma.wcid; ++ ++ return 0; ++} ++ + static int airoha_get_dsa_port(struct net_device **dev) + { + #if IS_ENABLED(CONFIG_NET_DSA) +@@ -220,9 +245,9 @@ static int airoha_ppe_foe_entry_prepare( + struct airoha_flow_data *data, + int l4proto) + { +- int dsa_port = airoha_get_dsa_port(&dev); ++ u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val; ++ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev); + struct airoha_foe_mac_info_common *l2; +- u32 qdata, ports_pad, val; + u8 smac_id = 0xf; + + memset(hwe, 0, sizeof(*hwe)); +@@ -236,31 +261,47 @@ static int airoha_ppe_foe_entry_prepare( + AIROHA_FOE_IB1_BIND_TTL; + hwe->ib1 = val; + +- val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) | +- AIROHA_FOE_IB2_PSE_QOS; +- if (dsa_port >= 0) +- val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); +- ++ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); + if (dev) { +- struct airoha_gdm_port *port = netdev_priv(dev); +- u8 pse_port; +- +- if (!airoha_is_valid_gdm_port(eth, port)) +- return -EINVAL; ++ struct airoha_wdma_info info = {}; + +- if (dsa_port >= 0) +- pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; +- else +- pse_port = 2; /* uplink relies on GDM2 loopback */ +- val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); +- +- /* For downlink traffic consume SRAM memory for hw forwarding +- * descriptors queue. +- */ +- if (airhoa_is_lan_gdm_port(port)) +- val |= AIROHA_FOE_IB2_FAST_PATH; ++ if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) { ++ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) | ++ FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, ++ FE_PSE_PORT_CDM4); ++ qdata |= FIELD_PREP(AIROHA_FOE_ACTDP, info.bss); ++ wlan_etype = FIELD_PREP(AIROHA_FOE_MAC_WDMA_BAND, ++ info.idx) | ++ FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID, ++ info.wcid); ++ } else { ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ u8 pse_port; ++ ++ if (!airoha_is_valid_gdm_port(eth, port)) ++ return -EINVAL; ++ ++ if (dsa_port >= 0) ++ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 ++ : port->id; ++ else ++ pse_port = 2; /* uplink relies on GDM2 ++ * loopback ++ */ ++ ++ val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port) | ++ AIROHA_FOE_IB2_PSE_QOS; ++ /* For downlink traffic consume SRAM memory for hw ++ * forwarding descriptors queue. ++ */ ++ if (airhoa_is_lan_gdm_port(port)) ++ val |= AIROHA_FOE_IB2_FAST_PATH; ++ if (dsa_port >= 0) ++ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, ++ dsa_port); + +- smac_id = port->id; ++ smac_id = port->id; ++ } + } + + if (is_multicast_ether_addr(data->eth.h_dest)) +@@ -272,7 +313,6 @@ static int airoha_ppe_foe_entry_prepare( + if (type == PPE_PKT_TYPE_IPV6_ROUTE_3T) + hwe->ipv6.ports = ports_pad; + +- qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); + if (type == PPE_PKT_TYPE_BRIDGE) { + airoha_ppe_foe_set_bridge_addrs(&hwe->bridge, &data->eth); + hwe->bridge.data = qdata; +@@ -313,7 +353,9 @@ static int airoha_ppe_foe_entry_prepare( + l2->vlan2 = data->vlan.hdr[1].id; + } + +- if (dsa_port >= 0) { ++ if (wlan_etype >= 0) { ++ l2->etype = wlan_etype; ++ } else if (dsa_port >= 0) { + l2->etype = BIT(dsa_port); + l2->etype |= !data->vlan.num ? BIT(15) : 0; + } else if (data->pppoe.num) { +@@ -490,6 +532,10 @@ static void airoha_ppe_foe_flow_stats_up + meter = &hwe->ipv4.l2.meter; + } + ++ pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); ++ if (pse_port == FE_PSE_PORT_CDM4) ++ return; ++ + airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, index); + + val = FIELD_GET(AIROHA_FOE_CHANNEL | AIROHA_FOE_QID, *data); +@@ -500,7 +546,6 @@ static void airoha_ppe_foe_flow_stats_up + AIROHA_FOE_IB2_PSE_QOS | AIROHA_FOE_IB2_FAST_PATH); + *meter |= FIELD_PREP(AIROHA_FOE_TUNNEL_MTU, val); + +- pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); + nbq = pse_port == 1 ? 6 : 5; + *ib2 &= ~(AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | + AIROHA_FOE_IB2_PSE_QOS); diff --git a/target/linux/airoha/patches-6.6/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch b/target/linux/airoha/patches-6.6/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch new file mode 100644 index 0000000000..cef2922869 --- /dev/null +++ b/target/linux/airoha/patches-6.6/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch @@ -0,0 +1,95 @@ +From 524a43c3a0c17fa0a1223eea36751dcba55e5530 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sat, 23 Aug 2025 09:56:02 +0200 +Subject: [PATCH 1/3] net: airoha: Rely on airoha_eth struct in + airoha_ppe_flow_offload_cmd signature + +Rely on airoha_eth struct in airoha_ppe_flow_offload_cmd routine +signature and in all the called subroutines. +This is a preliminary patch to introduce flowtable offload for traffic +received by the wlan NIC and forwarded to the ethernet one. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-1-f78600ec3ed8@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -935,11 +935,10 @@ static int airoha_ppe_entry_idle_time(st + return airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); + } + +-static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, ++static int airoha_ppe_flow_offload_replace(struct airoha_eth *eth, + struct flow_cls_offload *f) + { + struct flow_rule *rule = flow_cls_offload_flow_rule(f); +- struct airoha_eth *eth = port->qdma->eth; + struct airoha_flow_table_entry *e; + struct airoha_flow_data data = {}; + struct net_device *odev = NULL; +@@ -1136,10 +1135,9 @@ free_entry: + return err; + } + +-static int airoha_ppe_flow_offload_destroy(struct airoha_gdm_port *port, ++static int airoha_ppe_flow_offload_destroy(struct airoha_eth *eth, + struct flow_cls_offload *f) + { +- struct airoha_eth *eth = port->qdma->eth; + struct airoha_flow_table_entry *e; + + e = rhashtable_lookup(ð->flow_table, &f->cookie, +@@ -1182,10 +1180,9 @@ void airoha_ppe_foe_entry_get_stats(stru + rcu_read_unlock(); + } + +-static int airoha_ppe_flow_offload_stats(struct airoha_gdm_port *port, ++static int airoha_ppe_flow_offload_stats(struct airoha_eth *eth, + struct flow_cls_offload *f) + { +- struct airoha_eth *eth = port->qdma->eth; + struct airoha_flow_table_entry *e; + u32 idle; + +@@ -1209,16 +1206,16 @@ static int airoha_ppe_flow_offload_stats + return 0; + } + +-static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, ++static int airoha_ppe_flow_offload_cmd(struct airoha_eth *eth, + struct flow_cls_offload *f) + { + switch (f->command) { + case FLOW_CLS_REPLACE: +- return airoha_ppe_flow_offload_replace(port, f); ++ return airoha_ppe_flow_offload_replace(eth, f); + case FLOW_CLS_DESTROY: +- return airoha_ppe_flow_offload_destroy(port, f); ++ return airoha_ppe_flow_offload_destroy(eth, f); + case FLOW_CLS_STATS: +- return airoha_ppe_flow_offload_stats(port, f); ++ return airoha_ppe_flow_offload_stats(eth, f); + default: + break; + } +@@ -1288,7 +1285,6 @@ error_npu_put: + int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) + { + struct airoha_gdm_port *port = netdev_priv(dev); +- struct flow_cls_offload *cls = type_data; + struct airoha_eth *eth = port->qdma->eth; + int err = 0; + +@@ -1297,7 +1293,7 @@ int airoha_ppe_setup_tc_block_cb(struct + if (!eth->npu) + err = airoha_ppe_offload_setup(eth); + if (!err) +- err = airoha_ppe_flow_offload_cmd(port, cls); ++ err = airoha_ppe_flow_offload_cmd(eth, type_data); + + mutex_unlock(&flow_offload_mutex); + diff --git a/target/linux/airoha/patches-6.6/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch b/target/linux/airoha/patches-6.6/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch new file mode 100644 index 0000000000..7fa5f9bddd --- /dev/null +++ b/target/linux/airoha/patches-6.6/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch @@ -0,0 +1,223 @@ +From f45fc18b6de04483643e8aa2ab97737abfe03d59 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sat, 23 Aug 2025 09:56:03 +0200 +Subject: [PATCH 2/3] net: airoha: Add airoha_ppe_dev struct definition + +Introduce airoha_ppe_dev struct as container for PPE offload callbacks +consumed by the MT76 driver during flowtable offload for traffic +received by the wlan NIC and forwarded to the wired one. +Add airoha_ppe_setup_tc_block_cb routine to PPE offload ops for MT76 +driver. +Rely on airoha_ppe_dev pointer in airoha_ppe_setup_tc_block_cb +signature. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-2-f78600ec3ed8@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 +- + drivers/net/ethernet/airoha/airoha_eth.h | 4 +- + drivers/net/ethernet/airoha/airoha_npu.c | 1 - + drivers/net/ethernet/airoha/airoha_ppe.c | 67 +++++++++++++++++++++-- + include/linux/soc/airoha/airoha_offload.h | 35 ++++++++++++ + 5 files changed, 104 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2602,13 +2602,15 @@ static int airoha_dev_setup_tc_block_cb( + void *type_data, void *cb_priv) + { + struct net_device *dev = cb_priv; ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_eth *eth = port->qdma->eth; + + if (!tc_can_offload(dev)) + return -EOPNOTSUPP; + + switch (type) { + case TC_SETUP_CLSFLOWER: +- return airoha_ppe_setup_tc_block_cb(dev, type_data); ++ return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data); + case TC_SETUP_CLSMATCHALL: + return airoha_dev_tc_matchall(dev, type_data); + default: +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + + #define AIROHA_MAX_NUM_GDM_PORTS 4 +@@ -546,6 +547,7 @@ struct airoha_gdm_port { + #define AIROHA_RXD4_FOE_ENTRY GENMASK(15, 0) + + struct airoha_ppe { ++ struct airoha_ppe_dev dev; + struct airoha_eth *eth; + + void *foe; +@@ -622,7 +624,7 @@ bool airoha_is_valid_gdm_port(struct air + + void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, + u16 hash); +-int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); ++int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); + void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + + #include "airoha_eth.h" + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -6,8 +6,9 @@ + + #include + #include ++#include ++#include + #include +-#include + #include + #include + +@@ -1282,10 +1283,10 @@ error_npu_put: + return err; + } + +-int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) ++int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data) + { +- struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_eth *eth = port->qdma->eth; ++ struct airoha_ppe *ppe = dev->priv; ++ struct airoha_eth *eth = ppe->eth; + int err = 0; + + mutex_lock(&flow_offload_mutex); +@@ -1338,6 +1339,61 @@ void airoha_ppe_init_upd_mem(struct airo + PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); + } + ++struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) ++{ ++ struct platform_device *pdev; ++ struct device_node *np; ++ struct airoha_eth *eth; ++ ++ np = of_parse_phandle(dev->of_node, "airoha,eth", 0); ++ if (!np) ++ return ERR_PTR(-ENODEV); ++ ++ pdev = of_find_device_by_node(np); ++ if (!pdev) { ++ dev_err(dev, "cannot find device node %s\n", np->name); ++ of_node_put(np); ++ return ERR_PTR(-ENODEV); ++ } ++ of_node_put(np); ++ ++ if (!try_module_get(THIS_MODULE)) { ++ dev_err(dev, "failed to get the device driver module\n"); ++ goto error_pdev_put; ++ } ++ ++ eth = platform_get_drvdata(pdev); ++ if (!eth) ++ goto error_module_put; ++ ++ if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { ++ dev_err(&pdev->dev, ++ "failed to create device link to consumer %s\n", ++ dev_name(dev)); ++ goto error_module_put; ++ } ++ ++ return ð->ppe->dev; ++ ++error_module_put: ++ module_put(THIS_MODULE); ++error_pdev_put: ++ platform_device_put(pdev); ++ ++ return ERR_PTR(-ENODEV); ++} ++EXPORT_SYMBOL_GPL(airoha_ppe_get_dev); ++ ++void airoha_ppe_put_dev(struct airoha_ppe_dev *dev) ++{ ++ struct airoha_ppe *ppe = dev->priv; ++ struct airoha_eth *eth = ppe->eth; ++ ++ module_put(THIS_MODULE); ++ put_device(eth->dev); ++} ++EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); ++ + int airoha_ppe_init(struct airoha_eth *eth) + { + struct airoha_ppe *ppe; +@@ -1347,6 +1403,9 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe) + return -ENOMEM; + ++ ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; ++ ppe->dev.priv = ppe; ++ + foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); + ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, + GFP_KERNEL); +--- a/include/linux/soc/airoha/airoha_offload.h ++++ b/include/linux/soc/airoha/airoha_offload.h +@@ -9,6 +9,41 @@ + #include + #include + ++struct airoha_ppe_dev { ++ struct { ++ int (*setup_tc_block_cb)(struct airoha_ppe_dev *dev, ++ void *type_data); ++ } ops; ++ ++ void *priv; ++}; ++ ++#if (IS_BUILTIN(CONFIG_NET_AIROHA) || IS_MODULE(CONFIG_NET_AIROHA)) ++struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev); ++void airoha_ppe_put_dev(struct airoha_ppe_dev *dev); ++ ++static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev, ++ void *type_data) ++{ ++ return dev->ops.setup_tc_block_cb(dev, type_data); ++} ++#else ++static inline struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) ++{ ++ return NULL; ++} ++ ++static inline void airoha_ppe_put_dev(struct airoha_ppe_dev *dev) ++{ ++} ++ ++static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, ++ void *type_data) ++{ ++ return -EOPNOTSUPP; ++} ++#endif ++ + #define NPU_NUM_CORES 8 + #define NPU_NUM_IRQ 6 + #define NPU_RX0_DESC_NUM 512 diff --git a/target/linux/airoha/patches-6.6/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch b/target/linux/airoha/patches-6.6/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch new file mode 100644 index 0000000000..1edc2aa54c --- /dev/null +++ b/target/linux/airoha/patches-6.6/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch @@ -0,0 +1,207 @@ +From a7cc1aa151e3a9c0314b995f06102f7763d3bd71 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sat, 23 Aug 2025 09:56:04 +0200 +Subject: [PATCH 3/3] net: airoha: Introduce check_skb callback in ppe_dev ops + +Export airoha_ppe_check_skb routine in ppe_dev ops. check_skb callback +will be used by the MT76 driver in order to offload the traffic received +by the wlan NIC and forwarded to the ethernet one. +Add rx_wlan parameter to airoha_ppe_check_skb routine signature. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-3-f78600ec3ed8@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 3 ++- + drivers/net/ethernet/airoha/airoha_eth.h | 8 ++------ + drivers/net/ethernet/airoha/airoha_ppe.c | 25 +++++++++++++---------- + include/linux/soc/airoha/airoha_offload.h | 20 ++++++++++++++++++ + 4 files changed, 38 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -703,7 +703,8 @@ static int airoha_qdma_rx_process(struct + + reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); + if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) +- airoha_ppe_check_skb(eth->ppe, q->skb, hash); ++ airoha_ppe_check_skb(ð->ppe->dev, q->skb, hash, ++ false); + + done++; + napi_gro_receive(&q->napi, q->skb); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -230,10 +230,6 @@ struct airoha_hw_stats { + }; + + enum { +- PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, +-}; +- +-enum { + AIROHA_FOE_STATE_INVALID, + AIROHA_FOE_STATE_UNBIND, + AIROHA_FOE_STATE_BIND, +@@ -622,8 +618,8 @@ static inline bool airhoa_is_lan_gdm_por + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + +-void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, +- u16 hash); ++void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, ++ u16 hash, bool rx_wlan); + int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -616,7 +616,7 @@ static bool airoha_ppe_foe_compare_entry + + static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, + struct airoha_foe_entry *e, +- u32 hash) ++ u32 hash, bool rx_wlan) + { + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); + u32 ts = airoha_ppe_get_timestamp(ppe); +@@ -639,7 +639,8 @@ static int airoha_ppe_foe_commit_entry(s + goto unlock; + } + +- airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); ++ if (!rx_wlan) ++ airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); + + if (hash < PPE_SRAM_NUM_ENTRIES) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +@@ -665,7 +666,7 @@ static void airoha_ppe_foe_remove_flow(s + e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; + e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, + AIROHA_FOE_STATE_INVALID); +- airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); ++ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash, false); + e->hash = 0xffff; + } + if (e->type == FLOW_TYPE_L2_SUBFLOW) { +@@ -704,7 +705,7 @@ static void airoha_ppe_foe_flow_remove_e + static int + airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, + struct airoha_flow_table_entry *e, +- u32 hash) ++ u32 hash, bool rx_wlan) + { + u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; + struct airoha_foe_entry *hwe_p, hwe; +@@ -745,14 +746,14 @@ airoha_ppe_foe_commit_subflow_entry(stru + } + + hwe.bridge.data = e->data.bridge.data; +- airoha_ppe_foe_commit_entry(ppe, &hwe, hash); ++ airoha_ppe_foe_commit_entry(ppe, &hwe, hash, rx_wlan); + + return 0; + } + + static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, + struct sk_buff *skb, +- u32 hash) ++ u32 hash, bool rx_wlan) + { + struct airoha_flow_table_entry *e; + struct airoha_foe_bridge br = {}; +@@ -785,7 +786,7 @@ static void airoha_ppe_foe_insert_entry( + if (!airoha_ppe_foe_compare_entry(e, hwe)) + continue; + +- airoha_ppe_foe_commit_entry(ppe, &e->data, hash); ++ airoha_ppe_foe_commit_entry(ppe, &e->data, hash, rx_wlan); + commit_done = true; + e->hash = hash; + } +@@ -797,7 +798,7 @@ static void airoha_ppe_foe_insert_entry( + e = rhashtable_lookup_fast(&ppe->l2_flows, &br, + airoha_l2_flow_table_params); + if (e) +- airoha_ppe_foe_commit_subflow_entry(ppe, e, hash); ++ airoha_ppe_foe_commit_subflow_entry(ppe, e, hash, rx_wlan); + unlock: + spin_unlock_bh(&ppe_lock); + } +@@ -1301,9 +1302,10 @@ int airoha_ppe_setup_tc_block_cb(struct + return err; + } + +-void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, +- u16 hash) ++void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, ++ u16 hash, bool rx_wlan) + { ++ struct airoha_ppe *ppe = dev->priv; + u16 now, diff; + + if (hash > PPE_HASH_MASK) +@@ -1315,7 +1317,7 @@ void airoha_ppe_check_skb(struct airoha_ + return; + + ppe->foe_check_time[hash] = now; +- airoha_ppe_foe_insert_entry(ppe, skb, hash); ++ airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan); + } + + void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) +@@ -1404,6 +1406,7 @@ int airoha_ppe_init(struct airoha_eth *e + return -ENOMEM; + + ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; ++ ppe->dev.ops.check_skb = airoha_ppe_check_skb; + ppe->dev.priv = ppe; + + foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); +--- a/include/linux/soc/airoha/airoha_offload.h ++++ b/include/linux/soc/airoha/airoha_offload.h +@@ -9,10 +9,17 @@ + #include + #include + ++enum { ++ PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, ++}; ++ + struct airoha_ppe_dev { + struct { + int (*setup_tc_block_cb)(struct airoha_ppe_dev *dev, + void *type_data); ++ void (*check_skb)(struct airoha_ppe_dev *dev, ++ struct sk_buff *skb, u16 hash, ++ bool rx_wlan); + } ops; + + void *priv; +@@ -27,6 +34,13 @@ static inline int airoha_ppe_dev_setup_t + { + return dev->ops.setup_tc_block_cb(dev, type_data); + } ++ ++static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev, ++ struct sk_buff *skb, ++ u16 hash, bool rx_wlan) ++{ ++ dev->ops.check_skb(dev, skb, hash, rx_wlan); ++} + #else + static inline struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) + { +@@ -42,6 +56,12 @@ static inline int airoha_ppe_setup_tc_bl + { + return -EOPNOTSUPP; + } ++ ++static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev, ++ struct sk_buff *skb, u16 hash, ++ bool rx_wlan) ++{ ++} + #endif + + #define NPU_NUM_CORES 8 diff --git a/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch b/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch index 42873cf004..41f7570e32 100644 --- a/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch +++ b/target/linux/airoha/patches-6.6/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch @@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2064,11 +2064,14 @@ static int airoha_qdma_get_tx_ets_stats( +@@ -2184,11 +2184,14 @@ static int airoha_qdma_get_tx_ets_stats( static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, struct tc_ets_qopt_offload *opt) { From 6a7b16e61692fdab94094a5f1577311cbc611870 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 1 Sep 2025 18:30:27 +0200 Subject: [PATCH 040/128] airoha: add NPU and reserved memory node for AN7581 Add the NPU and reserved memory node for AN7581 dtsi since it's not supported. Link: https://github.com/openwrt/openwrt/pull/19816 Signed-off-by: Christian Marangi (cherry picked from commit 3dca527e6d1e19aa97ece32c27af5a59ecbe646d) --- target/linux/airoha/dts/an7581.dtsi | 58 ++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 3b9f0c6d65..5337d79a26 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -17,29 +17,39 @@ #size-cells = <2>; ranges; - npu-binary@84000000 { + atf@80000000 { + no-map; + reg = <0x0 0x80000000 0x0 0x200000>; + }; + + npu_binary: npu-binary@84000000 { no-map; reg = <0x0 0x84000000 0x0 0xa00000>; }; - npu-flag@84b0000 { + qdma0_buf: qdma0-buf@87000000 { no-map; - reg = <0x0 0x84b00000 0x0 0x100000>; + reg = <0x0 0x87000000 0x0 0x2000000>; }; - npu-pkt@85000000 { + qdma1_buf: qdma1-buf@89000000 { no-map; - reg = <0x0 0x85000000 0x0 0x1a00000>; + reg = <0x0 0x89000000 0x0 0x1000000>; }; - npu-phyaddr@86b00000 { + npu_pkt: npu-pkt@8a000000 { no-map; - reg = <0x0 0x86b00000 0x0 0x100000>; + reg = <0x0 0x8a000000 0x0 0x2c00000>; }; - npu-rxdesc@86d00000 { + npu_txpkt: npu-txpkt@8cc00000 { no-map; - reg = <0x0 0x86d00000 0x0 0x100000>; + reg = <0x0 0x8cc00000 0x0 0x4000000>; + }; + + npu_txbufid: npu-txbufid@90c00000 { + no-map; + reg = <0x0 0x90c00000 0x0 0x6800>; }; }; @@ -666,6 +676,31 @@ }; }; + npu: npu@1e900000 { + compatible = "airoha,en7581-npu"; + reg = <0x0 0x1e900000 0x0 0x313000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + memory-region = <&npu_binary>, <&npu_pkt>, <&npu_txpkt>, + <&npu_txbufid>; + memory-region-names = "binary", "pkt", "tx-pkt", + "tx-bufid"; + status = "disabled"; + }; + eth: ethernet@1fb50000 { compatible = "airoha,en7581-eth"; reg = <0 0x1fb50000 0 0x2600>, @@ -696,6 +731,11 @@ , ; + memory-region = <&qdma0_buf>, <&qdma1_buf>; + memory-region-names = "qdma0-buf", "qdma1-buf"; + + airoha,npu = <&npu>; + status = "disabled"; #address-cells = <1>; From dc11868486deb6688a1bb2fa4b04e84ce347eae8 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 8 Sep 2025 20:22:09 +0200 Subject: [PATCH 041/128] airoha: backport upstream fixes for pinctrl PHY LED and MDIO Backport fixes for Airoha pinctrl driver for PHY LED and MDIO bus. This fix a copy-paste error for PHY LED and a misconfiguration for MT7530 embedded Switch MDIO bus GPIO pin to permit usage of external PHYs. Signed-off-by: Christian Marangi (cherry picked from commit 35ff70e8073635d60b36875e62c9ba62b4af9182) --- ...ix-wrong-PHY-LED-mux-value-for-LED1-.patch | 68 +++++++++++++++++++ ...roha-fix-wrong-MDIO-function-bitmaks.patch | 58 ++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch create mode 100644 target/linux/airoha/patches-6.6/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch diff --git a/target/linux/airoha/patches-6.6/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch b/target/linux/airoha/patches-6.6/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch new file mode 100644 index 0000000000..f94eab4048 --- /dev/null +++ b/target/linux/airoha/patches-6.6/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch @@ -0,0 +1,68 @@ +From af87d38c442c75a40c7d0a7d8c31557e2e6ccf98 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 25 May 2025 20:22:40 +0200 +Subject: [PATCH 1/2] pinctrl: airoha: fix wrong PHY LED mux value for LED1 + GPIO46 + +In all the MUX value for LED1 GPIO46 there is a Copy-Paste error where +the MUX value is set to LED0_MODE_MASK instead of LED1_MODE_MASK. + +This wasn't notice as there were no board that made use of the +secondary PHY LED but looking at the internal Documentation the actual +value should be LED1_MODE_MASK similar to the other GPIO entry. + +Fix the wrong value to apply the correct MUX configuration. + +Cc: stable@vger.kernel.org +Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -1746,8 +1746,8 @@ static const struct airoha_pinctrl_func_ + .regmap[0] = { + AIROHA_FUNC_MUX, + REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK ++ GPIO_LAN3_LED1_MODE_MASK, ++ GPIO_LAN3_LED1_MODE_MASK + }, + .regmap[1] = { + AIROHA_FUNC_MUX, +@@ -1810,8 +1810,8 @@ static const struct airoha_pinctrl_func_ + .regmap[0] = { + AIROHA_FUNC_MUX, + REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK ++ GPIO_LAN3_LED1_MODE_MASK, ++ GPIO_LAN3_LED1_MODE_MASK + }, + .regmap[1] = { + AIROHA_FUNC_MUX, +@@ -1874,8 +1874,8 @@ static const struct airoha_pinctrl_func_ + .regmap[0] = { + AIROHA_FUNC_MUX, + REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK ++ GPIO_LAN3_LED1_MODE_MASK, ++ GPIO_LAN3_LED1_MODE_MASK + }, + .regmap[1] = { + AIROHA_FUNC_MUX, +@@ -1938,8 +1938,8 @@ static const struct airoha_pinctrl_func_ + .regmap[0] = { + AIROHA_FUNC_MUX, + REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK ++ GPIO_LAN3_LED1_MODE_MASK, ++ GPIO_LAN3_LED1_MODE_MASK + }, + .regmap[1] = { + AIROHA_FUNC_MUX, diff --git a/target/linux/airoha/patches-6.6/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch b/target/linux/airoha/patches-6.6/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch new file mode 100644 index 0000000000..45052b405b --- /dev/null +++ b/target/linux/airoha/patches-6.6/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch @@ -0,0 +1,58 @@ +From 110930eb12699b92f767fc599c7ab467dd42358a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 8 Jul 2025 14:49:56 +0200 +Subject: [PATCH 2/2] pinctrl: airoha: fix wrong MDIO function bitmaks + +With further testing with an attached Aeonsemi it was discovered that +the pinctrl MDIO function applied the wrong bitmask. The error was +probably caused by the confusing documentation related to these bits. + +Inspecting what the bootloader actually configure, the SGMII_MDIO_MODE +is never actually set but instead it's set force enable to the 2 GPIO +(gpio 1-2) for MDC and MDIO pin. + +Applying this configuration permits correct functionality of any +externally attached PHY. + +Cc: stable@vger.kernel.org +Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -102,6 +102,9 @@ + #define JTAG_UDI_EN_MASK BIT(4) + #define JTAG_DFD_EN_MASK BIT(3) + ++#define REG_FORCE_GPIO_EN 0x0228 ++#define FORCE_GPIO_EN(n) BIT(n) ++ + /* LED MAP */ + #define REG_LAN_LED0_MAPPING 0x027c + #define REG_LAN_LED1_MAPPING 0x0280 +@@ -713,16 +716,16 @@ static const struct airoha_pinctrl_func_ + .name = "mdio", + .regmap[0] = { + AIROHA_FUNC_MUX, +- REG_GPIO_PON_MODE, +- GPIO_SGMII_MDIO_MODE_MASK, +- GPIO_SGMII_MDIO_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, + REG_GPIO_2ND_I2C_MODE, + GPIO_MDC_IO_MASTER_MODE_MODE, + GPIO_MDC_IO_MASTER_MODE_MODE + }, ++ .regmap[1] = { ++ AIROHA_FUNC_MUX, ++ REG_FORCE_GPIO_EN, ++ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2), ++ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2) ++ }, + .regmap_size = 2, + }, + }; From f364fe5e09442e030e9b01b320d1664139ef9197 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Sun, 14 Sep 2025 17:38:24 +0200 Subject: [PATCH 042/128] airoha: an7581: enable uart baudrate control The baud rate control on Airoha does not function properly. This patch enables the inactive code responsible for this. The UART2 baud rate is correct. HSUART3 operates at twice the requested baud rate. The same problem exists in the current code, so this doesn't introduce any regression. Support for baud rates higher than 460800 is still required. This will be added in the future. Tested on Gemtek W1700k. UART2 and HSUART3 are working fine. Signed-off-by: Aleksander Jan Bajkowski Link: https://github.com/openwrt/openwrt/pull/20049 Signed-off-by: Robert Marko (cherry picked from commit 440b85f5b1025d26b3a40d6b55b34b17cb6520c8) [ solve conflict error ] Signed-off-by: Christian Marangi --- target/linux/airoha/an7581/config-6.6 | 1 + .../105-uart-add-en7523-support.patch | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 358a953393..8074e514f8 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -517,6 +517,7 @@ CONFIG_SECURITY=y CONFIG_SECURITYFS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY_NETWORK is not set +CONFIG_SERIAL_8250_AIROHA=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_NR_UARTS=5 diff --git a/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch b/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch index 9ea355370b..39a4944daf 100644 --- a/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch +++ b/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch @@ -135,6 +135,25 @@ /* * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR * is written without DLAB set, this mode will be disabled. +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -354,6 +354,16 @@ config SERIAL_8250_ACORN + system, say Y to this option. The driver can handle 1, 2, or 3 port + cards. If unsure, say N. + ++config SERIAL_8250_AIROHA ++ tristate "Airoha UART support" ++ depends on (ARCH_AIROHA || COMPILE_TEST) && OF && SERIAL_8250 ++ help ++ Selecting this option enables an Airoha SoC specific baud rate ++ calculation routine on an otherwise 16550 compatible UART hardware. ++ ++ If you have an Airoha based board and want to use the serial port, ++ say Y to this option. If unsure, say N. ++ + config SERIAL_8250_BCM2835AUX + tristate "BCM2835 auxiliar mini UART support" + depends on ARCH_BCM2835 || COMPILE_TEST --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SERIAL_8250_PERICOM) += 825 From 8c5ad273b465b605716f74caf2589b25234242ee Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Mon, 22 Sep 2025 19:53:29 +0200 Subject: [PATCH 043/128] airoha: en7581: dts: fix typo "disable" No functional changes intended. Fixes warning: /linux/arch/arm64/boot/dts/airoha/en7581-gemtek-w1700k.dtb: i2c1@1fbf8100 (mediatek,mt7621-i2c): status: 'oneOf' conditional failed, one must be fixed: ['disable'] is not of type 'object' 'disable' is not one of ['okay', 'disabled', 'reserved', 'fail', 'fail-needs-probe'] from schema $id: http://devicetree.org/schemas/dt-core.yaml# Signed-off-by: Aleksander Jan Bajkowski Link: https://github.com/openwrt/openwrt/pull/20131 Signed-off-by: Robert Marko (cherry picked from commit 3872e9d317c6daeb64ef6907d452a7625c979984) --- target/linux/airoha/dts/an7581.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 5337d79a26..dbff2385af 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -520,7 +520,7 @@ #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c1: i2c1@1fbf8100 { @@ -534,7 +534,7 @@ #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; snfi: spi@1fa10000 { From 48ec8469fdf5f6dc5e6391d6063486d4656258ee Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 26 Sep 2025 04:15:03 +0200 Subject: [PATCH 044/128] airoha: en7581: Add support for external PHY This add a pending version of the Airoha PCS driver to add support for External PHY. The Airoha PCS driver will receive some minor modification once we the PCS subsystem will be defined upstream. Add all the required node for GDM2 and GDM4 and enable the PCS config. (cherry picked from commit c3d70b1ae55ad0cfebac5cde7b41395cc3ebb3bd) [ fix conflict error ] Signed-off-by: Christian Marangi --- target/linux/airoha/an7581/config-6.6 | 2 +- target/linux/airoha/dts/an7581.dtsi | 58 + ...-airoha-deassert-XSI-line-on-hw-init.patch | 26 + ...eference-for-SPORT-GDM4-in-qdma_get_.patch | 31 + ...-airoha-drop-redundant-GDM3-4-define.patch | 52 + ...nitial-fixup-for-GDM3-4-port-support.patch | 40 + ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 44 + ...et-phylink-add-.pcs_link_down-PCS-OP.patch | 64 + ...airoha-add-PCS-driver-for-Airoha-SoC.patch | 3369 +++++++++++++++++ ...iroha-add-phylink-support-for-GDM2-4.patch | 257 ++ 10 files changed, 3942 insertions(+), 1 deletion(-) create mode 100644 target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch create mode 100644 target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch create mode 100644 target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch create mode 100644 target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch create mode 100644 target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch create mode 100644 target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch create mode 100644 target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch create mode 100644 target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 8074e514f8..69827464d6 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -447,7 +447,7 @@ CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_MSI=y CONFIG_PCPU_DEV_REFCNT=y -CONFIG_PCS_MTK_LYNXI=y +CONFIG_PCS_AIROHA_AN7581=y CONFIG_PERF_EVENTS=y CONFIG_PER_VMA_LOCK=y CONFIG_PGTABLE_LEVELS=3 diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index dbff2385af..1154cadd15 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -438,6 +438,48 @@ status = "disabled"; }; + pon_pcs: pcs@1fa08000 { + compatible = "airoha,an7581-pcs-pon"; + reg = <0x0 0x1fa08000 0x0 0x1000>, + <0x0 0x1fa80000 0x0 0x60>, + <0x0 0x1fa80a00 0x0 0x164>, + <0x0 0x1fa84000 0x0 0x450>, + <0x0 0x1fa85900 0x0 0x338>, + <0x0 0x1fa86000 0x0 0x300>, + <0x0 0x1fa8a000 0x0 0x1000>, + <0x0 0x1fa8b000 0x0 0x1000>; + reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", + "multi_sgmii", "usxgmii", + "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; + + resets = <&scuclk EN7581_XPON_MAC_RST>, + <&scuclk EN7581_XPON_PHY_RST>; + reset-names = "mac", "phy"; + + airoha,scu = <&scuclk>; + }; + + eth_pcs: pcs@1fa09000 { + compatible = "airoha,an7581-pcs-eth"; + reg = <0x0 0x1fa09000 0x0 0x1000>, + <0x0 0x1fa70000 0x0 0x60>, + <0x0 0x1fa70a00 0x0 0x164>, + <0x0 0x1fa74000 0x0 0x450>, + <0x0 0x1fa75900 0x0 0x338>, + <0x0 0x1fa76000 0x0 0x300>, + <0x0 0x1fa7a000 0x0 0x1000>, + <0x0 0x1fa7b000 0x0 0x1000>; + reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", + "multi_sgmii", "usxgmii", + "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; + + resets = <&scuclk EN7581_XSI_MAC_RST>, + <&scuclk EN7581_XSI_PHY_RST>; + reset-names = "mac", "phy"; + + airoha,scu = <&scuclk>; + }; + chip_scu: syscon@1fa20000 { compatible = "airoha,en7581-chip-scu", "syscon"; reg = <0x0 0x1fa20000 0x0 0x388>; @@ -753,6 +795,22 @@ pause; }; }; + + gdm2: ethernet@2 { + compatible = "airoha,eth-mac"; + reg = <2>; + pcs = <&pon_pcs>; + + status = "disabled"; + }; + + gdm4: ethernet@4 { + compatible = "airoha,eth-mac"; + reg = <4>; + pcs = <ð_pcs>; + + status = "disabled"; + }; }; switch: switch@1fb58000 { diff --git a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch new file mode 100644 index 0000000000..7537f659f9 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -0,0 +1,26 @@ +From 5cb5f11469dfcbd7568fbca8b79c0f20a21cfbf5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 10:09:15 +0100 +Subject: [PATCH 2/9] net: airoha: deassert XSI line on hw init + +In preparation for phylink support, deassert XSI line as we will naw +make actual use of them for external PHY/SFP cage support. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1401,6 +1401,10 @@ static int airoha_hw_init(struct platfor + if (err) + return err; + ++ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts); ++ if (err) ++ return err; ++ + msleep(20); + err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); + if (err) diff --git a/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch new file mode 100644 index 0000000000..b620ec62b9 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch @@ -0,0 +1,31 @@ +From ad29054f9b0e96e30a5d0bb6967d1204b8ea8bd1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 10:12:02 +0100 +Subject: [PATCH 3/9] net: airoha: add reference for SPORT GDM4 in + qdma_get_gdm_port + +Add SPORT reference in get gdm port as the on receive the SPORT 0x18 is +assigned for the GDM4 port. + +While at it also add comments to better identify GDM1 ports. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -605,8 +605,11 @@ static int airoha_qdma_get_gdm_port(stru + + sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); + switch (sport) { ++ case 0x18: ++ port = 3; /* GDM4 */ ++ break; + case 0x10 ... 0x14: +- port = 0; ++ port = 0; /* GDM1 */ + break; + case 0x2 ... 0x4: + port = sport - 1; diff --git a/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch b/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch new file mode 100644 index 0000000000..4cc1d6c6fc --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch @@ -0,0 +1,52 @@ +From 6fbb7d72520393a3d447399799d436f17c03ff24 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 10:29:52 +0100 +Subject: [PATCH 5/9] net: airoha: drop redundant GDM3/4 define + +The GDM FWD register are all the same hence it's redundant to have +specific define for GDM3 and GDM4. Drop the redundant define and use the +generic macro. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 ++-- + drivers/net/ethernet/airoha/airoha_regs.h | 8 +------- + 2 files changed, 3 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -507,8 +507,8 @@ static int airoha_fe_init(struct airoha_ + FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | + FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); + +- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN); + + airoha_fe_crsn_qsel_init(eth); + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -128,6 +128,7 @@ + GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) + + #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) ++#define GDM_PAD_EN BIT(28) + #define GDM_DROP_CRC_ERR BIT(23) + #define GDM_IP4_CKSUM BIT(22) + #define GDM_TCP_CKSUM BIT(21) +@@ -349,13 +350,6 @@ + #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) + #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) + +-#define REG_GDM3_FWD_CFG GDM3_BASE +-#define GDM3_PAD_EN_MASK BIT(28) +- +-#define REG_GDM4_FWD_CFG GDM4_BASE +-#define GDM4_PAD_EN_MASK BIT(28) +-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) +- + #define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) + #define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) + #define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch new file mode 100644 index 0000000000..4af0275688 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -0,0 +1,40 @@ +From a3cd6eb3259282a68b608fc923121460c0d3d2f7 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 10:35:41 +0100 +Subject: [PATCH 6/9] net: airoha: add initial fixup for GDM3/4 port support + +GDM3 and GDM4 require different configuration for max long frame +definition, needs the QDMA to strip CRC on RX and require the SPORT to +be enabled to correctly be identified. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 12 ++++++++++-- + drivers/net/ethernet/airoha/airoha_regs.h | 1 + + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -507,8 +507,10 @@ static int airoha_fe_init(struct airoha_ + FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | + FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); + +- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN); +- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), ++ GDM_PAD_EN | GDM_STRIP_CRC); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), ++ GDM_PAD_EN | GDM_STRIP_CRC); + + airoha_fe_crsn_qsel_init(eth); + +@@ -1643,7 +1645,8 @@ static int airoha_dev_open(struct net_de + if (err) + return err; + +- if (netdev_uses_dsa(dev)) ++ /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */ ++ if (netdev_uses_dsa(dev) || port->id > 2) + airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), + GDM_STAG_EN_MASK); + else diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch new file mode 100644 index 0000000000..3e9a92db6b --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -0,0 +1,44 @@ +From fecb65813ddf52abf310bc2227a0ac869dc897d1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 29 Jan 2025 14:47:41 +0100 +Subject: [PATCH 1/3] airoha: ethernet: drop xsi-mac reset + +In preparation for support for Ethernet and PON PCS, drop the xsi-mac +reset from airoha_eth. This reset is related to the Ethernet PCS and +should be handled in the dedicated driver. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++----- + drivers/net/ethernet/airoha/airoha_eth.h | 2 +- + 2 files changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2948,11 +2948,10 @@ static int airoha_probe(struct platform_ + return err; + } + +- eth->xsi_rsts[0].id = "xsi-mac"; +- eth->xsi_rsts[1].id = "hsi0-mac"; +- eth->xsi_rsts[2].id = "hsi1-mac"; +- eth->xsi_rsts[3].id = "hsi-mac"; +- eth->xsi_rsts[4].id = "xfp-mac"; ++ eth->xsi_rsts[0].id = "hsi0-mac"; ++ eth->xsi_rsts[1].id = "hsi1-mac"; ++ eth->xsi_rsts[2].id = "hsi-mac"; ++ eth->xsi_rsts[3].id = "xfp-mac"; + err = devm_reset_control_bulk_get_exclusive(eth->dev, + ARRAY_SIZE(eth->xsi_rsts), + eth->xsi_rsts); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -21,7 +21,7 @@ + #define AIROHA_MAX_NUM_IRQ_BANKS 4 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 +-#define AIROHA_MAX_NUM_XSI_RSTS 5 ++#define AIROHA_MAX_NUM_XSI_RSTS 4 + #define AIROHA_MAX_MTU 9216 + #define AIROHA_MAX_PACKET_SIZE 2048 + #define AIROHA_NUM_QOS_CHANNELS 4 diff --git a/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch new file mode 100644 index 0000000000..7accd73775 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch @@ -0,0 +1,64 @@ +From d5fb4ad1beec53ca5d3b44d9b88598ed4ab0b34d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 9 May 2025 16:36:22 +0200 +Subject: [PATCH 1/6] net: phylink: add .pcs_link_down PCS OP + +Permit for PCS driver to define specific operation to torn down the link +between the MAC and the PCS. + +This might be needed for some PCS that reset counter or require special +reset to correctly work if the link needs to be restored later. + +On phylink_link_down() call, the additional phylink_pcs_link_down() will +be called before .mac_link_down to torn down the link. + +PCS driver will need to define .pcs_link_down to make use of this. + +Signed-off-by: Christian Marangi +--- + drivers/net/phy/phylink.c | 8 ++++++++ + include/linux/phylink.h | 2 ++ + 2 files changed, 10 insertions(+) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -1041,6 +1041,12 @@ static void phylink_pcs_link_up(struct p + pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); + } + ++static void phylink_pcs_link_down(struct phylink_pcs *pcs) ++{ ++ if (pcs && pcs->ops->pcs_link_down) ++ pcs->ops->pcs_link_down(pcs); ++} ++ + static void phylink_pcs_poll_stop(struct phylink *pl) + { + if (pl->cfg_link_an_mode == MLO_AN_INBAND) +@@ -1454,6 +1460,8 @@ static void phylink_link_down(struct phy + + if (ndev) + netif_carrier_off(ndev); ++ phylink_pcs_link_down(pl->pcs); ++ + pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, + pl->cur_interface); + phylink_info(pl, "Link is Down\n"); +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -430,6 +430,7 @@ struct phylink_pcs { + * @pcs_an_restart: restart 802.3z BaseX autonegotiation. + * @pcs_link_up: program the PCS for the resolved link configuration + * (where necessary). ++ * @pcs_link_down: torn down link between MAC and PCS. + */ + struct phylink_pcs_ops { + int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, +@@ -450,6 +451,7 @@ struct phylink_pcs_ops { + void (*pcs_an_restart)(struct phylink_pcs *pcs); + void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, + phy_interface_t interface, int speed, int duplex); ++ void (*pcs_link_down)(struct phylink_pcs *pcs); + }; + + #if 0 /* For kernel-doc purposes only. */ diff --git a/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch b/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch new file mode 100644 index 0000000000..5bd7da4a43 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch @@ -0,0 +1,3369 @@ +From ddee0533ac9906ea5a40ac2e0474034135aa074d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 12:40:32 +0100 +Subject: [PATCH 4/8] net: pcs: airoha: add PCS driver for Airoha AN7581 SoC + +Add PCS driver for Airoha AN7581 SoC for ethernet SERDES and permit usage of +external PHY or connected SFP cage. Supported modes are USXGMII, +10G-BASER, 2500BASE-X, 1000BASE-X and SGMII. + +The driver probe and register the various needed registers and expose +the pcs_create and pcs_destroy symbol to make them usable by the Airoha +Ethernet driver. + +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/Kconfig | 2 + + drivers/net/pcs/Makefile | 2 + + drivers/net/pcs/airoha/Kconfig | 11 + + drivers/net/pcs/airoha/Makefile | 7 + + drivers/net/pcs/airoha/pcs-airoha-common.c | 1033 ++++++++++++++ + drivers/net/pcs/airoha/pcs-airoha.h | 822 ++++++++++++ + drivers/net/pcs/airoha/pcs-an7581.c | 1419 ++++++++++++++++++++ + include/linux/pcs/pcs-airoha.h | 9 + + 8 files changed, 3305 insertions(+) + create mode 100644 drivers/net/pcs/airoha/Kconfig + create mode 100644 drivers/net/pcs/airoha/Makefile + create mode 100644 drivers/net/pcs/airoha/pcs-airoha-common.c + create mode 100644 drivers/net/pcs/airoha/pcs-airoha.h + create mode 100644 drivers/net/pcs/airoha/pcs-an7581.c + create mode 100644 include/linux/pcs/pcs-airoha.h + +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -44,4 +44,6 @@ 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. + ++source "drivers/net/pcs/airoha/Kconfig" ++ + endmenu +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -9,3 +9,5 @@ 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_AIROHA) += airoha/ +--- /dev/null ++++ b/drivers/net/pcs/airoha/Kconfig +@@ -0,0 +1,11 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config PCS_AIROHA ++ tristate ++ ++config PCS_AIROHA_AN7581 ++ tristate "Airoha AN7581 PCS driver" ++ select PCS_AIROHA ++ help ++ This module provides helper to phylink for managing the Airoha ++ AN7581 PCS for SoC Ethernet and PON SERDES. +--- /dev/null ++++ b/drivers/net/pcs/airoha/Makefile +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y := pcs-airoha.o ++pcs-airoha-objs := pcs-airoha-common.o ++ifdef CONFIG_PCS_AIROHA_AN7581 ++pcs-airoha-objs += pcs-an7581.o ++endif +--- /dev/null ++++ b/drivers/net/pcs/airoha/pcs-airoha-common.c +@@ -0,0 +1,1035 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pcs-airoha.h" ++ ++static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 xsi_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ xsi_sel = AIROHA_SCU_ETH_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ default: ++ xsi_sel = AIROHA_SCU_ETH_XSI_USXGMII; ++ } ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_SSR3, ++ AIROHA_SCU_ETH_XSI_SEL, ++ xsi_sel); ++} ++ ++static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 xsi_sel, wan_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ wan_sel = AIROHA_SCU_WAN_SEL_SGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ wan_sel = AIROHA_SCU_WAN_SEL_HSGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ default: ++ wan_sel = AIROHA_SCU_WAN_SEL_USXGMII; ++ xsi_sel = AIROHA_SCU_PON_XSI_USXGMII; ++ } ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, ++ AIROHA_SCU_PON_XSI_SEL, ++ xsi_sel); ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF, ++ AIROHA_SCU_WAN_SEL, ++ wan_sel); ++} ++ ++static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ int ret; ++ ++ switch (data->port_type) { ++ case AIROHA_PCS_ETH: ++ airoha_pcs_setup_scu_eth(priv, interface); ++ break; ++ case AIROHA_PCS_PON: ++ airoha_pcs_setup_scu_pon(priv, interface); ++ break; ++ } ++ ++ /* TODO better handle reset from MAC */ ++ ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_bulk_deassert(ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ /* Disable Hibernation */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, ++ AIROHA_PCS_USXGMII_SPEED_SEL_H); ++ ++ /* FIXME: wait Airoha */ ++ /* Avoid PCS sending garbage to MAC in some HW revision (E0) */ ++ regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); ++} ++ ++static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_TBI_10B_MODE); ++} ++ ++static void airoha_pcs_init_sgmii(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, ++ AIROHA_PCS_HSGMII_XFI_SEL); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_TBI_10B_MODE); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, 0x07070707)); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, 0xff)); ++} ++ ++static void airoha_pcs_init(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ airoha_pcs_init_sgmii(priv); ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ airoha_pcs_init_hsgmii(priv); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ airoha_pcs_init_usxgmii(priv); ++ break; ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_interrupt_init_sgmii(struct airoha_pcs_priv *priv) ++{ ++ /* Disable every interrupt */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT); ++ ++ /* Clear interrupt */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, ++ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | ++ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); ++} ++ ++static void airoha_pcs_interrupt_init_usxgmii(struct airoha_pcs_priv *priv) ++{ ++ /* Disable every Interrupt */ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_0, ++ AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_1, ++ AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN | ++ AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN | ++ AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_2, ++ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN | ++ AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_3, ++ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN | ++ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN | ++ AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN | ++ AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN); ++ ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_4, ++ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN); ++ ++ /* Clear any pending interrupt */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_2, ++ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_E_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_T_INT | ++ AIROHA_PCS_USXGMII_R_TYPE_D_INT); ++ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_3, ++ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT | ++ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT | ++ AIROHA_PCS_USXGMII_LINK_UP_ST_INT | ++ AIROHA_PCS_USXGMII_HI_BER_ST_INT); ++ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_4, ++ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT); ++ ++ /* Interrupt saddly seems to be not weel supported for Link Down. ++ * PCS Poll is a must to correctly read and react on Cable Deatch ++ * as only cable attach interrupt are fired and Link Down interrupt ++ * are fired only in special case like AN restart. ++ */ ++} ++ ++static void airoha_pcs_interrupt_init(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ return airoha_pcs_interrupt_init_sgmii(priv); ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ return airoha_pcs_interrupt_init_usxgmii(priv); ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_get_state_sgmii(struct airoha_pcs_priv *priv, ++ struct phylink_link_state *state) ++{ ++ u32 bmsr, lpa; ++ ++ regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, ++ &bmsr); ++ regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5, ++ &lpa); ++ ++ bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE | ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT | ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY | ++ AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr; ++ lpa = AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY & lpa; ++ ++ phylink_mii_c22_pcs_decode_state(state, bmsr, lpa); ++} ++ ++static void airoha_pcs_get_state_hsgmii(struct airoha_pcs_priv *priv, ++ struct phylink_link_state *state) ++{ ++ u32 bmsr; ++ ++ regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, ++ &bmsr); ++ ++ bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE | ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT | ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY | ++ AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr; ++ ++ state->link = !!(bmsr & BMSR_LSTATUS); ++ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); ++ state->speed = SPEED_2500; ++ state->duplex = DUPLEX_FULL; ++} ++ ++static void airoha_pcs_get_state_usxgmii(struct airoha_pcs_priv *priv, ++ struct phylink_link_state *state) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ u32 an_done, lpa; ++ ++ /* Trigger HW workaround if needed. If an error is reported, ++ * consider link down and test again later. ++ */ ++ if (data->rxlock_workaround && data->rxlock_workaround(priv)) { ++ state->link = false; ++ return; ++ } ++ ++ /* Toggle AN Status */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &lpa); ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_2, &an_done); ++ ++ state->link = !!(lpa & MDIO_USXGMII_LINK); ++ state->an_complete = !!(an_done & AIROHA_PCS_USXGMII_PCS_AN_COMPLETE); ++ ++ phylink_decode_usxgmii_word(state, lpa); ++} ++ ++static void airoha_pcs_get_state_10gbaser(struct airoha_pcs_priv *priv, ++ struct phylink_link_state *state) ++{ ++ u32 status, curr_mode; ++ ++ /* Toggle AN Status */ ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, ++ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); ++ ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_BASE_R_10GB_T_PCS_STUS_1, ++ &status); ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &curr_mode); ++ ++ state->link = !!(status & AIROHA_PCS_USXGMII_RX_LINK_STUS); ++ ++ switch (curr_mode & AIROHA_PCS_USXGMII_CUR_USXGMII_MODE) { ++ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G: ++ state->speed = SPEED_10000; ++ break; ++ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G: ++ state->speed = SPEED_5000; ++ break; ++ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G: ++ state->speed = SPEED_2500; ++ break; ++ default: ++ state->speed = SPEED_UNKNOWN; ++ return; ++ } ++ ++ state->duplex = DUPLEX_FULL; ++} ++ ++static void airoha_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ airoha_pcs_get_state_sgmii(priv, state); ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ airoha_pcs_get_state_hsgmii(priv, state); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ airoha_pcs_get_state_usxgmii(priv, state); ++ break; ++ case PHY_INTERFACE_MODE_10GBASER: ++ airoha_pcs_get_state_10gbaser(priv, state); ++ break; ++ default: ++ return; ++ } ++} ++ ++static int airoha_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ const struct airoha_pcs_match_data *data; ++ u32 rate_adapt; ++ int ret; ++ ++ priv->interface = interface; ++ data = priv->data; ++ ++ /* Apply Analog and Digital configuration for PCS */ ++ if (data->bringup) { ++ ret = data->bringup(priv, interface); ++ if (ret) ++ return ret; ++ } ++ ++ /* Set final configuration for various modes */ ++ airoha_pcs_init(priv, interface); ++ ++ /* Configure Interrupt for various modes */ ++ airoha_pcs_interrupt_init(priv, interface); ++ ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN; ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII) ++ rate_adapt |= AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS; ++ ++ /* AN Auto Settings (Rate Adaptation) */ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN, rate_adapt); ++ ++ /* FIXME: With an attached Aeonsemi PHY, AN is needed ++ * even with no inband. ++ */ ++ if (interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER) { ++ if (interface == PHY_INTERFACE_MODE_USXGMII) ++ regmap_set_bits(priv->usxgmii_pcs, ++ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_ENABLE); ++ else ++ regmap_clear_bits(priv->usxgmii_pcs, ++ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_ENABLE); ++ } ++ ++ /* Clear any force bit that my be set by bootloader */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, ++ AIROHA_PCS_LINK_MODE_P0 | ++ AIROHA_PCS_FORCE_SPD_MODE_P0 | ++ AIROHA_PCS_FORCE_LINKDOWN_P0 | ++ AIROHA_PCS_FORCE_LINKUP_P0); ++ } ++ ++ /* Toggle Rate Adaption for SGMII/HSGMII mode */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) ++ regmap_clear_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, ++ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); ++ else ++ regmap_set_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, ++ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); ++ } ++ ++ /* Setup AN Link Timer */ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX) { ++ u32 an_timer; ++ ++ an_timer = phylink_get_link_timer_ns(interface); ++ ++ /* Value needs to be shifted by 4, seems value is internally * 16 */ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11, ++ AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, ++ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, ++ an_timer >> 4)); ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_3, ++ AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, ++ FIELD_PREP(AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, ++ an_timer >> 4)); ++ } ++ ++ /* Setup SGMII AN and advertisement in DEV_ABILITY */ ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ int advertise = phylink_mii_c22_pcs_encode_advertisement(interface, ++ advertising); ++ if (advertise < 0) ++ return advertise; ++ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4, ++ AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, ++ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, ++ advertise)); ++ ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); ++ } else { ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); ++ } ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) { ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_TX_ENABLE); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX) { ++ u32 if_mode = AIROHA_PCS_HSGMII_AN_SIDEBAND_EN; ++ ++ /* Toggle SGMII or 1000base-x mode */ ++ if (interface == PHY_INTERFACE_MODE_SGMII) ++ if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_EN; ++ ++ if (neg_mode & PHYLINK_PCS_NEG_INBAND) ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); ++ else ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); ++ ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ /* Clear force speed bits and MAC mode */ ++ regmap_clear_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | ++ AIROHA_PCS_HSGMII_PCS_MAC_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); ++ } else { ++ /* Enable compatibility with MAC PCS Layer */ ++ if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN; ++ ++ /* AN off force rate adaption, speed is set later in Link Up */ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_MAC_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); ++ } ++ ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0, if_mode); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_TX_ENABLE | ++ AIROHA_PCS_HSGMII_PCS_MODE2_EN); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_1000BASEX && ++ neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, ++ AIROHA_PCS_SGMII_SEND_AN_ERR_EN); ++ ++ regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37, ++ AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE); ++ } ++ ++ /* Configure Flow Control on XFI */ ++ regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN, ++ permit_pause_to_mac ? ++ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN : ++ 0); ++ ++ return 0; ++} ++ ++static void airoha_pcs_an_restart(struct phylink_pcs *pcs) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ ++ switch (priv->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); ++ udelay(3); ++ regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, ++ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_RESTART); ++ udelay(3); ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, ++ AIROHA_PCS_USXGMII_AN_RESTART); ++ default: ++ return; ++ } ++} ++ ++static void airoha_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, ++ phy_interface_t interface, int speed, int duplex) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ const struct airoha_pcs_match_data *data; ++ ++ data = priv->data; ++ ++ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ regmap_update_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0x0) | ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x0)); ++ udelay(1); ++ regmap_update_bits(priv->hsgmii_rate_adp, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | ++ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0xf) | ++ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x5)); ++ } ++ } else { ++ if (interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER) { ++ u32 mode; ++ u32 rate_adapt; ++ ++ switch (speed) { ++ case SPEED_10000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000; ++ mode = AIROHA_PCS_USXGMII_MODE_10000; ++ break; ++ case SPEED_5000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000; ++ mode = AIROHA_PCS_USXGMII_MODE_5000; ++ break; ++ case SPEED_2500: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500; ++ mode = AIROHA_PCS_USXGMII_MODE_2500; ++ break; ++ case SPEED_1000: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000; ++ mode = AIROHA_PCS_USXGMII_MODE_1000; ++ break; ++ case SPEED_100: ++ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100; ++ mode = AIROHA_PCS_USXGMII_MODE_100; ++ break; ++ } ++ ++ /* Trigger USXGMII change mode and force selected speed */ ++ regmap_update_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, ++ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE | ++ AIROHA_PCS_USXGMII_MODE, ++ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE | mode); ++ ++ regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11, ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, ++ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | ++ rate_adapt); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_1000BASEX) { ++ u32 force_speed; ++ u32 rate_adapt; ++ ++ switch (speed) { ++ case SPEED_1000: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000; ++ break; ++ case SPEED_100: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100; ++ break; ++ case SPEED_10: ++ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10; ++ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10; ++ break; ++ } ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | ++ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | ++ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, ++ force_speed | rate_adapt); ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII || ++ interface == PHY_INTERFACE_MODE_2500BASEX) { ++ u32 ck_gen_mode; ++ u32 speed_reg; ++ u32 if_mode; ++ ++ switch (speed) { ++ case SPEED_2500: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_2_5G; ++ break; ++ case SPEED_1000: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_1G; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000; ++ break; ++ case SPEED_100: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100; ++ break; ++ case SPEED_10: ++ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; ++ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10; ++ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10; ++ break; ++ } ++ ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, ++ AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, ++ if_mode); ++ ++ regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE, ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE | ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL, ++ ck_gen_mode | ++ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL); ++ } ++ ++ regmap_update_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, ++ AIROHA_PCS_LINK_MODE_P0 | ++ AIROHA_PCS_FORCE_SPD_MODE_P0, ++ speed_reg | ++ AIROHA_PCS_FORCE_SPD_MODE_P0); ++ } ++ } ++ ++ if (data->link_up) ++ data->link_up(priv); ++ ++ /* BPI BMI enable */ ++ regmap_clear_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_RXMPI_STOP | ++ AIROHA_PCS_XFI_RXMBI_STOP | ++ AIROHA_PCS_XFI_TXMPI_STOP | ++ AIROHA_PCS_XFI_TXMBI_STOP); ++} ++ ++static void airoha_pcs_link_down(struct phylink_pcs *pcs) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ ++ /* MPI MBI disable */ ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_RXMPI_STOP | ++ AIROHA_PCS_XFI_RXMBI_STOP | ++ AIROHA_PCS_XFI_TXMPI_STOP | ++ AIROHA_PCS_XFI_TXMBI_STOP); ++} ++ ++static void airoha_pcs_pre_config(struct phylink_pcs *pcs, ++ phy_interface_t interface) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ ++ /* Select HSGMII or USXGMII in SCU regs */ ++ airoha_pcs_setup_scu(priv, interface); ++ ++ /* MPI MBI disable */ ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_RXMPI_STOP | ++ AIROHA_PCS_XFI_RXMBI_STOP | ++ AIROHA_PCS_XFI_TXMPI_STOP | ++ AIROHA_PCS_XFI_TXMBI_STOP); ++ ++ /* Write 1 to trigger reset and clear */ ++ regmap_clear_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, ++ AIROHA_PCS_XFI_MAC_LOGIC_RST); ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, ++ AIROHA_PCS_XFI_MAC_LOGIC_RST); ++ ++ usleep_range(1000, 2000); ++ ++ /* Clear XFI MAC counter */ ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_CNT_CLR, ++ AIROHA_PCS_XFI_GLB_CNT_CLR); ++} ++ ++static int airoha_pcs_post_config(struct phylink_pcs *pcs, ++ phy_interface_t interface) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ struct airoha_pcs_priv *priv = port->priv; ++ ++ /* Frag disable */ ++ regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_RX_FRAG_LEN, ++ FIELD_PREP(AIROHA_PCS_XFI_RX_FRAG_LEN, 31)); ++ regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_TX_FRAG_LEN, ++ FIELD_PREP(AIROHA_PCS_XFI_TX_FRAG_LEN, 31)); ++ ++ /* IPG NUM */ ++ regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_IPG_NUM, ++ FIELD_PREP(AIROHA_PCS_XFI_IPG_NUM, 10)); ++ ++ /* Enable TX/RX flow control */ ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_TX_FC_EN); ++ regmap_set_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, ++ AIROHA_PCS_XFI_RX_FC_EN); ++ ++ return 0; ++} ++ ++static const struct phylink_pcs_ops airoha_pcs_ops = { ++ .pcs_pre_config = airoha_pcs_pre_config, ++ .pcs_post_config = airoha_pcs_post_config, ++ .pcs_get_state = airoha_pcs_get_state, ++ .pcs_config = airoha_pcs_config, ++ .pcs_an_restart = airoha_pcs_an_restart, ++ .pcs_link_up = airoha_pcs_link_up, ++ .pcs_link_down = airoha_pcs_link_down, ++}; ++ ++struct phylink_pcs *airoha_pcs_create(struct device *dev) ++{ ++ struct platform_device *pdev; ++ struct airoha_pcs_port *port; ++ struct device_node *np; ++ ++ np = of_parse_phandle(dev->of_node, "pcs", 0); ++ if (!np) ++ return ERR_PTR(-ENODEV); ++ ++ if (!of_device_is_available(np)) { ++ of_node_put(np); ++ return ERR_PTR(-ENODEV); ++ } ++ ++ pdev = of_find_device_by_node(np); ++ of_node_put(np); ++ if (!pdev || !platform_get_drvdata(pdev)) { ++ if (pdev) ++ put_device(&pdev->dev); ++ return ERR_PTR(-EPROBE_DEFER); ++ } ++ ++ port = kzalloc(sizeof(*port), GFP_KERNEL); ++ if (!port) ++ return ERR_PTR(-ENOMEM); ++ ++ port->priv = platform_get_drvdata(pdev); ++ port->pcs.ops = &airoha_pcs_ops; ++ port->pcs.neg_mode = true; ++ port->pcs.poll = true; ++ ++ return &port->pcs; ++} ++EXPORT_SYMBOL(airoha_pcs_create); ++ ++void airoha_pcs_destroy(struct phylink_pcs *pcs) ++{ ++ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); ++ ++ kfree(port); ++} ++EXPORT_SYMBOL(airoha_pcs_destroy); ++ ++static const struct regmap_config airoha_pcs_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ ++static int airoha_pcs_probe(struct platform_device *pdev) ++{ ++ struct regmap_config syscon_config = airoha_pcs_regmap_config; ++ const struct airoha_pcs_match_data *data; ++ struct device *dev = &pdev->dev; ++ struct airoha_pcs_priv *priv; ++ void *base; ++ int ret; ++ ++ data = of_device_get_match_data(dev); ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->dev = dev; ++ priv->data = data; ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_mac"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_mac"; ++ priv->xfi_mac = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_mac)) ++ return PTR_ERR(priv->xfi_mac); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_an"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_an"; ++ priv->hsgmii_an = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_an)) ++ return PTR_ERR(priv->hsgmii_an); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_pcs"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_pcs"; ++ priv->hsgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_pcs)) ++ return PTR_ERR(priv->hsgmii_pcs); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_rate_adp"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "hsgmii_rate_adp"; ++ priv->hsgmii_rate_adp = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->hsgmii_rate_adp)) ++ return PTR_ERR(priv->hsgmii_rate_adp); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "multi_sgmii"); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "multi_sgmii"; ++ priv->multi_sgmii = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->multi_sgmii)) ++ return PTR_ERR(priv->multi_sgmii); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "usxgmii"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "usxgmii"; ++ priv->usxgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->usxgmii_pcs)) ++ return PTR_ERR(priv->usxgmii_pcs); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_pma"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_pma"; ++ priv->xfi_pma = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_pma)) ++ return PTR_ERR(priv->xfi_pma); ++ ++ base = devm_platform_ioremap_resource_byname(pdev, "xfi_ana"); ++ if (IS_ERR(base) && PTR_ERR(base) != -ENOENT) ++ return PTR_ERR(base); ++ ++ syscon_config.name = "xfi_ana"; ++ priv->xfi_ana = devm_regmap_init_mmio(dev, base, &syscon_config); ++ if (IS_ERR(priv->xfi_ana)) ++ return PTR_ERR(priv->xfi_ana); ++ ++ /* SCU is used to toggle XFI or HSGMII in global SoC registers */ ++ priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu"); ++ if (IS_ERR(priv->scu)) ++ return PTR_ERR(priv->scu); ++ ++ priv->rsts[0].id = "mac"; ++ priv->rsts[1].id = "phy"; ++ ret = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(priv->rsts), ++ priv->rsts); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); ++ ++ /* For Ethernet PCS, read the AN7581 SoC revision to check if ++ * manual rx calibration is needed. This is only limited to ++ * any SoC revision before E2. ++ */ ++ if (data->port_type == AIROHA_PCS_ETH) { ++ u32 val; ++ ++ ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val); ++ if (ret) ++ return ret; ++ ++ if (FIELD_GET(AIROHA_SCU_PRODUCT_ID, val) < 0x2) ++ priv->manual_rx_calib = true; ++ } ++ ++ platform_set_drvdata(pdev, priv); ++ ++ return 0; ++} ++ ++static const struct airoha_pcs_match_data an7581_pcs_eth = { ++ .port_type = AIROHA_PCS_ETH, ++ .bringup = an7581_pcs_bringup, ++ .link_up = an7581_pcs_phya_link_up, ++ .rxlock_workaround = an7581_pcs_rxlock_workaround, ++}; ++ ++static const struct airoha_pcs_match_data an7581_pcs_pon = { ++ .port_type = AIROHA_PCS_PON, ++ .bringup = an7581_pcs_bringup, ++ .link_up = an7581_pcs_phya_link_up, ++}; ++ ++static const struct of_device_id airoha_pcs_of_table[] = { ++ { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth }, ++ { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(of, airoha_pcs_of_table); ++ ++static struct platform_driver airoha_pcs_driver = { ++ .driver = { ++ .name = "airoha-pcs", ++ .of_match_table = airoha_pcs_of_table, ++ }, ++ .probe = airoha_pcs_probe, ++}; ++module_platform_driver(airoha_pcs_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Airoha PCS driver"); ++MODULE_AUTHOR("Christian Marangi "); +--- /dev/null ++++ b/drivers/net/pcs/airoha/pcs-airoha.h +@@ -0,0 +1,822 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* SCU*/ ++#define AIROHA_SCU_PDIDR 0x5c ++#define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0) ++#define AIROHA_SCU_WAN_CONF 0x70 ++#define AIROHA_SCU_WAN_SEL GENMASK(7, 0) ++#define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10) ++#define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11) ++#define AIROHA_SCU_WAN_SEL_USXGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x12) ++#define AIROHA_SCU_SSR3 0x94 ++#define AIROHA_SCU_ETH_XSI_SEL GENMASK(14, 13) ++#define AIROHA_SCU_ETH_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x1) ++#define AIROHA_SCU_ETH_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x2) ++#define AIROHA_SCU_SSTR 0x9c ++#define AIROHA_SCU_PON_XSI_SEL GENMASK(10, 9) ++#define AIROHA_SCU_PON_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x1) ++#define AIROHA_SCU_PON_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x2) ++ ++/* XFI_MAC */ ++#define AIROHA_PCS_XFI_MAC_XFI_GIB_CFG 0x0 ++#define AIROHA_PCS_XFI_RX_FRAG_LEN GENMASK(26, 22) ++#define AIROHA_PCS_XFI_TX_FRAG_LEN GENMASK(21, 17) ++#define AIROHA_PCS_XFI_IPG_NUM GENMASK(15, 10) ++#define AIROHA_PCS_XFI_TX_FC_EN BIT(5) ++#define AIROHA_PCS_XFI_RX_FC_EN BIT(4) ++#define AIROHA_PCS_XFI_RXMPI_STOP BIT(3) ++#define AIROHA_PCS_XFI_RXMBI_STOP BIT(2) ++#define AIROHA_PCS_XFI_TXMPI_STOP BIT(1) ++#define AIROHA_PCS_XFI_TXMBI_STOP BIT(0) ++#define AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST 0x10 ++#define AIROHA_PCS_XFI_MAC_LOGIC_RST BIT(0) ++#define AIROHA_PCS_XFI_MAC_XFI_MACADDRH 0x60 ++#define AIROHA_PCS_XFI_MAC_MACADDRH GENMASK(15, 0) ++#define AIROHA_PCS_XFI_MAC_XFI_MACADDRL 0x64 ++#define AIROHA_PCS_XFI_MAC_MACADDRL GENMASK(31, 0) ++#define AIROHA_PCS_XFI_MAC_XFI_CNT_CLR 0x100 ++#define AIROHA_PCS_XFI_GLB_CNT_CLR BIT(0) ++ ++/* HSGMII_AN */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0 0x0 ++#define AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE BIT(12) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART BIT(9) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1 0x4 /* BMSR */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_UNIDIR_ABILITY BIT(6) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE BIT(5) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT BIT(4) ++#define AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY BIT(3) ++#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS BIT(2) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4 0x10 ++#define AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5 0x14 /* LPA */ ++#define AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11 0x2c ++#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER GENMASK(19, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13 0x34 ++#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS BIT(8) ++#define AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0 GENMASK(5, 0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN BIT(5) ++#define AIROHA_PCS_HSGMII_AN_DUPLEX_FORCE_MODE BIT(4) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE GENMASK(3, 2) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_AN_SIDEBAND_EN BIT(1) ++#define AIROHA_PCS_HSGMII_AN_SGMII_EN BIT(0) ++#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37 0x60 ++#define AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE BIT(0) ++ ++/* HSGMII_PCS */ ++#define AIROHA_PCS_HSGMII_PCS_CTROL_1 0x0 ++#define AIROHA_PCS_TBI_10B_MODE BIT(30) ++#define AIROHA_PCS_SGMII_SEND_AN_ERR_EN BIT(24) ++#define AIROHA_PCS_REMOTE_FAULT_DIS BIT(12) ++#define AIROHA_PCS_HSGMII_PCS_CTROL_3 0x8 ++#define AIROHA_PCS_HSGMII_PCS_LINK_STSTIME GENMASK(19, 0) ++#define AIROHA_PCS_HSGMII_PCS_CTROL_6 0x14 ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 BIT(14) ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 BIT(13) ++#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 BIT(12) ++#define AIROHA_PCS_HSGMII_PCS_MAC_MODE BIT(8) ++#define AIROHA_PCS_HSGMII_PCS_TX_ENABLE BIT(4) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL GENMASK(3, 2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x0) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x1) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT BIT(1) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_EN BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT 0x20 ++#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR BIT(11) ++#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT BIT(10) ++#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR BIT(9) ++#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT BIT(8) ++#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR BIT(5) ++#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT BIT(4) ++#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR BIT(3) ++#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR BIT(2) ++#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT BIT(1) ++#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE 0x24 ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE GENMASK(5, 4) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL BIT(0) ++#define ARIOHA_PCS_HSGMII_PCS_STATE_2 0x104 ++#define AIROHA_PCS_HSGMII_PCS_RX_SYNC BIT(5) ++#define AIROHA_PCS_HSGMII_PCS_AN_DONE BIT(0) ++#define AIROHA_PCS_HSGMII_PCS_INT_STATE 0x15c ++#define AIROHA_PCS_HSGMII_PCS_MODE2_REMOTE_FAULT_OCCUR_INT BIT(4) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_MLS BIT(3) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_CL37_TIMERDONE_INT BIT(2) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_RX_SYNC BIT(1) ++#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_DONE BIT(0) ++ ++/* MULTI_SGMII */ ++#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_EN_0 0x14 ++#define AIROHA_PCS_MULTI_SGMII_PCS_INT_EN_0 BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0 0x18 ++#define AIROHA_PCS_LINK_MODE_P0 GENMASK(5, 4) ++#define AIROHA_PCS_LINK_MODE_P0_2_5G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x3) ++#define AIROHA_PCS_LINK_MODE_P0_1G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x2) ++#define AIROHA_PCS_LINK_MODE_P0_100M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x1) ++#define AIROHA_PCS_LINK_MODE_P0_10M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x0) ++#define AIROHA_PCS_FORCE_SPD_MODE_P0 BIT(2) ++#define AIROHA_PCS_FORCE_LINKDOWN_P0 BIT(1) ++#define AIROHA_PCS_FORCE_LINKUP_P0 BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0 0x100 ++#define AIROHA_PCS_HSGMII_XFI_SEL BIT(28) ++#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_SEL 0x14c ++#define AIROHA_PCS_HSGMII_PCS_INT BIT(0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_15 0x43c ++#define AIROHA_PCS_LINK_STS_P0 BIT(3) ++#define AIROHA_PCS_SPEED_STS_P0 GENMASK(2, 0) ++#define AIROHA_PCS_SPEED_STS_P0_1G FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x2) ++#define AIROHA_PCS_SPEED_STS_P0_100M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x1) ++#define AIROHA_PCS_SPEED_STS_P0_10M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x0) ++#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_18 0x448 ++#define AIROHA_PCS_P0_SGMII_IS_10 BIT(2) ++#define AIROHA_PCS_P0_SGMII_IS_100 BIT(1) ++#define AIROHA_PCS_P0_SGMII_IS_1000 BIT(0) ++ ++/* HSGMII_RATE_ADP */ ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0 0x0 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS BIT(27) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS BIT(26) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN BIT(4) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN BIT(0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1 0x4 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR GENMASK(20, 16) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR GENMASK(28, 24) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6 0x18 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L GENMASK(31, 0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8 0x20 ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C GENMASK(7, 0) ++#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11 0x2c ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN BIT(8) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE GENMASK(15, 12) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x0) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x1) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x2) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x4) ++#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100 \ ++ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x6) ++#define AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0 0x100 ++#define AIROHA_PCS_HSGMII_P0_DIS_MII_MODE BIT(31) ++ ++/* USXGMII */ ++#define AIROHA_PCS_USXGMII_PCS_CTROL_1 0x0 ++#define AIROHA_PCS_USXGMII_SPEED_SEL_H BIT(13) ++#define AIROHA_PCS_USXGMII_PCS_STUS_1 0x4 ++#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS BIT(2) ++#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP \ ++ FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x1) ++#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_DOWN \ ++ FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x0) ++#define AIROHA_PCS_USXGMII_BASE_R_10GB_T_PCS_STUS_1 0x30 ++#define AIROHA_PCS_USXGMII_RX_LINK_STUS BIT(12) ++#define AIROHA_PCS_USXGMII_PRBS9_PATT_TST_ABILITY BIT(3) ++#define AIROHA_PCS_USXGMII_PRBS31_PATT_TST_ABILITY BIT(2) ++#define AIROHA_PCS_USXGMII_PCS_BLK_LK BIT(0) ++#define AIROHA_PCS_USGMII_VENDOR_DEFINE_116 0x22c ++#define AIROHA_PCS_USXGMII_PCS_CTRL_0 0x2c0 ++#define AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_1 0x2c4 ++#define AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_2 0x2c8 ++#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_3 0x2cc ++#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN BIT(24) ++#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN BIT(16) ++#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN BIT(8) ++#define AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_2 0x2d8 ++#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT BIT(24) ++#define AIROHA_PCS_USXGMII_R_TYPE_E_INT BIT(16) ++#define AIROHA_PCS_USXGMII_R_TYPE_T_INT BIT(8) ++#define AIROHA_PCS_USXGMII_R_TYPE_D_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_3 0x2dc ++#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT BIT(24) ++#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT BIT(16) ++#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT BIT(8) ++#define AIROHA_PCS_USXGMII_HI_BER_ST_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_CTRL_4 0x2e0 ++#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_INT_STA_4 0x2e4 ++#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0 0x2f8 ++#define AIROHA_PCS_USXGMII_AN_RESTART BIT(8) ++#define AIROHA_PCS_USXGMII_AN_ENABLE BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_STATS_0 0x310 ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE GENMASK(30, 28) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x0) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x1) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x2) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_1G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x3) ++#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_100M FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x4) ++#define AIROHA_PCS_USXGMII_PARTNER_ABILITY GENMASK(15, 0) ++#define AIROHA_PCS_USXGMII_PCS_AN_STATS_2 0x318 ++#define AIROHA_PCS_USXGMII_PCS_AN_COMPLETE BIT(24) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c ++#define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0) ++#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320 ++#define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12) ++#define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8) ++#define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x0) ++#define AIROHA_PCS_USXGMII_MODE_5000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x1) ++#define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x2) ++#define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x3) ++#define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x4) ++ ++/* PMA_PHYA */ ++#define AIROHA_PCS_ANA_PXP_CMN_EN 0x0 ++#define AIROHA_PCS_ANA_CMN_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4 ++#define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24) ++#define AIROHA_PCS_ANA_JCPLL_CHP_IBIAS GENMASK(21, 16) ++#define AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN BIT(8) ++#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR 0x8 ++#define AIROHA_PCS_ANA_JCPLL_LPF_BWR GENMASK(28, 24) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BP GENMASK(20, 16) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BC GENMASK(12, 8) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BR GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC 0xc ++#define AIROHA_PCS_ANA_JCPLL_KBAND_DIV GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_CODE GENMASK(23, 16) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_OPTION BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_LPF_BWC GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC 0x10 ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KS GENMASK(17, 16) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KF GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_KBAND_KFC GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE 0x14 ++#define AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 BIT(24) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x3) ++#define AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY 0x1c ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS GENMASK(25, 24) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_SDM_DI_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_PLL_RSTB BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY GENMASK(2, 0) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_20_25 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_40_50 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_80_100 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_300_400 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x5) ++#define AIROHA_PCS_ANA_JCPLL_RST_DLY_600_800 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x6) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM 0x20 ++#define AIROHA_PCS_ANA_JCPLL_SDM_OUT BIT(24) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD GENMASK(17, 16) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_SDM_MODE GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_SDM_IFM BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN 0x24 ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF GENMASK(28, 24) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_10 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN BIT(8) ++#define AIROHA_PCS_ANA_JCPLL_SDM_HREN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN 0x28 ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x1) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x2) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x3) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x4) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x6) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24) ++#define AIROHA_PCS_ANA_PXP_JCPLL_VCODIV 0x2c ++#define AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR GENMASK(26, 24) ++#define AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_VCO_CFIX GENMASK(9, 8) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV GENMASK(1, 0) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x0) ++#define AIROHA_PCS_ANA_JCPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x1) ++#define AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR 0x30 ++#define AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI BIT(17) ++#define AIROHA_PCS_ANA_JCPLL_SSC_EN BIT(16) ++#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(10, 8) ++#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(5, 3) ++#define AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR GENMASK(2, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN 0x34 ++#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 GENMASK(23, 8) ++#define AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA 0x38 ++#define AIROHA_PCS_ANA_JCPLL_SSC_PERIOD GENMASK(31, 16) ++#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H 0x48 ++#define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16) ++#define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8) ++#define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5)) ++#define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50 ++#define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16) ++#define AIROHA_PCS_ANA_TXPLL_CHP_IOFST GENMASK(13, 8) ++#define AIROHA_PCS_ANA_TXPLL_CHP_IBIAS GENMASK(5, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP 0x54 ++#define AIROHA_PCS_ANA_TXPLL_KBAND_OPTION BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BWC GENMASK(20, 16) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BWR GENMASK(12, 8) ++#define AIROHA_PCS_ANA_TXPLL_LPF_BP GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE 0x58 ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KF GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KFC GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_DIV GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_CODE GENMASK(7, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS 0x5c ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64 ++#define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV GENMASK(9, 8) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN 0x68 ++#define AIROHA_PCS_ANA_TXPLL_SDM_MODE GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_SDM_IFM BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS GENMASK(9, 8) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_SDM_DI_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD 0x6c ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_SDM_HREN BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SDM_OUT BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD GENMASK(1, 0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x3) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN 0x70 ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF GENMASK(12, 8) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN GENMASK(2, 0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x4) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN 0x74 ++#define AIROHA_PCS_ANA_TXPLL_VCO_CFIX GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x1) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x2) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x3) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x4) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x6) ++#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN 0x78 ++#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(29, 27) ++#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(26, 24) ++#define AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR GENMASK(18, 16) ++#define AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN 0x7c ++#define AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_SSC_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1 0x80 ++#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA GENMASK(31, 16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA1 GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD 0x84 ++#define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24) ++#define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16) ++#define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94 ++#define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) ++#define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4 ++#define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24) ++#define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24) ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_PR FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x0) ++#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x1) ++#define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4 ++#define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16) ++#define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) ++#define AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) ++#define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) ++#define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18) ++#define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16) ++#define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8 ++#define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24) ++#define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16) ++#define AIROHA_PCS_ANA_RX_PHYCK_SEL GENMASK(9, 8) ++#define AIROHA_PCS_ANA_RX_PHYCK_DIV GENMASK(7, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc ++#define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8) ++#define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0) ++#define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8 ++#define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8) ++#define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE 0xf4 ++#define AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF BIT(24) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC 0xf8 ++#define AIROHA_PCS_ANA_CDR_PR_KBAND_DIV GENMASK(26, 24) ++#define AIROHA_PCS_ANA_CDR_PR_BETA_SEL GENMASK(19, 16) ++#define AIROHA_PCS_ANA_CDR_PR_VCOADC_OS GENMASK(11, 8) ++#define AIROHA_PCS_ANA_CDR_PR_BETA_DAC GENMASK(6, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL 0xfc ++#define AIROHA_PCS_ANA_CDR_PR_FBKSEL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_CDR_PR_DAC_BAND GENMASK(20, 16) ++#define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8) ++#define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c ++#define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24) ++#define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19) ++#define AIROHA_PCS_ANA_CDR_BUF_IN_SR GENMASK(18, 16) ++#define AIROHA_PCS_ANA_CDR_PR_XFICK_EN BIT(2) ++#define AIROHA_PCS_ANA_CDR_PR_MONDPI_EN BIT(1) ++#define AIROHA_PCS_ANA_CDR_PR_MONDPR_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110 ++#define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114 ++#define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16) ++#define AIROHA_PCS_ANA_RX_SIGDET_PEAK GENMASK(9, 8) ++#define AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN 0x118 ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN BIT(24) ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN BIT(16) ++#define AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN BIT(8) ++#define AIROHA_PCS_ANA_RX_FE_EQ_HZEN BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB 0x11c ++#define AIROHA_PCS_ANA_FE_VCM_GEN_PWDB BIT(0) ++#define AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW 0x120 ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE GENMASK(17, 8) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(0)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(1)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(2)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(3)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(4)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(5)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(6)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(7)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(8)) ++#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(9)) ++#define AIROHA_PCS_ANA_PXP_AEQ_CFORCE 0x13c ++#define AIROHA_PCS_ANA_AEQ_OFORCE GENMASK(19, 8) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_SAOS FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(0)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP1 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(1)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP2 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(2)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP3 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(3)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP4 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(4)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP5 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(5)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP6 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(6)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP7 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(7)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_VGA FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(8)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_CTLE FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(9)) ++#define AIROHA_PCS_ANA_AEQ_OFORCE_ATT FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(10)) ++#define AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB 0x144 ++#define AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ BIT(24) ++#define AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ 0x148 ++#define AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ BIT(24) ++#define AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ BIT(16) ++#define AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ BIT(8) ++#define AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ BIT(0) ++ ++/* PMA_PHYD */ ++#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0 ++#define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4 ++#define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88 ++#define AIROHA_PCS_PMA_DATA_SHIFT BIT(8) ++#define AIROHA_PCS_PMA_EYECNT_FAST BIT(0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0 0x8c ++#define AIROHA_PCS_PMA_RX_OS_START GENMASK(23, 8) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT GENMASK(2, 0) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_05 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x0) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x1) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x2) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x3) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x4) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_1_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x5) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_3_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x6) ++#define AIROHA_PCS_PMA_OSC_SPEED_OPT_6_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x7) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1 0x90 ++#define AIROHA_PCS_PMA_RX_PICAL_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_PICAL_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2 0x94 ++#define AIROHA_PCS_PMA_RX_PDOS_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_PDOS_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3 0x98 ++#define AIROHA_PCS_PMA_RX_FEOS_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_FEOS_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4 0x9c ++#define AIROHA_PCS_PMA_RX_SDCAL_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_SDCAL_START GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5 0x100 ++#define AIROHA_PCS_PMA_RX_RDY GENMASK(31, 16) ++#define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104 ++#define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c ++#define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114 ++#define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_2 0x120 ++#define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16) ++#define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8) ++#define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c ++#define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_2 0x150 ++#define AIROHA_PCS_PMA_LOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_LOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_3 0x154 ++#define AIROHA_PCS_PMA_UNLOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_UNLOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_4 0x158 ++#define AIROHA_PCS_PMA_LOCK_UNLOCKTH GENMASK(15, 12) ++#define AIROHA_PCS_PMA_LOCK_LOCKTH GENMASK(11, 8) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN GENMASK(2, 0) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x0) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x1) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3) ++#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7) ++#define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c ++#define AIROHA_PCS_PMA_SIGDET_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_FLL_1 0x174 ++#define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_FLL_2 0x178 ++#define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16) ++#define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0) ++#define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1) ++#define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2) ++#define AIROHA_PCS_PMA_RX_FLL_5 0x184 ++#define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16) ++#define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_FLL_B 0x19c ++#define AIROHA_PCS_PMA_LOAD_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_RESET_1 0x208 ++#define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8) ++#define AIROHA_PCS_PMA_TX_RST_B 0x260 ++#define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8) ++#define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320 ++#define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330 ++#define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c ++#define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c ++#define AIROHA_PCS_PMA_XPON_CDR_PD_PWDB BIT(24) ++#define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16) ++#define AIROHA_PCS_PMA_XPON_CDR_PW_PWDB BIT(8) ++#define AIROHA_PCS_PMA_XPON_RX_FE_PWDB BIT(0) ++#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1 0x350 ++#define AIROHA_PCS_PMA_RX_SIDGET_PWDB BIT(0) ++#define AIROHA_PCS_PMA_DIG_RESERVE_0 0x360 ++#define AIROHA_PCS_TRIGGER_RX_SIDGET_SCAN GENMASK(17, 16) ++#define AIROHA_PCS_PMA_XPON_RX_RESERVED_1 0x374 ++#define AIROHA_PCS_PMA_XPON_RX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_DIG_RO_RESERVE_2 0x380 ++#define AIROHA_PCS_RX_SIGDET BIT(8) ++#define AIROHA_PCS_PMA_RX_SYS_EN_SEL_0 0x38c ++#define AIROHA_PCS_PMA_RX_SYS_EN_SEL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_0 0x390 ++#define AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_1 0x394 ++#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_END GENMASK(31, 16) ++#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c ++#define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8) ++#define AIROHA_PCS_PMA_SW_RST_SET 0x460 ++#define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11) ++#define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10) ++#define AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N BIT(9) ++#define AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N BIT(8) ++#define AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N BIT(7) ++#define AIROHA_PCS_PMA_SW_TX_FIFO_RST_N BIT(6) ++#define AIROHA_PCS_PMA_SW_REF_RST_N BIT(5) ++#define AIROHA_PCS_PMA_SW_ALLPCS_RST_N BIT(4) ++#define AIROHA_PCS_PMA_SW_PMA_RST_N BIT(3) ++#define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2) ++#define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1) ++#define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0) ++#define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474 ++#define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16) ++#define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c ++#define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16) ++#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c ++#define AIROHA_PCS_PMA_DISB_LEQ BIT(0) ++#define AIROHA_PCS_PMA_RX_FREQDET 0x530 ++#define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580 ++#define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL GENMASK(19, 16) ++#define AIROHA_PCS_PMA_PXP_AEQ_SPEED 0x76c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_OSR_SEL GENMASK(17, 16) ++#define AIROHA_PCS_PMA_PXP_TX_FIR_C0B 0x778 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 GENMASK(20, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_TX_TERM_SEL 0x77c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR GENMASK(19, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL GENMASK(2, 0) ++#define AIROHA_PCS_PMA_PXP_TX_FIR_C1 0x780 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 GENMASK(20, 16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16) ++#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC GENMASK(10, 0) ++#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR GENMASK(10, 8) ++#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW 0x798 ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW GENMASK(30, 0) ++#define AIROHA_PCS_PMA_PXP_RX_FE_VOS 0x79c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_FE_VOS GENMASK(5, 0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW 0x800 ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW GENMASK(30, 0) ++#define AIROHA_PCS_PMA_PXP_AEQ_BYPASS 0x80c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON BIT(16) ++#define AIROHA_PCS_PMA_PXP_AEQ_RSTB 0x814 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL BIT(16) ++#define AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA 0x818 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PD_PWDB 0x81c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN 0x820 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB 0x824 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB BIT(0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN 0x828 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B BIT(0) ++#define AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN 0x854 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16) ++#define AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL 0x88c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_RX_FE_PWDB 0x894 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0) ++ ++#define AIROHA_PCS_MAX_CALIBRATION_TRY 50 ++#define AIROHA_PCS_MAX_NUM_RSTS 2 ++ ++enum xfi_port_type { ++ AIROHA_PCS_ETH, ++ AIROHA_PCS_PON, ++}; ++ ++struct airoha_pcs_priv { ++ struct device *dev; ++ const struct airoha_pcs_match_data *data; ++ phy_interface_t interface; ++ ++ struct regmap *scu; ++ ++ struct regmap *xfi_mac; ++ struct regmap *hsgmii_an; ++ struct regmap *hsgmii_pcs; ++ struct regmap *hsgmii_rate_adp; ++ struct regmap *multi_sgmii; ++ struct regmap *usxgmii_pcs; ++ ++ struct regmap *xfi_pma; ++ struct regmap *xfi_ana; ++ ++ struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; ++ ++ bool manual_rx_calib; ++}; ++ ++struct airoha_pcs_port { ++ struct airoha_pcs_priv *priv; ++ ++ struct phylink_pcs pcs; ++}; ++ ++struct airoha_pcs_match_data { ++ enum xfi_port_type port_type; ++ ++ int (*bringup)(struct airoha_pcs_priv *priv, ++ phy_interface_t interface); ++ void (*link_up)(struct airoha_pcs_priv *priv); ++ int (*rxlock_workaround)(struct airoha_pcs_priv *priv); ++}; ++ ++#define to_airoha_pcs_port(n) container_of(n, struct airoha_pcs_port, pcs); ++ ++#ifdef CONFIG_PCS_AIROHA_AN7581 ++int an7581_pcs_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface); ++ ++void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv); ++int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv); ++#else ++static inline int an7581_pcs_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv) ++{ ++} ++ ++static inline int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv) ++{ ++ return 0; ++} ++#endif +--- /dev/null ++++ b/drivers/net/pcs/airoha/pcs-an7581.c +@@ -0,0 +1,1419 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++#include ++#include ++ ++#include "pcs-airoha.h" ++ ++static void an7581_pcs_jcpll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 kband_vref; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ kband_vref = 0x10; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ kband_vref = 0xf; ++ break; ++ default: ++ return; ++ } ++ ++ /* Setup LDO */ ++ usleep_range(200, 300); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, ++ AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO); ++ ++ /* Setup RSTB */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_PLL_RSTB); ++ ++ /* Enable PLL force selection and Force Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN); ++ ++ /* Setup SDM */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_LS | ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_EN, ++ AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, ++ AIROHA_PCS_ANA_JCPLL_SDM_OUT | ++ AIROHA_PCS_ANA_JCPLL_SDM_ORD | ++ AIROHA_PCS_ANA_JCPLL_SDM_MODE | ++ AIROHA_PCS_ANA_JCPLL_SDM_IFM, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0) | ++ AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_MODE, 0x0)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, ++ AIROHA_PCS_ANA_JCPLL_SDM_HREN); ++ ++ /* Setup SSC */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, ++ AIROHA_PCS_ANA_JCPLL_SSC_PERIOD | ++ AIROHA_PCS_ANA_JCPLL_SSC_DELTA, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_PERIOD, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, ++ AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 | ++ AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA1, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, ++ AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI | ++ AIROHA_PCS_ANA_JCPLL_SSC_EN | ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x0)); ++ ++ /* Setup LPF */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, ++ AIROHA_PCS_ANA_JCPLL_CHP_IOFST | ++ AIROHA_PCS_ANA_JCPLL_CHP_IBIAS | ++ AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IOFST, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IBIAS, 0x18)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, ++ AIROHA_PCS_ANA_JCPLL_LPF_BWR | ++ AIROHA_PCS_ANA_JCPLL_LPF_BP | ++ AIROHA_PCS_ANA_JCPLL_LPF_BC | ++ AIROHA_PCS_ANA_JCPLL_LPF_BR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWR, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BP, 0x10) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BC, 0x1f) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BR, BIT(3) | BIT(1))); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, ++ AIROHA_PCS_ANA_JCPLL_LPF_BWC, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWC, 0x0)); ++ ++ /* Setup VCO */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR | ++ AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN | ++ AIROHA_PCS_ANA_JCPLL_VCO_CFIX, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR, 0x4) | ++ AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_CFIX, 0x1)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H | ++ AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x3)); ++ ++ /* Setup PCW */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW, ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, 0x25800000)); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW); ++ ++ /* Setup DIV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, ++ AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 | ++ AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, ++ AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCODIV, ++ AIROHA_PCS_ANA_JCPLL_VCODIV_1); ++ ++ /* Setup KBand */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, ++ AIROHA_PCS_ANA_JCPLL_KBAND_KS | ++ AIROHA_PCS_ANA_JCPLL_KBAND_KF | ++ AIROHA_PCS_ANA_JCPLL_KBAND_KFC, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KS, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KF, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KFC, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, ++ AIROHA_PCS_ANA_JCPLL_KBAND_DIV | ++ AIROHA_PCS_ANA_JCPLL_KBAND_CODE | ++ AIROHA_PCS_ANA_JCPLL_KBAND_OPTION, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_DIV, 0x2) | ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_CODE, 0xe4)); ++ ++ /* Setup TCL */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, ++ AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF, kband_vref)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF, 0x5) | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 | ++ AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW | ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 | ++ AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN); ++ ++ /* Enable PLL */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN); ++ ++ /* Enale PLL Output */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN | ++ AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN); ++} ++ ++static void an7581_pcs_txpll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 lpf_chp_ibias, lpf_bp, lpf_bwr, lpf_bwc; ++ u32 vco_cfix; ++ u32 pcw; ++ u32 tcl_amp_vref; ++ bool sdm_hren; ++ bool vcodiv; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ lpf_chp_ibias = 0xf; ++ lpf_bp = BIT(1); ++ lpf_bwr = BIT(3) | BIT(1) | BIT(0); ++ lpf_bwc = BIT(4) | BIT(3); ++ vco_cfix = BIT(1) | BIT(0); ++ pcw = BIT(27); ++ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); ++ vcodiv = false; ++ sdm_hren = false; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ lpf_chp_ibias = 0xa; ++ lpf_bp = BIT(2) | BIT(0); ++ lpf_bwr = 0; ++ lpf_bwc = 0; ++ vco_cfix = 0; ++ pcw = BIT(27) | BIT(25); ++ tcl_amp_vref = BIT(3) | BIT(2) | BIT(0); ++ vcodiv = true; ++ sdm_hren = false; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ lpf_chp_ibias = 0xf; ++ lpf_bp = BIT(1); ++ lpf_bwr = BIT(3) | BIT(1) | BIT(0); ++ lpf_bwc = BIT(4) | BIT(3); ++ vco_cfix = BIT(0); ++ pcw = BIT(27) | BIT(22); ++ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); ++ vcodiv = false; ++ sdm_hren = true; ++ break; ++ default: ++ return; ++ } ++ ++ /* Setup VCO LDO Output */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT | ++ AIROHA_PCS_ANA_TXPLL_LDO_OUT, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1)); ++ ++ /* Setup RSTB */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ AIROHA_PCS_ANA_TXPLL_RST_DLY | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV | ++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 | ++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL); ++ ++ /* Enable PLL force selection and Force Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN); ++ ++ /* Setup SDM */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, ++ AIROHA_PCS_ANA_TXPLL_SDM_MODE | ++ AIROHA_PCS_ANA_TXPLL_SDM_IFM | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_SDM_HREN | ++ AIROHA_PCS_ANA_TXPLL_SDM_OUT | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD, ++ (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM); ++ ++ /* Setup SSC */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA | ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, ++ AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN | ++ AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI | ++ AIROHA_PCS_ANA_TXPLL_SSC_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0)); ++ ++ /* Setup LPF */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, ++ AIROHA_PCS_ANA_TXPLL_LPF_BC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BR | ++ AIROHA_PCS_ANA_TXPLL_CHP_IOFST | ++ AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, 0x5) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, lpf_chp_ibias)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_LPF_BWC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BWR | ++ AIROHA_PCS_ANA_TXPLL_LPF_BP, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, lpf_bwc) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, lpf_bp)); ++ ++ /* Setup VCO */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_CFIX, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H | ++ AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR | ++ AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN); ++ ++ /* Setup PCW */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); ++ ++ /* Setup KBand */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KF | ++ AIROHA_PCS_ANA_TXPLL_KBAND_KFC | ++ AIROHA_PCS_ANA_TXPLL_KBAND_DIV | ++ AIROHA_PCS_ANA_TXPLL_KBAND_CODE, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_KBAND_OPTION); ++ ++ /* Setup DIV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE | ++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCODIV, ++ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : ++ AIROHA_PCS_ANA_TXPLL_VCODIV_1); ++ ++ /* Setup TCL */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN); ++ ++ /* Enable PLL */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); ++ ++ /* Enale PLL Output */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN); ++} ++ ++static void an7581_pcs_tx_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 tx_rate_ctrl; ++ u32 ckin_divisor; ++ u32 fir_cn1, fir_c0b, fir_c1; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ ckin_divisor = BIT(1); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 12; ++ fir_c1 = 0; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ ckin_divisor = BIT(2); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 11; ++ fir_c1 = 1; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ ckin_divisor = BIT(2) | BIT(0); ++ tx_rate_ctrl = BIT(1); ++ fir_cn1 = 1; ++ fir_c0b = 1; ++ fir_c1 = 11; ++ break; ++ default: ++ return; ++ } ++ ++ /* Set TX rate ctrl */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ /* Setup TX Config */ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, ++ AIROHA_PCS_ANA_TX_DMEDGEGEN_EN | ++ AIROHA_PCS_ANA_TX_CKLDO_EN); ++ ++ udelay(1); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL); ++ ++ /* FIXME: Ask Airoha TX term is OK to reset? */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, ++ ckin_divisor) | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ /* Setup TX FIR Load Parameters (Reference 660mV) */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1)); ++ ++ /* Reset TX Bar */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B, ++ AIROHA_PCS_PMA_TXCALIB_RST_B | AIROHA_PCS_PMA_TX_TOP_RST_B); ++} ++ ++static void an7581_pcs_rx_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 rx_rate_ctrl; ++ u32 osr; ++ u32 pr_cdr_beta_dac; ++ u32 cdr_pr_buf_in_sr; ++ bool cdr_pr_cap_en; ++ u32 sigdet_vth_sel; ++ u32 phyck_div, phyck_sel; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ osr = BIT(1) | BIT(0); /* 1.25G */ ++ pr_cdr_beta_dac = BIT(3); ++ rx_rate_ctrl = 0; ++ cdr_pr_cap_en = false; ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); ++ sigdet_vth_sel = BIT(2) | BIT(1); ++ phyck_div = BIT(5) | BIT(3) | BIT(0); ++ phyck_sel = BIT(0); ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ osr = BIT(0); /* 2.5G */ ++ pr_cdr_beta_dac = BIT(2) | BIT(1); ++ rx_rate_ctrl = 0; ++ cdr_pr_cap_en = true; ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1); ++ sigdet_vth_sel = BIT(2) | BIT(1); ++ phyck_div = BIT(3) | BIT(1) | BIT(0); ++ phyck_sel = BIT(0); ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ osr = 0; /* 10G */ ++ cdr_pr_cap_en = false; ++ pr_cdr_beta_dac = BIT(3); ++ rx_rate_ctrl = BIT(1); ++ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); ++ sigdet_vth_sel = BIT(1); ++ phyck_div = BIT(6) | BIT(1); ++ phyck_sel = BIT(1); ++ break; ++ default: ++ return; ++ } ++ ++ /* Set RX rate ctrl */ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_2, ++ AIROHA_PCS_PMA_CK_RATE, ++ AIROHA_PCS_PMA_CK_RATE_10); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1, ++ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl)); ++ ++ /* Setup RX Path */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_5, ++ AIROHA_PCS_PMA_FLL_IDAC_MIN | ++ AIROHA_PCS_PMA_FLL_IDAC_MAX, ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) | ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x3ff)); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, ++ AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ | ++ AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB, ++ AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, ++ AIROHA_PCS_ANA_FE_VCM_GEN_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, ++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_AEQ_CFORCE, ++ AIROHA_PCS_ANA_AEQ_OFORCE, ++ AIROHA_PCS_ANA_AEQ_OFORCE_CTLE); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, ++ AIROHA_PCS_PMA_DISB_BLWC_OFFSET); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, ++ AIROHA_PCS_PMA_DISB_LEQ); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, ++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS | ++ AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_BYPASS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON | ++ AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_RX_DAC_MON | ++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN | ++ AIROHA_PCS_ANA_CDR_PR_MONDPI_EN | ++ AIROHA_PCS_ANA_CDR_PR_MONDPR_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_MON, 0x0) | ++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN); ++ ++ /* Setup FE Gain and FE Peacking */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0)); ++ ++ /* Setup FE VOS */ ++ if (interface != PHY_INTERFACE_MODE_USXGMII && ++ interface != PHY_INTERFACE_MODE_10GBASER) ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | ++ AIROHA_PCS_PMA_FORCE_DA_FE_VOS, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_FE_VOS, 0x0)); ++ ++ /* Setup FLL PR FMeter (no bypass mode)*/ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_0, ++ AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, 0x1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_1, ++ AIROHA_PCS_PMA_PLL_LOCK_TARGET_END | ++ AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_END, 0xffff) | ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_3, ++ AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, ++ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, 0x1)); ++ ++ /* FIXME: Warn and Ask Airoha about typo in air_eth_xsgmii.c line 1391 */ ++ /* AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL is set 0x0 in SDK but seems a typo */ ++ /* Setup REV */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, ++ AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0)); ++ ++ /* Setup Rdy Timeout */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5, ++ AIROHA_PCS_PMA_RX_RDY | ++ AIROHA_PCS_PMA_RX_BLWC_RDY_EN, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5)); ++ ++ /* Setup CaBoundry Init */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, ++ AIROHA_PCS_PMA_RX_OS_START | ++ AIROHA_PCS_PMA_OSC_SPEED_OPT, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1) | ++ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6, ++ AIROHA_PCS_PMA_RX_OS_END, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1, ++ AIROHA_PCS_PMA_RX_PICAL_END | ++ AIROHA_PCS_PMA_RX_PICAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4, ++ AIROHA_PCS_PMA_RX_SDCAL_END | ++ AIROHA_PCS_PMA_RX_SDCAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2, ++ AIROHA_PCS_PMA_RX_PDOS_END | ++ AIROHA_PCS_PMA_RX_PDOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3, ++ AIROHA_PCS_PMA_RX_FEOS_END | ++ AIROHA_PCS_PMA_RX_FEOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x32) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2)); ++ ++ /* Setup By Serdes*/ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr)); ++ ++ /* Setup RX OSR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, ++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS, ++ osr ? AIROHA_PCS_ANA_CDR_PD_EDGE_DIS : 0); ++ ++ /* Setup CDR LPF Ratio */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, ++ AIROHA_PCS_ANA_CDR_LPF_TOP_LIM | ++ AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x20000) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, osr)); ++ ++ /* Setup CDR PR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, ++ AIROHA_PCS_ANA_CDR_PR_KBAND_DIV | ++ AIROHA_PCS_ANA_CDR_PR_BETA_SEL | ++ AIROHA_PCS_ANA_CDR_PR_VCOADC_OS | ++ AIROHA_PCS_ANA_CDR_PR_BETA_DAC, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_KBAND_DIV, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_SEL, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VCOADC_OS, 0x8) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC, pr_cdr_beta_dac)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, ++ AIROHA_PCS_ANA_CDR_PR_FBKSEL | ++ AIROHA_PCS_ANA_CDR_PR_DAC_BAND | ++ AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL | ++ AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_DAC_BAND, pr_cdr_beta_dac) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x6) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x6)); ++ ++ /* Setup Eye Mon */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, ++ AIROHA_PCS_PMA_EQ_DEBUG_SEL | ++ AIROHA_PCS_PMA_FOM_NUM_ORDER | ++ AIROHA_PCS_PMA_A_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_DEBUG_SEL, 0x0) | ++ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) | ++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, ++ AIROHA_PCS_PMA_DATA_SHIFT | ++ AIROHA_PCS_PMA_EYECNT_FAST, ++ AIROHA_PCS_PMA_EYECNT_FAST); ++ ++ /* Calibration Start */ ++ ++ /* Enable SYS */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0, ++ AIROHA_PCS_PMA_RX_SYS_EN_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1)); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0, ++ AIROHA_PCS_PMA_SW_LCPLL_EN); ++ ++ usleep_range(500, 600); ++ ++ /* Setup FLL PR FMeter (bypass mode)*/ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_FBCK_LOCK); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_FBCK_LOCK); ++ ++ /* Enable CMLEQ */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN | ++ AIROHA_PCS_ANA_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN); ++ ++ /* Setup CDR PR */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_CDR_PR_CAP_EN | ++ AIROHA_PCS_ANA_CDR_BUF_IN_SR, ++ (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr)); ++ ++ /* Setup CDR xxx Pwdb, set force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, ++ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | ++ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); ++ ++ /* FIXME: Ask Airoha WHY it's cleared? */ ++ /* regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ * AIROHA_PCS_ANA_RX_FE_50OHMS_SEL); ++ */ ++ ++ /* Setup SigDet */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL | ++ AIROHA_PCS_ANA_RX_SIGDET_PEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, sigdet_vth_sel) | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, BIT(1))); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, ++ AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, BIT(1) | BIT(0))); ++ ++ /* Disable SigDet Pwdb */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, ++ AIROHA_PCS_PMA_RX_SIDGET_PWDB); ++ ++ /* Setup PHYCK */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_TDC_CK_SEL | ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ AIROHA_PCS_ANA_RX_PHYCK_SEL | ++ AIROHA_PCS_ANA_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel) | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE | ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE); ++ ++ usleep_range(100, 200); ++ ++ /* Enable CDR xxx Pwdb */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, ++ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | ++ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); ++ ++ /* Enable SigDet Pwdb */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, ++ AIROHA_PCS_PMA_RX_SIDGET_PWDB); ++} ++ ++static unsigned int an7581_pcs_apply_cdr_pr_idac(struct airoha_pcs_priv *priv, ++ u32 cdr_pr_idac) ++{ ++ u32 val; ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, ++ cdr_pr_idac)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN, ++ AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL); ++ ++ usleep_range(5000, 7000); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); ++ ++ return FIELD_GET(AIROHA_PCS_PMA_FL_OUT, val); ++} ++ ++static u32 an7581_pcs_rx_prcal_idac_major(struct airoha_pcs_priv *priv, ++ u32 target_fl_out) ++{ ++ unsigned int fl_out_diff = UINT_MAX; ++ unsigned int prcal_search; ++ u32 cdr_pr_idac = 0; ++ ++ for (prcal_search = 0; prcal_search < 8 ; prcal_search++) { ++ unsigned int fl_out_diff_new; ++ unsigned int fl_out; ++ u32 cdr_pr_idac_tmp; ++ ++ /* try to find the upper value by setting the last 3 bit */ ++ cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, ++ prcal_search); ++ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", ++ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); ++ if (fl_out_diff_new < fl_out_diff) { ++ cdr_pr_idac = cdr_pr_idac_tmp; ++ fl_out_diff = fl_out_diff_new; ++ } ++ } ++ ++ return cdr_pr_idac; ++} ++ ++static u32 an7581_pcs_rx_prcal_idac_minor(struct airoha_pcs_priv *priv, u32 target_fl_out, ++ u32 cdr_pr_idac_major) ++{ ++ unsigned int remaining_prcal_search_bits = 0; ++ u32 cdr_pr_idac = cdr_pr_idac_major; ++ unsigned int fl_out, fl_out_diff; ++ int best_prcal_search_bit = -1; ++ int prcal_search_bit; ++ ++ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac); ++ fl_out_diff = abs(fl_out - target_fl_out); ++ ++ /* Deadline search part. ++ * We start from top bits to bottom as we progressively decrease the ++ * signal. ++ */ ++ for (prcal_search_bit = 7; prcal_search_bit >= 0; prcal_search_bit--) { ++ unsigned int fl_out_diff_new; ++ u32 cdr_pr_idac_tmp; ++ ++ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); ++ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", ++ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); ++ if (fl_out_diff_new < fl_out_diff) { ++ best_prcal_search_bit = prcal_search_bit; ++ fl_out_diff = fl_out_diff_new; ++ } ++ } ++ ++ /* Set the idac with the best value we found and ++ * reset the search bit to start from bottom to top. ++ */ ++ if (best_prcal_search_bit >= 0) { ++ cdr_pr_idac |= BIT(best_prcal_search_bit); ++ remaining_prcal_search_bits = best_prcal_search_bit; ++ prcal_search_bit = 0; ++ } ++ ++ /* Fine tune part. ++ * Test remaining bits to find an even closer signal level to target ++ * by increasing the signal. ++ */ ++ while (remaining_prcal_search_bits) { ++ unsigned int fl_out_diff_new; ++ u32 cdr_pr_idac_tmp; ++ ++ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); ++ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ ++ /* Use absolute values to find the closest one to target */ ++ fl_out_diff_new = abs(fl_out - target_fl_out); ++ /* Assume we found the deadline when the new absolue signal difference ++ * from target is greater than the previous and the difference is at ++ * least 10% greater between the old and new value. ++ * This is to account for signal detection level tollerance making ++ * sure we are actually over a deadline (AKA we are getting farther ++ * from target) ++ */ ++ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", ++ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); ++ if (fl_out_diff_new > fl_out_diff && ++ (abs(fl_out_diff_new - fl_out_diff) * 100) / fl_out_diff > 10) { ++ /* Exit early if we are already at the deadline */ ++ if (prcal_search_bit == 0) ++ break; ++ ++ /* We found the deadline, set the value to the previous ++ * bit, and reset the loop to fine tune with the ++ * remaining values. ++ */ ++ cdr_pr_idac |= BIT(prcal_search_bit - 1); ++ remaining_prcal_search_bits = prcal_search_bit - 1; ++ prcal_search_bit = 0; ++ } else { ++ /* Update the signal level diff and try the next bit */ ++ fl_out_diff = fl_out_diff_new; ++ ++ /* If we didn't found the deadline, set the last bit ++ * and reset the loop to fine tune with the remainig ++ * values. ++ */ ++ if (prcal_search_bit == remaining_prcal_search_bits - 1) { ++ cdr_pr_idac |= BIT(prcal_search_bit); ++ remaining_prcal_search_bits = prcal_search_bit; ++ prcal_search_bit = 0; ++ } else { ++ prcal_search_bit++; ++ } ++ } ++ } ++ ++ return cdr_pr_idac; ++} ++ ++static void an7581_pcs_rx_prcal(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 cdr_pr_idac_major, cdr_pr_idac; ++ unsigned int fl_out, fl_out_diff; ++ ++ u32 target_fl_out; ++ u32 cyclecnt; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: /* DS_1.25G / US_1.25G */ ++ case PHY_INTERFACE_MODE_1000BASEX: ++ target_fl_out = 0xa3d6; ++ cyclecnt = 32767; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: /* DS_9.95328G / US_9.95328G */ ++ target_fl_out = 0xa000; ++ cyclecnt = 20000; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: /* DS_10.3125G / US_1.25G */ ++ case PHY_INTERFACE_MODE_10GBASER: ++ target_fl_out = 0x9edf; ++ cyclecnt = 32767; ++ break; ++ default: ++ return; ++ } ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_2, ++ AIROHA_PCS_PMA_LOCK_TARGET_END | ++ AIROHA_PCS_PMA_LOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_END, target_fl_out + 100) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_BEG, target_fl_out - 100)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_1, ++ AIROHA_PCS_PMA_UNLOCK_CYCLECNT | ++ AIROHA_PCS_PMA_LOCK_CYCLECNT, ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_CYCLECNT, cyclecnt) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_CYCLECNT, cyclecnt)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, ++ AIROHA_PCS_PMA_LOCK_UNLOCKTH | ++ AIROHA_PCS_PMA_LOCK_LOCKTH, ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_UNLOCKTH, 3) | ++ FIELD_PREP(AIROHA_PCS_PMA_LOCK_LOCKTH, 3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_3, ++ AIROHA_PCS_PMA_UNLOCK_TARGET_END | ++ AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_END, target_fl_out + 100) | ++ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, target_fl_out - 100)); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, ++ AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ /* Calibration logic: ++ * First check the major value by looping with every ++ * value in the last 3 bit of CDR_PR_IDAC. ++ * Get the signal level and save the value that is closer to ++ * the target. ++ * ++ * Then check each remaining 7 bits in search of the deadline ++ * where the signal gets farther than signal target. ++ * ++ * Finally fine tune for the remaining bits to find the one that ++ * produce the closest signal level. ++ */ ++ cdr_pr_idac_major = an7581_pcs_rx_prcal_idac_major(priv, target_fl_out); ++ ++ cdr_pr_idac = an7581_pcs_rx_prcal_idac_minor(priv, target_fl_out, cdr_pr_idac_major); ++ ++ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac); ++ fl_out_diff = abs(fl_out - target_fl_out); ++ if (fl_out_diff > 100) { ++ u32 pr_idac_major = FIELD_GET(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, ++ cdr_pr_idac_major); ++ unsigned int fl_out_tmp, fl_out_diff_tmp; ++ u32 cdr_pr_idac_tmp; ++ ++ if (pr_idac_major > 0) { ++ cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, ++ pr_idac_major - 1); ++ ++ dev_dbg(priv->dev, "Fl Out is %d far from target %d with Pr Idac %x. Trying with Pr Idac %x.\n", ++ fl_out_diff, target_fl_out, cdr_pr_idac_major, cdr_pr_idac_tmp); ++ ++ cdr_pr_idac_tmp = an7581_pcs_rx_prcal_idac_minor(priv, target_fl_out, ++ cdr_pr_idac_tmp); ++ ++ fl_out_tmp = an7581_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp); ++ fl_out_diff_tmp = abs(fl_out_tmp - target_fl_out); ++ if (fl_out_diff_tmp < fl_out_diff) { ++ fl_out = fl_out_tmp; ++ fl_out_diff = fl_out_diff_tmp; ++ cdr_pr_idac = cdr_pr_idac_tmp; ++ } ++ } ++ } ++ dev_dbg(priv->dev, "Selected CDR Pr Idac: %x Fl Out: %x\n", cdr_pr_idac, fl_out); ++ if (fl_out_diff > 100) ++ dev_dbg(priv->dev, "Fl Out is %d far from target %d on intermediate calibration.\n", ++ fl_out_diff, target_fl_out); ++ ++ ++ /* Setup Load Band */ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, ++ AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF); ++ ++ /* Disable force of LPF C previously enabled */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_B, ++ AIROHA_PCS_PMA_LOAD_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_1, ++ AIROHA_PCS_PMA_LPATH_IDAC, ++ FIELD_PREP(AIROHA_PCS_PMA_LPATH_IDAC, cdr_pr_idac)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++} ++ ++/* This is used to both calibrate and lock to signal (after a previous ++ * calibration) after a global reset. ++ */ ++static void an7581_pcs_cdr_reset(struct airoha_pcs_priv *priv, ++ phy_interface_t interface, bool calibrate) ++{ ++ /* Setup LPF L2D force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++ ++ /* Calibrate IDAC and setup Load Band */ ++ if (calibrate) ++ an7581_pcs_rx_prcal(priv, interface); ++ ++ /* Setup LPF RSTB force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ usleep_range(700, 1000); ++ ++ /* Force Enable LPF RSTB */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++ ++ usleep_range(100, 200); ++ ++ /* Force Enable LPF L2D */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); ++ ++ /* Disable LPF RSTB force bit */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ /* Disable LPF L2D force bit */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++} ++ ++static int an7581_pcs_phya_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ int calibration_try = 0; ++ u32 val; ++ ++ an7581_pcs_tx_bringup(priv, interface); ++ an7581_pcs_rx_bringup(priv, interface); ++ ++ usleep_range(100, 200); ++ ++retry_calibration: ++ an7581_pcs_cdr_reset(priv, interface, priv->manual_rx_calib); ++ ++ /* Global reset clear */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_REF_RST_N | ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | ++ AIROHA_PCS_PMA_SW_PMA_RST_N | ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ usleep_range(100, 200); ++ ++ /* Global reset */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_REF_RST_N | ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | ++ AIROHA_PCS_PMA_SW_PMA_RST_N | ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); ++ ++ usleep_range(5000, 7000); ++ ++ an7581_pcs_cdr_reset(priv, interface, false); ++ ++ /* Manual RX calibration is required only for SoC before E2 ++ * revision. E2+ SoC autocalibrate RX and only CDR reset is needed. ++ */ ++ if (!priv->manual_rx_calib) ++ return 0; ++ ++ /* It was discovered that after a global reset and auto mode gets ++ * actually enabled, the fl_out from calibration might change and ++ * might deviates a lot from the expected value it was calibrated for. ++ * To correctly work, the PCS FreqDet module needs to Lock to the fl_out ++ * (frequency level output) or no signal can correctly be transmitted. ++ * This is detected by checking the FreqDet module Lock bit. ++ * ++ * If it's detected that the FreqDet module is not locked, retry ++ * calibration. From observation on real hardware with a 10g SFP module, ++ * it required a maximum of an additional calibration to actually make ++ * the FreqDet module to lock. Try 10 times before failing to handle ++ * really strange case. ++ */ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); ++ if (!(val & AIROHA_PCS_PMA_FBCK_LOCK)) { ++ if (calibration_try > AIROHA_PCS_MAX_CALIBRATION_TRY) { ++ dev_err(priv->dev, "No FBCK Lock from FreqDet module after %d calibration try. PCS won't work.\n", ++ AIROHA_PCS_MAX_CALIBRATION_TRY); ++ return -EIO; ++ } ++ ++ calibration_try++; ++ ++ dev_dbg(priv->dev, "No FBCK Lock from FreqDet module, retry calibration.\n"); ++ goto retry_calibration; ++ } ++ ++ return 0; ++} ++ ++static void an7581_pcs_pll_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ an7581_pcs_jcpll_bringup(priv, interface); ++ ++ usleep_range(200, 300); ++ ++ an7581_pcs_txpll_bringup(priv, interface); ++ ++ usleep_range(200, 300); ++} ++ ++int an7581_pcs_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ /* Enable Analog Common Lane */ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CMN_EN, ++ AIROHA_PCS_ANA_CMN_EN); ++ ++ /* Setup PLL */ ++ an7581_pcs_pll_bringup(priv, interface); ++ ++ /* Setup PHYA */ ++ return an7581_pcs_phya_bringup(priv, interface); ++} ++ ++void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv) ++{ ++ /* Reset TXPCS on link up */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); ++ ++ usleep_range(100, 200); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); ++} ++ ++static bool an7581_pcs_have_rx_signal(struct airoha_pcs_priv *priv) ++{ ++ unsigned int count = 0; ++ u32 val; ++ int i; ++ ++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RESERVE_0, ++ AIROHA_PCS_TRIGGER_RX_SIDGET_SCAN); ++ ++ /* Scan 5 times for RX sigdet module to detect RX signal */ ++ for (i = 0; i <= 5; i++) { ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RO_RESERVE_2, ++ &val); ++ if (val & AIROHA_PCS_RX_SIGDET) ++ count++; ++ } ++ ++ /* Consider signal presence if we detect signal at least 4 times */ ++ return count >= 4; ++} ++ ++int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv) ++{ ++ u32 val; ++ ++ /* Check if PCS is UP or Down */ ++ regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_STUS_1, &val); ++ if (val & AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP) ++ return 0; ++ ++ /* Validate if this is consistent with RX SigDet module */ ++ if (!an7581_pcs_have_rx_signal(priv)) ++ return 0; ++ ++ /* If PCS is down but RX SigDet module detected signal, ++ * trigger CDR reset. ++ */ ++ an7581_pcs_cdr_reset(priv, PHY_INTERFACE_MODE_NA, false); ++ ++ /* Report there is an error with Link Detection and we ++ * should test again later. ++ */ ++ return -EINVAL; ++} +--- /dev/null ++++ b/include/linux/pcs/pcs-airoha.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef __LINUX_PCS_AIROHA_H ++#define __LINUX_PCS_AIROHA_H ++ ++struct phylink_pcs *airoha_pcs_create(struct device *dev); ++void airoha_pcs_destroy(struct phylink_pcs *pcs); ++ ++#endif /* __LINUX_PCS_AIROHA_H */ diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch new file mode 100644 index 0000000000..68671eb496 --- /dev/null +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -0,0 +1,257 @@ +From bdcad9ab6b0f071e8492d88064a58323d7155aa7 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 17 Jan 2025 13:23:13 +0100 +Subject: [PATCH] net: airoha: add phylink support for GDM2/4 + +Add phylink support for GDM2/4 port that require configuration of the +PCS to make the external PHY or attached SFP cage work. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 133 ++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_eth.h | 4 + + drivers/net/ethernet/airoha/airoha_regs.h | 12 ++ + 3 files changed, 149 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -71,6 +72,11 @@ static void airoha_qdma_irq_disable(stru + airoha_qdma_set_irqmask(irq_bank, index, mask, 0); + } + ++static bool airhoa_is_phy_external(struct airoha_gdm_port *port) ++{ ++ return port->id != 1; ++} ++ + static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) + { + struct airoha_eth *eth = port->qdma->eth; +@@ -1640,6 +1646,17 @@ static int airoha_dev_open(struct net_de + struct airoha_gdm_port *port = netdev_priv(dev); + struct airoha_qdma *qdma = port->qdma; + ++ if (airhoa_is_phy_external(port)) { ++ err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); ++ if (err) { ++ netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, ++ err); ++ return err; ++ } ++ ++ phylink_start(port->phylink); ++ } ++ + netif_tx_start_all_queues(dev); + err = airoha_set_vip_for_gdm_port(port, true); + if (err) +@@ -1693,6 +1710,11 @@ static int airoha_dev_stop(struct net_de + } + } + ++ if (airhoa_is_phy_external(port)) { ++ phylink_stop(port->phylink); ++ phylink_disconnect_phy(port->phylink); ++ } ++ + return 0; + } + +@@ -2781,6 +2803,20 @@ static const struct ethtool_ops airoha_e + .get_rmon_stats = airoha_ethtool_get_rmon_stats, + }; + ++static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config, ++ phy_interface_t interface) ++{ ++ struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port, ++ phylink_config); ++ ++ return port->pcs; ++} ++ ++static void airoha_mac_config(struct phylink_config *config, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++} ++ + static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) + { + int i; +@@ -2825,6 +2861,99 @@ bool airoha_is_valid_gdm_port(struct air + return false; + } + ++static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) ++{ ++ struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port, ++ phylink_config); ++ struct airoha_qdma *qdma = port->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ u32 frag_size_tx, frag_size_rx; ++ ++ switch (speed) { ++ case SPEED_10000: ++ case SPEED_5000: ++ frag_size_tx = 8; ++ frag_size_rx = 8; ++ break; ++ case SPEED_2500: ++ frag_size_tx = 2; ++ frag_size_rx = 1; ++ break; ++ default: ++ frag_size_tx = 1; ++ frag_size_rx = 0; ++ } ++ ++ /* Configure TX/RX frag based on speed */ ++ if (port->id == 4) { ++ airoha_fe_rmw(eth, REG_GDMA4_TMBI_FRAG, GDMA4_SGMII0_TX_FRAG_SIZE, ++ FIELD_PREP(GDMA4_SGMII0_TX_FRAG_SIZE, frag_size_tx)); ++ ++ airoha_fe_rmw(eth, REG_GDMA4_RMBI_FRAG, GDMA4_SGMII0_RX_FRAG_SIZE, ++ FIELD_PREP(GDMA4_SGMII0_RX_FRAG_SIZE, frag_size_rx)); ++ } ++} ++ ++static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode, ++ phy_interface_t interface) ++{ ++} ++ ++static const struct phylink_mac_ops airoha_phylink_ops = { ++ .mac_select_pcs = airoha_phylink_mac_select_pcs, ++ .mac_config = airoha_mac_config, ++ .mac_link_up = airoha_mac_link_up, ++ .mac_link_down = airoha_mac_link_down, ++}; ++ ++static int airoha_setup_phylink(struct net_device *dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct device_node *np = dev->dev.of_node; ++ phy_interface_t phy_mode; ++ struct phylink *phylink; ++ int err; ++ ++ err = of_get_phy_mode(np, &phy_mode); ++ if (err) { ++ dev_err(&dev->dev, "incorrect phy-mode\n"); ++ return err; ++ } ++ ++ port->phylink_config.dev = &dev->dev; ++ port->phylink_config.type = PHYLINK_NETDEV; ++ port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | ++ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD | ++ MAC_5000FD | MAC_10000FD; ++ ++ __set_bit(PHY_INTERFACE_MODE_SGMII, ++ port->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_1000BASEX, ++ port->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_2500BASEX, ++ port->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, ++ port->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, ++ port->phylink_config.supported_interfaces); ++ ++ port->pcs = airoha_pcs_create(&dev->dev); ++ if (IS_ERR(port->pcs)) ++ return PTR_ERR(port->pcs); ++ ++ phylink = phylink_create(&port->phylink_config, ++ of_fwnode_handle(np), ++ phy_mode, &airoha_phylink_ops); ++ if (IS_ERR(phylink)) ++ return PTR_ERR(phylink); ++ ++ port->phylink = phylink; ++ ++ return 0; ++} ++ + static int airoha_alloc_gdm_port(struct airoha_eth *eth, + struct device_node *np, int index) + { +@@ -2903,6 +3032,12 @@ static int airoha_alloc_gdm_port(struct + if (err) + return err; + ++ if (airhoa_is_phy_external(port)) { ++ err = airoha_setup_phylink(dev); ++ if (err) ++ goto free_metadata_dst; ++ } ++ + err = register_netdev(dev); + if (err) + goto free_metadata_dst; +@@ -3006,6 +3141,10 @@ error_hw_cleanup: + if (port && port->dev->reg_state == NETREG_REGISTERED) { + unregister_netdev(port->dev); + airoha_metadata_dst_free(port); ++ if (airhoa_is_phy_external(port)) { ++ phylink_destroy(port->phylink); ++ airoha_pcs_destroy(port->pcs); ++ } + } + } + free_netdev(eth->napi_dev); +@@ -3033,6 +3172,10 @@ static void airoha_remove(struct platfor + airoha_dev_stop(port->dev); + unregister_netdev(port->dev); + airoha_metadata_dst_free(port); ++ if (airhoa_is_phy_external(port)) { ++ phylink_destroy(port->phylink); ++ airoha_pcs_destroy(port->pcs); ++ } + } + free_netdev(eth->napi_dev); + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -528,6 +528,10 @@ struct airoha_gdm_port { + struct net_device *dev; + int id; + ++ struct phylink *phylink; ++ struct phylink_config phylink_config; ++ struct phylink_pcs *pcs; ++ + struct airoha_hw_stats stats; + + DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -361,6 +361,18 @@ + #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) + #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) + ++#define REG_GDMA4_TMBI_FRAG 0x2028 ++#define GDMA4_SGMII1_TX_WEIGHT GENMASK(31, 26) ++#define GDMA4_SGMII1_TX_FRAG_SIZE GENMASK(25, 16) ++#define GDMA4_SGMII0_TX_WEIGHT GENMASK(15, 10) ++#define GDMA4_SGMII0_TX_FRAG_SIZE GENMASK(9, 0) ++ ++#define REG_GDMA4_RMBI_FRAG 0x202c ++#define GDMA4_SGMII1_RX_WEIGHT GENMASK(31, 26) ++#define GDMA4_SGMII1_RX_FRAG_SIZE GENMASK(25, 16) ++#define GDMA4_SGMII0_RX_WEIGHT GENMASK(15, 10) ++#define GDMA4_SGMII0_RX_FRAG_SIZE GENMASK(9, 0) ++ + #define REG_MC_VLAN_EN 0x2100 + #define MC_VLAN_EN_MASK BIT(0) + From 1181c031a0458a25d0ddd2898cebf4ca2a2de5ee Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 26 Sep 2025 04:52:36 +0200 Subject: [PATCH 045/128] airoha: en7581: Add pending ASOC driver Add pending ASOC driver for I2S sound support on Airoha EN7581 SoC. (cherry picked from commit 14bc87cf7658c0a6c4891aba5890f2fafaab2a8e) [ fix conflict error ] Signed-off-by: Christian Marangi --- ...k-move-some-header-to-global-include.patch | 410 ++++++++++ ...AFE-and-I2S-driver-for-Airoha-AN7581.patch | 729 ++++++++++++++++++ 2 files changed, 1139 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch create mode 100644 target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch diff --git a/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch b/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch new file mode 100644 index 0000000000..c9cdb9a326 --- /dev/null +++ b/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch @@ -0,0 +1,410 @@ +From 527123b53739a2f73ca924b9c6e2f63dc66739a5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 1 Aug 2025 11:06:56 +0200 +Subject: [PATCH 1/3] ASoC: mediatek: move some header to global include + +In preparation for support of Airoha SoC sound system based on Mediatek +AFE, move some header to global include to prevent having to use complex +redirection for inclusion. + +Signed-off-by: Christian Marangi +--- + .../common => include/sound/mediatek}/mtk-afe-fe-dai.h | 0 + .../sound/mediatek}/mtk-afe-platform-driver.h | 0 + sound/soc/mediatek/common/mtk-afe-fe-dai.c | 4 ++-- + sound/soc/mediatek/common/mtk-afe-platform-driver.c | 2 +- + sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt6797/mt6797-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c | 2 +- + sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 2 +- + sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8186/mt8186-misc-control.c | 4 ++-- + sound/soc/mediatek/mt8186/mt8186-mt6366-common.c | 2 +- + sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +- + sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8188/mt8188-mt6359.c | 2 +- + sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 2 +- + sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 4 ++-- + sound/soc/mediatek/mt8195/mt8195-mt6359.c | 2 +- + sound/soc/mediatek/mt8365/mt8365-afe-pcm.c | 4 ++-- + 22 files changed, 32 insertions(+), 32 deletions(-) + rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-fe-dai.h (100%) + rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-platform-driver.h (100%) + +--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c ++++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c +@@ -11,9 +11,9 @@ + #include + #include + #include +-#include "mtk-afe-platform-driver.h" ++#include + #include +-#include "mtk-afe-fe-dai.h" ++#include + #include "mtk-base-afe.h" + + #define AFE_BASE_END_OFFSET 8 +--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c ++++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c +@@ -10,7 +10,7 @@ + #include + #include + +-#include "mtk-afe-platform-driver.h" ++#include + #include "mtk-base-afe.h" + + int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe) +--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c ++++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +@@ -16,8 +16,8 @@ + + #include "mt2701-afe-common.h" + #include "mt2701-afe-clock-ctrl.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + static const struct snd_pcm_hardware mt2701_afe_hardware = { + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED +--- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c ++++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c +@@ -16,8 +16,8 @@ + #include "mt6797-afe-clk.h" + #include "mt6797-interconnection.h" + #include "mt6797-reg.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + enum { + MTK_AFE_RATE_8K = 0, +--- a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c ++++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c +@@ -16,8 +16,8 @@ + + #include "mt7986-afe-common.h" + #include "mt7986-reg.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + enum { + MTK_AFE_RATE_8K = 0, +--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c ++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +@@ -19,8 +19,8 @@ + #include + #include "mt8173-afe-common.h" + #include "../common/mtk-base-afe.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + /***************************************************************************** + * R E G I S T E R D E F I N I T I O N +--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c ++++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c +@@ -18,8 +18,8 @@ + #include "mt8183-afe-clk.h" + #include "mt8183-interconnection.h" + #include "mt8183-reg.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + enum { + MTK_AFE_RATE_8K = 0, +--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c ++++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c +@@ -16,7 +16,7 @@ + + #include "../../codecs/da7219.h" + #include "../../codecs/rt1015.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include + #include "mt8183-afe-common.h" + + #define DA7219_CODEC_DAI "da7219-hifi" +--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c ++++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +@@ -15,7 +15,7 @@ + + #include "../../codecs/rt1015.h" + #include "../../codecs/ts3a227e.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include + #include "mt8183-afe-common.h" + + #define RT1015_CODEC_DAI "rt1015-aif" +--- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c ++++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c +@@ -15,8 +15,8 @@ + #include + #include + +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + #include "mt8186-afe-common.h" + #include "mt8186-afe-clk.h" +--- a/sound/soc/mediatek/mt8186/mt8186-misc-control.c ++++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c +@@ -11,8 +11,8 @@ + #include + #include + +-#include "../common/mtk-afe-fe-dai.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include ++#include + #include "mt8186-afe-common.h" + + static const char * const mt8186_sgen_mode_str[] = { +--- a/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c ++++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c +@@ -9,7 +9,7 @@ + #include + + #include "../../codecs/mt6358.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include + #include "mt8186-afe-common.h" + #include "mt8186-mt6366-common.h" + +--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c ++++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +@@ -24,8 +24,8 @@ + #include "mt8188-afe-common.h" + #include "mt8188-afe-clk.h" + #include "mt8188-reg.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + #define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40) + #define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff) +--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c ++++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c +@@ -17,8 +17,8 @@ + #include + #include + +-#include "../common/mtk-afe-fe-dai.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include ++#include + + #include "mt8192-afe-common.h" + #include "mt8192-afe-clk.h" +--- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c ++++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c +@@ -20,8 +20,8 @@ + #include "mt8195-afe-common.h" + #include "mt8195-afe-clk.h" + #include "mt8195-reg.h" +-#include "../common/mtk-afe-platform-driver.h" +-#include "../common/mtk-afe-fe-dai.h" ++#include ++#include + + #define MT8195_MEMIF_BUFFER_BYTES_ALIGN (0x40) + #define MT8195_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff) +--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c ++++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c +@@ -19,7 +19,7 @@ + #include "../../codecs/mt6359.h" + #include "../../codecs/rt1011.h" + #include "../../codecs/rt5682.h" +-#include "../common/mtk-afe-platform-driver.h" ++#include + #include "../common/mtk-dsp-sof-common.h" + #include "../common/mtk-soc-card.h" + #include "../common/mtk-soundcard-driver.h" +--- /dev/null ++++ b/include/sound/mediatek/mtk-afe-fe-dai.h +@@ -0,0 +1,53 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition ++ * ++ * Copyright (c) 2016 MediaTek Inc. ++ * Author: Garlic Tseng ++ */ ++ ++#ifndef _MTK_AFE_FE_DAI_H_ ++#define _MTK_AFE_FE_DAI_H_ ++ ++struct snd_soc_dai_ops; ++struct mtk_base_afe; ++struct mtk_base_afe_memif; ++ ++int mtk_afe_fe_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai); ++void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai); ++int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai); ++int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai); ++int mtk_afe_fe_prepare(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai); ++int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai); ++ ++extern const struct snd_soc_dai_ops mtk_afe_fe_ops; ++ ++int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe); ++int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id); ++int mtk_afe_suspend(struct snd_soc_component *component); ++int mtk_afe_resume(struct snd_soc_component *component); ++ ++int mtk_memif_set_enable(struct mtk_base_afe *afe, int id); ++int mtk_memif_set_disable(struct mtk_base_afe *afe, int id); ++int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, ++ unsigned char *dma_area, ++ dma_addr_t dma_addr, ++ size_t dma_bytes); ++int mtk_memif_set_channel(struct mtk_base_afe *afe, ++ int id, unsigned int channel); ++int mtk_memif_set_rate(struct mtk_base_afe *afe, ++ int id, unsigned int rate); ++int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, ++ int id, unsigned int rate); ++int mtk_memif_set_format(struct mtk_base_afe *afe, ++ int id, snd_pcm_format_t format); ++int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe, ++ int id, int pbuf_size); ++#endif +--- /dev/null ++++ b/include/sound/mediatek/mtk-afe-platform-driver.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition ++ * ++ * Copyright (c) 2016 MediaTek Inc. ++ * Author: Garlic Tseng ++ */ ++ ++#ifndef _MTK_AFE_PLATFORM_DRIVER_H_ ++#define _MTK_AFE_PLATFORM_DRIVER_H_ ++ ++#define AFE_PCM_NAME "mtk-afe-pcm" ++extern const struct snd_soc_component_driver mtk_afe_pcm_platform; ++ ++struct mtk_base_afe; ++struct snd_pcm; ++struct snd_soc_component; ++struct snd_soc_pcm_runtime; ++ ++snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, ++ struct snd_pcm_substream *substream); ++int mtk_afe_pcm_new(struct snd_soc_component *component, ++ struct snd_soc_pcm_runtime *rtd); ++ ++int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe); ++int mtk_afe_add_sub_dai_control(struct snd_soc_component *component); ++#endif ++ +--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h ++++ /dev/null +@@ -1,53 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition +- * +- * Copyright (c) 2016 MediaTek Inc. +- * Author: Garlic Tseng +- */ +- +-#ifndef _MTK_AFE_FE_DAI_H_ +-#define _MTK_AFE_FE_DAI_H_ +- +-struct snd_soc_dai_ops; +-struct mtk_base_afe; +-struct mtk_base_afe_memif; +- +-int mtk_afe_fe_startup(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai); +-void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai); +-int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct snd_soc_dai *dai); +-int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai); +-int mtk_afe_fe_prepare(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai); +-int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, +- struct snd_soc_dai *dai); +- +-extern const struct snd_soc_dai_ops mtk_afe_fe_ops; +- +-int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe); +-int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id); +-int mtk_afe_suspend(struct snd_soc_component *component); +-int mtk_afe_resume(struct snd_soc_component *component); +- +-int mtk_memif_set_enable(struct mtk_base_afe *afe, int id); +-int mtk_memif_set_disable(struct mtk_base_afe *afe, int id); +-int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, +- unsigned char *dma_area, +- dma_addr_t dma_addr, +- size_t dma_bytes); +-int mtk_memif_set_channel(struct mtk_base_afe *afe, +- int id, unsigned int channel); +-int mtk_memif_set_rate(struct mtk_base_afe *afe, +- int id, unsigned int rate); +-int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, +- int id, unsigned int rate); +-int mtk_memif_set_format(struct mtk_base_afe *afe, +- int id, snd_pcm_format_t format); +-int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe, +- int id, int pbuf_size); +-#endif +--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition +- * +- * Copyright (c) 2016 MediaTek Inc. +- * Author: Garlic Tseng +- */ +- +-#ifndef _MTK_AFE_PLATFORM_DRIVER_H_ +-#define _MTK_AFE_PLATFORM_DRIVER_H_ +- +-#define AFE_PCM_NAME "mtk-afe-pcm" +-extern const struct snd_soc_component_driver mtk_afe_pcm_platform; +- +-struct mtk_base_afe; +-struct snd_pcm; +-struct snd_soc_component; +-struct snd_soc_pcm_runtime; +- +-snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, +- struct snd_pcm_substream *substream); +-int mtk_afe_pcm_new(struct snd_soc_component *component, +- struct snd_soc_pcm_runtime *rtd); +- +-int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe); +-int mtk_afe_add_sub_dai_control(struct snd_soc_component *component); +-#endif +- diff --git a/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch b/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch new file mode 100644 index 0000000000..00578601c4 --- /dev/null +++ b/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch @@ -0,0 +1,729 @@ +From 9989af6ed0dba86f57ac4aa1574f9ce9b1e640af Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 31 Jul 2025 15:32:32 +0200 +Subject: [PATCH 2/3] ASoC: airoha: Add AFE and I2S driver for Airoha AN7581 + +Add support for the Sound system present on Airoha AN7581 SoC. This is +based on the mediatek AFE drivers. + +Also add the I2S driver to create an actual sound card for the AFE. + +Signed-off-by: Christian Marangi +--- + sound/soc/Kconfig | 1 + + sound/soc/Makefile | 1 + + sound/soc/airoha/Kconfig | 19 + + sound/soc/airoha/Makefile | 2 + + sound/soc/airoha/an7581/Makefile | 8 + + sound/soc/airoha/an7581/an7581-afe-common.h | 35 ++ + sound/soc/airoha/an7581/an7581-afe-pcm.c | 455 ++++++++++++++++++++ + sound/soc/airoha/an7581/an7581-i2s.c | 110 +++++ + sound/soc/airoha/an7581/an7581-reg.h | 29 ++ + 9 files changed, 660 insertions(+) + create mode 100644 sound/soc/airoha/Kconfig + create mode 100644 sound/soc/airoha/Makefile + create mode 100644 sound/soc/airoha/an7581/Makefile + create mode 100644 sound/soc/airoha/an7581/an7581-afe-common.h + create mode 100644 sound/soc/airoha/an7581/an7581-afe-pcm.c + create mode 100644 sound/soc/airoha/an7581/an7581-i2s.c + create mode 100644 sound/soc/airoha/an7581/an7581-reg.h + +--- a/sound/soc/Kconfig ++++ b/sound/soc/Kconfig +@@ -86,6 +86,7 @@ config SND_SOC_ACPI + + # All the supported SoCs + source "sound/soc/adi/Kconfig" ++source "sound/soc/airoha/Kconfig" + source "sound/soc/amd/Kconfig" + source "sound/soc/apple/Kconfig" + source "sound/soc/atmel/Kconfig" +--- a/sound/soc/Makefile ++++ b/sound/soc/Makefile +@@ -40,6 +40,7 @@ obj-$(CONFIG_SND_SOC) += codecs/ + obj-$(CONFIG_SND_SOC) += generic/ + obj-$(CONFIG_SND_SOC) += apple/ + obj-$(CONFIG_SND_SOC) += adi/ ++obj-$(CONFIG_SND_SOC) += airoha/ + obj-$(CONFIG_SND_SOC) += amd/ + obj-$(CONFIG_SND_SOC) += atmel/ + obj-$(CONFIG_SND_SOC) += au1x/ +--- /dev/null ++++ b/sound/soc/airoha/Kconfig +@@ -0,0 +1,19 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++config SND_SOC_AN7581 ++ tristate "ASoC support for Airoha AN7581 chip" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ select SND_SOC_MEDIATEK ++ help ++ This adds ASoC driver for Airoha AN7581 boards ++ that can be used with other codecs. ++ Select Y if you have such device. ++ If unsure select "N". ++ ++config SND_SOC_AN7581_I2S ++ tristate "I2S support for Airoha AN7581 chip" ++ depends on SND_SOC_AN7581 ++ help ++ This adds I2S driver for Airoha AN7581 boards ++ that can be used with other codecs. ++ Select Y if you have such device. ++ If unsure select "N". +--- /dev/null ++++ b/sound/soc/airoha/Makefile +@@ -0,0 +1,2 @@ ++# SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_SND_SOC_AN7581) += an7581/ +--- /dev/null ++++ b/sound/soc/airoha/an7581/Makefile +@@ -0,0 +1,8 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++# platform driver ++snd-soc-an7581-afe-y := \ ++ an7581-afe-pcm.o ++ ++obj-$(CONFIG_SND_SOC_AN7581) += snd-soc-an7581-afe.o ++obj-$(CONFIG_SND_SOC_AN7581_I2S) += an7581-i2s.o +--- /dev/null ++++ b/sound/soc/airoha/an7581/an7581-afe-common.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * an7581-afe-common.h -- Airoha AN7581 audio driver definitions ++ */ ++ ++#ifndef _AN7581_AFE_COMMON_H_ ++#define _AN7581_AFE_COMMON_H_ ++ ++#include ++#include ++#include ++#include "../../mediatek/common/mtk-base-afe.h" ++ ++enum { ++ AN7581_MEMIF_DL1, ++ AN7581_MEMIF_UL1, ++ AN7581_MEMIF_NUM, ++ AN7581_DAI_NUM = AN7581_MEMIF_NUM, ++}; ++ ++enum { ++ AN7581_IRQ_0, ++ AN7581_IRQ_1, ++ AN7581_IRQ_NUM, ++}; ++ ++struct an7581_afe_private { ++ /* dai */ ++ void *dai_priv[AN7581_DAI_NUM]; ++}; ++ ++unsigned int an7581_afe_rate_transform(struct device *dev, ++ unsigned int rate); ++ ++#endif +--- /dev/null ++++ b/sound/soc/airoha/an7581/an7581-afe-pcm.c +@@ -0,0 +1,455 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Airoha ALSA SoC AFE platform driver for AN7581 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "an7581-afe-common.h" ++#include "an7581-reg.h" ++#include ++#include ++ ++enum { ++ ARH_AFE_RATE_7K = 16, ++ ARH_AFE_RATE_8K = 0, ++ ARH_AFE_RATE_11K = 17, ++ ARH_AFE_RATE_12K = 1, ++ ARH_AFE_RATE_14K = 18, ++ ARH_AFE_RATE_16K = 2, ++ ARH_AFE_RATE_22K = 19, ++ ARH_AFE_RATE_24K = 3, ++ ARH_AFE_RATE_29K = 20, ++ ARH_AFE_RATE_32K = 4, ++ ARH_AFE_RATE_44K = 21, ++ ARH_AFE_RATE_48K = 5, ++ ARH_AFE_RATE_88K = 22, ++ ARH_AFE_RATE_96K = 6, ++ ARH_AFE_RATE_176K = 23, ++ ARH_AFE_RATE_192K = 7, ++ ARH_AFE_RATE_352K = 24, ++ ARH_AFE_RATE_384K = 8, ++}; ++ ++unsigned int an7581_afe_rate_transform(struct device *dev, unsigned int rate) ++{ ++ switch (rate) { ++ case 7350: ++ return ARH_AFE_RATE_7K; ++ case 8000: ++ return ARH_AFE_RATE_8K; ++ case 11025: ++ return ARH_AFE_RATE_11K; ++ case 12000: ++ return ARH_AFE_RATE_12K; ++ case 14700: ++ return ARH_AFE_RATE_14K; ++ case 16000: ++ return ARH_AFE_RATE_16K; ++ case 22050: ++ return ARH_AFE_RATE_22K; ++ case 24000: ++ return ARH_AFE_RATE_24K; ++ case 29400: ++ return ARH_AFE_RATE_29K; ++ case 32000: ++ return ARH_AFE_RATE_32K; ++ case 44100: ++ return ARH_AFE_RATE_44K; ++ case 48000: ++ return ARH_AFE_RATE_48K; ++ case 88200: ++ return ARH_AFE_RATE_88K; ++ case 96000: ++ return ARH_AFE_RATE_96K; ++ case 176400: ++ return ARH_AFE_RATE_176K; ++ case 192000: ++ return ARH_AFE_RATE_192K; ++ case 352800: ++ return ARH_AFE_RATE_352K; ++ case 384000: ++ return ARH_AFE_RATE_384K; ++ default: ++ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n", ++ __func__, rate, ARH_AFE_RATE_48K); ++ return ARH_AFE_RATE_48K; ++ } ++} ++ ++static const int an7581_memif_specified_irqs[AN7581_MEMIF_NUM] = { ++ [AN7581_MEMIF_DL1] = AN7581_IRQ_0, ++ [AN7581_MEMIF_UL1] = AN7581_IRQ_1, ++}; ++ ++static const struct snd_pcm_hardware an7581_afe_hardware = { ++ .info = SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP_VALID, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .period_bytes_min = 512, ++ .period_bytes_max = 128 * 1024, ++ .periods_min = 2, ++ .periods_max = 256, ++ .buffer_bytes_max = 256 * 1024, ++ .fifo_size = 0, ++}; ++ ++static int an7581_memif_fs(struct snd_pcm_substream *substream, ++ unsigned int rate) ++{ ++ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); ++ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); ++ ++ return an7581_afe_rate_transform(afe->dev, rate); ++} ++ ++static int an7581_irq_fs(struct snd_pcm_substream *substream, ++ unsigned int rate) ++{ ++ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); ++ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); ++ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); ++ ++ return an7581_afe_rate_transform(afe->dev, rate); ++} ++ ++#define ARH_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ ++ SNDRV_PCM_FMTBIT_S32_LE) ++ ++static struct snd_soc_dai_driver an7581_memif_dai_driver[] = { ++ /* FE DAIs: memory intefaces to CPU */ ++ { ++ .name = "DL1", ++ .id = AN7581_MEMIF_DL1, ++ .playback = { ++ .stream_name = "DL1", ++ .channels_min = 1, ++ .channels_max = 8, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = ARH_PCM_FORMATS, ++ }, ++ .ops = &mtk_afe_fe_ops, ++ }, ++ { ++ .name = "UL1", ++ .id = AN7581_MEMIF_UL1, ++ .capture = { ++ .stream_name = "UL1", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = ARH_PCM_FORMATS, ++ }, ++ .ops = &mtk_afe_fe_ops, ++ }, ++}; ++ ++static const struct snd_soc_component_driver an7581_afe_pcm_dai_component = { ++ .name = "an7581-afe-pcm-dai", ++}; ++ ++static const struct mtk_base_memif_data memif_data[AN7581_MEMIF_NUM] = { ++ [AN7581_MEMIF_DL1] = { ++ .name = "DL1", ++ .id = AN7581_MEMIF_DL1, ++ .reg_ofs_base = AFE_DL1_BASE, ++ .reg_ofs_cur = AFE_DL1_CUR, ++ .reg_ofs_end = AFE_DL1_END, ++ .fs_reg = -1, ++ .fs_shift = -1, ++ .fs_maskbit = -1, ++ .mono_reg = -1, ++ .mono_shift = -1, ++ .hd_reg = -1, ++ .hd_shift = -1, ++ .enable_reg = AFE_DAC_CON0, ++ .enable_shift = 17, ++ .msb_reg = -1, ++ .msb_shift = -1, ++ .agent_disable_reg = -1, ++ .agent_disable_shift = -1, ++ }, ++ [AN7581_MEMIF_UL1] = { ++ .name = "UL1", ++ .id = AN7581_MEMIF_UL1, ++ .reg_ofs_base = AFE_UL1_BASE, ++ .reg_ofs_cur = AFE_UL1_CUR, ++ .reg_ofs_end = AFE_UL1_END, ++ .fs_reg = -1, ++ .fs_shift = -1, ++ .fs_maskbit = -1, ++ .mono_reg = -1, ++ .mono_shift = -1, ++ .hd_reg = -1, ++ .hd_shift = -1, ++ .enable_reg = AFE_DAC_CON0, ++ .enable_shift = 1, ++ .msb_reg = -1, ++ .msb_shift = -1, ++ .agent_disable_reg = -1, ++ .agent_disable_shift = -1, ++ }, ++}; ++ ++static const struct mtk_base_irq_data irq_data[AN7581_IRQ_NUM] = { ++ [AN7581_IRQ_0] = { ++ .id = AN7581_IRQ_0, ++ .irq_cnt_reg = -1, ++ .irq_cnt_shift = -1, ++ .irq_cnt_maskbit = -1, ++ .irq_en_reg = AFE_IRQ1_CON0, ++ .irq_en_shift = 4, ++ .irq_fs_reg = -1, ++ .irq_fs_shift = -1, ++ .irq_fs_maskbit = -1, ++ .irq_clr_reg = AFE_IRQ1_CON0, ++ .irq_clr_shift = 0, ++ }, ++ [AN7581_IRQ_1] = { ++ .id = AN7581_IRQ_1, ++ .irq_cnt_reg = -1, ++ .irq_cnt_shift = -1, ++ .irq_cnt_maskbit = -1, ++ .irq_en_reg = AFE_IRQ0_CON0, ++ .irq_en_shift = 4, ++ .irq_fs_reg = -1, ++ .irq_fs_shift = -1, ++ .irq_fs_maskbit = -1, ++ .irq_clr_reg = AFE_IRQ0_CON0, ++ .irq_clr_shift = 1, ++ }, ++}; ++ ++static const struct regmap_config an7581_afe_regmap_config = { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = AFE_MAX_REGISTER, ++ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1), ++}; ++ ++static irqreturn_t an7581_afe_irq_handler(int irq_id, void *dev) ++{ ++ struct mtk_base_afe *afe = dev; ++ struct mtk_base_afe_irq *irq; ++ u32 status; ++ u32 reg; ++ int i; ++ ++ regmap_read(afe->regmap, AFE_IRQ_STS, &status); ++ ++ if (status & AFE_IRQ_STS_RECORD) ++ reg = AFE_IRQ0_CON0; ++ else ++ reg = AFE_IRQ1_CON0; ++ ++ regmap_set_bits(afe->regmap, reg, BIT(2)); ++ regmap_clear_bits(afe->regmap, reg, BIT(2)); ++ ++ regmap_set_bits(afe->regmap, reg, BIT(3)); ++ regmap_clear_bits(afe->regmap, reg, BIT(3)); ++ ++ for (i = 0; i < AN7581_MEMIF_NUM; i++) { ++ struct mtk_base_afe_memif *memif = &afe->memif[i]; ++ ++ if (!memif->substream) ++ continue; ++ ++ if (memif->irq_usage < 0) ++ continue; ++ ++ irq = &afe->irqs[memif->irq_usage]; ++ ++ if (status & (1 << irq->irq_data->irq_clr_shift)) ++ snd_pcm_period_elapsed(memif->substream); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int an7581_afe_runtime_suspend(struct device *dev) ++{ ++ return 0; ++} ++ ++static int an7581_afe_runtime_resume(struct device *dev) ++{ ++ return 0; ++} ++ ++static int an7581_dai_memif_register(struct mtk_base_afe *afe) ++{ ++ struct mtk_base_afe_dai *dai; ++ ++ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); ++ if (!dai) ++ return -ENOMEM; ++ ++ list_add(&dai->list, &afe->sub_dais); ++ ++ dai->dai_drivers = an7581_memif_dai_driver; ++ dai->num_dai_drivers = ARRAY_SIZE(an7581_memif_dai_driver); ++ ++ return 0; ++} ++ ++typedef int (*dai_register_cb)(struct mtk_base_afe *); ++static const dai_register_cb dai_register_cbs[] = { ++ an7581_dai_memif_register, ++}; ++ ++static int an7581_afe_pcm_dev_probe(struct platform_device *pdev) ++{ ++ struct mtk_base_afe *afe; ++ struct an7581_afe_private *afe_priv; ++ struct device *dev; ++ int i, irq_id, ret; ++ ++ afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); ++ if (!afe) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, afe); ++ ++ afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), ++ GFP_KERNEL); ++ if (!afe->platform_priv) ++ return -ENOMEM; ++ ++ afe_priv = afe->platform_priv; ++ afe->dev = &pdev->dev; ++ dev = afe->dev; ++ ++ afe->base_addr = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(afe->base_addr)) ++ return PTR_ERR(afe->base_addr); ++ ++ ret = devm_pm_runtime_enable(dev); ++ if (ret) ++ return ret; ++ ++ pm_runtime_get_sync(&pdev->dev); ++ ++ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, ++ &an7581_afe_regmap_config); ++ ++ pm_runtime_put_sync(&pdev->dev); ++ if (IS_ERR(afe->regmap)) ++ return PTR_ERR(afe->regmap); ++ ++ mutex_init(&afe->irq_alloc_lock); ++ ++ /* irq initialize */ ++ afe->irqs_size = AN7581_IRQ_NUM; ++ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), ++ GFP_KERNEL); ++ if (!afe->irqs) ++ return -ENOMEM; ++ ++ for (i = 0; i < afe->irqs_size; i++) ++ afe->irqs[i].irq_data = &irq_data[i]; ++ ++ /* request irq */ ++ irq_id = platform_get_irq(pdev, 0); ++ if (irq_id < 0) ++ return irq_id; ++ ++ ret = devm_request_irq(dev, irq_id, an7581_afe_irq_handler, ++ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n"); ++ ++ /* init memif */ ++ afe->memif_size = AN7581_MEMIF_NUM; ++ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), ++ GFP_KERNEL); ++ if (!afe->memif) ++ return -ENOMEM; ++ ++ for (i = 0; i < afe->memif_size; i++) { ++ int sel_irq = an7581_memif_specified_irqs[i]; ++ ++ afe->memif[i].data = &memif_data[i]; ++ afe->memif[i].irq_usage = sel_irq; ++ afe->memif[i].const_irq = 1; ++ afe->irqs[sel_irq].irq_occupyed = true; ++ } ++ ++ /* init sub_dais */ ++ INIT_LIST_HEAD(&afe->sub_dais); ++ ++ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { ++ ret = dai_register_cbs[i](afe); ++ if (ret) ++ return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i); ++ } ++ ++ /* init dai_driver and component_driver */ ++ ret = mtk_afe_combine_sub_dai(afe); ++ if (ret) ++ return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n"); ++ ++ afe->mtk_afe_hardware = &an7581_afe_hardware; ++ afe->memif_fs = an7581_memif_fs; ++ afe->irq_fs = an7581_irq_fs; ++ ++ afe->runtime_resume = an7581_afe_runtime_resume; ++ afe->runtime_suspend = an7581_afe_runtime_suspend; ++ ++ /* register component */ ++ ret = devm_snd_soc_register_component(&pdev->dev, ++ &mtk_afe_pcm_platform, ++ NULL, 0); ++ if (ret) ++ return dev_err_probe(dev, ret, "Cannot register AFE component\n"); ++ ++ ret = devm_snd_soc_register_component(afe->dev, ++ &an7581_afe_pcm_dai_component, ++ afe->dai_drivers, ++ afe->num_dai_drivers); ++ if (ret) ++ return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n"); ++ ++ return 0; ++} ++ ++static void an7581_afe_pcm_dev_remove(struct platform_device *pdev) ++{ ++ pm_runtime_disable(&pdev->dev); ++ if (!pm_runtime_status_suspended(&pdev->dev)) ++ an7581_afe_runtime_suspend(&pdev->dev); ++} ++ ++static const struct of_device_id an7581_afe_pcm_dt_match[] = { ++ { .compatible = "airoha,an7581-afe" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, an7581_afe_pcm_dt_match); ++ ++static const struct dev_pm_ops an7581_afe_pm_ops = { ++ RUNTIME_PM_OPS(an7581_afe_runtime_suspend, ++ an7581_afe_runtime_resume, NULL) ++}; ++ ++static struct platform_driver an7581_afe_pcm_driver = { ++ .driver = { ++ .name = "an7581-audio", ++ .of_match_table = an7581_afe_pcm_dt_match, ++ .pm = pm_ptr(&an7581_afe_pm_ops), ++ }, ++ .probe = an7581_afe_pcm_dev_probe, ++ .remove_new = an7581_afe_pcm_dev_remove, ++}; ++module_platform_driver(an7581_afe_pcm_driver); ++ ++MODULE_DESCRIPTION("Airoha SoC AFE platform driver for ALSA AN7581"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/airoha/an7581/an7581-i2s.c +@@ -0,0 +1,110 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Airoha ALSA SoC I2S platform driver for AN7581 ++ * ++ */ ++ ++#include ++#include ++ ++#include "an7581-afe-common.h" ++ ++SND_SOC_DAILINK_DEFS(playback, ++ DAILINK_COMP_ARRAY(COMP_CPU("DL1")), ++ DAILINK_COMP_ARRAY(COMP_DUMMY()), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++SND_SOC_DAILINK_DEFS(capture, ++ DAILINK_COMP_ARRAY(COMP_CPU("UL1")), ++ DAILINK_COMP_ARRAY(COMP_DUMMY()), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++static struct snd_soc_dai_link an7581_i2s_dai_links[] = { ++ { ++ .name = "an7581-i2s-playback", ++ .stream_name = "an7581-i2s-playback", ++ .trigger = {SND_SOC_DPCM_TRIGGER_POST, ++ SND_SOC_DPCM_TRIGGER_POST}, ++ .dynamic = 0, ++ .playback_only = 1, ++ SND_SOC_DAILINK_REG(playback), ++ }, ++ { ++ .name = "an7581-i2s-capture", ++ .stream_name = "an7581-i2s-capture", ++ .trigger = {SND_SOC_DPCM_TRIGGER_POST, ++ SND_SOC_DPCM_TRIGGER_POST}, ++ .dynamic = 0, ++ .capture_only = 1, ++ SND_SOC_DAILINK_REG(capture), ++ }, ++}; ++ ++static struct snd_soc_card an7581_i2s_card = { ++ .name = "an7581-i2s", ++ .owner = THIS_MODULE, ++ .dai_link = an7581_i2s_dai_links, ++ .num_links = ARRAY_SIZE(an7581_i2s_dai_links), ++}; ++ ++static int an7581_i2s_machine_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = &an7581_i2s_card; ++ struct device_node *platform_dai_node; ++ struct snd_soc_dai_link *dai_link; ++ struct device_node *platform; ++ int ret, i; ++ ++ card->dev = &pdev->dev; ++ ++ platform = of_get_child_by_name(pdev->dev.of_node, "platform"); ++ ++ if (platform) { ++ platform_dai_node = of_parse_phandle(platform, "sound-dai", 0); ++ of_node_put(platform); ++ ++ if (!platform_dai_node) { ++ dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n"); ++ return -EINVAL; ++ } ++ } else { ++ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ for_each_card_prelinks(card, i, dai_link) { ++ if (dai_link->platforms->name) ++ continue; ++ dai_link->platforms->of_node = platform_dai_node; ++ } ++ ++ ret = devm_snd_soc_register_card(&pdev->dev, card); ++ if (ret) { ++ dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__); ++ goto err_of_node_put; ++ } ++ ++ return 0; ++ ++err_of_node_put: ++ of_node_put(platform_dai_node); ++ return ret; ++} ++ ++static const struct of_device_id an7581_i2s_machine_dt_match[] = { ++ { .compatible = "airoha,an7581-i2s" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, an7581_i2s_machine_dt_match); ++ ++static struct platform_driver an7581_i2s_driver = { ++ .driver = { ++ .name = "an7581-i2s", ++ .of_match_table = an7581_i2s_machine_dt_match, ++ }, ++ .probe = an7581_i2s_machine_probe, ++}; ++module_platform_driver(an7581_i2s_driver); ++ ++MODULE_DESCRIPTION("Airoha SoC I2S platform driver for ALSA AN7581"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/airoha/an7581/an7581-reg.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * an7581-reg.h -- Airoha AN7581 audio driver reg definition ++ */ ++ ++#ifndef _AN7581_REG_H_ ++#define _AN7581_REG_H_ ++ ++#define AFE_DAC_CON0 0x0 ++ ++#define AFE_DL1_BASE 0xa8 ++#define AFE_DL1_END 0xac ++#define AFE_DL1_CUR 0xb0 ++ ++#define AFE_UL1_BASE 0xc4 ++#define AFE_UL1_END 0xc8 ++#define AFE_UL1_CUR 0xcc ++ ++#define AFE_IRQ0_CON0 0xe4 ++ ++#define AFE_IRQ_STS 0xf8 ++#define AFE_IRQ_STS_PLAY BIT(1) ++#define AFE_IRQ_STS_RECORD BIT(0) ++ ++#define AFE_IRQ1_CON0 0x100 ++ ++#define AFE_MAX_REGISTER AFE_IRQ1_CON0 ++ ++#endif From 0272d79e347a1b9478285fdb2c7f903a2260a143 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 26 Sep 2025 04:55:19 +0200 Subject: [PATCH 046/128] airoha: Introduce support for Airoha AN7583 SoC Introduce initial support for Airoha AN7583 SoC and add all the required patch for basic functionality of the SoC. Airoha AN7583 is based on Airoha EN7581 SoC with some major changes on the PHY handling and Serdes. It can be see as a lower spec of EN7581 with modern and simplified implementations. All the patch are sent upstream and are pending revision. Support for PCIe and USB will come later as soon as DT structure is accepted upstream. (cherry picked from commit c5b12fc02ab133be1c18722e9b3c5b93e7772925) [ fix conflict errors, add MDIO_AIROHA config ] Signed-off-by: Christian Marangi --- target/linux/airoha/Makefile | 2 +- target/linux/airoha/an7581/config-6.6 | 2 + .../an7583/base-files/etc/board.d/02_network | 28 + target/linux/airoha/an7583/config-6.6 | 402 +++ target/linux/airoha/an7583/target.mk | 11 + target/linux/airoha/dts/an7583-evb.dts | 215 ++ target/linux/airoha/dts/an7583.dtsi | 818 +++++ target/linux/airoha/image/an7583.mk | 55 + ...DIO-bus-controller-for-Airoha-AN7583.patch | 342 ++ ...-airoha-generalize-pins-group-functi.patch | 772 +++++ ...airoha-convert-PHY-LED-GPIO-to-macro.patch | 616 ++++ ...trl-airoha-convert-PWM-GPIO-to-macro.patch | 491 +++ ...a-add-support-for-Airoha-AN7583-PINs.patch | 919 +++++ ...02-net-dsa-mt7530-Add-AN7583-support.patch | 140 + ...thermal-airoha-convert-to-regmap-API.patch | 194 ++ ...ers-airoha-Generalize-probe-function.patch | 226 ++ ...airoha-generalize-get_thermal_ADC-an.patch | 129 + ...rivers-airoha-Add-support-for-AN7583.patch | 277 ++ ...eq-airoha-Add-support-for-AN7583-SoC.patch | 35 + ...-en7523-convert-driver-to-regmap-API.patch | 351 ++ ...-generalize-register-clocks-function.patch | 258 ++ ...onvert-to-full-clk_hw-implementation.patch | 147 + ...clk-en7523-add-support-for-.set_rate.patch | 173 + ...t-to-reference-Chip-SCU-from-phandle.patch | 37 + ...reword-and-clean-clk_probe-variables.patch | 53 + ...23-add-support-for-probing-SCU-child.patch | 57 + ...k-airoha-Document-support-for-AN7583.patch | 122 + ...-add-support-for-Airoha-AN7583-clock.patch | 328 ++ ...et-pcs-airoha-add-support-for-AN7583.patch | 3002 +++++++++++++++++ ...t-airoha-define-sport-value-for-GDM3.patch | 26 + ...dd-support-for-optional-xfi-reset-li.patch | 63 + 31 files changed, 10290 insertions(+), 1 deletion(-) create mode 100644 target/linux/airoha/an7583/base-files/etc/board.d/02_network create mode 100644 target/linux/airoha/an7583/config-6.6 create mode 100644 target/linux/airoha/an7583/target.mk create mode 100644 target/linux/airoha/dts/an7583-evb.dts create mode 100644 target/linux/airoha/dts/an7583.dtsi create mode 100644 target/linux/airoha/image/an7583.mk create mode 100644 target/linux/airoha/patches-6.6/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch create mode 100644 target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch create mode 100644 target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch create mode 100644 target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch create mode 100644 target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch create mode 100644 target/linux/airoha/patches-6.6/401-02-net-dsa-mt7530-Add-AN7583-support.patch create mode 100644 target/linux/airoha/patches-6.6/402-01-thermal-airoha-convert-to-regmap-API.patch create mode 100644 target/linux/airoha/patches-6.6/402-02-thermal-drivers-airoha-Generalize-probe-function.patch create mode 100644 target/linux/airoha/patches-6.6/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch create mode 100644 target/linux/airoha/patches-6.6/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch create mode 100644 target/linux/airoha/patches-6.6/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch create mode 100644 target/linux/airoha/patches-6.6/600-01-clk-en7523-convert-driver-to-regmap-API.patch create mode 100644 target/linux/airoha/patches-6.6/600-02-clk-en7523-generalize-register-clocks-function.patch create mode 100644 target/linux/airoha/patches-6.6/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch create mode 100644 target/linux/airoha/patches-6.6/600-04-clk-en7523-add-support-for-.set_rate.patch create mode 100644 target/linux/airoha/patches-6.6/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch create mode 100644 target/linux/airoha/patches-6.6/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch create mode 100644 target/linux/airoha/patches-6.6/600-08-clk-en7523-add-support-for-probing-SCU-child.patch create mode 100644 target/linux/airoha/patches-6.6/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch create mode 100644 target/linux/airoha/patches-6.6/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch create mode 100644 target/linux/airoha/patches-6.6/604-01-net-pcs-airoha-add-support-for-AN7583.patch create mode 100644 target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch create mode 100644 target/linux/airoha/patches-6.6/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch diff --git a/target/linux/airoha/Makefile b/target/linux/airoha/Makefile index 61b7b87692..7c58488314 100644 --- a/target/linux/airoha/Makefile +++ b/target/linux/airoha/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=airoha BOARDNAME:=Airoha ARM -SUBTARGETS:=en7523 an7581 +SUBTARGETS:=en7523 an7581 an7583 FEATURES:=dt squashfs nand ramdisk gpio KERNEL_PATCHVER:=6.6 diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 69827464d6..8d253214f7 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -345,6 +345,7 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_LRU_GEN is not set CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +# CONFIG_MDIO_AIROHA is not set CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_DEVRES=y @@ -448,6 +449,7 @@ CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_MSI=y CONFIG_PCPU_DEV_REFCNT=y CONFIG_PCS_AIROHA_AN7581=y +# CONFIG_PCS_AIROHA_AN7583 is not set CONFIG_PERF_EVENTS=y CONFIG_PER_VMA_LOCK=y CONFIG_PGTABLE_LEVELS=3 diff --git a/target/linux/airoha/an7583/base-files/etc/board.d/02_network b/target/linux/airoha/an7583/base-files/etc/board.d/02_network new file mode 100644 index 0000000000..077d193ed5 --- /dev/null +++ b/target/linux/airoha/an7583/base-files/etc/board.d/02_network @@ -0,0 +1,28 @@ +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# Copyright (c) 2011-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +an7583_setup_interfaces() +{ + local board="$1" + + case "$board" in + airoha,an7583-evb) + ucidef_set_interface_lan "lan1 lan2 lan3 lan4 eth1" + ;; + *) + echo "Unsupported hardware. Network interfaces not initialized" + ;; + esac +} + +board_config_update +board=$(board_name) +an7583_setup_interfaces $board +board_config_flush + +exit 0 diff --git a/target/linux/airoha/an7583/config-6.6 b/target/linux/airoha/an7583/config-6.6 new file mode 100644 index 0000000000..b95bfa67c6 --- /dev/null +++ b/target/linux/airoha/an7583/config-6.6 @@ -0,0 +1,402 @@ +CONFIG_64BIT=y +CONFIG_AIROHA_CPU_PM_DOMAIN=y +CONFIG_AIROHA_SCU_SSR=y +CONFIG_AIROHA_THERMAL=y +CONFIG_AIROHA_WATCHDOG=y +CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y +CONFIG_ARCH_AIROHA=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_FORCE_MAX_ORDER=10 +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PLATFORM_DEVICES=y +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_VA_BITS_39=y +# CONFIG_ARM64_VA_BITS_48 is not set +# CONFIG_ARM64_VA_BITS_52 is not set +CONFIG_ARM_AIROHA_SOC_CPUFREQ=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_DEBUG_WX is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_PMU=y +CONFIG_ARM_PMUV3=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_SMCCC_SOC_ID=y +# CONFIG_ARM_SMMU is not set +# CONFIG_ARM_SMMU_V3 is not set +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BUFFER_HEAD=y +CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_EN7523=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +# CONFIG_COMPAT_32BIT_TIME is not set +# CONFIG_COMPRESSED_INSTALL is not set +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_RMAP=y +CONFIG_CRC16=y +CONFIG_CRC_CCITT=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_EIP93=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64 +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32 +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_MISC=y +CONFIG_DMADEVICES=y +CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_NEED_SYNC=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS_HELPERS=y +CONFIG_DTC=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EXT4_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FRAME_POINTER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FUNCTION_ALIGNMENT=4 +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_CACHE=y +# CONFIG_FW_LOADER_USER_HELPER is not set +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_DEVICES=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_EN7523=y +CONFIG_GPIO_GENERIC=y +CONFIG_GRO_CELLS=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AIROHA=y +# CONFIG_HISILICON_ERRATUM_162100801 is not set +# CONFIG_IDPF is not set +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +# CONFIG_INET_ESP_OFFLOAD is not set +CONFIG_INET_IPCOMP=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_IO_URING=y +CONFIG_IPC_NS=y +CONFIG_IPV6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_COMMON=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MSI_LIB=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LRU_GEN_WALKS_MMU=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_AIROHA=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MEDIATEK_GE_SOC_PHY is not set +# CONFIG_MEMCG is not set +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_MTK_BMT=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_AIROHA=y +CONFIG_NET_AIROHA_FLOW_STATS=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_MT7530_MDIO=y +CONFIG_NET_DSA_MT7530_MMIO=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +# CONFIG_NET_MEDIATEK_SOC is not set +CONFIG_NET_SELFTESTS=y +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_VENDOR_AIROHA=y +# CONFIG_NET_VENDOR_MEDIATEK is not set +CONFIG_NLS=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +CONFIG_NVMEM_BLOCK=y +CONFIG_NVMEM_LAYOUTS=y +CONFIG_NVMEM_LAYOUT_ASCII_ENV=y +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_PERFORMANCE=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_MEDIATEK_GEN3=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +# CONFIG_PCS_AIROHA_AN7581 is not set +CONFIG_PCS_AIROHA_AN7583=y +CONFIG_PERF_EVENTS=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_AIROHA_PCIE=y +# CONFIG_PHY_AIROHA_USB is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_AIROHA=y +# CONFIG_PINCTRL_MT2712 is not set +# CONFIG_PINCTRL_MT6765 is not set +# CONFIG_PINCTRL_MT6795 is not set +# CONFIG_PINCTRL_MT6797 is not set +# CONFIG_PINCTRL_MT7622 is not set +# CONFIG_PINCTRL_MT7981 is not set +# CONFIG_PINCTRL_MT7986 is not set +# CONFIG_PINCTRL_MT8173 is not set +# CONFIG_PINCTRL_MT8183 is not set +# CONFIG_PINCTRL_MT8186 is not set +# CONFIG_PINCTRL_MT8188 is not set +# CONFIG_PINCTRL_MT8516 is not set +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_OPP=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_SUPPLY=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RANDSTRUCT_NONE=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_RELOCATABLE=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_RPS=y +CONFIG_RTL8261N_PHY=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SERIAL_8250_AIROHA=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SGL_ALLOC=y +CONFIG_SKB_EXTENSIONS=y +CONFIG_SMP=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOC_BUS=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +# CONFIG_SPI_AIROHA_EN7523 is not set +CONFIG_SPI_AIROHA_SNFI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +# CONFIG_TEST_FPU is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +# CONFIG_UNMAP_KERNEL_AT_EL0 is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_VDSO_GETRANDOM=y +CONFIG_VMAP_STACK=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WLAN is not set +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_XFRM_AH=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_ESP=y +CONFIG_XFRM_IPCOMP=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/airoha/an7583/target.mk b/target/linux/airoha/an7583/target.mk new file mode 100644 index 0000000000..dacbe0928e --- /dev/null +++ b/target/linux/airoha/an7583/target.mk @@ -0,0 +1,11 @@ +ARCH:=aarch64 +SUBTARGET:=an7583 +BOARDNAME:=AN7583 +CPU_TYPE:=cortex-a53 +KERNELNAME:=Image dtbs +FEATURES+=pwm source-only + +define Target/Description + Build firmware images for Airoha an7583 ARM based boards. +endef + diff --git a/target/linux/airoha/dts/an7583-evb.dts b/target/linux/airoha/dts/an7583-evb.dts new file mode 100644 index 0000000000..fdd5b2aa92 --- /dev/null +++ b/target/linux/airoha/dts/an7583-evb.dts @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/dts-v1/; + +#include +#include +#include +#include "an7583.dtsi" + +/ { + model = "Airoha AN7583 Evaluation Board"; + compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583"; + + aliases { + serial0 = &uart1; + }; + + chosen { + bootargs = "console=ttyS0,115200 earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x2 0x00000000>; + }; +}; + +&an7583_pinctrl { + gpio-ranges = <&an7583_pinctrl 0 2 53>; + + mdio0_pins: mdio0-pins { + conf { + pins = "mdio_0"; + output-high; + }; + }; + + pcie0_rst_pins: pcie0-rst-pins { + conf { + pins = "pcie_reset0"; + drive-open-drain = <1>; + }; + }; + + pcie1_rst_pins: pcie1-rst-pins { + conf { + pins = "pcie_reset1"; + drive-open-drain = <1>; + }; + }; + + gswp1_led0_pins: gswp1-led0-pins { + mux { + function = "phy1_led0"; + pins = "gpio1"; + }; + }; +}; + +&snfi { + status = "okay"; +}; + + +&spi_nand { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + bl2@0 { + label = "bl2"; + reg = <0x0 0x20000>; + }; + + ubi@20000 { + label = "ubi"; + reg = <0x20000 0x0>; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +ð { + status = "okay"; +}; + +&gdm1 { + status = "okay"; +}; + +&switch { + status = "okay"; +}; + +&gsw_phy1 { + pinctrl-names = "gbe-led"; + pinctrl-0 = <&gswp1_led0_pins>; + status = "okay"; +}; + +&gsw_phy1_led0 { + status = "okay"; + active-low; +}; + +&gsw_port2 { + status = "disabled"; +}; + +&gsw_port3 { + status = "disabled"; +}; + +&gsw_port4 { + status = "disabled"; +}; + +&gsw_phy2 { + status = "disabled"; +}; + +&gsw_phy3 { + status = "disabled"; +}; + +&gsw_phy4 { + status = "disabled"; +}; + +&mdio_0 { + pinctrl-names = "default"; + pinctrl-0 = <&mdio0_pins>; + + as21xx_0: ethernet-phy@1d { + reg = <0x1d>; + compatible = "ethernet-phy-ieee802.3-c45"; + + firmware-name = "as21x1x_fw.bin"; + + reset-deassert-us = <350000>; + reset-assert-us = <200000>; + reset-gpios = <&an7583_pinctrl 34 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + default-state = "keep"; + }; + }; + }; + + as21xx_1: ethernet-phy@1f { + reg = <0x1f>; + compatible = "ethernet-phy-ieee802.3-c45"; + + firmware-name = "as21x1x_fw.bin"; + + reset-deassert-us = <350000>; + reset-assert-us = <200000>; + reset-gpios = <&an7583_pinctrl 35 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + default-state = "keep"; + }; + }; + }; +}; + +&gdm3 { + status = "okay"; + + phy-handle = <&as21xx_1>; + phy-mode = "usxgmii"; +}; + +&gdm2 { + status = "okay"; + + phy-handle = <&as21xx_0>; + phy-mode = "usxgmii"; +}; diff --git a/target/linux/airoha/dts/an7583.dtsi b/target/linux/airoha/dts/an7583.dtsi new file mode 100644 index 0000000000..43e60ebf66 --- /dev/null +++ b/target/linux/airoha/dts/an7583.dtsi @@ -0,0 +1,818 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + atf@80000000 { + no-map; + reg = <0x0 0x80000000 0x0 0x200000>; + }; + + npu_binary: npu-binary@84000000 { + no-map; + reg = <0x0 0x84000000 0x0 0xa00000>; + }; + + qdma0_buf: qdma0-buf@87000000 { + no-map; + reg = <0x0 0x87000000 0x0 0x2000000>; + }; + + qdma1_buf: qdma1-buf@89000000 { + no-map; + reg = <0x0 0x89000000 0x0 0x1000000>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + operating-points-v2 = <&cpu_opp_table>; + enable-method = "psci"; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; + next-level-cache = <&l2>; + #cooling-cells = <2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + enable-method = "psci"; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; + next-level-cache = <&l2>; + #cooling-cells = <2>; + }; + + l2: l2-cache { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <64>; + cache-level = <2>; + cache-unified; + }; + }; + + cpufreq: cpufreq { + compatible = "airoha,en7581-cpufreq"; + + operating-points-v2 = <&cpu_smcc_opp_table>; + + #power-domain-cells = <0>; + #clock-cells = <0>; + }; + + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + required-opps = <&smcc_opp0>; + }; + + opp-550000000 { + opp-hz = /bits/ 64 <550000000>; + required-opps = <&smcc_opp1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&smcc_opp2>; + }; + + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + required-opps = <&smcc_opp3>; + }; + + opp-7000000000 { + opp-hz = /bits/ 64 <700000000>; + required-opps = <&smcc_opp4>; + }; + + opp-7500000000 { + opp-hz = /bits/ 64 <750000000>; + required-opps = <&smcc_opp5>; + }; + + opp-8000000000 { + opp-hz = /bits/ 64 <800000000>; + required-opps = <&smcc_opp6>; + }; + + opp-8500000000 { + opp-hz = /bits/ 64 <850000000>; + required-opps = <&smcc_opp7>; + }; + + opp-9000000000 { + opp-hz = /bits/ 64 <900000000>; + required-opps = <&smcc_opp8>; + }; + + opp-9500000000 { + opp-hz = /bits/ 64 <950000000>; + required-opps = <&smcc_opp9>; + }; + + opp-10000000000 { + opp-hz = /bits/ 64 <1000000000>; + required-opps = <&smcc_opp10>; + }; + + opp-10500000000 { + opp-hz = /bits/ 64 <1050000000>; + required-opps = <&smcc_opp11>; + }; + + opp-11000000000 { + opp-hz = /bits/ 64 <1100000000>; + required-opps = <&smcc_opp12>; + }; + + opp-11500000000 { + opp-hz = /bits/ 64 <1150000000>; + required-opps = <&smcc_opp13>; + }; + + opp-12000000000 { + opp-hz = /bits/ 64 <1200000000>; + required-opps = <&smcc_opp14>; + }; + }; + + cpu_smcc_opp_table: opp-table-cpu-smcc { + compatible = "operating-points-v2"; + + smcc_opp0: opp0 { + opp-level = <0>; + }; + + smcc_opp1: opp1 { + opp-level = <1>; + }; + + smcc_opp2: opp2 { + opp-level = <2>; + }; + + smcc_opp3: opp3 { + opp-level = <3>; + }; + + smcc_opp4: opp4 { + opp-level = <4>; + }; + + smcc_opp5: opp5 { + opp-level = <5>; + }; + + smcc_opp6: opp6 { + opp-level = <6>; + }; + + smcc_opp7: opp7 { + opp-level = <7>; + }; + + smcc_opp8: opp8 { + opp-level = <8>; + }; + + smcc_opp9: opp9 { + opp-level = <9>; + }; + + smcc_opp10: opp10 { + opp-level = <10>; + }; + + smcc_opp11: opp11 { + opp-level = <11>; + }; + + smcc_opp12: opp12 { + opp-level = <12>; + }; + + smcc_opp13: opp13 { + opp-level = <13>; + }; + + smcc_opp14: opp14 { + opp-level = <14>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <10000>; + polling-delay = <5000>; + + thermal-sensors = <&thermal 0>; + + trips { + cpu_hot: cpu-hot { + temperature = <95000>; + hysteresis = <1000>; + type = "hot"; + }; + + cpu-critical { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + clk25m: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "clkxtal"; + }; + + sys_hclk: clk-oscillator-100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "sys_hclk"; + }; + + vmmc_3v3: regulator-vmmc-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vmmc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + sfp1: sfp1 { + compatible = "sff,sfp"; + }; + + sfp2: sfp2 { + compatible = "sff,sfp"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic: interrupt-controller@9000000 { + compatible = "arm,gic-v3"; + interrupt-controller; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x09000000 0x0 0x20000>, + <0x0 0x09080000 0x0 0x80000>, + <0x0 0x09400000 0x0 0x2000>, + <0x0 0x09500000 0x0 0x2000>, + <0x0 0x09600000 0x0 0x20000>; + interrupts = ; + }; + + chip_scu: syscon@1fa20000 { + compatible = "airoha,en7581-chip-scu", "syscon", "simple-mfd"; + reg = <0x0 0x1fa20000 0x0 0x388>; + + thermal: thermal { + compatible = "airoha,an7583-thermal"; + + #thermal-sensor-cells = <0>; + }; + }; + + pbus_csr: syscon@1fbe3400 { + compatible = "airoha,en7581-pbus-csr", "syscon"; + reg = <0x0 0x1fbe3400 0x0 0xff>; + }; + + scuclk: system-controller@1fa20000 { + compatible = "airoha,an7583-scu", "syscon"; + reg = <0x0 0x1fb00000 0x0 0x970>; + + #address-cells = <1>; + #size-cells = <0>; + + #clock-cells = <1>; + #reset-cells = <1>; + + airoha,chip-scu = <&chip_scu>; + + mdio_0: mdio-bus@c8 { + compatible = "airoha,an7583-mdio"; + reg = <0xc8>; + + clocks = <&scuclk AN7583_CLK_MDIO0>; + resets = <&scuclk AN7583_MDIO0>; + }; + + mdio_1: mdio-bus@cc { + compatible = "airoha,an7583-mdio"; + reg = <0xcc>; + + clocks = <&scuclk AN7583_CLK_MDIO1>; + resets = <&scuclk AN7583_MDIO1>; + }; + }; + + system-controller@1fbf0200 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0x1fbf0200 0x0 0xc0>; + + an7583_pinctrl: pinctrl { + compatible = "airoha,an7583-pinctrl"; + + interrupt-parent = <&gic>; + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + i2cclock: i2cclock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + + /* 20 MHz */ + clock-frequency = <20000000>; + }; + + i2c0: i2c0@1fbf8000 { + compatible = "airoha,an7581-i2c"; + reg = <0x0 0x1fbf8000 0x0 0x100>; + + clocks = <&i2cclock>; + + /* 100 kHz */ + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disable"; + }; + + i2c1: i2c1@1fbf8100 { + compatible = "airoha,an7581-i2c"; + reg = <0x0 0x1fbf8100 0x0 0x100>; + + clocks = <&i2cclock>; + + /* 100 kHz */ + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disable"; + }; + + mmc0: mmc@1fa0e000 { + compatible = "mediatek,mt7622-mmc"; + reg = <0x0 0x1fa0e000 0x0 0x1000>, + <0x0 0x1fa0c000 0x0 0x60>; + interrupts = ; + clocks = <&scuclk EN7581_CLK_EMMC>, <&clk25m>; + clock-names = "source", "hclk"; + bus-width = <4>; + max-frequency = <52000000>; + vmmc-supply = <&vmmc_3v3>; + disable-wp; + cap-mmc-highspeed; + non-removable; + + status = "disabled"; + }; + + snfi: spi@1fa10000 { + compatible = "airoha,en7581-snand"; + reg = <0x0 0x1fa10000 0x0 0x140>, + <0x0 0x1fa11000 0x0 0x160>; + + clocks = <&scuclk EN7523_CLK_SPI>; + clock-names = "spi"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + spi_nand: nand@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <2>; + }; + }; + + uart1: serial@1fbf0000 { + compatible = "ns16550"; + reg = <0x0 0x1fbf0000 0x0 0x30>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = ; + clock-frequency = <1843200>; + }; + + watchdog@1fbf0100 { + compatible = "airoha,en7581-wdt"; + reg = <0x0 0x1fbf0100 0x0 0x38>; + + clocks = <&sys_hclk>; + clock-names = "bus"; + }; + + uart2: serial@1fbf0300 { + compatible = "airoha,en7523-uart"; + reg = <0x0 0x1fbf0300 0x0 0x30>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = ; + clock-frequency = <7372800>; + + status = "disabled"; + }; + + hsuart3: serial@1fbe1000 { + compatible = "airoha,en7523-uart"; + reg = <0x0 0x1fbe1000 0x0 0x40>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = ; + clock-frequency = <7372800>; + + status = "disabled"; + }; + + uart4: serial@1fbf0600 { + compatible = "airoha,en7523-uart"; + reg = <0x0 0x1fbf0600 0x0 0x30>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = ; + clock-frequency = <7372800>; + + status = "disabled"; + }; + + uart5: serial@1fbf0700 { + compatible = "airoha,en7523-uart"; + reg = <0x0 0x1fbf0700 0x0 0x30>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = ; + clock-frequency = <7372800>; + + status = "disabled"; + }; + + crypto@1e004000 { + compatible = "inside-secure,safexcel-eip93ies"; + reg = <0x0 0x1fb70000 0x0 0x1000>; + + interrupts = ; + }; + + pon_pcs: pcs@1fa08000 { + compatible = "airoha,an7583-pcs-pon"; + reg = <0x0 0x1fa08000 0x0 0x1000>, + <0x0 0x1fa80000 0x0 0x60>, + <0x0 0x1fa80a00 0x0 0x164>, + <0x0 0x1fa84000 0x0 0x450>, + <0x0 0x1fa85900 0x0 0x338>, + <0x0 0x1fa86000 0x0 0x300>, + <0x0 0x1fa8f000 0x0 0x1000>, + <0x0 0x1fa8e000 0x0 0x1000>; + reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", + "multi_sgmii", "usxgmii", + "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; + + resets = <&scuclk AN7583_XPON_MAC_RST>, + <&scuclk AN7583_XPON_PHY_RST>, + <&scuclk AN7583_XPON_XFI_RST>; + reset-names = "mac", "phy", "xfi"; + + airoha,scu = <&scuclk>; + }; + + eth_pcs: pcs@1fa09000 { + compatible = "airoha,an7583-pcs-eth"; + reg = <0x0 0x1fa09000 0x0 0x1000>, + <0x0 0x1fa70000 0x0 0x60>, + <0x0 0x1fa70a00 0x0 0x164>, + <0x0 0x1fa74000 0x0 0x450>, + <0x0 0x1fa75900 0x0 0x338>, + <0x0 0x1fa76000 0x0 0x300>, + <0x0 0x1fa7f000 0x0 0x1000>, + <0x0 0x1fa7e000 0x0 0x1000>; + reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs", + "multi_sgmii", "usxgmii", + "hsgmii_rate_adp", "xfi_ana", "xfi_pma"; + + resets = <&scuclk AN7583_XSI_MAC_RST>, + <&scuclk AN7583_XSI_PHY_RST>; + reset-names = "mac", "phy"; + + airoha,scu = <&scuclk>; + }; + + eth: ethernet@1fb50000 { + compatible = "airoha,an7583-eth"; + reg = <0 0x1fb50000 0 0x2600>, + <0 0x1fb54000 0 0x2000>, + <0 0x1fb56000 0 0x2000>; + reg-names = "fe", "qdma0", "qdma1"; + + resets = <&scuclk AN7583_FE_RST>, + <&scuclk AN7583_FE_PDMA_RST>, + <&scuclk AN7583_FE_QDMA_RST>, + <&scuclk AN7583_DUAL_HSI0_MAC_RST>, + <&scuclk AN7583_DUAL_HSI1_MAC_RST>, + <&scuclk AN7583_XFP_MAC_RST>; + reset-names = "fe", "pdma", "qdma", + "hsi0-mac", "hsi1-mac", + "xfp-mac"; + + interrupts = , + , + , + , + , + , + , + , + , + ; + + memory-region = <&qdma0_buf>, <&qdma1_buf>; + memory-region-names = "qdma0-buf", "qdma1-buf"; + + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + + gdm1: ethernet@1 { + compatible = "airoha,eth-mac"; + reg = <1>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <10000>; + full-duplex; + pause; + }; + }; + + gdm2: ethernet@2 { + compatible = "airoha,eth-mac"; + reg = <2>; + pcs = <&pon_pcs>; + + status = "disabled"; + }; + + gdm3: ethernet@3 { + compatible = "airoha,eth-mac"; + reg = <3>; + pcs = <ð_pcs>; + airoha,gdm-srcport = <0x16>; + + status = "disabled"; + }; + }; + + switch: switch@1fb58000 { + compatible = "airoha,an7583-switch"; + reg = <0 0x1fb58000 0 0x8000>; + resets = <&scuclk AN7583_GSW_RST>; + + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + + status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + gsw_port1: port@1 { + reg = <1>; + label = "lan1"; + phy-mode = "internal"; + phy-handle = <&gsw_phy1>; + }; + + gsw_port2: port@2 { + reg = <2>; + label = "lan2"; + phy-mode = "internal"; + phy-handle = <&gsw_phy2>; + }; + + gsw_port3: port@3 { + reg = <3>; + label = "lan3"; + phy-mode = "internal"; + phy-handle = <&gsw_phy3>; + }; + + gsw_port4: port@4 { + reg = <4>; + label = "lan4"; + phy-mode = "internal"; + phy-handle = <&gsw_phy4>; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gdm1>; + phy-mode = "internal"; + + fixed-link { + speed = <10000>; + full-duplex; + pause; + }; + }; + }; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + + gsw_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <9>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + gsw_phy1_led0: gsw-phy1-led0@0 { + reg = <0>; + function = "phy1_led0"; + status = "disabled"; + }; + + gsw_phy1_led1: gsw-phy1-led1@1 { + reg = <1>; + function = "phy1_led1"; + status = "disabled"; + }; + }; + }; + + gsw_phy2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <10>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + gsw_phy2_led0: gsw-phy2-led0@0 { + reg = <0>; + function = "phy2_led0"; + status = "disabled"; + }; + + gsw_phy2_led1: gsw-phy2-led1@1 { + reg = <1>; + function = "phy1_led1"; + status = "disabled"; + }; + }; + }; + + gsw_phy3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <11>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + gsw_phy3_led0: gsw-phy3-led0@0 { + reg = <0>; + function = LED_FUNCTION_LAN; + status = "disabled"; + }; + + gsw_phy3_led1: gsw-phy3-led1@1 { + reg = <1>; + function = LED_FUNCTION_LAN; + status = "disabled"; + }; + }; + }; + + gsw_phy4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <12>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + gsw_phy4_led0: gsw-phy4-led0@0 { + reg = <0>; + function = LED_FUNCTION_LAN; + status = "disabled"; + }; + + gsw_phy4_led1: gsw-phy4-led1@1 { + reg = <1>; + function = LED_FUNCTION_LAN; + status = "disabled"; + }; + }; + }; + }; + }; + }; +}; diff --git a/target/linux/airoha/image/an7583.mk b/target/linux/airoha/image/an7583.mk new file mode 100644 index 0000000000..6ebec7af1b --- /dev/null +++ b/target/linux/airoha/image/an7583.mk @@ -0,0 +1,55 @@ +define Build/an7583-bl2-bl31-uboot + head -c $$((0x800)) /dev/zero > $@ + cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ + dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-uboot.img of=$@ bs=1 seek=$$((0x20000)) conv=notrunc +endef + +define Build/an7583-emmc-bl2-bl31-uboot + head -c $$((0x800)) /dev/zero > $@ + cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ + dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip of=$@ bs=1 seek=$$((0x20000)) conv=notrunc +endef + +define Build/an7583-preloader + cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ +endef + +define Build/an7583-bl31-uboot + cat $(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip >> $@ +endef + +define Device/FitImageLzma + KERNEL_SUFFIX := -uImage.itb + KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/airoha_an7583-evb + $(call Device/FitImageLzma) + DEVICE_VENDOR := Airoha + DEVICE_MODEL := AN7583 Evaluation Board (SNAND) + DEVICE_PACKAGES := kmod-leds-pwm kmod-input-gpio-keys-polled + DEVICE_DTS := an7583-evb + DEVICE_DTS_DIR := ../dts + DEVICE_DTS_CONFIG := config@1 + KERNEL_LOADADDR := 0x80088000 + IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata + ARTIFACT/bl2-bl31-uboot.bin := an7583-bl2-bl31-uboot rfb + ARTIFACT/preloader.bin := an7583-preloader rfb + ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb + ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip +endef +TARGET_DEVICES += airoha_an7583-evb + +define Device/airoha_an7583-evb-emmc + DEVICE_VENDOR := Airoha + DEVICE_MODEL := AN7583 Evaluation Board (EMMC) + DEVICE_DTS := an7583-evb-emmc + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-i2c-an7581 + ARTIFACT/preloader.bin := an7583-preloader rfb + ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb + ARTIFACT/bl2-bl31-uboot.bin := an7583-emmc-bl2-bl31-uboot rfb + ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip +endef +TARGET_DEVICES += airoha_an7583-evb-emmc diff --git a/target/linux/airoha/patches-6.6/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch b/target/linux/airoha/patches-6.6/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch new file mode 100644 index 0000000000..37b0ed5c78 --- /dev/null +++ b/target/linux/airoha/patches-6.6/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch @@ -0,0 +1,342 @@ +From 67e3ba978361cb262f8f8981ab88ccb97f1e2bda Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 11:16:53 +0200 +Subject: [PATCH] net: mdio: Add MDIO bus controller for Airoha AN7583 + +Airoha AN7583 SoC have 2 dedicated MDIO bus controller in the SCU +register map. To driver register an MDIO controller based on the DT +reg property and access the register by accessing the parent syscon. + +The MDIO bus logic is similar to the MT7530 internal MDIO bus but +deviates of some setting and some HW bug. + +On Airoha AN7583 the MDIO clock is set to 25MHz by default and needs to +be correctly setup to 2.5MHz to correctly work (by setting the divisor +to 10x). + +There seems to be Hardware bug where AN7583_MII_RWDATA +is not wiped in the context of unconnected PHY and the +previous read value is returned. + +Example: (only one PHY on the BUS at 0x1f) + - read at 0x1f report at 0x2 0x7500 + - read at 0x0 report 0x7500 on every address + +To workaround this, we reset the Mdio BUS at every read +to have consistent values on read operation. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/mdio/Kconfig | 7 + + drivers/net/mdio/Makefile | 1 + + drivers/net/mdio/mdio-airoha.c | 276 +++++++++++++++++++++++++++++++++ + 3 files changed, 284 insertions(+) + create mode 100644 drivers/net/mdio/mdio-airoha.c + +--- a/drivers/net/mdio/Kconfig ++++ b/drivers/net/mdio/Kconfig +@@ -46,6 +46,13 @@ if MDIO_BUS + config MDIO_DEVRES + tristate + ++config MDIO_AIROHA ++ tristate "Airoha AN7583 MDIO bus controller" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ help ++ This module provides a driver for the MDIO busses found in the ++ Airoha AN7583 SoC's. ++ + config MDIO_SUN4I + tristate "Allwinner sun4i MDIO interface support" + depends on ARCH_SUNXI || COMPILE_TEST +--- a/drivers/net/mdio/Makefile ++++ b/drivers/net/mdio/Makefile +@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO) += acpi_mdio.o + obj-$(CONFIG_FWNODE_MDIO) += fwnode_mdio.o + obj-$(CONFIG_OF_MDIO) += of_mdio.o + ++obj-$(CONFIG_MDIO_AIROHA) += mdio-airoha.o + obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o + obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o + obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o +--- /dev/null ++++ b/drivers/net/mdio/mdio-airoha.c +@@ -0,0 +1,276 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Airoha AN7583 MDIO interface driver ++ * ++ * Copyright (C) 2025 Christian Marangi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* MII address register definitions */ ++#define AN7583_MII_BUSY BIT(31) ++#define AN7583_MII_RDY BIT(30) /* RO signal BUS is ready */ ++#define AN7583_MII_CL22_REG_ADDR GENMASK(29, 25) ++#define AN7583_MII_CL45_DEV_ADDR AN7583_MII_CL22_REG_ADDR ++#define AN7583_MII_PHY_ADDR GENMASK(24, 20) ++#define AN7583_MII_CMD GENMASK(19, 18) ++#define AN7583_MII_CMD_CL22_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1) ++#define AN7583_MII_CMD_CL22_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x2) ++#define AN7583_MII_CMD_CL45_ADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x0) ++#define AN7583_MII_CMD_CL45_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1) ++#define AN7583_MII_CMD_CL45_POSTREAD_INCADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x2) ++#define AN7583_MII_CMD_CL45_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x3) ++#define AN7583_MII_ST GENMASK(17, 16) ++#define AN7583_MII_ST_CL45 FIELD_PREP_CONST(AN7583_MII_ST, 0x0) ++#define AN7583_MII_ST_CL22 FIELD_PREP_CONST(AN7583_MII_ST, 0x1) ++#define AN7583_MII_RWDATA GENMASK(15, 0) ++#define AN7583_MII_CL45_REG_ADDR AN7583_MII_RWDATA ++ ++#define AN7583_MII_MDIO_DELAY_USEC 100 ++#define AN7583_MII_MDIO_RETRY_MSEC 100 ++ ++struct airoha_mdio_data { ++ u32 base_addr; ++ struct regmap *regmap; ++ struct clk *clk; ++ struct reset_control *reset; ++}; ++ ++static int airoha_mdio_wait_busy(struct airoha_mdio_data *priv) ++{ ++ u32 busy; ++ ++ return regmap_read_poll_timeout(priv->regmap, priv->base_addr, busy, ++ !(busy & AN7583_MII_BUSY), ++ AN7583_MII_MDIO_DELAY_USEC, ++ AN7583_MII_MDIO_RETRY_MSEC * USEC_PER_MSEC); ++} ++ ++static void airoha_mdio_reset(struct airoha_mdio_data *priv) ++{ ++ /* There seems to be Hardware bug where AN7583_MII_RWDATA ++ * is not wiped in the context of unconnected PHY and the ++ * previous read value is returned. ++ * ++ * Example: (only one PHY on the BUS at 0x1f) ++ * - read at 0x1f report at 0x2 0x7500 ++ * - read at 0x0 report 0x7500 on every address ++ * ++ * To workaround this, we reset the Mdio BUS at every read ++ * to have consistent values on read operation. ++ */ ++ reset_control_assert(priv->reset); ++ reset_control_deassert(priv->reset); ++} ++ ++static int airoha_mdio_read(struct mii_bus *bus, int addr, int regnum) ++{ ++ struct airoha_mdio_data *priv = bus->priv; ++ u32 val; ++ int ret; ++ ++ airoha_mdio_reset(priv); ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 | ++ AN7583_MII_CMD_CL22_READ; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(priv->regmap, priv->base_addr, &val); ++ if (ret) ++ return ret; ++ ++ return FIELD_GET(AN7583_MII_RWDATA, val); ++} ++ ++static int airoha_mdio_write(struct mii_bus *bus, int addr, int regnum, ++ u16 value) ++{ ++ struct airoha_mdio_data *priv = bus->priv; ++ u32 val; ++ int ret; ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 | ++ AN7583_MII_CMD_CL22_WRITE; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum); ++ val |= FIELD_PREP(AN7583_MII_RWDATA, value); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ ++ return ret; ++} ++ ++static int airoha_mdio_cl45_read(struct mii_bus *bus, int addr, int devnum, ++ int regnum) ++{ ++ struct airoha_mdio_data *priv = bus->priv; ++ u32 val; ++ int ret; ++ ++ airoha_mdio_reset(priv); ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | ++ AN7583_MII_CMD_CL45_ADDR; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); ++ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ if (ret) ++ return ret; ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | ++ AN7583_MII_CMD_CL45_READ; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(priv->regmap, priv->base_addr, &val); ++ if (ret) ++ return ret; ++ ++ return FIELD_GET(AN7583_MII_RWDATA, val); ++} ++ ++static int airoha_mdio_cl45_write(struct mii_bus *bus, int addr, int devnum, ++ int regnum, u16 value) ++{ ++ struct airoha_mdio_data *priv = bus->priv; ++ u32 val; ++ int ret; ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | ++ AN7583_MII_CMD_CL45_ADDR; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); ++ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ if (ret) ++ return ret; ++ ++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | ++ AN7583_MII_CMD_CL45_WRITE; ++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); ++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); ++ val |= FIELD_PREP(AN7583_MII_RWDATA, value); ++ ++ ret = regmap_write(priv->regmap, priv->base_addr, val); ++ if (ret) ++ return ret; ++ ++ ret = airoha_mdio_wait_busy(priv); ++ ++ return ret; ++} ++ ++static int airoha_mdio_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct airoha_mdio_data *priv; ++ struct mii_bus *bus; ++ u32 addr, freq; ++ int ret; ++ ++ ret = of_property_read_u32(dev->of_node, "reg", &addr); ++ if (ret) ++ return ret; ++ ++ bus = devm_mdiobus_alloc_size(dev, sizeof(*priv)); ++ if (!bus) ++ return -ENOMEM; ++ ++ priv = bus->priv; ++ priv->base_addr = addr; ++ priv->regmap = device_node_to_regmap(dev->parent->of_node); ++ ++ priv->clk = devm_clk_get_enabled(dev, NULL); ++ if (IS_ERR(priv->clk)) ++ return PTR_ERR(priv->clk); ++ ++ priv->reset = devm_reset_control_get_exclusive(dev, NULL); ++ if (IS_ERR(priv->reset)) ++ return PTR_ERR(priv->reset); ++ ++ reset_control_deassert(priv->reset); ++ ++ bus->name = "airoha_mdio_bus"; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); ++ bus->parent = dev; ++ bus->read = airoha_mdio_read; ++ bus->write = airoha_mdio_write; ++ bus->read_c45 = airoha_mdio_cl45_read; ++ bus->write_c45 = airoha_mdio_cl45_write; ++ ++ /* Check if a custom frequency is defined in DT or default to 2.5 MHz */ ++ if (of_property_read_u32(dev->of_node, "clock-frequency", &freq)) ++ freq = 2500000; ++ ++ ret = clk_set_rate(priv->clk, freq); ++ if (ret) ++ return ret; ++ ++ ret = devm_of_mdiobus_register(dev, bus, dev->of_node); ++ if (ret) { ++ reset_control_assert(priv->reset); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id airoha_mdio_dt_ids[] = { ++ { .compatible = "airoha,an7583-mdio" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, airoha_mdio_dt_ids); ++ ++static struct platform_driver airoha_mdio_driver = { ++ .probe = airoha_mdio_probe, ++ .driver = { ++ .name = "airoha-mdio", ++ .of_match_table = airoha_mdio_dt_ids, ++ }, ++}; ++ ++module_platform_driver(airoha_mdio_driver); ++ ++MODULE_DESCRIPTION("Airoha AN7583 MDIO interface driver"); ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch b/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch new file mode 100644 index 0000000000..b7940f0603 --- /dev/null +++ b/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch @@ -0,0 +1,772 @@ +From e77c958d8eab1c29008ab57a2be82daefe886e0a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 25 May 2025 19:25:20 +0200 +Subject: [PATCH 2/5] pinctrl: mediatek: airoha: generalize + pins/group/function/confs handling + +In preparation for support of Airoha AN7583, generalize +pins/group/function/confs handling and move them in match_data. +Inner function will base the values on the pinctrl priv struct instead of +relying on hardcoded struct. + +This permits to use different PIN data while keeping the same logic. + +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 569 ++++++++++++---------- + 1 file changed, 319 insertions(+), 250 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -30,14 +30,14 @@ + #include "../pinconf.h" + #include "../pinmux.h" + +-#define PINCTRL_PIN_GROUP(id) \ +- PINCTRL_PINGROUP(#id, id##_pins, ARRAY_SIZE(id##_pins)) ++#define PINCTRL_PIN_GROUP(id, table) \ ++ PINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins)) + +-#define PINCTRL_FUNC_DESC(id) \ ++#define PINCTRL_FUNC_DESC(id, table) \ + { \ +- .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) }, \ +- .groups = id##_func_group, \ +- .group_size = ARRAY_SIZE(id##_func_group), \ ++ .desc = { #id, table##_groups, ARRAY_SIZE(table##_groups) },\ ++ .groups = table##_func_group, \ ++ .group_size = ARRAY_SIZE(table##_func_group), \ + } + + #define PINCTRL_CONF_DESC(p, offset, mask) \ +@@ -362,16 +362,46 @@ struct airoha_pinctrl_gpiochip { + u32 irq_type[AIROHA_NUM_PINS]; + }; + ++struct airoha_pinctrl_confs_info { ++ const struct airoha_pinctrl_conf *confs; ++ unsigned int num_confs; ++}; ++ ++enum airoha_pinctrl_confs_type { ++ AIROHA_PINCTRL_CONFS_PULLUP, ++ AIROHA_PINCTRL_CONFS_PULLDOWN, ++ AIROHA_PINCTRL_CONFS_DRIVE_E2, ++ AIROHA_PINCTRL_CONFS_DRIVE_E4, ++ AIROHA_PINCTRL_CONFS_PCIE_RST_OD, ++ ++ AIROHA_PINCTRL_CONFS_MAX, ++}; ++ + struct airoha_pinctrl { + struct pinctrl_dev *ctrl; + ++ struct pinctrl_desc desc; ++ const struct pingroup *grps; ++ const struct airoha_pinctrl_func *funcs; ++ const struct airoha_pinctrl_confs_info *confs_info; ++ + struct regmap *chip_scu; + struct regmap *regmap; + + struct airoha_pinctrl_gpiochip gpiochip; + }; + +-static struct pinctrl_pin_desc airoha_pinctrl_pins[] = { ++struct airoha_pinctrl_match_data { ++ const struct pinctrl_pin_desc *pins; ++ const unsigned int num_pins; ++ const struct pingroup *grps; ++ const unsigned int num_grps; ++ const struct airoha_pinctrl_func *funcs; ++ const unsigned int num_funcs; ++ const struct airoha_pinctrl_confs_info confs_info[AIROHA_PINCTRL_CONFS_MAX]; ++}; ++ ++static struct pinctrl_pin_desc en7581_pinctrl_pins[] = { + PINCTRL_PIN(0, "uart1_txd"), + PINCTRL_PIN(1, "uart1_rxd"), + PINCTRL_PIN(2, "i2c_scl"), +@@ -432,172 +462,172 @@ static struct pinctrl_pin_desc airoha_pi + PINCTRL_PIN(63, "pcie_reset2"), + }; + +-static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 }; +-static const int pon_tod_1pps_pins[] = { 46 }; +-static const int gsw_tod_1pps_pins[] = { 46 }; +-static const int sipo_pins[] = { 16, 17 }; +-static const int sipo_rclk_pins[] = { 16, 17, 43 }; +-static const int mdio_pins[] = { 14, 15 }; +-static const int uart2_pins[] = { 48, 55 }; +-static const int uart2_cts_rts_pins[] = { 46, 47 }; +-static const int hsuart_pins[] = { 28, 29 }; +-static const int hsuart_cts_rts_pins[] = { 26, 27 }; +-static const int uart4_pins[] = { 38, 39 }; +-static const int uart5_pins[] = { 18, 19 }; +-static const int i2c0_pins[] = { 2, 3 }; +-static const int i2c1_pins[] = { 14, 15 }; +-static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 }; +-static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 }; +-static const int i2s_pins[] = { 26, 27, 28, 29 }; +-static const int pcm1_pins[] = { 22, 23, 24, 25 }; +-static const int pcm2_pins[] = { 18, 19, 20, 21 }; +-static const int spi_quad_pins[] = { 32, 33 }; +-static const int spi_pins[] = { 4, 5, 6, 7 }; +-static const int spi_cs1_pins[] = { 34 }; +-static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 }; +-static const int pcm_spi_int_pins[] = { 14 }; +-static const int pcm_spi_rst_pins[] = { 15 }; +-static const int pcm_spi_cs1_pins[] = { 43 }; +-static const int pcm_spi_cs2_pins[] = { 40 }; +-static const int pcm_spi_cs2_p128_pins[] = { 40 }; +-static const int pcm_spi_cs2_p156_pins[] = { 40 }; +-static const int pcm_spi_cs3_pins[] = { 41 }; +-static const int pcm_spi_cs4_pins[] = { 42 }; +-static const int emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 }; +-static const int pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 }; +-static const int gpio0_pins[] = { 13 }; +-static const int gpio1_pins[] = { 14 }; +-static const int gpio2_pins[] = { 15 }; +-static const int gpio3_pins[] = { 16 }; +-static const int gpio4_pins[] = { 17 }; +-static const int gpio5_pins[] = { 18 }; +-static const int gpio6_pins[] = { 19 }; +-static const int gpio7_pins[] = { 20 }; +-static const int gpio8_pins[] = { 21 }; +-static const int gpio9_pins[] = { 22 }; +-static const int gpio10_pins[] = { 23 }; +-static const int gpio11_pins[] = { 24 }; +-static const int gpio12_pins[] = { 25 }; +-static const int gpio13_pins[] = { 26 }; +-static const int gpio14_pins[] = { 27 }; +-static const int gpio15_pins[] = { 28 }; +-static const int gpio16_pins[] = { 29 }; +-static const int gpio17_pins[] = { 30 }; +-static const int gpio18_pins[] = { 31 }; +-static const int gpio19_pins[] = { 32 }; +-static const int gpio20_pins[] = { 33 }; +-static const int gpio21_pins[] = { 34 }; +-static const int gpio22_pins[] = { 35 }; +-static const int gpio23_pins[] = { 36 }; +-static const int gpio24_pins[] = { 37 }; +-static const int gpio25_pins[] = { 38 }; +-static const int gpio26_pins[] = { 39 }; +-static const int gpio27_pins[] = { 40 }; +-static const int gpio28_pins[] = { 41 }; +-static const int gpio29_pins[] = { 42 }; +-static const int gpio30_pins[] = { 43 }; +-static const int gpio31_pins[] = { 44 }; +-static const int gpio33_pins[] = { 46 }; +-static const int gpio34_pins[] = { 47 }; +-static const int gpio35_pins[] = { 48 }; +-static const int gpio36_pins[] = { 49 }; +-static const int gpio37_pins[] = { 50 }; +-static const int gpio38_pins[] = { 51 }; +-static const int gpio39_pins[] = { 52 }; +-static const int gpio40_pins[] = { 53 }; +-static const int gpio41_pins[] = { 54 }; +-static const int gpio42_pins[] = { 55 }; +-static const int gpio43_pins[] = { 56 }; +-static const int gpio44_pins[] = { 57 }; +-static const int gpio45_pins[] = { 58 }; +-static const int gpio46_pins[] = { 59 }; +-static const int pcie_reset0_pins[] = { 61 }; +-static const int pcie_reset1_pins[] = { 62 }; +-static const int pcie_reset2_pins[] = { 63 }; +- +-static const struct pingroup airoha_pinctrl_groups[] = { +- PINCTRL_PIN_GROUP(pon), +- PINCTRL_PIN_GROUP(pon_tod_1pps), +- PINCTRL_PIN_GROUP(gsw_tod_1pps), +- PINCTRL_PIN_GROUP(sipo), +- PINCTRL_PIN_GROUP(sipo_rclk), +- PINCTRL_PIN_GROUP(mdio), +- PINCTRL_PIN_GROUP(uart2), +- PINCTRL_PIN_GROUP(uart2_cts_rts), +- PINCTRL_PIN_GROUP(hsuart), +- PINCTRL_PIN_GROUP(hsuart_cts_rts), +- PINCTRL_PIN_GROUP(uart4), +- PINCTRL_PIN_GROUP(uart5), +- PINCTRL_PIN_GROUP(i2c0), +- PINCTRL_PIN_GROUP(i2c1), +- PINCTRL_PIN_GROUP(jtag_udi), +- PINCTRL_PIN_GROUP(jtag_dfd), +- PINCTRL_PIN_GROUP(i2s), +- PINCTRL_PIN_GROUP(pcm1), +- PINCTRL_PIN_GROUP(pcm2), +- PINCTRL_PIN_GROUP(spi), +- PINCTRL_PIN_GROUP(spi_quad), +- PINCTRL_PIN_GROUP(spi_cs1), +- PINCTRL_PIN_GROUP(pcm_spi), +- PINCTRL_PIN_GROUP(pcm_spi_int), +- PINCTRL_PIN_GROUP(pcm_spi_rst), +- PINCTRL_PIN_GROUP(pcm_spi_cs1), +- PINCTRL_PIN_GROUP(pcm_spi_cs2_p128), +- PINCTRL_PIN_GROUP(pcm_spi_cs2_p156), +- PINCTRL_PIN_GROUP(pcm_spi_cs2), +- PINCTRL_PIN_GROUP(pcm_spi_cs3), +- PINCTRL_PIN_GROUP(pcm_spi_cs4), +- PINCTRL_PIN_GROUP(emmc), +- PINCTRL_PIN_GROUP(pnand), +- PINCTRL_PIN_GROUP(gpio0), +- PINCTRL_PIN_GROUP(gpio1), +- PINCTRL_PIN_GROUP(gpio2), +- PINCTRL_PIN_GROUP(gpio3), +- PINCTRL_PIN_GROUP(gpio4), +- PINCTRL_PIN_GROUP(gpio5), +- PINCTRL_PIN_GROUP(gpio6), +- PINCTRL_PIN_GROUP(gpio7), +- PINCTRL_PIN_GROUP(gpio8), +- PINCTRL_PIN_GROUP(gpio9), +- PINCTRL_PIN_GROUP(gpio10), +- PINCTRL_PIN_GROUP(gpio11), +- PINCTRL_PIN_GROUP(gpio12), +- PINCTRL_PIN_GROUP(gpio13), +- PINCTRL_PIN_GROUP(gpio14), +- PINCTRL_PIN_GROUP(gpio15), +- PINCTRL_PIN_GROUP(gpio16), +- PINCTRL_PIN_GROUP(gpio17), +- PINCTRL_PIN_GROUP(gpio18), +- PINCTRL_PIN_GROUP(gpio19), +- PINCTRL_PIN_GROUP(gpio20), +- PINCTRL_PIN_GROUP(gpio21), +- PINCTRL_PIN_GROUP(gpio22), +- PINCTRL_PIN_GROUP(gpio23), +- PINCTRL_PIN_GROUP(gpio24), +- PINCTRL_PIN_GROUP(gpio25), +- PINCTRL_PIN_GROUP(gpio26), +- PINCTRL_PIN_GROUP(gpio27), +- PINCTRL_PIN_GROUP(gpio28), +- PINCTRL_PIN_GROUP(gpio29), +- PINCTRL_PIN_GROUP(gpio30), +- PINCTRL_PIN_GROUP(gpio31), +- PINCTRL_PIN_GROUP(gpio33), +- PINCTRL_PIN_GROUP(gpio34), +- PINCTRL_PIN_GROUP(gpio35), +- PINCTRL_PIN_GROUP(gpio36), +- PINCTRL_PIN_GROUP(gpio37), +- PINCTRL_PIN_GROUP(gpio38), +- PINCTRL_PIN_GROUP(gpio39), +- PINCTRL_PIN_GROUP(gpio40), +- PINCTRL_PIN_GROUP(gpio41), +- PINCTRL_PIN_GROUP(gpio42), +- PINCTRL_PIN_GROUP(gpio43), +- PINCTRL_PIN_GROUP(gpio44), +- PINCTRL_PIN_GROUP(gpio45), +- PINCTRL_PIN_GROUP(gpio46), +- PINCTRL_PIN_GROUP(pcie_reset0), +- PINCTRL_PIN_GROUP(pcie_reset1), +- PINCTRL_PIN_GROUP(pcie_reset2), ++static const int en7581_pon_pins[] = { 49, 50, 51, 52, 53, 54 }; ++static const int en7581_pon_tod_1pps_pins[] = { 46 }; ++static const int en7581_gsw_tod_1pps_pins[] = { 46 }; ++static const int en7581_sipo_pins[] = { 16, 17 }; ++static const int en7581_sipo_rclk_pins[] = { 16, 17, 43 }; ++static const int en7581_mdio_pins[] = { 14, 15 }; ++static const int en7581_uart2_pins[] = { 48, 55 }; ++static const int en7581_uart2_cts_rts_pins[] = { 46, 47 }; ++static const int en7581_hsuart_pins[] = { 28, 29 }; ++static const int en7581_hsuart_cts_rts_pins[] = { 26, 27 }; ++static const int en7581_uart4_pins[] = { 38, 39 }; ++static const int en7581_uart5_pins[] = { 18, 19 }; ++static const int en7581_i2c0_pins[] = { 2, 3 }; ++static const int en7581_i2c1_pins[] = { 14, 15 }; ++static const int en7581_jtag_udi_pins[] = { 16, 17, 18, 19, 20 }; ++static const int en7581_jtag_dfd_pins[] = { 16, 17, 18, 19, 20 }; ++static const int en7581_i2s_pins[] = { 26, 27, 28, 29 }; ++static const int en7581_pcm1_pins[] = { 22, 23, 24, 25 }; ++static const int en7581_pcm2_pins[] = { 18, 19, 20, 21 }; ++static const int en7581_spi_quad_pins[] = { 32, 33 }; ++static const int en7581_spi_pins[] = { 4, 5, 6, 7 }; ++static const int en7581_spi_cs1_pins[] = { 34 }; ++static const int en7581_pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 }; ++static const int en7581_pcm_spi_int_pins[] = { 14 }; ++static const int en7581_pcm_spi_rst_pins[] = { 15 }; ++static const int en7581_pcm_spi_cs1_pins[] = { 43 }; ++static const int en7581_pcm_spi_cs2_pins[] = { 40 }; ++static const int en7581_pcm_spi_cs2_p128_pins[] = { 40 }; ++static const int en7581_pcm_spi_cs2_p156_pins[] = { 40 }; ++static const int en7581_pcm_spi_cs3_pins[] = { 41 }; ++static const int en7581_pcm_spi_cs4_pins[] = { 42 }; ++static const int en7581_emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 }; ++static const int en7581_pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 }; ++static const int en7581_gpio0_pins[] = { 13 }; ++static const int en7581_gpio1_pins[] = { 14 }; ++static const int en7581_gpio2_pins[] = { 15 }; ++static const int en7581_gpio3_pins[] = { 16 }; ++static const int en7581_gpio4_pins[] = { 17 }; ++static const int en7581_gpio5_pins[] = { 18 }; ++static const int en7581_gpio6_pins[] = { 19 }; ++static const int en7581_gpio7_pins[] = { 20 }; ++static const int en7581_gpio8_pins[] = { 21 }; ++static const int en7581_gpio9_pins[] = { 22 }; ++static const int en7581_gpio10_pins[] = { 23 }; ++static const int en7581_gpio11_pins[] = { 24 }; ++static const int en7581_gpio12_pins[] = { 25 }; ++static const int en7581_gpio13_pins[] = { 26 }; ++static const int en7581_gpio14_pins[] = { 27 }; ++static const int en7581_gpio15_pins[] = { 28 }; ++static const int en7581_gpio16_pins[] = { 29 }; ++static const int en7581_gpio17_pins[] = { 30 }; ++static const int en7581_gpio18_pins[] = { 31 }; ++static const int en7581_gpio19_pins[] = { 32 }; ++static const int en7581_gpio20_pins[] = { 33 }; ++static const int en7581_gpio21_pins[] = { 34 }; ++static const int en7581_gpio22_pins[] = { 35 }; ++static const int en7581_gpio23_pins[] = { 36 }; ++static const int en7581_gpio24_pins[] = { 37 }; ++static const int en7581_gpio25_pins[] = { 38 }; ++static const int en7581_gpio26_pins[] = { 39 }; ++static const int en7581_gpio27_pins[] = { 40 }; ++static const int en7581_gpio28_pins[] = { 41 }; ++static const int en7581_gpio29_pins[] = { 42 }; ++static const int en7581_gpio30_pins[] = { 43 }; ++static const int en7581_gpio31_pins[] = { 44 }; ++static const int en7581_gpio33_pins[] = { 46 }; ++static const int en7581_gpio34_pins[] = { 47 }; ++static const int en7581_gpio35_pins[] = { 48 }; ++static const int en7581_gpio36_pins[] = { 49 }; ++static const int en7581_gpio37_pins[] = { 50 }; ++static const int en7581_gpio38_pins[] = { 51 }; ++static const int en7581_gpio39_pins[] = { 52 }; ++static const int en7581_gpio40_pins[] = { 53 }; ++static const int en7581_gpio41_pins[] = { 54 }; ++static const int en7581_gpio42_pins[] = { 55 }; ++static const int en7581_gpio43_pins[] = { 56 }; ++static const int en7581_gpio44_pins[] = { 57 }; ++static const int en7581_gpio45_pins[] = { 58 }; ++static const int en7581_gpio46_pins[] = { 59 }; ++static const int en7581_pcie_reset0_pins[] = { 61 }; ++static const int en7581_pcie_reset1_pins[] = { 62 }; ++static const int en7581_pcie_reset2_pins[] = { 63 }; ++ ++static const struct pingroup en7581_pinctrl_groups[] = { ++ PINCTRL_PIN_GROUP("pon", en7581_pon), ++ PINCTRL_PIN_GROUP("pon_tod_1pps", en7581_pon_tod_1pps), ++ PINCTRL_PIN_GROUP("gsw_tod_1pps", en7581_gsw_tod_1pps), ++ PINCTRL_PIN_GROUP("sipo", en7581_sipo), ++ PINCTRL_PIN_GROUP("sipo_rclk", en7581_sipo_rclk), ++ PINCTRL_PIN_GROUP("mdio", en7581_mdio), ++ PINCTRL_PIN_GROUP("uart2", en7581_uart2), ++ PINCTRL_PIN_GROUP("uart2_cts_rts", en7581_uart2_cts_rts), ++ PINCTRL_PIN_GROUP("hsuart", en7581_hsuart), ++ PINCTRL_PIN_GROUP("hsuart_cts_rts", en7581_hsuart_cts_rts), ++ PINCTRL_PIN_GROUP("uart4", en7581_uart4), ++ PINCTRL_PIN_GROUP("uart5", en7581_uart5), ++ PINCTRL_PIN_GROUP("i2c0", en7581_i2c0), ++ PINCTRL_PIN_GROUP("i2c1", en7581_i2c1), ++ PINCTRL_PIN_GROUP("jtag_udi", en7581_jtag_udi), ++ PINCTRL_PIN_GROUP("jtag_dfd", en7581_jtag_dfd), ++ PINCTRL_PIN_GROUP("i2s", en7581_i2s), ++ PINCTRL_PIN_GROUP("pcm1", en7581_pcm1), ++ PINCTRL_PIN_GROUP("pcm2", en7581_pcm2), ++ PINCTRL_PIN_GROUP("spi", en7581_spi), ++ PINCTRL_PIN_GROUP("spi_quad", en7581_spi_quad), ++ PINCTRL_PIN_GROUP("spi_cs1", en7581_spi_cs1), ++ PINCTRL_PIN_GROUP("pcm_spi", en7581_pcm_spi), ++ PINCTRL_PIN_GROUP("pcm_spi_int", en7581_pcm_spi_int), ++ PINCTRL_PIN_GROUP("pcm_spi_rst", en7581_pcm_spi_rst), ++ PINCTRL_PIN_GROUP("pcm_spi_cs1", en7581_pcm_spi_cs1), ++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", en7581_pcm_spi_cs2_p128), ++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", en7581_pcm_spi_cs2_p156), ++ PINCTRL_PIN_GROUP("pcm_spi_cs2", en7581_pcm_spi_cs2), ++ PINCTRL_PIN_GROUP("pcm_spi_cs3", en7581_pcm_spi_cs3), ++ PINCTRL_PIN_GROUP("pcm_spi_cs4", en7581_pcm_spi_cs4), ++ PINCTRL_PIN_GROUP("emmc", en7581_emmc), ++ PINCTRL_PIN_GROUP("pnand", en7581_pnand), ++ PINCTRL_PIN_GROUP("gpio0", en7581_gpio0), ++ PINCTRL_PIN_GROUP("gpio1", en7581_gpio1), ++ PINCTRL_PIN_GROUP("gpio2", en7581_gpio2), ++ PINCTRL_PIN_GROUP("gpio3", en7581_gpio3), ++ PINCTRL_PIN_GROUP("gpio4", en7581_gpio4), ++ PINCTRL_PIN_GROUP("gpio5", en7581_gpio5), ++ PINCTRL_PIN_GROUP("gpio6", en7581_gpio6), ++ PINCTRL_PIN_GROUP("gpio7", en7581_gpio7), ++ PINCTRL_PIN_GROUP("gpio8", en7581_gpio8), ++ PINCTRL_PIN_GROUP("gpio9", en7581_gpio9), ++ PINCTRL_PIN_GROUP("gpio10", en7581_gpio10), ++ PINCTRL_PIN_GROUP("gpio11", en7581_gpio11), ++ PINCTRL_PIN_GROUP("gpio12", en7581_gpio12), ++ PINCTRL_PIN_GROUP("gpio13", en7581_gpio13), ++ PINCTRL_PIN_GROUP("gpio14", en7581_gpio14), ++ PINCTRL_PIN_GROUP("gpio15", en7581_gpio15), ++ PINCTRL_PIN_GROUP("gpio16", en7581_gpio16), ++ PINCTRL_PIN_GROUP("gpio17", en7581_gpio17), ++ PINCTRL_PIN_GROUP("gpio18", en7581_gpio18), ++ PINCTRL_PIN_GROUP("gpio19", en7581_gpio19), ++ PINCTRL_PIN_GROUP("gpio20", en7581_gpio20), ++ PINCTRL_PIN_GROUP("gpio21", en7581_gpio21), ++ PINCTRL_PIN_GROUP("gpio22", en7581_gpio22), ++ PINCTRL_PIN_GROUP("gpio23", en7581_gpio23), ++ PINCTRL_PIN_GROUP("gpio24", en7581_gpio24), ++ PINCTRL_PIN_GROUP("gpio25", en7581_gpio25), ++ PINCTRL_PIN_GROUP("gpio26", en7581_gpio26), ++ PINCTRL_PIN_GROUP("gpio27", en7581_gpio27), ++ PINCTRL_PIN_GROUP("gpio28", en7581_gpio28), ++ PINCTRL_PIN_GROUP("gpio29", en7581_gpio29), ++ PINCTRL_PIN_GROUP("gpio30", en7581_gpio30), ++ PINCTRL_PIN_GROUP("gpio31", en7581_gpio31), ++ PINCTRL_PIN_GROUP("gpio33", en7581_gpio33), ++ PINCTRL_PIN_GROUP("gpio34", en7581_gpio34), ++ PINCTRL_PIN_GROUP("gpio35", en7581_gpio35), ++ PINCTRL_PIN_GROUP("gpio36", en7581_gpio36), ++ PINCTRL_PIN_GROUP("gpio37", en7581_gpio37), ++ PINCTRL_PIN_GROUP("gpio38", en7581_gpio38), ++ PINCTRL_PIN_GROUP("gpio39", en7581_gpio39), ++ PINCTRL_PIN_GROUP("gpio40", en7581_gpio40), ++ PINCTRL_PIN_GROUP("gpio41", en7581_gpio41), ++ PINCTRL_PIN_GROUP("gpio42", en7581_gpio42), ++ PINCTRL_PIN_GROUP("gpio43", en7581_gpio43), ++ PINCTRL_PIN_GROUP("gpio44", en7581_gpio44), ++ PINCTRL_PIN_GROUP("gpio45", en7581_gpio45), ++ PINCTRL_PIN_GROUP("gpio46", en7581_gpio46), ++ PINCTRL_PIN_GROUP("pcie_reset0", en7581_pcie_reset0), ++ PINCTRL_PIN_GROUP("pcie_reset1", en7581_pcie_reset1), ++ PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2), + }; + + static const char *const pon_groups[] = { "pon" }; +@@ -1960,33 +1990,33 @@ static const struct airoha_pinctrl_func_ + }, + }; + +-static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = { +- PINCTRL_FUNC_DESC(pon), +- PINCTRL_FUNC_DESC(tod_1pps), +- PINCTRL_FUNC_DESC(sipo), +- PINCTRL_FUNC_DESC(mdio), +- PINCTRL_FUNC_DESC(uart), +- PINCTRL_FUNC_DESC(i2c), +- PINCTRL_FUNC_DESC(jtag), +- PINCTRL_FUNC_DESC(pcm), +- PINCTRL_FUNC_DESC(spi), +- PINCTRL_FUNC_DESC(pcm_spi), +- PINCTRL_FUNC_DESC(i2s), +- PINCTRL_FUNC_DESC(emmc), +- PINCTRL_FUNC_DESC(pnand), +- PINCTRL_FUNC_DESC(pcie_reset), +- PINCTRL_FUNC_DESC(pwm), +- PINCTRL_FUNC_DESC(phy1_led0), +- PINCTRL_FUNC_DESC(phy2_led0), +- PINCTRL_FUNC_DESC(phy3_led0), +- PINCTRL_FUNC_DESC(phy4_led0), +- PINCTRL_FUNC_DESC(phy1_led1), +- PINCTRL_FUNC_DESC(phy2_led1), +- PINCTRL_FUNC_DESC(phy3_led1), +- PINCTRL_FUNC_DESC(phy4_led1), ++static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { ++ PINCTRL_FUNC_DESC("pon", pon), ++ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), ++ PINCTRL_FUNC_DESC("sipo", sipo), ++ PINCTRL_FUNC_DESC("mdio", mdio), ++ PINCTRL_FUNC_DESC("uart", uart), ++ PINCTRL_FUNC_DESC("i2c", i2c), ++ PINCTRL_FUNC_DESC("jtag", jtag), ++ PINCTRL_FUNC_DESC("pcm", pcm), ++ PINCTRL_FUNC_DESC("spi", spi), ++ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi), ++ PINCTRL_FUNC_DESC("i2s", i2s), ++ PINCTRL_FUNC_DESC("emmc", emmc), ++ PINCTRL_FUNC_DESC("pnand", pnand), ++ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset), ++ PINCTRL_FUNC_DESC("pwm", pwm), ++ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0), ++ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0), ++ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0), ++ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0), ++ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1), ++ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1), ++ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1), ++ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1), + }; + +-static const struct airoha_pinctrl_conf airoha_pinctrl_pullup_conf[] = { ++static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), + PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), +@@ -2047,7 +2077,7 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), + }; + +-static const struct airoha_pinctrl_conf airoha_pinctrl_pulldown_conf[] = { ++static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), + PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), +@@ -2108,7 +2138,7 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), + }; + +-static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e2_conf[] = { ++static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), + PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), +@@ -2169,7 +2199,7 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), + }; + +-static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e4_conf[] = { ++static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), + PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), +@@ -2230,7 +2260,7 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), + }; + +-static const struct airoha_pinctrl_conf airoha_pinctrl_pcie_rst_od_conf[] = { ++static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = { + PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), + PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), + PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), +@@ -2552,12 +2582,17 @@ airoha_pinctrl_get_conf_reg(const struct + } + + static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl, +- const struct airoha_pinctrl_conf *conf, +- int conf_size, int pin, u32 *val) ++ enum airoha_pinctrl_confs_type conf_type, ++ int pin, u32 *val) + { ++ const struct airoha_pinctrl_confs_info *confs_info; + const struct airoha_pinctrl_reg *reg; + +- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); ++ confs_info = &pinctrl->confs_info[conf_type]; ++ ++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs, ++ confs_info->num_confs, ++ pin); + if (!reg) + return -EINVAL; + +@@ -2570,12 +2605,17 @@ static int airoha_pinctrl_get_conf(struc + } + + static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl, +- const struct airoha_pinctrl_conf *conf, +- int conf_size, int pin, u32 val) ++ enum airoha_pinctrl_confs_type conf_type, ++ int pin, u32 val) + { ++ const struct airoha_pinctrl_confs_info *confs_info; + const struct airoha_pinctrl_reg *reg = NULL; + +- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); ++ confs_info = &pinctrl->confs_info[conf_type]; ++ ++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs, ++ confs_info->num_confs, ++ pin); + if (!reg) + return -EINVAL; + +@@ -2588,44 +2628,34 @@ static int airoha_pinctrl_set_conf(struc + } + + #define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \ +- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pullup_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ ++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \ + (pin), (val)) + #define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \ +- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ ++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \ + (pin), (val)) + #define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \ +- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ +- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ ++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \ + (pin), (val)) + #define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \ +- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ +- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ ++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \ + (pin), (val)) + #define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \ +- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ ++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \ + (pin), (val)) + #define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \ +- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pullup_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ ++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \ + (pin), (val)) + #define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \ +- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ ++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \ + (pin), (val)) + #define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \ +- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ +- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ ++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \ + (pin), (val)) + #define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \ +- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ +- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ ++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \ + (pin), (val)) + #define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \ +- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ +- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ ++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \ + (pin), (val)) + + static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p) +@@ -2804,12 +2834,13 @@ static int airoha_pinconf_set(struct pin + static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev, + unsigned int group, unsigned long *config) + { ++ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 cur_config = 0; + int i; + +- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { ++ for (i = 0; i < pinctrl->grps[group].npins; i++) { + if (airoha_pinconf_get(pctrl_dev, +- airoha_pinctrl_groups[group].pins[i], ++ pinctrl->grps[group].pins[i], + config)) + return -ENOTSUPP; + +@@ -2826,13 +2857,14 @@ static int airoha_pinconf_group_set(stru + unsigned int group, unsigned long *configs, + unsigned int num_configs) + { ++ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + int i; + +- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { ++ for (i = 0; i < pinctrl->grps[group].npins; i++) { + int err; + + err = airoha_pinconf_set(pctrl_dev, +- airoha_pinctrl_groups[group].pins[i], ++ pinctrl->grps[group].pins[i], + configs, num_configs); + if (err) + return err; +@@ -2858,23 +2890,16 @@ static const struct pinctrl_ops airoha_p + .dt_free_map = pinconf_generic_dt_free_map, + }; + +-static struct pinctrl_desc airoha_pinctrl_desc = { +- .name = KBUILD_MODNAME, +- .owner = THIS_MODULE, +- .pctlops = &airoha_pctlops, +- .pmxops = &airoha_pmxops, +- .confops = &airoha_confops, +- .pins = airoha_pinctrl_pins, +- .npins = ARRAY_SIZE(airoha_pinctrl_pins), +-}; +- + static int airoha_pinctrl_probe(struct platform_device *pdev) + { ++ const struct airoha_pinctrl_match_data *data; + struct device *dev = &pdev->dev; + struct airoha_pinctrl *pinctrl; + struct regmap *map; + int err, i; + ++ data = device_get_match_data(dev); ++ + pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL); + if (!pinctrl) + return -ENOMEM; +@@ -2889,14 +2914,23 @@ static int airoha_pinctrl_probe(struct p + + pinctrl->chip_scu = map; + +- err = devm_pinctrl_register_and_init(dev, &airoha_pinctrl_desc, ++ /* Init pinctrl desc struct */ ++ pinctrl->desc.name = KBUILD_MODNAME; ++ pinctrl->desc.owner = THIS_MODULE, ++ pinctrl->desc.pctlops = &airoha_pctlops, ++ pinctrl->desc.pmxops = &airoha_pmxops, ++ pinctrl->desc.confops = &airoha_confops, ++ pinctrl->desc.pins = data->pins, ++ pinctrl->desc.npins = data->num_pins, ++ ++ err = devm_pinctrl_register_and_init(dev, &pinctrl->desc, + pinctrl, &pinctrl->ctrl); + if (err) + return err; + + /* build pin groups */ +- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_groups); i++) { +- const struct pingroup *grp = &airoha_pinctrl_groups[i]; ++ for (i = 0; i < data->num_grps; i++) { ++ const struct pingroup *grp = &data->grps[i]; + + err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name, + grp->pins, grp->npins, +@@ -2909,10 +2943,10 @@ static int airoha_pinctrl_probe(struct p + } + + /* build functions */ +- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_funcs); i++) { ++ for (i = 0; i < data->num_funcs; i++) { + const struct airoha_pinctrl_func *func; + +- func = &airoha_pinctrl_funcs[i]; ++ func = &data->funcs[i]; + err = pinmux_generic_add_function(pinctrl->ctrl, + func->desc.func.name, + func->desc.func.groups, +@@ -2925,6 +2959,10 @@ static int airoha_pinctrl_probe(struct p + } + } + ++ pinctrl->grps = data->grps; ++ pinctrl->funcs = data->funcs; ++ pinctrl->confs_info = data->confs_info; ++ + err = pinctrl_enable(pinctrl->ctrl); + if (err) + return err; +@@ -2933,8 +2971,39 @@ static int airoha_pinctrl_probe(struct p + return airoha_pinctrl_add_gpiochip(pinctrl, pdev); + } + ++static const struct airoha_pinctrl_match_data en7581_pinctrl_match_data = { ++ .pins = en7581_pinctrl_pins, ++ .num_pins = ARRAY_SIZE(en7581_pinctrl_pins), ++ .grps = en7581_pinctrl_groups, ++ .num_grps = ARRAY_SIZE(en7581_pinctrl_groups), ++ .funcs = en7581_pinctrl_funcs, ++ .num_funcs = ARRAY_SIZE(en7581_pinctrl_funcs), ++ .confs_info = { ++ [AIROHA_PINCTRL_CONFS_PULLUP] = { ++ .confs = en7581_pinctrl_pullup_conf, ++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pullup_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = { ++ .confs = en7581_pinctrl_pulldown_conf, ++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pulldown_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = { ++ .confs = en7581_pinctrl_drive_e2_conf, ++ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e2_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = { ++ .confs = en7581_pinctrl_drive_e4_conf, ++ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e4_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = { ++ .confs = en7581_pinctrl_pcie_rst_od_conf, ++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pcie_rst_od_conf), ++ }, ++ }, ++}; ++ + static const struct of_device_id airoha_pinctrl_of_match[] = { +- { .compatible = "airoha,en7581-pinctrl" }, ++ { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match); diff --git a/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch b/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch new file mode 100644 index 0000000000..df1d96699e --- /dev/null +++ b/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch @@ -0,0 +1,616 @@ +From ee980d96b6ecd385691f101e641f3e15513ce8c3 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 25 May 2025 20:28:34 +0200 +Subject: [PATCH 3/5] pinctrl: airoha: convert PHY LED GPIO to macro + +PHY LED GPIO pinctrl struct definition is very similar across the +different 4 PHY and 2 LED and it can be generelized to a macro. + +To reduce code size, convert them to a common macro. + +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 570 ++++------------------ + 1 file changed, 82 insertions(+), 488 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -1478,516 +1478,110 @@ static const struct airoha_pinctrl_func_ + }, + }; + ++#define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \ ++ { \ ++ .name = (gpio), \ ++ .regmap[0] = { \ ++ AIROHA_FUNC_MUX, \ ++ REG_GPIO_2ND_I2C_MODE, \ ++ (mux_val), \ ++ (mux_val), \ ++ }, \ ++ .regmap[1] = { \ ++ AIROHA_FUNC_MUX, \ ++ REG_LAN_LED0_MAPPING, \ ++ (map_mask), \ ++ (map_val), \ ++ }, \ ++ .regmap_size = 2, \ ++ } ++ + static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = { +- { +- .name = "gpio33", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED0_MODE_MASK, +- GPIO_LAN0_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio34", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED0_MODE_MASK, +- GPIO_LAN1_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio35", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED0_MODE_MASK, +- GPIO_LAN2_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio42", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), + }; + + static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = { +- { +- .name = "gpio33", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED0_MODE_MASK, +- GPIO_LAN0_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio34", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED0_MODE_MASK, +- GPIO_LAN1_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio35", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED0_MODE_MASK, +- GPIO_LAN2_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio42", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), + }; + + static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = { +- { +- .name = "gpio33", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED0_MODE_MASK, +- GPIO_LAN0_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio34", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED0_MODE_MASK, +- GPIO_LAN1_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio35", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED0_MODE_MASK, +- GPIO_LAN2_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio42", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), + }; + + static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = { +- { +- .name = "gpio33", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED0_MODE_MASK, +- GPIO_LAN0_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio34", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED0_MODE_MASK, +- GPIO_LAN1_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio35", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED0_MODE_MASK, +- GPIO_LAN2_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio42", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED0_MODE_MASK, +- GPIO_LAN3_LED0_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED0_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), + }; + + static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = { +- { +- .name = "gpio43", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED1_MODE_MASK, +- GPIO_LAN0_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio44", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED1_MODE_MASK, +- GPIO_LAN1_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio45", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED1_MODE_MASK, +- GPIO_LAN2_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio46", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED1_MODE_MASK, +- GPIO_LAN3_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(0) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), + }; + + static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = { +- { +- .name = "gpio43", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED1_MODE_MASK, +- GPIO_LAN0_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio44", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED1_MODE_MASK, +- GPIO_LAN1_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio45", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED1_MODE_MASK, +- GPIO_LAN2_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio46", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED1_MODE_MASK, +- GPIO_LAN3_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(1) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), + }; + + static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = { +- { +- .name = "gpio43", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED1_MODE_MASK, +- GPIO_LAN0_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio44", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED1_MODE_MASK, +- GPIO_LAN1_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio45", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED1_MODE_MASK, +- GPIO_LAN2_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio46", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED1_MODE_MASK, +- GPIO_LAN3_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(2) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), + }; + + static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = { +- { +- .name = "gpio43", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN0_LED1_MODE_MASK, +- GPIO_LAN0_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN0_LED_MAPPING_MASK, +- LAN0_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio44", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN1_LED1_MODE_MASK, +- GPIO_LAN1_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN1_LED_MAPPING_MASK, +- LAN1_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio45", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN2_LED1_MODE_MASK, +- GPIO_LAN2_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN2_LED_MAPPING_MASK, +- LAN2_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, { +- .name = "gpio46", +- .regmap[0] = { +- AIROHA_FUNC_MUX, +- REG_GPIO_2ND_I2C_MODE, +- GPIO_LAN3_LED1_MODE_MASK, +- GPIO_LAN3_LED1_MODE_MASK +- }, +- .regmap[1] = { +- AIROHA_FUNC_MUX, +- REG_LAN_LED1_MAPPING, +- LAN3_LED_MAPPING_MASK, +- LAN3_PHY_LED_MAP(3) +- }, +- .regmap_size = 2, +- }, ++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), + }; + + static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { diff --git a/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch b/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch new file mode 100644 index 0000000000..e541cdd610 --- /dev/null +++ b/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch @@ -0,0 +1,491 @@ +From 83c79d127c610063e1b86c3f7f8d5e0145ffe9c6 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 25 May 2025 20:43:47 +0200 +Subject: [PATCH 4/5] pinctrl: airoha: convert PWM GPIO to macro + +The PWM GPIO struct definition follow the same pattern for every GPIO +pin hence it can be converted to a macro. + +Create 2 macro one for normal mux and one for ext mux and convert all +the entry to these new macro to reduce code size. + +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 465 ++++------------------ + 1 file changed, 68 insertions(+), 397 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -1078,404 +1078,75 @@ static const struct airoha_pinctrl_func_ + }; + + /* PWM */ ++#define AIROHA_PINCTRL_PWM(gpio, mux_val) \ ++ { \ ++ .name = (gpio), \ ++ .regmap[0] = { \ ++ AIROHA_FUNC_PWM_MUX, \ ++ REG_GPIO_FLASH_MODE_CFG, \ ++ (mux_val), \ ++ (mux_val) \ ++ }, \ ++ .regmap_size = 1, \ ++ } \ ++ ++#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \ ++ { \ ++ .name = (gpio), \ ++ .regmap[0] = { \ ++ AIROHA_FUNC_PWM_EXT_MUX, \ ++ REG_GPIO_FLASH_MODE_CFG_EXT, \ ++ (mux_val), \ ++ (mux_val) \ ++ }, \ ++ .regmap_size = 1, \ ++ } \ ++ + static const struct airoha_pinctrl_func_group pwm_func_group[] = { +- { +- .name = "gpio0", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO0_FLASH_MODE_CFG, +- GPIO0_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio1", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO1_FLASH_MODE_CFG, +- GPIO1_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio2", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO2_FLASH_MODE_CFG, +- GPIO2_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio3", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO3_FLASH_MODE_CFG, +- GPIO3_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio4", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO4_FLASH_MODE_CFG, +- GPIO4_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio5", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO5_FLASH_MODE_CFG, +- GPIO5_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio6", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO6_FLASH_MODE_CFG, +- GPIO6_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio7", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO7_FLASH_MODE_CFG, +- GPIO7_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio8", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO8_FLASH_MODE_CFG, +- GPIO8_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio9", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO9_FLASH_MODE_CFG, +- GPIO9_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio10", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO10_FLASH_MODE_CFG, +- GPIO10_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio11", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO11_FLASH_MODE_CFG, +- GPIO11_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio12", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO12_FLASH_MODE_CFG, +- GPIO12_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio13", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO13_FLASH_MODE_CFG, +- GPIO13_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio14", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO14_FLASH_MODE_CFG, +- GPIO14_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio15", +- .regmap[0] = { +- AIROHA_FUNC_PWM_MUX, +- REG_GPIO_FLASH_MODE_CFG, +- GPIO15_FLASH_MODE_CFG, +- GPIO15_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio16", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO16_FLASH_MODE_CFG, +- GPIO16_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio17", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO17_FLASH_MODE_CFG, +- GPIO17_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio18", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO18_FLASH_MODE_CFG, +- GPIO18_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio19", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO19_FLASH_MODE_CFG, +- GPIO19_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio20", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO20_FLASH_MODE_CFG, +- GPIO20_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio21", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO21_FLASH_MODE_CFG, +- GPIO21_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio22", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO22_FLASH_MODE_CFG, +- GPIO22_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio23", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO23_FLASH_MODE_CFG, +- GPIO23_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio24", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO24_FLASH_MODE_CFG, +- GPIO24_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio25", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO25_FLASH_MODE_CFG, +- GPIO25_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio26", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO26_FLASH_MODE_CFG, +- GPIO26_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio27", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO27_FLASH_MODE_CFG, +- GPIO27_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio28", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO28_FLASH_MODE_CFG, +- GPIO28_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio29", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO29_FLASH_MODE_CFG, +- GPIO29_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio30", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO30_FLASH_MODE_CFG, +- GPIO30_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio31", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO31_FLASH_MODE_CFG, +- GPIO31_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio36", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO36_FLASH_MODE_CFG, +- GPIO36_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio37", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO37_FLASH_MODE_CFG, +- GPIO37_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio38", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO38_FLASH_MODE_CFG, +- GPIO38_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio39", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO39_FLASH_MODE_CFG, +- GPIO39_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio40", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO40_FLASH_MODE_CFG, +- GPIO40_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio41", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO41_FLASH_MODE_CFG, +- GPIO41_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio42", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO42_FLASH_MODE_CFG, +- GPIO42_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio43", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO43_FLASH_MODE_CFG, +- GPIO43_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio44", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO44_FLASH_MODE_CFG, +- GPIO44_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio45", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO45_FLASH_MODE_CFG, +- GPIO45_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio46", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO46_FLASH_MODE_CFG, +- GPIO46_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, { +- .name = "gpio47", +- .regmap[0] = { +- AIROHA_FUNC_PWM_EXT_MUX, +- REG_GPIO_FLASH_MODE_CFG_EXT, +- GPIO47_FLASH_MODE_CFG, +- GPIO47_FLASH_MODE_CFG +- }, +- .regmap_size = 1, +- }, ++ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio28", GPIO28_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio29", GPIO29_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio30", GPIO30_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio31", GPIO31_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio36", GPIO36_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio37", GPIO37_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio38", GPIO38_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio39", GPIO39_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio40", GPIO40_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio41", GPIO41_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio42", GPIO42_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio43", GPIO43_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio44", GPIO44_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio45", GPIO45_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio46", GPIO46_FLASH_MODE_CFG), ++ AIROHA_PINCTRL_PWM_EXT("gpio47", GPIO47_FLASH_MODE_CFG), + }; + + #define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \ diff --git a/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch b/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch new file mode 100644 index 0000000000..37d3b29f2d --- /dev/null +++ b/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch @@ -0,0 +1,919 @@ +From cc92581b44cc3a6821c540ddbe27d4c009a7d312 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 25 May 2025 21:32:25 +0200 +Subject: [PATCH 5/5] pinctrl: airoha: add support for Airoha AN7583 PINs + +Add all the required entry to add suppot for Airoha AN7583 PINs. + +Where possible the same function group are used from Airoha EN7581 to +reduce code duplication. + +Signed-off-by: Christian Marangi +--- + drivers/pinctrl/mediatek/pinctrl-airoha.c | 733 ++++++++++++++++++++++ + 1 file changed, 733 insertions(+) + +--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c ++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c +@@ -75,6 +75,7 @@ + #define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20) + #define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19) + #define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18) ++#define AN7583_GPIO_PCM_SPI_CS2_MODE_MASK BIT(18) + #define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17) + #define GPIO_PCM_SPI_MODE_MASK BIT(16) + #define GPIO_PCM2_MODE_MASK BIT(13) +@@ -132,6 +133,8 @@ + + /* CONF */ + #define REG_I2C_SDA_E2 0x001c ++#define AN7583_I2C1_SCL_E2_MASK BIT(16) ++#define AN7583_I2C1_SDA_E2_MASK BIT(15) + #define SPI_MISO_E2_MASK BIT(14) + #define SPI_MOSI_E2_MASK BIT(13) + #define SPI_CLK_E2_MASK BIT(12) +@@ -139,12 +142,16 @@ + #define PCIE2_RESET_E2_MASK BIT(10) + #define PCIE1_RESET_E2_MASK BIT(9) + #define PCIE0_RESET_E2_MASK BIT(8) ++#define AN7583_MDIO_0_E2_MASK BIT(5) ++#define AN7583_MDC_0_E2_MASK BIT(4) + #define UART1_RXD_E2_MASK BIT(3) + #define UART1_TXD_E2_MASK BIT(2) + #define I2C_SCL_E2_MASK BIT(1) + #define I2C_SDA_E2_MASK BIT(0) + + #define REG_I2C_SDA_E4 0x0020 ++#define AN7583_I2C1_SCL_E4_MASK BIT(16) ++#define AN7583_I2C1_SDA_E4_MASK BIT(15) + #define SPI_MISO_E4_MASK BIT(14) + #define SPI_MOSI_E4_MASK BIT(13) + #define SPI_CLK_E4_MASK BIT(12) +@@ -152,6 +159,8 @@ + #define PCIE2_RESET_E4_MASK BIT(10) + #define PCIE1_RESET_E4_MASK BIT(9) + #define PCIE0_RESET_E4_MASK BIT(8) ++#define AN7583_MDIO_0_E4_MASK BIT(5) ++#define AN7583_MDC_0_E4_MASK BIT(4) + #define UART1_RXD_E4_MASK BIT(3) + #define UART1_TXD_E4_MASK BIT(2) + #define I2C_SCL_E4_MASK BIT(1) +@@ -163,6 +172,8 @@ + #define REG_GPIO_H_E4 0x0030 + + #define REG_I2C_SDA_PU 0x0044 ++#define AN7583_I2C1_SCL_PU_MASK BIT(16) ++#define AN7583_I2C1_SDA_PU_MASK BIT(15) + #define SPI_MISO_PU_MASK BIT(14) + #define SPI_MOSI_PU_MASK BIT(13) + #define SPI_CLK_PU_MASK BIT(12) +@@ -170,12 +181,16 @@ + #define PCIE2_RESET_PU_MASK BIT(10) + #define PCIE1_RESET_PU_MASK BIT(9) + #define PCIE0_RESET_PU_MASK BIT(8) ++#define AN7583_MDIO_0_PU_MASK BIT(5) ++#define AN7583_MDC_0_PU_MASK BIT(4) + #define UART1_RXD_PU_MASK BIT(3) + #define UART1_TXD_PU_MASK BIT(2) + #define I2C_SCL_PU_MASK BIT(1) + #define I2C_SDA_PU_MASK BIT(0) + + #define REG_I2C_SDA_PD 0x0048 ++#define AN7583_I2C1_SDA_PD_MASK BIT(16) ++#define AN7583_I2C1_SCL_PD_MASK BIT(15) + #define SPI_MISO_PD_MASK BIT(14) + #define SPI_MOSI_PD_MASK BIT(13) + #define SPI_CLK_PD_MASK BIT(12) +@@ -183,6 +198,8 @@ + #define PCIE2_RESET_PD_MASK BIT(10) + #define PCIE1_RESET_PD_MASK BIT(9) + #define PCIE0_RESET_PD_MASK BIT(8) ++#define AN7583_MDIO_0_PD_MASK BIT(5) ++#define AN7583_MDC_0_PD_MASK BIT(4) + #define UART1_RXD_PD_MASK BIT(3) + #define UART1_TXD_PD_MASK BIT(2) + #define I2C_SCL_PD_MASK BIT(1) +@@ -630,10 +647,223 @@ static const struct pingroup en7581_pinc + PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2), + }; + ++static struct pinctrl_pin_desc an7583_pinctrl_pins[] = { ++ PINCTRL_PIN(2, "gpio0"), ++ PINCTRL_PIN(3, "gpio1"), ++ PINCTRL_PIN(4, "gpio2"), ++ PINCTRL_PIN(5, "gpio3"), ++ PINCTRL_PIN(6, "gpio4"), ++ PINCTRL_PIN(7, "gpio5"), ++ PINCTRL_PIN(8, "gpio6"), ++ PINCTRL_PIN(9, "gpio7"), ++ PINCTRL_PIN(10, "gpio8"), ++ PINCTRL_PIN(11, "gpio9"), ++ PINCTRL_PIN(12, "gpio10"), ++ PINCTRL_PIN(13, "gpio11"), ++ PINCTRL_PIN(14, "gpio12"), ++ PINCTRL_PIN(15, "gpio13"), ++ PINCTRL_PIN(16, "gpio14"), ++ PINCTRL_PIN(17, "gpio15"), ++ PINCTRL_PIN(18, "gpio16"), ++ PINCTRL_PIN(19, "gpio17"), ++ PINCTRL_PIN(20, "gpio18"), ++ PINCTRL_PIN(21, "gpio19"), ++ PINCTRL_PIN(22, "gpio20"), ++ PINCTRL_PIN(23, "gpio21"), ++ PINCTRL_PIN(24, "gpio22"), ++ PINCTRL_PIN(25, "gpio23"), ++ PINCTRL_PIN(26, "gpio24"), ++ PINCTRL_PIN(27, "gpio25"), ++ PINCTRL_PIN(28, "gpio26"), ++ PINCTRL_PIN(29, "gpio27"), ++ PINCTRL_PIN(30, "gpio28"), ++ PINCTRL_PIN(31, "gpio29"), ++ PINCTRL_PIN(32, "gpio30"), ++ PINCTRL_PIN(33, "gpio31"), ++ PINCTRL_PIN(34, "gpio32"), ++ PINCTRL_PIN(35, "gpio33"), ++ PINCTRL_PIN(36, "gpio34"), ++ PINCTRL_PIN(37, "gpio35"), ++ PINCTRL_PIN(38, "gpio36"), ++ PINCTRL_PIN(39, "gpio37"), ++ PINCTRL_PIN(40, "gpio38"), ++ PINCTRL_PIN(41, "i2c0_scl"), ++ PINCTRL_PIN(42, "i2c0_sda"), ++ PINCTRL_PIN(43, "i2c1_scl"), ++ PINCTRL_PIN(44, "i2c1_sda"), ++ PINCTRL_PIN(45, "spi_clk"), ++ PINCTRL_PIN(46, "spi_cs"), ++ PINCTRL_PIN(47, "spi_mosi"), ++ PINCTRL_PIN(48, "spi_miso"), ++ PINCTRL_PIN(49, "uart_txd"), ++ PINCTRL_PIN(50, "uart_rxd"), ++ PINCTRL_PIN(51, "pcie_reset0"), ++ PINCTRL_PIN(52, "pcie_reset1"), ++ PINCTRL_PIN(53, "mdc_0"), ++ PINCTRL_PIN(54, "mdio_0"), ++}; ++ ++static const int an7583_pon_pins[] = { 15, 16, 17, 18, 19, 20 }; ++static const int an7583_pon_tod_1pps_pins[] = { 32 }; ++static const int an7583_gsw_tod_1pps_pins[] = { 32 }; ++static const int an7583_sipo_pins[] = { 34, 35 }; ++static const int an7583_sipo_rclk_pins[] = { 34, 35, 33 }; ++static const int an7583_mdio_pins[] = { 43, 44 }; ++static const int an7583_uart2_pins[] = { 34, 35 }; ++static const int an7583_uart2_cts_rts_pins[] = { 32, 33 }; ++static const int an7583_hsuart_pins[] = { 30, 31 }; ++static const int an7583_hsuart_cts_rts_pins[] = { 28, 29 }; ++static const int an7583_npu_uart_pins[] = { 7, 8 }; ++static const int an7583_uart4_pins[] = { 7, 8 }; ++static const int an7583_uart5_pins[] = { 23, 24 }; ++static const int an7583_i2c0_pins[] = { 41, 42 }; ++static const int an7583_i2c1_pins[] = { 43, 44 }; ++static const int an7583_jtag_udi_pins[] = { 23, 24, 22, 25, 26 }; ++static const int an7583_jtag_dfd_pins[] = { 23, 24, 22, 25, 26 }; ++static const int an7583_pcm1_pins[] = { 10, 11, 12, 13, 14 }; ++static const int an7583_pcm2_pins[] = { 28, 29, 30, 31, 24 }; ++static const int an7583_spi_pins[] = { 28, 29, 30, 31 }; ++static const int an7583_spi_quad_pins[] = { 25, 26 }; ++static const int an7583_spi_cs1_pins[] = { 27 }; ++static const int an7583_pcm_spi_pins[] = { 28, 29, 30, 31, 10, 11, 12, 13 }; ++static const int an7583_pcm_spi_rst_pins[] = { 14 }; ++static const int an7583_pcm_spi_cs1_pins[] = { 24 }; ++static const int an7583_emmc_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 45, 46, 47 }; ++static const int an7583_pnand_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 45, 46, 47, 48 }; ++static const int an7583_gpio0_pins[] = { 2 }; ++static const int an7583_gpio1_pins[] = { 3 }; ++static const int an7583_gpio2_pins[] = { 4 }; ++static const int an7583_gpio3_pins[] = { 5 }; ++static const int an7583_gpio4_pins[] = { 6 }; ++static const int an7583_gpio5_pins[] = { 7 }; ++static const int an7583_gpio6_pins[] = { 8 }; ++static const int an7583_gpio7_pins[] = { 9 }; ++static const int an7583_gpio8_pins[] = { 10 }; ++static const int an7583_gpio9_pins[] = { 11 }; ++static const int an7583_gpio10_pins[] = { 12 }; ++static const int an7583_gpio11_pins[] = { 13 }; ++static const int an7583_gpio12_pins[] = { 14 }; ++static const int an7583_gpio13_pins[] = { 15 }; ++static const int an7583_gpio14_pins[] = { 16 }; ++static const int an7583_gpio15_pins[] = { 17 }; ++static const int an7583_gpio16_pins[] = { 18 }; ++static const int an7583_gpio17_pins[] = { 19 }; ++static const int an7583_gpio18_pins[] = { 20 }; ++static const int an7583_gpio19_pins[] = { 21 }; ++static const int an7583_gpio20_pins[] = { 22 }; ++static const int an7583_gpio21_pins[] = { 24 }; ++static const int an7583_gpio23_pins[] = { 25 }; ++static const int an7583_gpio24_pins[] = { 26 }; ++static const int an7583_gpio25_pins[] = { 27 }; ++static const int an7583_gpio26_pins[] = { 28 }; ++static const int an7583_gpio27_pins[] = { 29 }; ++static const int an7583_gpio28_pins[] = { 30 }; ++static const int an7583_gpio29_pins[] = { 31 }; ++static const int an7583_gpio30_pins[] = { 32 }; ++static const int an7583_gpio31_pins[] = { 33 }; ++static const int an7583_gpio33_pins[] = { 35 }; ++static const int an7583_gpio34_pins[] = { 36 }; ++static const int an7583_gpio35_pins[] = { 37 }; ++static const int an7583_gpio36_pins[] = { 38 }; ++static const int an7583_gpio37_pins[] = { 39 }; ++static const int an7583_gpio38_pins[] = { 40 }; ++static const int an7583_gpio39_pins[] = { 41 }; ++static const int an7583_gpio40_pins[] = { 42 }; ++static const int an7583_gpio41_pins[] = { 43 }; ++static const int an7583_gpio42_pins[] = { 44 }; ++static const int an7583_gpio43_pins[] = { 45 }; ++static const int an7583_gpio44_pins[] = { 46 }; ++static const int an7583_gpio45_pins[] = { 47 }; ++static const int an7583_gpio46_pins[] = { 48 }; ++static const int an7583_gpio47_pins[] = { 49 }; ++static const int an7583_gpio48_pins[] = { 50 }; ++static const int an7583_pcie_reset0_pins[] = { 51 }; ++static const int an7583_pcie_reset1_pins[] = { 52 }; ++ ++static const struct pingroup an7583_pinctrl_groups[] = { ++ PINCTRL_PIN_GROUP("pon", an7583_pon), ++ PINCTRL_PIN_GROUP("pon_tod_1pps", an7583_pon_tod_1pps), ++ PINCTRL_PIN_GROUP("gsw_tod_1pps", an7583_gsw_tod_1pps), ++ PINCTRL_PIN_GROUP("sipo", an7583_sipo), ++ PINCTRL_PIN_GROUP("sipo_rclk", an7583_sipo_rclk), ++ PINCTRL_PIN_GROUP("mdio", an7583_mdio), ++ PINCTRL_PIN_GROUP("uart2", an7583_uart2), ++ PINCTRL_PIN_GROUP("uart2_cts_rts", an7583_uart2_cts_rts), ++ PINCTRL_PIN_GROUP("hsuart", an7583_hsuart), ++ PINCTRL_PIN_GROUP("hsuart_cts_rts", an7583_hsuart_cts_rts), ++ PINCTRL_PIN_GROUP("npu_uart", an7583_npu_uart), ++ PINCTRL_PIN_GROUP("uart4", an7583_uart4), ++ PINCTRL_PIN_GROUP("uart5", an7583_uart5), ++ PINCTRL_PIN_GROUP("i2c0", an7583_i2c0), ++ PINCTRL_PIN_GROUP("i2c1", an7583_i2c1), ++ PINCTRL_PIN_GROUP("jtag_udi", an7583_jtag_udi), ++ PINCTRL_PIN_GROUP("jtag_dfd", an7583_jtag_dfd), ++ PINCTRL_PIN_GROUP("pcm1", an7583_pcm1), ++ PINCTRL_PIN_GROUP("pcm2", an7583_pcm2), ++ PINCTRL_PIN_GROUP("spi", an7583_spi), ++ PINCTRL_PIN_GROUP("spi_quad", an7583_spi_quad), ++ PINCTRL_PIN_GROUP("spi_cs1", an7583_spi_cs1), ++ PINCTRL_PIN_GROUP("pcm_spi", an7583_pcm_spi), ++ PINCTRL_PIN_GROUP("pcm_spi_rst", an7583_pcm_spi_rst), ++ PINCTRL_PIN_GROUP("pcm_spi_cs1", an7583_pcm_spi_cs1), ++ PINCTRL_PIN_GROUP("emmc", an7583_emmc), ++ PINCTRL_PIN_GROUP("pnand", an7583_pnand), ++ PINCTRL_PIN_GROUP("gpio0", an7583_gpio0), ++ PINCTRL_PIN_GROUP("gpio1", an7583_gpio1), ++ PINCTRL_PIN_GROUP("gpio2", an7583_gpio2), ++ PINCTRL_PIN_GROUP("gpio3", an7583_gpio3), ++ PINCTRL_PIN_GROUP("gpio4", an7583_gpio4), ++ PINCTRL_PIN_GROUP("gpio5", an7583_gpio5), ++ PINCTRL_PIN_GROUP("gpio6", an7583_gpio6), ++ PINCTRL_PIN_GROUP("gpio7", an7583_gpio7), ++ PINCTRL_PIN_GROUP("gpio8", an7583_gpio8), ++ PINCTRL_PIN_GROUP("gpio9", an7583_gpio9), ++ PINCTRL_PIN_GROUP("gpio10", an7583_gpio10), ++ PINCTRL_PIN_GROUP("gpio11", an7583_gpio11), ++ PINCTRL_PIN_GROUP("gpio12", an7583_gpio12), ++ PINCTRL_PIN_GROUP("gpio13", an7583_gpio13), ++ PINCTRL_PIN_GROUP("gpio14", an7583_gpio14), ++ PINCTRL_PIN_GROUP("gpio15", an7583_gpio15), ++ PINCTRL_PIN_GROUP("gpio16", an7583_gpio16), ++ PINCTRL_PIN_GROUP("gpio17", an7583_gpio17), ++ PINCTRL_PIN_GROUP("gpio18", an7583_gpio18), ++ PINCTRL_PIN_GROUP("gpio19", an7583_gpio19), ++ PINCTRL_PIN_GROUP("gpio20", an7583_gpio20), ++ PINCTRL_PIN_GROUP("gpio21", an7583_gpio21), ++ PINCTRL_PIN_GROUP("gpio23", an7583_gpio23), ++ PINCTRL_PIN_GROUP("gpio24", an7583_gpio24), ++ PINCTRL_PIN_GROUP("gpio25", an7583_gpio25), ++ PINCTRL_PIN_GROUP("gpio26", an7583_gpio26), ++ PINCTRL_PIN_GROUP("gpio27", an7583_gpio27), ++ PINCTRL_PIN_GROUP("gpio28", an7583_gpio28), ++ PINCTRL_PIN_GROUP("gpio29", an7583_gpio29), ++ PINCTRL_PIN_GROUP("gpio30", an7583_gpio30), ++ PINCTRL_PIN_GROUP("gpio31", an7583_gpio31), ++ PINCTRL_PIN_GROUP("gpio33", an7583_gpio33), ++ PINCTRL_PIN_GROUP("gpio34", an7583_gpio34), ++ PINCTRL_PIN_GROUP("gpio35", an7583_gpio35), ++ PINCTRL_PIN_GROUP("gpio36", an7583_gpio36), ++ PINCTRL_PIN_GROUP("gpio37", an7583_gpio37), ++ PINCTRL_PIN_GROUP("gpio38", an7583_gpio38), ++ PINCTRL_PIN_GROUP("gpio39", an7583_gpio39), ++ PINCTRL_PIN_GROUP("gpio40", an7583_gpio40), ++ PINCTRL_PIN_GROUP("gpio41", an7583_gpio41), ++ PINCTRL_PIN_GROUP("gpio42", an7583_gpio42), ++ PINCTRL_PIN_GROUP("gpio43", an7583_gpio43), ++ PINCTRL_PIN_GROUP("gpio44", an7583_gpio44), ++ PINCTRL_PIN_GROUP("gpio45", an7583_gpio45), ++ PINCTRL_PIN_GROUP("gpio46", an7583_gpio46), ++ PINCTRL_PIN_GROUP("gpio47", an7583_gpio47), ++ PINCTRL_PIN_GROUP("gpio48", an7583_gpio48), ++ PINCTRL_PIN_GROUP("pcie_reset0", an7583_pcie_reset0), ++ PINCTRL_PIN_GROUP("pcie_reset1", an7583_pcie_reset1), ++}; ++ + static const char *const pon_groups[] = { "pon" }; + static const char *const tod_1pps_groups[] = { "pon_tod_1pps", "gsw_tod_1pps" }; + static const char *const sipo_groups[] = { "sipo", "sipo_rclk" }; + static const char *const mdio_groups[] = { "mdio" }; ++static const char *const an7583_mdio_groups[] = { "mdio" }; + static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart", + "hsuart_cts_rts", "uart4", + "uart5" }; +@@ -646,11 +876,16 @@ static const char *const pcm_spi_groups[ + "pcm_spi_cs2_p156", + "pcm_spi_cs2_p128", + "pcm_spi_cs3", "pcm_spi_cs4" }; ++static const char *const an7583_pcm_spi_groups[] = { "pcm_spi", "pcm_spi_int", ++ "pcm_spi_rst", "pcm_spi_cs1", ++ "pcm_spi_cs2", "pcm_spi_cs3", ++ "pcm_spi_cs4" }; + static const char *const i2s_groups[] = { "i2s" }; + static const char *const emmc_groups[] = { "emmc" }; + static const char *const pnand_groups[] = { "pnand" }; + static const char *const pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1", + "pcie_reset2" }; ++static const char *const an7583_pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1" }; + static const char *const pwm_groups[] = { "gpio0", "gpio1", + "gpio2", "gpio3", + "gpio4", "gpio5", +@@ -689,6 +924,22 @@ static const char *const phy3_led1_group + "gpio45", "gpio46" }; + static const char *const phy4_led1_groups[] = { "gpio43", "gpio44", + "gpio45", "gpio46" }; ++static const char *const an7583_phy1_led0_groups[] = { "gpio1", "gpio2", ++ "gpio3", "gpio4" }; ++static const char *const an7583_phy2_led0_groups[] = { "gpio1", "gpio2", ++ "gpio3", "gpio4" }; ++static const char *const an7583_phy3_led0_groups[] = { "gpio1", "gpio2", ++ "gpio3", "gpio4" }; ++static const char *const an7583_phy4_led0_groups[] = { "gpio1", "gpio2", ++ "gpio3", "gpio4" }; ++static const char *const an7583_phy1_led1_groups[] = { "gpio8", "gpio9", ++ "gpio10", "gpio11" }; ++static const char *const an7583_phy2_led1_groups[] = { "gpio8", "gpio9", ++ "gpio10", "gpio11" }; ++static const char *const an7583_phy3_led1_groups[] = { "gpio8", "gpio9", ++ "gpio10", "gpio11" }; ++static const char *const an7583_phy4_led1_groups[] = { "gpio8", "gpio9", ++ "gpio10", "gpio11" }; + + static const struct airoha_pinctrl_func_group pon_func_group[] = { + { +@@ -766,6 +1017,25 @@ static const struct airoha_pinctrl_func_ + }, + }; + ++static const struct airoha_pinctrl_func_group an7583_mdio_func_group[] = { ++ { ++ .name = "mdio", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_PON_MODE, ++ GPIO_SGMII_MDIO_MODE_MASK, ++ GPIO_SGMII_MDIO_MODE_MASK ++ }, ++ .regmap[1] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_MDC_IO_MASTER_MODE_MODE, ++ GPIO_MDC_IO_MASTER_MODE_MODE ++ }, ++ .regmap_size = 2, ++ }, ++}; ++ + static const struct airoha_pinctrl_func_group uart_func_group[] = { + { + .name = "uart2", +@@ -1007,6 +1277,73 @@ static const struct airoha_pinctrl_func_ + }, + }; + ++static const struct airoha_pinctrl_func_group an7583_pcm_spi_func_group[] = { ++ { ++ .name = "pcm_spi", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_SPI_MODE_MASK, ++ GPIO_PCM_SPI_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_int", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_INT_MODE_MASK, ++ GPIO_PCM_INT_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_rst", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_RESET_MODE_MASK, ++ GPIO_PCM_RESET_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_cs1", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_SPI_CS1_MODE_MASK, ++ GPIO_PCM_SPI_CS1_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_cs2", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK, ++ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_cs3", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_SPI_CS3_MODE_MASK, ++ GPIO_PCM_SPI_CS3_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcm_spi_cs4", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_SPI_CS1_MODE, ++ GPIO_PCM_SPI_CS4_MODE_MASK, ++ GPIO_PCM_SPI_CS4_MODE_MASK ++ }, ++ .regmap_size = 1, ++ }, ++}; ++ + static const struct airoha_pinctrl_func_group i2s_func_group[] = { + { + .name = "i2s", +@@ -1077,6 +1414,28 @@ static const struct airoha_pinctrl_func_ + }, + }; + ++static const struct airoha_pinctrl_func_group an7583_pcie_reset_func_group[] = { ++ { ++ .name = "pcie_reset0", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_PON_MODE, ++ GPIO_PCIE_RESET0_MASK, ++ GPIO_PCIE_RESET0_MASK ++ }, ++ .regmap_size = 1, ++ }, { ++ .name = "pcie_reset1", ++ .regmap[0] = { ++ AIROHA_FUNC_MUX, ++ REG_GPIO_PON_MODE, ++ GPIO_PCIE_RESET1_MASK, ++ GPIO_PCIE_RESET1_MASK ++ }, ++ .regmap_size = 1, ++ }, ++}; ++ + /* PWM */ + #define AIROHA_PINCTRL_PWM(gpio, mux_val) \ + { \ +@@ -1255,6 +1614,94 @@ static const struct airoha_pinctrl_func_ + LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), + }; + ++static const struct airoha_pinctrl_func_group an7583_phy1_led0_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy2_led0_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy3_led0_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy4_led0_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), ++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy1_led1_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), ++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy2_led1_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), ++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy3_led1_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), ++}; ++ ++static const struct airoha_pinctrl_func_group an7583_phy4_led1_func_group[] = { ++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK, ++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK, ++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK, ++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), ++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK, ++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), ++}; ++ + static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { + PINCTRL_FUNC_DESC("pon", pon), + PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), +@@ -1281,6 +1728,31 @@ static const struct airoha_pinctrl_func + PINCTRL_FUNC_DESC("phy4_led1", phy4_led1), + }; + ++static const struct airoha_pinctrl_func an7583_pinctrl_funcs[] = { ++ PINCTRL_FUNC_DESC("pon", pon), ++ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), ++ PINCTRL_FUNC_DESC("sipo", sipo), ++ PINCTRL_FUNC_DESC("mdio", an7583_mdio), ++ PINCTRL_FUNC_DESC("uart", uart), ++ PINCTRL_FUNC_DESC("i2c", i2c), ++ PINCTRL_FUNC_DESC("jtag", jtag), ++ PINCTRL_FUNC_DESC("pcm", pcm), ++ PINCTRL_FUNC_DESC("spi", spi), ++ PINCTRL_FUNC_DESC("pcm_spi", an7583_pcm_spi), ++ PINCTRL_FUNC_DESC("emmc", emmc), ++ PINCTRL_FUNC_DESC("pnand", pnand), ++ PINCTRL_FUNC_DESC("pcie_reset", an7583_pcie_reset), ++ PINCTRL_FUNC_DESC("pwm", pwm), ++ PINCTRL_FUNC_DESC("phy1_led0", an7583_phy1_led0), ++ PINCTRL_FUNC_DESC("phy2_led0", an7583_phy2_led0), ++ PINCTRL_FUNC_DESC("phy3_led0", an7583_phy3_led0), ++ PINCTRL_FUNC_DESC("phy4_led0", an7583_phy4_led0), ++ PINCTRL_FUNC_DESC("phy1_led1", an7583_phy1_led1), ++ PINCTRL_FUNC_DESC("phy2_led1", an7583_phy2_led1), ++ PINCTRL_FUNC_DESC("phy3_led1", an7583_phy3_led1), ++ PINCTRL_FUNC_DESC("phy4_led1", an7583_phy4_led1), ++}; ++ + static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), +@@ -1342,6 +1814,62 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), + }; + ++static const struct airoha_pinctrl_conf an7583_pinctrl_pullup_conf[] = { ++ PINCTRL_CONF_DESC(2, REG_GPIO_L_PU, BIT(0)), ++ PINCTRL_CONF_DESC(3, REG_GPIO_L_PU, BIT(1)), ++ PINCTRL_CONF_DESC(4, REG_GPIO_L_PU, BIT(2)), ++ PINCTRL_CONF_DESC(5, REG_GPIO_L_PU, BIT(3)), ++ PINCTRL_CONF_DESC(6, REG_GPIO_L_PU, BIT(4)), ++ PINCTRL_CONF_DESC(7, REG_GPIO_L_PU, BIT(5)), ++ PINCTRL_CONF_DESC(8, REG_GPIO_L_PU, BIT(6)), ++ PINCTRL_CONF_DESC(9, REG_GPIO_L_PU, BIT(7)), ++ PINCTRL_CONF_DESC(10, REG_GPIO_L_PU, BIT(8)), ++ PINCTRL_CONF_DESC(11, REG_GPIO_L_PU, BIT(9)), ++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(10)), ++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(11)), ++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(12)), ++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(13)), ++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(14)), ++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(15)), ++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(16)), ++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(17)), ++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(18)), ++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(18)), ++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(20)), ++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(21)), ++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(22)), ++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(23)), ++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(24)), ++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(25)), ++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(26)), ++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(27)), ++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(28)), ++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(29)), ++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(30)), ++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(31)), ++ PINCTRL_CONF_DESC(34, REG_GPIO_H_PU, BIT(0)), ++ PINCTRL_CONF_DESC(35, REG_GPIO_H_PU, BIT(1)), ++ PINCTRL_CONF_DESC(36, REG_GPIO_H_PU, BIT(2)), ++ PINCTRL_CONF_DESC(37, REG_GPIO_H_PU, BIT(3)), ++ PINCTRL_CONF_DESC(38, REG_GPIO_H_PU, BIT(4)), ++ PINCTRL_CONF_DESC(39, REG_GPIO_H_PU, BIT(5)), ++ PINCTRL_CONF_DESC(40, REG_GPIO_H_PU, BIT(6)), ++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PU, I2C_SCL_PU_MASK), ++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), ++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PU, AN7583_I2C1_SCL_PU_MASK), ++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PU, AN7583_I2C1_SDA_PU_MASK), ++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PU, SPI_CLK_PU_MASK), ++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PU, SPI_CS0_PU_MASK), ++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK), ++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PU, SPI_MISO_PU_MASK), ++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), ++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), ++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK), ++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK), ++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PU, AN7583_MDC_0_PU_MASK), ++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PU, AN7583_MDIO_0_PU_MASK), ++}; ++ + static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), +@@ -1403,6 +1931,62 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), + }; + ++static const struct airoha_pinctrl_conf an7583_pinctrl_pulldown_conf[] = { ++ PINCTRL_CONF_DESC(2, REG_GPIO_L_PD, BIT(0)), ++ PINCTRL_CONF_DESC(3, REG_GPIO_L_PD, BIT(1)), ++ PINCTRL_CONF_DESC(4, REG_GPIO_L_PD, BIT(2)), ++ PINCTRL_CONF_DESC(5, REG_GPIO_L_PD, BIT(3)), ++ PINCTRL_CONF_DESC(6, REG_GPIO_L_PD, BIT(4)), ++ PINCTRL_CONF_DESC(7, REG_GPIO_L_PD, BIT(5)), ++ PINCTRL_CONF_DESC(8, REG_GPIO_L_PD, BIT(6)), ++ PINCTRL_CONF_DESC(9, REG_GPIO_L_PD, BIT(7)), ++ PINCTRL_CONF_DESC(10, REG_GPIO_L_PD, BIT(8)), ++ PINCTRL_CONF_DESC(11, REG_GPIO_L_PD, BIT(9)), ++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(10)), ++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(11)), ++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(12)), ++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(13)), ++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(14)), ++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(15)), ++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(16)), ++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(17)), ++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(18)), ++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(18)), ++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(20)), ++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(21)), ++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(22)), ++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(23)), ++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(24)), ++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(25)), ++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(26)), ++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(27)), ++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(28)), ++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(29)), ++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(30)), ++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(31)), ++ PINCTRL_CONF_DESC(34, REG_GPIO_H_PD, BIT(0)), ++ PINCTRL_CONF_DESC(35, REG_GPIO_H_PD, BIT(1)), ++ PINCTRL_CONF_DESC(36, REG_GPIO_H_PD, BIT(2)), ++ PINCTRL_CONF_DESC(37, REG_GPIO_H_PD, BIT(3)), ++ PINCTRL_CONF_DESC(38, REG_GPIO_H_PD, BIT(4)), ++ PINCTRL_CONF_DESC(39, REG_GPIO_H_PD, BIT(5)), ++ PINCTRL_CONF_DESC(40, REG_GPIO_H_PD, BIT(6)), ++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PD, I2C_SCL_PD_MASK), ++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), ++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PD, AN7583_I2C1_SCL_PD_MASK), ++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PD, AN7583_I2C1_SDA_PD_MASK), ++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PD, SPI_CLK_PD_MASK), ++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PD, SPI_CS0_PD_MASK), ++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK), ++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PD, SPI_MISO_PD_MASK), ++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), ++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), ++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK), ++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK), ++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PD, AN7583_MDC_0_PD_MASK), ++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PD, AN7583_MDIO_0_PD_MASK), ++}; ++ + static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), +@@ -1464,6 +2048,62 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), + }; + ++static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e2_conf[] = { ++ PINCTRL_CONF_DESC(2, REG_GPIO_L_E2, BIT(0)), ++ PINCTRL_CONF_DESC(3, REG_GPIO_L_E2, BIT(1)), ++ PINCTRL_CONF_DESC(4, REG_GPIO_L_E2, BIT(2)), ++ PINCTRL_CONF_DESC(5, REG_GPIO_L_E2, BIT(3)), ++ PINCTRL_CONF_DESC(6, REG_GPIO_L_E2, BIT(4)), ++ PINCTRL_CONF_DESC(7, REG_GPIO_L_E2, BIT(5)), ++ PINCTRL_CONF_DESC(8, REG_GPIO_L_E2, BIT(6)), ++ PINCTRL_CONF_DESC(9, REG_GPIO_L_E2, BIT(7)), ++ PINCTRL_CONF_DESC(10, REG_GPIO_L_E2, BIT(8)), ++ PINCTRL_CONF_DESC(11, REG_GPIO_L_E2, BIT(9)), ++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(10)), ++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(11)), ++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(12)), ++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(13)), ++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(14)), ++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(15)), ++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(16)), ++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(17)), ++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(18)), ++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(18)), ++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(20)), ++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(21)), ++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(22)), ++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(23)), ++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(24)), ++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(25)), ++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(26)), ++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(27)), ++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(28)), ++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(29)), ++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(30)), ++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(31)), ++ PINCTRL_CONF_DESC(34, REG_GPIO_H_E2, BIT(0)), ++ PINCTRL_CONF_DESC(35, REG_GPIO_H_E2, BIT(1)), ++ PINCTRL_CONF_DESC(36, REG_GPIO_H_E2, BIT(2)), ++ PINCTRL_CONF_DESC(37, REG_GPIO_H_E2, BIT(3)), ++ PINCTRL_CONF_DESC(38, REG_GPIO_H_E2, BIT(4)), ++ PINCTRL_CONF_DESC(39, REG_GPIO_H_E2, BIT(5)), ++ PINCTRL_CONF_DESC(40, REG_GPIO_H_E2, BIT(6)), ++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E2, I2C_SCL_E2_MASK), ++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), ++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E2, AN7583_I2C1_SCL_E2_MASK), ++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E2, AN7583_I2C1_SDA_E2_MASK), ++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E2, SPI_CLK_E2_MASK), ++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E2, SPI_CS0_E2_MASK), ++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK), ++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E2, SPI_MISO_E2_MASK), ++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), ++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), ++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK), ++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK), ++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E2, AN7583_MDC_0_E2_MASK), ++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E2, AN7583_MDIO_0_E2_MASK), ++}; ++ + static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = { + PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), + PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), +@@ -1525,12 +2165,73 @@ static const struct airoha_pinctrl_conf + PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), + }; + ++static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e4_conf[] = { ++ PINCTRL_CONF_DESC(2, REG_GPIO_L_E4, BIT(0)), ++ PINCTRL_CONF_DESC(3, REG_GPIO_L_E4, BIT(1)), ++ PINCTRL_CONF_DESC(4, REG_GPIO_L_E4, BIT(2)), ++ PINCTRL_CONF_DESC(5, REG_GPIO_L_E4, BIT(3)), ++ PINCTRL_CONF_DESC(6, REG_GPIO_L_E4, BIT(4)), ++ PINCTRL_CONF_DESC(7, REG_GPIO_L_E4, BIT(5)), ++ PINCTRL_CONF_DESC(8, REG_GPIO_L_E4, BIT(6)), ++ PINCTRL_CONF_DESC(9, REG_GPIO_L_E4, BIT(7)), ++ PINCTRL_CONF_DESC(10, REG_GPIO_L_E4, BIT(8)), ++ PINCTRL_CONF_DESC(11, REG_GPIO_L_E4, BIT(9)), ++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(10)), ++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(11)), ++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(12)), ++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(13)), ++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(14)), ++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(15)), ++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(16)), ++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(17)), ++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(18)), ++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(18)), ++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(20)), ++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(21)), ++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(22)), ++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(23)), ++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(24)), ++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(25)), ++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(26)), ++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(27)), ++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(28)), ++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(29)), ++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(30)), ++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(31)), ++ PINCTRL_CONF_DESC(34, REG_GPIO_H_E4, BIT(0)), ++ PINCTRL_CONF_DESC(35, REG_GPIO_H_E4, BIT(1)), ++ PINCTRL_CONF_DESC(36, REG_GPIO_H_E4, BIT(2)), ++ PINCTRL_CONF_DESC(37, REG_GPIO_H_E4, BIT(3)), ++ PINCTRL_CONF_DESC(38, REG_GPIO_H_E4, BIT(4)), ++ PINCTRL_CONF_DESC(39, REG_GPIO_H_E4, BIT(5)), ++ PINCTRL_CONF_DESC(40, REG_GPIO_H_E4, BIT(6)), ++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E4, I2C_SCL_E4_MASK), ++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), ++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E4, AN7583_I2C1_SCL_E4_MASK), ++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E4, AN7583_I2C1_SDA_E4_MASK), ++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E4, SPI_CLK_E4_MASK), ++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E4, SPI_CS0_E4_MASK), ++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK), ++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E4, SPI_MISO_E4_MASK), ++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), ++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), ++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK), ++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK), ++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E4, AN7583_MDC_0_E4_MASK), ++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E4, AN7583_MDIO_0_E4_MASK), ++}; ++ + static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = { + PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), + PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), + PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), + }; + ++static const struct airoha_pinctrl_conf an7583_pinctrl_pcie_rst_od_conf[] = { ++ PINCTRL_CONF_DESC(51, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), ++ PINCTRL_CONF_DESC(52, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), ++}; ++ + static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev, + struct pinctrl_gpio_range *range, + int pin) +@@ -2267,8 +2968,40 @@ static const struct airoha_pinctrl_match + }, + }; + ++static const struct airoha_pinctrl_match_data an7583_pinctrl_match_data = { ++ .pins = an7583_pinctrl_pins, ++ .num_pins = ARRAY_SIZE(an7583_pinctrl_pins), ++ .grps = an7583_pinctrl_groups, ++ .num_grps = ARRAY_SIZE(an7583_pinctrl_groups), ++ .funcs = an7583_pinctrl_funcs, ++ .num_funcs = ARRAY_SIZE(an7583_pinctrl_funcs), ++ .confs_info = { ++ [AIROHA_PINCTRL_CONFS_PULLUP] = { ++ .confs = an7583_pinctrl_pullup_conf, ++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pullup_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = { ++ .confs = an7583_pinctrl_pulldown_conf, ++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pulldown_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = { ++ .confs = en7581_pinctrl_drive_e2_conf, ++ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e2_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = { ++ .confs = an7583_pinctrl_drive_e4_conf, ++ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e4_conf), ++ }, ++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = { ++ .confs = an7583_pinctrl_pcie_rst_od_conf, ++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pcie_rst_od_conf), ++ }, ++ }, ++}; ++ + static const struct of_device_id airoha_pinctrl_of_match[] = { + { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data }, ++ { .compatible = "airoha,an7583-pinctrl", .data = &an7583_pinctrl_match_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match); diff --git a/target/linux/airoha/patches-6.6/401-02-net-dsa-mt7530-Add-AN7583-support.patch b/target/linux/airoha/patches-6.6/401-02-net-dsa-mt7530-Add-AN7583-support.patch new file mode 100644 index 0000000000..0d72a59ad9 --- /dev/null +++ b/target/linux/airoha/patches-6.6/401-02-net-dsa-mt7530-Add-AN7583-support.patch @@ -0,0 +1,140 @@ +From 7e112e51d48db09739dd73c90411fc8a5635747f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 22 May 2025 15:13:10 +0200 +Subject: [PATCH 2/3] net: dsa: mt7530: Add AN7583 support + +Add Airoha AN7583 Switch support. This is based on Airoha EN7581 that is +based on Mediatek MT7988 Switch. + +Airoha AN7583 require additional tweak to the GEPHY_CONN_CFG register to +make the internal PHY work. + +Signed-off-by: Christian Marangi +--- + drivers/net/dsa/mt7530-mmio.c | 1 + + drivers/net/dsa/mt7530.c | 24 ++++++++++++++++++++++-- + drivers/net/dsa/mt7530.h | 18 ++++++++++++++---- + 3 files changed, 37 insertions(+), 6 deletions(-) + +--- a/drivers/net/dsa/mt7530-mmio.c ++++ b/drivers/net/dsa/mt7530-mmio.c +@@ -11,6 +11,7 @@ + #include "mt7530.h" + + static const struct of_device_id mt7988_of_match[] = { ++ { .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], }, + { .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], }, + { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], }, + { /* sentinel */ }, +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -1153,7 +1153,7 @@ mt753x_cpu_port_enable(struct dsa_switch + * is affine to the inbound user port. + */ + if (priv->id == ID_MT7531 || priv->id == ID_MT7988 || +- priv->id == ID_EN7581) ++ priv->id == ID_EN7581 || priv->id == ID_AN7583) + mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port))); + + /* CPU port gets connected to all user ports of +@@ -2589,7 +2589,7 @@ mt7531_setup_common(struct dsa_switch *d + mt7530_set(priv, MT753X_AGC, LOCAL_EN); + + /* Enable Special Tag for rx frames */ +- if (priv->id == ID_EN7581) ++ if (priv->id == ID_EN7581 || priv->id == ID_AN7583) + mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, + CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); + +@@ -3157,6 +3157,16 @@ static int mt7988_setup(struct dsa_switc + reset_control_deassert(priv->rstc); + usleep_range(20, 50); + ++ /* AN7583 require additional tweak to CONN_CFG */ ++ if (priv->id == ID_AN7583) ++ mt7530_rmw(priv, AN7583_GEPHY_CONN_CFG, ++ AN7583_CSR_DPHY_CKIN_SEL | ++ AN7583_CSR_PHY_CORE_REG_CLK_SEL | ++ AN7583_CSR_ETHER_AFE_PWD, ++ AN7583_CSR_DPHY_CKIN_SEL | ++ AN7583_CSR_PHY_CORE_REG_CLK_SEL | ++ FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0)); ++ + /* Reset the switch PHYs */ + mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST); + +@@ -3253,6 +3263,16 @@ const struct mt753x_info mt753x_table[] + .pcs_ops = &mt7530_pcs_ops, + .sw_setup = mt7988_setup, + .phy_read_c22 = mt7531_ind_c22_phy_read, ++ .phy_write_c22 = mt7531_ind_c22_phy_write, ++ .phy_read_c45 = mt7531_ind_c45_phy_read, ++ .phy_write_c45 = mt7531_ind_c45_phy_write, ++ .mac_port_get_caps = en7581_mac_port_get_caps, ++ }, ++ [ID_AN7583] = { ++ .id = ID_AN7583, ++ .pcs_ops = &mt7530_pcs_ops, ++ .sw_setup = mt7988_setup, ++ .phy_read_c22 = mt7531_ind_c22_phy_read, + .phy_write_c22 = mt7531_ind_c22_phy_write, + .phy_read_c45 = mt7531_ind_c45_phy_read, + .phy_write_c45 = mt7531_ind_c45_phy_write, +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -20,6 +20,7 @@ enum mt753x_id { + ID_MT7531 = 2, + ID_MT7988 = 3, + ID_EN7581 = 4, ++ ID_AN7583 = 5, + }; + + #define NUM_TRGMII_CTRL 5 +@@ -66,7 +67,8 @@ enum mt753x_id { + + #define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \ + id == ID_MT7988 || \ +- id == ID_EN7581) ? \ ++ id == ID_EN7581 || \ ++ id == ID_AN7583) ? \ + MT7531_CFC : MT753X_MFC) + + #define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \ +@@ -76,19 +78,22 @@ enum mt753x_id { + + #define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \ + id == ID_MT7988 || \ +- id == ID_EN7581) ? \ ++ id == ID_EN7581 || \ ++ id == ID_AN7583) ? \ + MT7531_MIRROR_PORT_MASK : \ + MT7530_MIRROR_PORT_MASK) + + #define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \ + id == ID_MT7988 || \ +- id == ID_EN7581) ? \ ++ id == ID_EN7581 || \ ++ id == ID_AN7583) ? \ + MT7531_MIRROR_PORT_GET(val) : \ + MT7530_MIRROR_PORT_GET(val)) + + #define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \ + id == ID_MT7988 || \ +- id == ID_EN7581) ? \ ++ id == ID_EN7581 || \ ++ id == ID_AN7583) ? \ + MT7531_MIRROR_PORT_SET(val) : \ + MT7530_MIRROR_PORT_SET(val)) + +@@ -619,6 +624,11 @@ enum mt7531_xtal_fsel { + #define CPORT_SW2FE_STAG_EN BIT(1) + #define CPORT_FE2SW_STAG_EN BIT(0) + ++#define AN7583_GEPHY_CONN_CFG 0x7c14 ++#define AN7583_CSR_DPHY_CKIN_SEL BIT(31) ++#define AN7583_CSR_PHY_CORE_REG_CLK_SEL BIT(30) ++#define AN7583_CSR_ETHER_AFE_PWD GENMASK(28, 24) ++ + /* Registers for LED GPIO control (MT7530 only) + * All registers follow this pattern: + * [ 2: 0] port 0 diff --git a/target/linux/airoha/patches-6.6/402-01-thermal-airoha-convert-to-regmap-API.patch b/target/linux/airoha/patches-6.6/402-01-thermal-airoha-convert-to-regmap-API.patch new file mode 100644 index 0000000000..9414bef9cb --- /dev/null +++ b/target/linux/airoha/patches-6.6/402-01-thermal-airoha-convert-to-regmap-API.patch @@ -0,0 +1,194 @@ +From 7d55e75edc87022a4c1820588f70a80cebb13c5f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 23 May 2025 19:34:54 +0200 +Subject: [PATCH 1/5] thermal: airoha: convert to regmap API + +In preparation for support of Airoha AN7583, convert the driver to +regmap API. This is needed as Airoha AN7583 will be based on syscon +regmap. + +Signed-off-by: Christian Marangi +--- + drivers/thermal/airoha_thermal.c | 72 +++++++++++++++++++------------- + 1 file changed, 42 insertions(+), 30 deletions(-) + +--- a/drivers/thermal/airoha_thermal.c ++++ b/drivers/thermal/airoha_thermal.c +@@ -194,7 +194,7 @@ + #define AIROHA_MAX_SAMPLES 6 + + struct airoha_thermal_priv { +- void __iomem *base; ++ struct regmap *map; + struct regmap *chip_scu; + struct resource scu_adc_res; + +@@ -265,8 +265,8 @@ static int airoha_thermal_set_trips(stru + RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); + + /* We offset the high temp of 1°C to trigger correct event */ +- writel(TEMP_TO_RAW(priv, high) >> 4, +- priv->base + EN7581_TEMPOFFSETH); ++ regmap_write(priv->map, EN7581_TEMPOFFSETH, ++ TEMP_TO_RAW(priv, high) >> 4); + + enable_monitor = true; + } +@@ -277,15 +277,15 @@ static int airoha_thermal_set_trips(stru + RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); + + /* We offset the low temp of 1°C to trigger correct event */ +- writel(TEMP_TO_RAW(priv, low) >> 4, +- priv->base + EN7581_TEMPOFFSETL); ++ regmap_write(priv->map, EN7581_TEMPOFFSETL, ++ TEMP_TO_RAW(priv, high) >> 4); + + enable_monitor = true; + } + + /* Enable sensor 0 monitor after trip are set */ + if (enable_monitor) +- writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); ++ regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN); + + return 0; + } +@@ -302,7 +302,7 @@ static irqreturn_t airoha_thermal_irq(in + bool update = false; + u32 status; + +- status = readl(priv->base + EN7581_TEMPMONINTSTS); ++ regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status); + switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) { + case EN7581_HOFSINTSTS0: + event = THERMAL_TRIP_VIOLATED; +@@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(in + } + + /* Reset Interrupt */ +- writel(status, priv->base + EN7581_TEMPMONINTSTS); ++ regmap_write(priv->map, EN7581_TEMPMONINTSTS, status); + + if (update) + thermal_zone_device_update(priv->tz, event); +@@ -336,11 +336,11 @@ static void airoha_thermal_setup_adc_val + /* sleep 10 ms for ADC to enable */ + usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); + +- efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG); ++ regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); + if (efuse_calib_info) { + priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); + /* Different slope are applied if the sensor is used for CPU or for package */ +- cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG); ++ regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor); + if (cpu_sensor) { + priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; + priv->init_temp = EN7581_INIT_TEMP_FTK_X10; +@@ -359,8 +359,8 @@ static void airoha_thermal_setup_adc_val + static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) + { + /* Set measure mode */ +- writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4), +- priv->base + EN7581_TEMPMSRCTL0); ++ regmap_write(priv->map, EN7581_TEMPMSRCTL0, ++ FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4)); + + /* + * Configure ADC valid reading addr +@@ -375,15 +375,15 @@ static void airoha_thermal_setup_monitor + * We set valid instead of volt as we don't enable valid/volt + * split reading and AHB read valid addr in such case. + */ +- writel(priv->scu_adc_res.start + EN7581_DOUT_TADC, +- priv->base + EN7581_TEMPADCVALIDADDR); ++ regmap_write(priv->map, EN7581_TEMPADCVALIDADDR, ++ priv->scu_adc_res.start + EN7581_DOUT_TADC); + + /* + * Configure valid bit on a fake value of bit 16. The ADC outputs + * max of 2 bytes for voltage. + */ +- writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16), +- priv->base + EN7581_TEMPADCVALIDMASK); ++ regmap_write(priv->map, EN7581_TEMPADCVALIDMASK, ++ FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16)); + + /* + * AHB supports max 12 bytes for ADC voltage. Shift the read +@@ -391,40 +391,52 @@ static void airoha_thermal_setup_monitor + * in the order of half a °C and is acceptable in the context + * of triggering interrupt in critical condition. + */ +- writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4), +- priv->base + EN7581_TEMPADCVOLTAGESHIFT); ++ regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT, ++ FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4)); + + /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */ +- writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3), +- priv->base + EN7581_TEMPMONCTL1); ++ regmap_write(priv->map, EN7581_TEMPMONCTL1, ++ FIELD_PREP(EN7581_PERIOD_UNIT, 3)); + + /* + * filt interval is 1 * 52.715us = 52.715us, + * sen interval is 379 * 52.715us = 19.97ms + */ +- writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) | +- FIELD_PREP(EN7581_FILT_INTERVAL, 379), +- priv->base + EN7581_TEMPMONCTL2); ++ regmap_write(priv->map, EN7581_TEMPMONCTL2, ++ FIELD_PREP(EN7581_FILT_INTERVAL, 1) | ++ FIELD_PREP(EN7581_FILT_INTERVAL, 379)); + + /* AHB poll is set to 146 * 68.64 = 10.02us */ +- writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146), +- priv->base + EN7581_TEMPAHBPOLL); ++ regmap_write(priv->map, EN7581_TEMPAHBPOLL, ++ FIELD_PREP(EN7581_ADC_POLL_INTVL, 146)); + } + ++static const struct regmap_config airoha_thermal_regmap_config = { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++}; ++ + static int airoha_thermal_probe(struct platform_device *pdev) + { + struct airoha_thermal_priv *priv; + struct device_node *chip_scu_np; + struct device *dev = &pdev->dev; ++ void __iomem *base; + int irq, ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + +- priv->base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(priv->base)) +- return PTR_ERR(priv->base); ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ priv->map = devm_regmap_init_mmio(dev, base, ++ &airoha_thermal_regmap_config); ++ if (IS_ERR(priv->map)) ++ return PTR_ERR(priv->map); + + chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0); + if (!chip_scu_np) +@@ -462,8 +474,8 @@ static int airoha_thermal_probe(struct p + platform_set_drvdata(pdev, priv); + + /* Enable LOW and HIGH interrupt */ +- writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0, +- priv->base + EN7581_TEMPMONINT); ++ regmap_write(priv->map, EN7581_TEMPMONINT, ++ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); + + return 0; + } diff --git a/target/linux/airoha/patches-6.6/402-02-thermal-drivers-airoha-Generalize-probe-function.patch b/target/linux/airoha/patches-6.6/402-02-thermal-drivers-airoha-Generalize-probe-function.patch new file mode 100644 index 0000000000..b306b2308b --- /dev/null +++ b/target/linux/airoha/patches-6.6/402-02-thermal-drivers-airoha-Generalize-probe-function.patch @@ -0,0 +1,226 @@ +From 6c0f01b16687dc582f0470a5d5b20084fb3a290f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 23 May 2025 19:48:32 +0200 +Subject: [PATCH 2/5] thermal/drivers: airoha: Generalize probe function + +In preparation for support of Airoha AN7583, generalize the probe +function to address for the 2 SoC differece. + +Implement a match_data struct where it's possible to define a more +specific probe and post_probe function and specific thermal ops and +pllrg protect value. + +Signed-off-by: Christian Marangi +--- + drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++-------- + 1 file changed, 75 insertions(+), 27 deletions(-) + +--- a/drivers/thermal/airoha_thermal.c ++++ b/drivers/thermal/airoha_thermal.c +@@ -198,12 +198,23 @@ struct airoha_thermal_priv { + struct regmap *chip_scu; + struct resource scu_adc_res; + ++ u32 pllrg_protect; ++ + struct thermal_zone_device *tz; + int init_temp; + int default_slope; + int default_offset; + }; + ++struct airoha_thermal_soc_data { ++ u32 pllrg_protect; ++ ++ const struct thermal_zone_device_ops *thdev_ops; ++ int (*probe)(struct platform_device *pdev, ++ struct airoha_thermal_priv *priv); ++ int (*post_probe)(struct platform_device *pdev); ++}; ++ + static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) + { + u32 val; +@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode + regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); + + /* Give access to thermal regs */ +- regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY); ++ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, ++ priv->pllrg_protect); + adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); + regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); + +@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode + regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); + } + +-static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) ++static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp) + { + struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); + int min_value, max_value, avg_value, value; +@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struc + return 0; + } + +-static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, ++static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low, + int high) + { + struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); +@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(stru + return 0; + } + +-static const struct thermal_zone_device_ops thdev_ops = { +- .get_temp = airoha_thermal_get_temp, +- .set_trips = airoha_thermal_set_trips, ++static const struct thermal_zone_device_ops en7581_thdev_ops = { ++ .get_temp = en7581_thermal_get_temp, ++ .set_trips = en7581_thermal_set_trips, + }; + +-static irqreturn_t airoha_thermal_irq(int irq, void *data) ++static irqreturn_t en7581_thermal_irq(int irq, void *data) + { + struct airoha_thermal_priv *priv = data; + enum thermal_notify_event event; +@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(in + return IRQ_HANDLED; + } + +-static void airoha_thermal_setup_adc_val(struct device *dev, ++static void en7581_thermal_setup_adc_val(struct device *dev, + struct airoha_thermal_priv *priv) + { + u32 efuse_calib_info, cpu_sensor; +@@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val + } + } + +-static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) ++static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv) + { + /* Set measure mode */ + regmap_write(priv->map, EN7581_TEMPMSRCTL0, +@@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor + FIELD_PREP(EN7581_ADC_POLL_INTVL, 146)); + } + +-static const struct regmap_config airoha_thermal_regmap_config = { ++static const struct regmap_config en7581_thermal_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + }; + +-static int airoha_thermal_probe(struct platform_device *pdev) ++static int en7581_thermal_probe(struct platform_device *pdev, ++ struct airoha_thermal_priv *priv) + { +- struct airoha_thermal_priv *priv; + struct device_node *chip_scu_np; + struct device *dev = &pdev->dev; + void __iomem *base; + int irq, ret; + +- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->map = devm_regmap_init_mmio(dev, base, +- &airoha_thermal_regmap_config); ++ &en7581_thermal_regmap_config); + if (IS_ERR(priv->map)) + return PTR_ERR(priv->map); + +@@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct p + return irq; + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, +- airoha_thermal_irq, IRQF_ONESHOT, ++ en7581_thermal_irq, IRQF_ONESHOT, + pdev->name, priv); + if (ret) { + dev_err(dev, "Can't get interrupt working.\n"); + return ret; + } + +- airoha_thermal_setup_monitor(priv); +- airoha_thermal_setup_adc_val(dev, priv); ++ en7581_thermal_setup_monitor(priv); ++ en7581_thermal_setup_adc_val(dev, priv); ++ ++ return 0; ++} ++ ++static int en7581_thermal_post_probe(struct platform_device *pdev) ++{ ++ struct airoha_thermal_priv *priv = platform_get_drvdata(pdev); ++ ++ /* Enable LOW and HIGH interrupt (if supported) */ ++ regmap_write(priv->map, EN7581_TEMPMONINT, ++ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); ++ ++ return 0; ++} ++ ++static int airoha_thermal_probe(struct platform_device *pdev) ++{ ++ const struct airoha_thermal_soc_data *soc_data; ++ struct airoha_thermal_priv *priv; ++ struct device *dev = &pdev->dev; ++ int ret; ++ ++ soc_data = device_get_match_data(dev); ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->pllrg_protect = soc_data->pllrg_protect; ++ ++ if (!soc_data->probe) ++ return -EINVAL; ++ ++ ret = soc_data->probe(pdev, priv); ++ if (ret) ++ return ret; + + /* register of thermal sensor and get info from DT */ +- priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops); ++ priv->tz = devm_thermal_of_zone_register(dev, 0, priv, ++ soc_data->thdev_ops); + if (IS_ERR(priv->tz)) { + dev_err(dev, "register thermal zone sensor failed\n"); + return PTR_ERR(priv->tz); +@@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct p + + platform_set_drvdata(pdev, priv); + +- /* Enable LOW and HIGH interrupt */ +- regmap_write(priv->map, EN7581_TEMPMONINT, +- EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); +- +- return 0; ++ return soc_data->post_probe ? soc_data->post_probe(pdev) : 0; + } + ++static const struct airoha_thermal_soc_data en7581_data = { ++ .pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY, ++ .thdev_ops = &en7581_thdev_ops, ++ .probe = &en7581_thermal_probe, ++ .post_probe = &en7581_thermal_post_probe, ++}; ++ + static const struct of_device_id airoha_thermal_match[] = { +- { .compatible = "airoha,en7581-thermal" }, ++ { .compatible = "airoha,en7581-thermal", .data = &en7581_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, airoha_thermal_match); diff --git a/target/linux/airoha/patches-6.6/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch b/target/linux/airoha/patches-6.6/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch new file mode 100644 index 0000000000..5f6ae2c08a --- /dev/null +++ b/target/linux/airoha/patches-6.6/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch @@ -0,0 +1,129 @@ +From 1e623852d07759c3c076505193bd7f0bd3486774 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 23 May 2025 19:54:53 +0200 +Subject: [PATCH 3/5] thermal/drivers: airoha: generalize get_thermal_ADC and + set_mux function + +In preparation for support of Airoha AN7583, generalize +get_thermal_ADC() and set_thermal_mux() with the use of reg_field API. + +This is to account the same logic between the current supported SoC and +the new one but with different register address. + +While at it also further improve some comments and move sleep inside the +set_thermal_mux function. + +Signed-off-by: Christian Marangi +--- + drivers/thermal/airoha_thermal.c | 54 +++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 12 deletions(-) + +--- a/drivers/thermal/airoha_thermal.c ++++ b/drivers/thermal/airoha_thermal.c +@@ -193,9 +193,18 @@ + + #define AIROHA_MAX_SAMPLES 6 + ++enum airoha_thermal_chip_scu_field { ++ AIROHA_THERMAL_DOUT_TADC, ++ AIROHA_THERMAL_MUX_TADC, ++ ++ /* keep last */ ++ AIROHA_THERMAL_FIELD_MAX, ++}; ++ + struct airoha_thermal_priv { + struct regmap *map; + struct regmap *chip_scu; ++ struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX]; + struct resource scu_adc_res; + + u32 pllrg_protect; +@@ -219,22 +228,29 @@ static int airoha_get_thermal_ADC(struct + { + u32 val; + +- regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val); +- return FIELD_GET(EN7581_DOUT_TADC_MASK, val); ++ regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC], ++ &val); ++ return val; + } + +-static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv) ++static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, ++ int tdac_idx) + { +- u32 adc_mux, pllrg; ++ u32 pllrg; + + /* Save PLLRG current value */ + regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); + +- /* Give access to thermal regs */ ++ /* Give access to Thermal regs */ + regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, + priv->pllrg_protect); +- adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); +- regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); ++ ++ /* Configure Thermal ADC mux to tdac_idx */ ++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], ++ tdac_idx); ++ ++ /* Sleep 10 ms for Thermal ADC to enable */ ++ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); + + /* Restore PLLRG value on exit */ + regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); +@@ -343,10 +359,8 @@ static void en7581_thermal_setup_adc_val + { + u32 efuse_calib_info, cpu_sensor; + +- /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */ +- airoha_init_thermal_ADC_mode(priv); +- /* sleep 10 ms for ADC to enable */ +- usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); ++ /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */ ++ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1); + + regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); + if (efuse_calib_info) { +@@ -429,13 +443,18 @@ static const struct regmap_config en7581 + .val_bits = 32, + }; + ++static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = { ++ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15), ++ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3), ++}; ++ + static int en7581_thermal_probe(struct platform_device *pdev, + struct airoha_thermal_priv *priv) + { + struct device_node *chip_scu_np; + struct device *dev = &pdev->dev; + void __iomem *base; +- int irq, ret; ++ int i, irq, ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) +@@ -454,6 +473,17 @@ static int en7581_thermal_probe(struct p + if (IS_ERR(priv->chip_scu)) + return PTR_ERR(priv->chip_scu); + ++ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { ++ struct regmap_field *field; ++ ++ field = devm_regmap_field_alloc(dev, priv->chip_scu, ++ en7581_chip_scu_fields[i]); ++ if (IS_ERR(field)) ++ return PTR_ERR(field); ++ ++ priv->chip_scu_fields[i] = field; ++ } ++ + of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res); + of_node_put(chip_scu_np); + diff --git a/target/linux/airoha/patches-6.6/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch b/target/linux/airoha/patches-6.6/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch new file mode 100644 index 0000000000..51332350ef --- /dev/null +++ b/target/linux/airoha/patches-6.6/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch @@ -0,0 +1,277 @@ +From 5891a9e5fbdf9a305b5f81e2625455efb2a886f0 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 23 May 2025 19:59:20 +0200 +Subject: [PATCH 5/5] thermal/drivers: airoha: Add support for AN7583 + +Add support for Airoha AN7583 Thermal driver. This apply similar logic +on how to read the temperature but totally drop support for the +PTP_THERMAL subsystem. PTP_THERMAL subsystem was a way to trigger trip +point from hardware by configuring how to read the temperature +internally. + +This subsystem has been totally removed from Airoha AN7583 permitting +only to read the temperature. + +The SoC support up to 3 sensor but the original driver always read the +BGA sensor hence it's currently implemented reading only this specific +sensor. Reference and values for the other 2 sensor are defined for +further implementation if confirmed working. + +set_thermal_mux() is extended to also address muxing the sensor as +AN7583 use a different way to read the temperature from 3 different +diode. The EN7581 code is updated to account for these changes. + +Signed-off-by: Christian Marangi +--- + drivers/thermal/airoha_thermal.c | 158 ++++++++++++++++++++++++++++++- + 1 file changed, 154 insertions(+), 4 deletions(-) + +--- a/drivers/thermal/airoha_thermal.c ++++ b/drivers/thermal/airoha_thermal.c +@@ -18,6 +18,12 @@ + #define EN7581_DOUT_TADC 0x2f8 + #define EN7581_DOUT_TADC_MASK GENMASK(15, 0) + ++#define AN7583_MUX_SENSOR 0x2a0 ++#define AN7583_LOAD_ADJ GENMASK(3, 2) ++#define AN7583_MUX_TADC 0x2e4 ++#define AN7583_MUX_TADC_MASK GENMASK(3, 1) ++#define AN7583_DOUT_TADC 0x2f0 ++ + /* PTP_THERMAL regs */ + #define EN7581_TEMPMONCTL0 0x800 + #define EN7581_SENSE3_EN BIT(3) +@@ -181,6 +187,11 @@ + #define EN7581_SCU_THERMAL_PROTECT_KEY 0x12 + #define EN7581_SCU_THERMAL_MUX_DIODE1 0x7 + ++#define AN7583_SCU_THERMAL_PROTECT_KEY 0x80 ++#define AN7583_NUM_SENSOR 3 ++ ++#define AIROHA_THERMAL_NO_MUX_SENSOR -1 ++ + /* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */ + #define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \ + (priv)->default_slope) / 1000) + \ +@@ -193,8 +204,39 @@ + + #define AIROHA_MAX_SAMPLES 6 + ++/* ++ * AN7583 supports all these ADC mux but the original driver ++ * always checked temp with the AN7583_BGP_TEMP_SENSOR. ++ * Assume using the other sensor temperature is invalid and ++ * always read from AN7583_BGP_TEMP_SENSOR. ++ * ++ * On top of this it's defined that AN7583 supports 3 ++ * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR, ++ * AN7583_CPU_TEMP_SENSOR. ++ * ++ * Provide the ADC mux for reference. ++ */ ++enum an7583_thermal_adc_mux { ++ AN7583_BGP_TEMP_SENSOR, ++ AN7583_PAD_AVS, ++ AN7583_CORE_POWER, ++ AN7583_AVSDAC_OUT, ++ AN7583_VCM, ++ AN7583_GBE_TEMP_SENSOR, ++ AN7583_CPU_TEMP_SENSOR, ++ ++ AN7583_ADC_MUX_MAX, ++}; ++ ++enum an7583_thermal_diode_mux { ++ AN7583_D0_TADC, ++ AN7583_ZERO_TADC, ++ AN7583_D1_TADC, ++}; ++ + enum airoha_thermal_chip_scu_field { + AIROHA_THERMAL_DOUT_TADC, ++ AIROHA_THERMAL_MUX_SENSOR, + AIROHA_THERMAL_MUX_TADC, + + /* keep last */ +@@ -208,6 +250,7 @@ struct airoha_thermal_priv { + struct resource scu_adc_res; + + u32 pllrg_protect; ++ int current_adc; + + struct thermal_zone_device *tz; + int init_temp; +@@ -224,6 +267,24 @@ struct airoha_thermal_soc_data { + int (*post_probe)(struct platform_device *pdev); + }; + ++static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = { ++ [AN7583_BGP_TEMP_SENSOR] = 973, ++ [AN7583_GBE_TEMP_SENSOR] = 995, ++ [AN7583_CPU_TEMP_SENSOR] = 1035, ++}; ++ ++static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = { ++ [AN7583_BGP_TEMP_SENSOR] = 7440, ++ [AN7583_GBE_TEMP_SENSOR] = 7620, ++ [AN7583_CPU_TEMP_SENSOR] = 8390, ++}; ++ ++static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = { ++ [AN7583_BGP_TEMP_SENSOR] = 294, ++ [AN7583_GBE_TEMP_SENSOR] = 298, ++ [AN7583_CPU_TEMP_SENSOR] = 344, ++}; ++ + static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) + { + u32 val; +@@ -234,7 +295,7 @@ static int airoha_get_thermal_ADC(struct + } + + static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, +- int tdac_idx) ++ int tdac_idx, int sensor_idx) + { + u32 pllrg; + +@@ -245,9 +306,20 @@ static void airoha_set_thermal_mux(struc + regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, + priv->pllrg_protect); + ++ /* ++ * Configure Thermal Sensor mux to sensor_idx. ++ * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR) ++ */ ++ if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR) ++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR], ++ sensor_idx); ++ + /* Configure Thermal ADC mux to tdac_idx */ +- regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], +- tdac_idx); ++ if (priv->current_adc != tdac_idx) { ++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], ++ tdac_idx); ++ priv->current_adc = tdac_idx; ++ } + + /* Sleep 10 ms for Thermal ADC to enable */ + usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); +@@ -360,7 +432,8 @@ static void en7581_thermal_setup_adc_val + u32 efuse_calib_info, cpu_sensor; + + /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */ +- airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1); ++ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1, ++ AIROHA_THERMAL_NO_MUX_SENSOR); + + regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); + if (efuse_calib_info) { +@@ -476,6 +549,10 @@ static int en7581_thermal_probe(struct p + for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { + struct regmap_field *field; + ++ /* Skip registering MUX_SENSOR field as not supported */ ++ if (i == AIROHA_THERMAL_MUX_SENSOR) ++ continue; ++ + field = devm_regmap_field_alloc(dev, priv->chip_scu, + en7581_chip_scu_fields[i]); + if (IS_ERR(field)) +@@ -516,6 +593,71 @@ static int en7581_thermal_post_probe(str + return 0; + } + ++static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp) ++{ ++ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); ++ int sensor_idx; ++ int delta_diode, delta_gain; ++ int coeff, slope, offset; ++ ++ int diode_zero, diode_d0, diode_d1; ++ ++ /* Always read sensor AN7583_BGP_TEMP_SENSOR */ ++ sensor_idx = AN7583_BGP_TEMP_SENSOR; ++ ++ coeff = an7583_thermal_coeff[sensor_idx]; ++ slope = an7583_thermal_slope[sensor_idx]; ++ offset = an7583_thermal_offset[sensor_idx]; ++ ++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_ZERO_TADC); ++ diode_zero = airoha_get_thermal_ADC(priv); ++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D0_TADC); ++ diode_d0 = airoha_get_thermal_ADC(priv); ++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D1_TADC); ++ diode_d1 = airoha_get_thermal_ADC(priv); ++ ++ delta_diode = diode_d1 - diode_d0; ++ delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1); ++ *temp = (slope * delta_diode * 10) / delta_gain - offset * 10; ++ *temp *= 100; ++ ++ return 0; ++} ++ ++static const struct thermal_zone_device_ops an7583_tz_ops = { ++ .get_temp = an7583_thermal_get_temp, ++}; ++ ++static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = { ++ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31), ++ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3), ++ [AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3), ++}; ++ ++static int an7583_thermal_probe(struct platform_device *pdev, ++ struct airoha_thermal_priv *priv) ++{ ++ struct device *dev = &pdev->dev; ++ int i; ++ ++ priv->chip_scu = device_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(priv->map)) ++ return PTR_ERR(priv->map); ++ ++ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { ++ struct regmap_field *field; ++ ++ field = devm_regmap_field_alloc(dev, priv->chip_scu, ++ an7583_chip_scu_fields[i]); ++ if (IS_ERR(field)) ++ return PTR_ERR(field); ++ ++ priv->chip_scu_fields[i] = field; ++ } ++ ++ return 0; ++} ++ + static int airoha_thermal_probe(struct platform_device *pdev) + { + const struct airoha_thermal_soc_data *soc_data; +@@ -530,6 +672,7 @@ static int airoha_thermal_probe(struct p + return -ENOMEM; + + priv->pllrg_protect = soc_data->pllrg_protect; ++ priv->current_adc = -1; + + if (!soc_data->probe) + return -EINVAL; +@@ -558,8 +701,15 @@ static const struct airoha_thermal_soc_d + .post_probe = &en7581_thermal_post_probe, + }; + ++static const struct airoha_thermal_soc_data an7583_data = { ++ .pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY, ++ .thdev_ops = &an7583_tz_ops, ++ .probe = &an7583_thermal_probe, ++}; ++ + static const struct of_device_id airoha_thermal_match[] = { + { .compatible = "airoha,en7581-thermal", .data = &en7581_data }, ++ { .compatible = "airoha,an7583-thermal", .data = &an7583_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, airoha_thermal_match); diff --git a/target/linux/airoha/patches-6.6/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch b/target/linux/airoha/patches-6.6/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch new file mode 100644 index 0000000000..3c076b4173 --- /dev/null +++ b/target/linux/airoha/patches-6.6/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch @@ -0,0 +1,35 @@ +From 8a38220c6bf6d79ecb1c95b083e062bd7221dea9 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 9 Aug 2025 13:24:57 +0200 +Subject: [PATCH] cpufreq: airoha: Add support for AN7583 SoC + +New Airoha AN7583 SoC use the same exact logic to control the CPU +frequency. Add the Device compatible to the block list for +cpufreq-dt-plat and to the Airoha CPUFreq driver compatible list. + +Signed-off-by: Christian Marangi +--- + drivers/cpufreq/airoha-cpufreq.c | 1 + + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/cpufreq/airoha-cpufreq.c ++++ b/drivers/cpufreq/airoha-cpufreq.c +@@ -121,6 +121,7 @@ static struct platform_driver airoha_cpu + }; + + static const struct of_device_id airoha_cpufreq_match_list[] __initconst = { ++ { .compatible = "airoha,an7583" }, + { .compatible = "airoha,en7581" }, + {}, + }; +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -103,6 +103,7 @@ static const struct of_device_id allowli + * platforms using "operating-points-v2" property. + */ + static const struct of_device_id blocklist[] __initconst = { ++ { .compatible = "airoha,an7583", }, + { .compatible = "airoha,en7581", }, + + { .compatible = "allwinner,sun50i-h6", }, diff --git a/target/linux/airoha/patches-6.6/600-01-clk-en7523-convert-driver-to-regmap-API.patch b/target/linux/airoha/patches-6.6/600-01-clk-en7523-convert-driver-to-regmap-API.patch new file mode 100644 index 0000000000..85bd2c214e --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-01-clk-en7523-convert-driver-to-regmap-API.patch @@ -0,0 +1,351 @@ +From 8d5a00b3b83f76d255bcffc91d5263f72b27547a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 7 Feb 2025 23:51:23 +0100 +Subject: [PATCH 01/10] clk: en7523: convert driver to regmap API + +Convert driver to regmap API, in preparation for support of Airoha +AN7523 as the SCU will be an MFD and the regmap will be provided in the +parent node. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 137 ++++++++++++++++++++++----------------- + 1 file changed, 76 insertions(+), 61 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + ++#include + #include + #include + #include +@@ -34,6 +35,7 @@ + #define REG_RESET_CONTROL_PCIE2 BIT(26) + /* EN7581 */ + #define REG_NP_SCU_PCIC 0x88 ++#define REG_PCIE_CTRL GENMASK(7, 0) + #define REG_NP_SCU_SSTR 0x9c + #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) + #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) +@@ -63,14 +65,14 @@ struct en_clk_desc { + }; + + struct en_clk_gate { +- void __iomem *base; ++ struct regmap *map; + struct clk_hw hw; + }; + + struct en_rst_data { + const u16 *bank_ofs; + const u16 *idx_map; +- void __iomem *base; ++ struct regmap *map; + struct reset_controller_dev rcdev; + }; + +@@ -388,44 +390,44 @@ static u32 en7523_get_div(const struct e + static int en7523_pci_is_enabled(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); ++ u32 val; + +- return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1); ++ regmap_read(cg->map, REG_PCI_CONTROL, &val); ++ return !!(val & REG_PCI_CONTROL_REFCLK_EN1); + } + + static int en7523_pci_prepare(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +- void __iomem *np_base = cg->base; +- u32 val, mask; ++ struct regmap *map = cg->map; ++ u32 mask; + + /* Need to pull device low before reset */ +- val = readl(np_base + REG_PCI_CONTROL); +- val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT); +- writel(val, np_base + REG_PCI_CONTROL); ++ regmap_clear_bits(map, REG_PCI_CONTROL, ++ REG_PCI_CONTROL_PERSTOUT1 | ++ REG_PCI_CONTROL_PERSTOUT); + usleep_range(1000, 2000); + + /* Enable PCIe port 1 */ +- val |= REG_PCI_CONTROL_REFCLK_EN1; +- writel(val, np_base + REG_PCI_CONTROL); ++ regmap_set_bits(map, REG_PCI_CONTROL, ++ REG_PCI_CONTROL_REFCLK_EN1); + usleep_range(1000, 2000); + + /* Reset to default */ +- val = readl(np_base + REG_RESET_CONTROL1); + mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | + REG_RESET_CONTROL_PCIEHB; +- writel(val & ~mask, np_base + REG_RESET_CONTROL1); ++ regmap_clear_bits(map, REG_RESET_CONTROL1, mask); + usleep_range(1000, 2000); +- writel(val | mask, np_base + REG_RESET_CONTROL1); ++ regmap_set_bits(map, REG_RESET_CONTROL1, mask); + msleep(100); +- writel(val & ~mask, np_base + REG_RESET_CONTROL1); ++ regmap_clear_bits(map, REG_RESET_CONTROL1, mask); + usleep_range(5000, 10000); + + /* Release device */ + mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT; +- val = readl(np_base + REG_PCI_CONTROL); +- writel(val & ~mask, np_base + REG_PCI_CONTROL); ++ regmap_clear_bits(map, REG_PCI_CONTROL, mask); + usleep_range(1000, 2000); +- writel(val | mask, np_base + REG_PCI_CONTROL); ++ regmap_set_bits(map, REG_PCI_CONTROL, mask); + msleep(250); + + return 0; +@@ -434,16 +436,13 @@ static int en7523_pci_prepare(struct clk + static void en7523_pci_unprepare(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +- void __iomem *np_base = cg->base; +- u32 val; ++ struct regmap *map = cg->map; + +- val = readl(np_base + REG_PCI_CONTROL); +- val &= ~REG_PCI_CONTROL_REFCLK_EN1; +- writel(val, np_base + REG_PCI_CONTROL); ++ regmap_clear_bits(map, REG_PCI_CONTROL, REG_PCI_CONTROL_REFCLK_EN1); + } + + static struct clk_hw *en7523_register_pcie_clk(struct device *dev, +- void __iomem *np_base) ++ struct regmap *clk_map) + { + const struct en_clk_soc_data *soc_data = device_get_match_data(dev); + struct clk_init_data init = { +@@ -456,7 +455,7 @@ static struct clk_hw *en7523_register_pc + if (!cg) + return NULL; + +- cg->base = np_base; ++ cg->map = clk_map; + cg->hw.init = &init; + + if (init.ops->unprepare) +@@ -474,21 +473,20 @@ static int en7581_pci_is_enabled(struct + u32 val, mask; + + mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; +- val = readl(cg->base + REG_PCI_CONTROL); ++ regmap_read(cg->map, REG_PCI_CONTROL, &val); + return (val & mask) == mask; + } + + static int en7581_pci_enable(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +- void __iomem *np_base = cg->base; +- u32 val, mask; ++ struct regmap *map = cg->map; ++ u32 mask; + + mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | + REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | + REG_PCI_CONTROL_PERSTOUT; +- val = readl(np_base + REG_PCI_CONTROL); +- writel(val | mask, np_base + REG_PCI_CONTROL); ++ regmap_set_bits(map, REG_PCI_CONTROL, mask); + + return 0; + } +@@ -496,19 +494,18 @@ static int en7581_pci_enable(struct clk_ + static void en7581_pci_disable(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +- void __iomem *np_base = cg->base; +- u32 val, mask; ++ struct regmap *map = cg->map; ++ u32 mask; + + mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | + REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | + REG_PCI_CONTROL_PERSTOUT; +- val = readl(np_base + REG_PCI_CONTROL); +- writel(val & ~mask, np_base + REG_PCI_CONTROL); ++ regmap_clear_bits(map, REG_PCI_CONTROL, mask); + usleep_range(1000, 2000); + } + + static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, +- void __iomem *base, void __iomem *np_base) ++ struct regmap *map, struct regmap *clk_map) + { + struct clk_hw *hw; + u32 rate; +@@ -517,10 +514,12 @@ static void en7523_register_clocks(struc + for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { + const struct en_clk_desc *desc = &en7523_base_clks[i]; + u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; +- u32 val = readl(base + desc->base_reg); ++ u32 val; ++ ++ regmap_read(map, desc->base_reg, &val); + + rate = en7523_get_base_rate(desc, val); +- val = readl(base + reg); ++ regmap_read(map, reg, &val); + rate /= en7523_get_div(desc, val); + + hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); +@@ -533,30 +532,47 @@ static void en7523_register_clocks(struc + clk_data->hws[desc->id] = hw; + } + +- hw = en7523_register_pcie_clk(dev, np_base); ++ hw = en7523_register_pcie_clk(dev, clk_map); + clk_data->hws[EN7523_CLK_PCIE] = hw; + } + ++static const struct regmap_config en7523_clk_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ + static int en7523_clk_hw_init(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data) + { + void __iomem *base, *np_base; ++ struct regmap *map, *clk_map; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + ++ map = devm_regmap_init_mmio(&pdev->dev, base, ++ &en7523_clk_regmap_config); ++ if (IS_ERR(map)) ++ return PTR_ERR(map); ++ + np_base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(np_base)) + return PTR_ERR(np_base); + +- en7523_register_clocks(&pdev->dev, clk_data, base, np_base); ++ clk_map = devm_regmap_init_mmio(&pdev->dev, np_base, ++ &en7523_clk_regmap_config); ++ if (IS_ERR(clk_map)) ++ return PTR_ERR(clk_map); ++ ++ en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); + + return 0; + } + + static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, +- struct regmap *map, void __iomem *base) ++ struct regmap *map, struct regmap *clk_map) + { + struct clk_hw *hw; + u32 rate; +@@ -593,7 +609,7 @@ static void en7581_register_clocks(struc + clk_data->hws[desc->id] = hw; + } + +- hw = en7523_register_pcie_clk(dev, base); ++ hw = en7523_register_pcie_clk(dev, clk_map); + clk_data->hws[EN7523_CLK_PCIE] = hw; + } + +@@ -601,15 +617,10 @@ static int en7523_reset_update(struct re + unsigned long id, bool assert) + { + struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); +- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; +- u32 val; ++ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; + +- val = readl(addr); +- if (assert) +- val |= BIT(id % RST_NR_PER_BANK); +- else +- val &= ~BIT(id % RST_NR_PER_BANK); +- writel(val, addr); ++ regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK), ++ assert ? BIT(id % RST_NR_PER_BANK) : 0); + + return 0; + } +@@ -630,9 +641,11 @@ static int en7523_reset_status(struct re + unsigned long id) + { + struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); +- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; ++ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; ++ u32 val; + +- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK)); ++ regmap_read(rst_data->map, addr, &val); ++ return !!(val & BIT(id % RST_NR_PER_BANK)); + } + + static int en7523_reset_xlate(struct reset_controller_dev *rcdev, +@@ -652,7 +665,7 @@ static const struct reset_control_ops en + .status = en7523_reset_status, + }; + +-static int en7581_reset_register(struct device *dev, void __iomem *base) ++static int en7581_reset_register(struct device *dev, struct regmap *map) + { + struct en_rst_data *rst_data; + +@@ -662,7 +675,7 @@ static int en7581_reset_register(struct + + rst_data->bank_ofs = en7581_rst_ofs; + rst_data->idx_map = en7581_rst_map; +- rst_data->base = base; ++ rst_data->map = map; + + rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); + rst_data->rcdev.of_xlate = en7523_reset_xlate; +@@ -678,9 +691,8 @@ static int en7581_reset_register(struct + static int en7581_clk_hw_init(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data) + { +- struct regmap *map; ++ struct regmap *map, *clk_map; + void __iomem *base; +- u32 val; + + map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); + if (IS_ERR(map)) +@@ -690,15 +702,18 @@ static int en7581_clk_hw_init(struct pla + if (IS_ERR(base)) + return PTR_ERR(base); + +- en7581_register_clocks(&pdev->dev, clk_data, map, base); +- +- val = readl(base + REG_NP_SCU_SSTR); +- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); +- writel(val, base + REG_NP_SCU_SSTR); +- val = readl(base + REG_NP_SCU_PCIC); +- writel(val | 3, base + REG_NP_SCU_PCIC); ++ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config); ++ if (IS_ERR(clk_map)) ++ return PTR_ERR(clk_map); ++ ++ en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); ++ ++ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, ++ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); ++ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, ++ FIELD_PREP(REG_PCIE_CTRL, 3)); + +- return en7581_reset_register(&pdev->dev, base); ++ return en7581_reset_register(&pdev->dev, clk_map); + } + + static int en7523_clk_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.6/600-02-clk-en7523-generalize-register-clocks-function.patch b/target/linux/airoha/patches-6.6/600-02-clk-en7523-generalize-register-clocks-function.patch new file mode 100644 index 0000000000..b8d892ffb4 --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-02-clk-en7523-generalize-register-clocks-function.patch @@ -0,0 +1,258 @@ +From 36a3a919391dea2000f355125f0a161c453fcf78 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 8 Feb 2025 00:08:08 +0100 +Subject: [PATCH 02/10] clk: en7523: generalize register clocks function + +Generalize register clocks function for Airoha EN7523 and EN7581 clocks +driver. The same logic is applied for both clock hence code can be +reduced and simplified by putting the base_clocks struct in the soc_data +and passing that to a generic register clocks function. + +While at it rework some function to return error and use devm variant +for clk_hw_regiser. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 148 +++++++++++++++++---------------------- + 1 file changed, 66 insertions(+), 82 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -78,8 +78,10 @@ struct en_rst_data { + + struct en_clk_soc_data { + u32 num_clocks; ++ const struct en_clk_desc *base_clks; + const struct clk_ops pcie_ops; + int (*hw_init)(struct platform_device *pdev, ++ const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data); + }; + +@@ -450,10 +452,11 @@ static struct clk_hw *en7523_register_pc + .ops = &soc_data->pcie_ops, + }; + struct en_clk_gate *cg; ++ int err; + + cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); + if (!cg) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + cg->map = clk_map; + cg->hw.init = &init; +@@ -461,12 +464,62 @@ static struct clk_hw *en7523_register_pc + if (init.ops->unprepare) + init.ops->unprepare(&cg->hw); + +- if (clk_hw_register(dev, &cg->hw)) +- return NULL; ++ err = devm_clk_hw_register(dev, &cg->hw); ++ if (err) ++ return ERR_PTR(err); + + return &cg->hw; + } + ++static int en75xx_register_clocks(struct device *dev, ++ const struct en_clk_soc_data *soc_data, ++ struct clk_hw_onecell_data *clk_data, ++ struct regmap *map, struct regmap *clk_map) ++{ ++ struct clk_hw *hw; ++ u32 rate; ++ int i; ++ ++ for (i = 0; i < soc_data->num_clocks - 1; i++) { ++ const struct en_clk_desc *desc = &soc_data->base_clks[i]; ++ u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; ++ int err; ++ ++ err = regmap_read(map, desc->base_reg, &val); ++ if (err) { ++ pr_err("Failed reading fixed clk rate %s: %d\n", ++ desc->name, err); ++ return err; ++ } ++ rate = en7523_get_base_rate(desc, val); ++ ++ err = regmap_read(map, reg, &val); ++ if (err) { ++ pr_err("Failed reading fixed clk div %s: %d\n", ++ desc->name, err); ++ return err; ++ } ++ rate /= en7523_get_div(desc, val); ++ ++ hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); ++ if (IS_ERR(hw)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ desc->name, PTR_ERR(hw)); ++ return PTR_ERR(hw); ++ } ++ ++ clk_data->hws[desc->id] = hw; ++ } ++ ++ hw = en7523_register_pcie_clk(dev, clk_map); ++ if (IS_ERR(hw)) ++ return PTR_ERR(hw); ++ ++ clk_data->hws[EN7523_CLK_PCIE] = hw; ++ ++ return 0; ++} ++ + static int en7581_pci_is_enabled(struct clk_hw *hw) + { + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +@@ -504,38 +557,6 @@ static void en7581_pci_disable(struct cl + usleep_range(1000, 2000); + } + +-static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, +- struct regmap *map, struct regmap *clk_map) +-{ +- struct clk_hw *hw; +- u32 rate; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { +- const struct en_clk_desc *desc = &en7523_base_clks[i]; +- u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; +- u32 val; +- +- regmap_read(map, desc->base_reg, &val); +- +- rate = en7523_get_base_rate(desc, val); +- regmap_read(map, reg, &val); +- rate /= en7523_get_div(desc, val); +- +- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); +- if (IS_ERR(hw)) { +- pr_err("Failed to register clk %s: %ld\n", +- desc->name, PTR_ERR(hw)); +- continue; +- } +- +- clk_data->hws[desc->id] = hw; +- } +- +- hw = en7523_register_pcie_clk(dev, clk_map); +- clk_data->hws[EN7523_CLK_PCIE] = hw; +-} +- + static const struct regmap_config en7523_clk_regmap_config = { + .reg_bits = 32, + .val_bits = 32, +@@ -543,6 +564,7 @@ static const struct regmap_config en7523 + }; + + static int en7523_clk_hw_init(struct platform_device *pdev, ++ const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data) + { + void __iomem *base, *np_base; +@@ -566,51 +588,7 @@ static int en7523_clk_hw_init(struct pla + if (IS_ERR(clk_map)) + return PTR_ERR(clk_map); + +- en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); +- +- return 0; +-} +- +-static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, +- struct regmap *map, struct regmap *clk_map) +-{ +- struct clk_hw *hw; +- u32 rate; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { +- const struct en_clk_desc *desc = &en7581_base_clks[i]; +- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; +- int err; +- +- err = regmap_read(map, desc->base_reg, &val); +- if (err) { +- pr_err("Failed reading fixed clk rate %s: %d\n", +- desc->name, err); +- continue; +- } +- rate = en7523_get_base_rate(desc, val); +- +- err = regmap_read(map, reg, &val); +- if (err) { +- pr_err("Failed reading fixed clk div %s: %d\n", +- desc->name, err); +- continue; +- } +- rate /= en7523_get_div(desc, val); +- +- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); +- if (IS_ERR(hw)) { +- pr_err("Failed to register clk %s: %ld\n", +- desc->name, PTR_ERR(hw)); +- continue; +- } +- +- clk_data->hws[desc->id] = hw; +- } +- +- hw = en7523_register_pcie_clk(dev, clk_map); +- clk_data->hws[EN7523_CLK_PCIE] = hw; ++ return en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); + } + + static int en7523_reset_update(struct reset_controller_dev *rcdev, +@@ -689,10 +667,12 @@ static int en7581_reset_register(struct + } + + static int en7581_clk_hw_init(struct platform_device *pdev, ++ const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data) + { + struct regmap *map, *clk_map; + void __iomem *base; ++ int ret; + + map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); + if (IS_ERR(map)) +@@ -706,7 +686,9 @@ static int en7581_clk_hw_init(struct pla + if (IS_ERR(clk_map)) + return PTR_ERR(clk_map); + +- en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); ++ ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); ++ if (ret) ++ return ret; + + regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, + REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); +@@ -732,7 +714,7 @@ static int en7523_clk_probe(struct platf + return -ENOMEM; + + clk_data->num = soc_data->num_clocks; +- r = soc_data->hw_init(pdev, clk_data); ++ r = soc_data->hw_init(pdev, soc_data, clk_data); + if (r) + return r; + +@@ -740,6 +722,7 @@ static int en7523_clk_probe(struct platf + } + + static const struct en_clk_soc_data en7523_data = { ++ .base_clks = en7523_base_clks, + .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1, + .pcie_ops = { + .is_enabled = en7523_pci_is_enabled, +@@ -750,6 +733,7 @@ static const struct en_clk_soc_data en75 + }; + + static const struct en_clk_soc_data en7581_data = { ++ .base_clks = en7581_base_clks, + /* We increment num_clocks by 1 to account for additional PCIe clock */ + .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, + .pcie_ops = { diff --git a/target/linux/airoha/patches-6.6/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch b/target/linux/airoha/patches-6.6/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch new file mode 100644 index 0000000000..31b5bce636 --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch @@ -0,0 +1,147 @@ +From 933030fd268ac111eb9db13b5a90b7c66cd9df41 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 11:38:21 +0200 +Subject: [PATCH 03/10] clk: en7523: convert to full clk_hw implementation + +In preparation for support of .set_rate, convert the clock register +logic from fixed clock implementation to full clk_hw implementation with +dedicated OPs. + +This is just a rework and no behaviour change is expected. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 83 ++++++++++++++++++++++++++++------------ + 1 file changed, 59 insertions(+), 24 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -69,6 +69,12 @@ struct en_clk_gate { + struct clk_hw hw; + }; + ++struct en_clk { ++ struct regmap *map; ++ const struct en_clk_desc *desc; ++ struct clk_hw hw; ++}; ++ + struct en_rst_data { + const u16 *bank_ofs; + const u16 *idx_map; +@@ -471,44 +477,73 @@ static struct clk_hw *en7523_register_pc + return &cg->hw; + } + ++static unsigned long en75xx_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct en_clk *c = container_of(hw, struct en_clk, hw); ++ const struct en_clk_desc *desc = c->desc; ++ struct regmap *map = c->map; ++ u32 val, reg; ++ u32 rate; ++ int err; ++ ++ err = regmap_read(map, desc->base_reg, &val); ++ if (err) { ++ pr_err("Failed reading fixed clk rate %s: %d\n", ++ desc->name, err); ++ return err; ++ } ++ rate = en7523_get_base_rate(desc, val); ++ ++ reg = desc->div_reg ? desc->div_reg : desc->base_reg; ++ err = regmap_read(map, reg, &val); ++ if (err) { ++ pr_err("Failed reading fixed clk div %s: %d\n", ++ desc->name, err); ++ return err; ++ } ++ ++ return rate / en7523_get_div(desc, val); ++} ++ ++static const struct clk_ops en75xx_clk_ops = { ++ .recalc_rate = en75xx_recalc_rate, ++}; ++ + static int en75xx_register_clocks(struct device *dev, + const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data, + struct regmap *map, struct regmap *clk_map) + { + struct clk_hw *hw; +- u32 rate; + int i; + + for (i = 0; i < soc_data->num_clocks - 1; i++) { + const struct en_clk_desc *desc = &soc_data->base_clks[i]; +- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; ++ struct clk_init_data init = { ++ .ops = &en75xx_clk_ops, ++ }; ++ struct en_clk *en_clk; + int err; + +- err = regmap_read(map, desc->base_reg, &val); +- if (err) { +- pr_err("Failed reading fixed clk rate %s: %d\n", +- desc->name, err); +- return err; +- } +- rate = en7523_get_base_rate(desc, val); ++ en_clk = devm_kzalloc(dev, sizeof(*en_clk), GFP_KERNEL); ++ if (!en_clk) ++ return -ENOMEM; + +- err = regmap_read(map, reg, &val); ++ init.name = desc->name; ++ ++ en_clk->map = map; ++ en_clk->desc = desc; ++ en_clk->hw.init = &init; ++ ++ err = devm_clk_hw_register(dev, &en_clk->hw); + if (err) { +- pr_err("Failed reading fixed clk div %s: %d\n", ++ pr_err("Failed to register clk %s: %d\n", + desc->name, err); + return err; + } +- rate /= en7523_get_div(desc, val); +- +- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); +- if (IS_ERR(hw)) { +- pr_err("Failed to register clk %s: %ld\n", +- desc->name, PTR_ERR(hw)); +- return PTR_ERR(hw); +- } + +- clk_data->hws[desc->id] = hw; ++ clk_data->hws[desc->id] = &en_clk->hw; + } + + hw = en7523_register_pcie_clk(dev, clk_map); +@@ -672,7 +707,7 @@ static int en7581_clk_hw_init(struct pla + { + struct regmap *map, *clk_map; + void __iomem *base; +- int ret; ++ int err; + + map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); + if (IS_ERR(map)) +@@ -686,9 +721,9 @@ static int en7581_clk_hw_init(struct pla + if (IS_ERR(clk_map)) + return PTR_ERR(clk_map); + +- ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); +- if (ret) +- return ret; ++ err = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); ++ if (err) ++ return err; + + regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, + REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); diff --git a/target/linux/airoha/patches-6.6/600-04-clk-en7523-add-support-for-.set_rate.patch b/target/linux/airoha/patches-6.6/600-04-clk-en7523-add-support-for-.set_rate.patch new file mode 100644 index 0000000000..fc2656aeb7 --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-04-clk-en7523-add-support-for-.set_rate.patch @@ -0,0 +1,173 @@ +From fe71e8f734a5c9b808a68b8abaa0156de605df4f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 12:28:41 +0200 +Subject: [PATCH 04/10] clk: en7523: add support for .set_rate + +Add support for EN7523 driver to configure rate. The SoC expose both +base clock selector and clock divisor hence it's possible to change the +rate. + +This will be especially needed for new SoC AN7583 that require changes +for the MDIO and the eMMC. + +The clock were assumed correctly configured by the bootloader but this +goes against the rule of "kernel should not depend on external +configuration". + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 141 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 141 insertions(+) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -506,8 +506,149 @@ static unsigned long en75xx_recalc_rate( + return rate / en7523_get_div(desc, val); + } + ++static int en75xx_get_base_val_for_rate(const struct en_clk_desc *desc, ++ int div, unsigned long rate) ++{ ++ int i; ++ ++ /* Single base rate */ ++ if (!desc->base_bits) { ++ if (rate != desc->base_value / div) ++ goto err; ++ ++ return 0; ++ } ++ ++ /* Check every base rate with provided divisor */ ++ for (i = 0; i < desc->n_base_values; i++) ++ if (rate == desc->base_values[i] / div) ++ return i; ++ ++err: ++ return -EINVAL; ++} ++ ++static int en75xx_get_vals_for_rate(const struct en_clk_desc *desc, ++ unsigned long rate, ++ u32 *base_val, u32 *div_val) ++{ ++ int tmp_base_val = 0; ++ int tmp_div_val = 0; ++ ++ if (!desc->base_bits && !desc->div_bits) ++ return -EINVAL; ++ ++ /* Divisor not supported, just search in base rate */ ++ if (!desc->div_bits) { ++ tmp_base_val = en75xx_get_base_val_for_rate(desc, 1, rate); ++ if (tmp_base_val < 0) { ++ pr_err("Invalid rate for clock %s\n", ++ desc->name); ++ return -EINVAL; ++ } ++ ++ goto exit; ++ } ++ ++ /* Check if div0 satisfy the request */ ++ if (desc->div_val0) { ++ tmp_base_val = en75xx_get_base_val_for_rate(desc, ++ desc->div_val0, ++ rate); ++ if (tmp_base_val >= 0) ++ goto exit; ++ ++ /* Skip checking first divisor val */ ++ tmp_div_val = 1; ++ } ++ ++ /* Simulate rate with every divisor supported */ ++ for (; tmp_div_val < BIT(desc->div_bits); tmp_div_val++) { ++ int div = (tmp_div_val + desc->div_offset) * desc->div_step; ++ ++ tmp_base_val = en75xx_get_base_val_for_rate(desc, div, ++ rate); ++ if (tmp_base_val >= 0) ++ goto exit; ++ } ++ ++ if (tmp_div_val == BIT(desc->div_bits)) { ++ pr_err("Invalid rate for clock %s\n", ++ desc->name); ++ return -EINVAL; ++ } ++ ++exit: ++ *base_val = tmp_base_val; ++ *div_val = tmp_div_val; ++ ++ return 0; ++} ++ ++static long en75xx_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct en_clk *en_clk = container_of(hw, struct en_clk, hw); ++ u32 div_val, base_val; ++ int err; ++ ++ /* Just check if the rate is possible */ ++ err = en75xx_get_vals_for_rate(en_clk->desc, rate, ++ &base_val, &div_val); ++ if (err) ++ return err; ++ ++ return rate; ++} ++ ++static int en75xx_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct en_clk *en_clk = container_of(hw, struct en_clk, hw); ++ const struct en_clk_desc *desc = en_clk->desc; ++ struct regmap *map = en_clk->map; ++ u32 base_val, div_val; ++ u32 reg, val, mask; ++ int err; ++ ++ err = en75xx_get_vals_for_rate(en_clk->desc, rate, ++ &base_val, &div_val); ++ if (err) ++ return err; ++ ++ if (desc->div_bits) { ++ reg = desc->div_reg ? desc->div_reg : desc->base_reg; ++ ++ mask = (BIT(desc->div_bits) - 1) << desc->div_shift; ++ val = div_val << desc->div_shift; ++ ++ err = regmap_update_bits(map, reg, mask, val); ++ if (err) { ++ pr_err("Failed to update div reg for clock %s\n", ++ desc->name); ++ return -EINVAL; ++ } ++ } ++ ++ if (desc->base_bits) { ++ mask = (BIT(desc->base_bits) - 1) << desc->base_shift; ++ val = base_val << desc->base_shift; ++ ++ err = regmap_update_bits(map, desc->base_reg, mask, val); ++ if (err) { ++ pr_err("Failed to update reg for clock %s\n", ++ desc->name); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ + static const struct clk_ops en75xx_clk_ops = { + .recalc_rate = en75xx_recalc_rate, ++ .round_rate = en75xx_round_rate, ++ .set_rate = en75xx_set_rate, + }; + + static int en75xx_register_clocks(struct device *dev, diff --git a/target/linux/airoha/patches-6.6/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch b/target/linux/airoha/patches-6.6/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch new file mode 100644 index 0000000000..059d8083cf --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch @@ -0,0 +1,37 @@ +From 397a132fb8173a9d728bc7c7a31ff5c0590d076f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 12:48:35 +0200 +Subject: [PATCH 05/10] clk: en7523: permit to reference Chip SCU from phandle + +In preparation for support of AN7583 and to make Chip SCU reference more +robust, permit to reference the Chip SCU syscon regmap also with the +"airoha,chip-scu" property in DT. + +Legacy implementation is kept by fallbacking in the absence of +"airoha,chip-scu" property. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -846,11 +846,16 @@ static int en7581_clk_hw_init(struct pla + const struct en_clk_soc_data *soc_data, + struct clk_hw_onecell_data *clk_data) + { ++ struct device *dev = &pdev->dev; + struct regmap *map, *clk_map; + void __iomem *base; + int err; + +- map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); ++ if (of_property_present(dev->of_node, "airoha,chip-scu")) ++ map = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "airoha,chip-scu"); ++ else ++ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); + if (IS_ERR(map)) + return PTR_ERR(map); + diff --git a/target/linux/airoha/patches-6.6/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch b/target/linux/airoha/patches-6.6/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch new file mode 100644 index 0000000000..5de1768f1d --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch @@ -0,0 +1,53 @@ +From d05fc5c8a9ab7bbda80e4fc728902f8d48d3e8aa Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 14:53:56 +0200 +Subject: [PATCH 07/10] clk: en7523: reword and clean clk_probe variables + +Rework and clean en7523_clk_probe variables to make them consistent with +the rest of the source. Also apply some minor cleanup for pdev +variables. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -881,25 +881,27 @@ static int en7581_clk_hw_init(struct pla + + static int en7523_clk_probe(struct platform_device *pdev) + { +- struct device_node *node = pdev->dev.of_node; + const struct en_clk_soc_data *soc_data; + struct clk_hw_onecell_data *clk_data; +- int r; ++ struct device *dev = &pdev->dev; ++ int err; + +- soc_data = device_get_match_data(&pdev->dev); ++ soc_data = device_get_match_data(dev); + +- clk_data = devm_kzalloc(&pdev->dev, +- struct_size(clk_data, hws, soc_data->num_clocks), ++ clk_data = devm_kzalloc(dev, ++ struct_size(clk_data, hws, ++ soc_data->num_clocks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = soc_data->num_clocks; +- r = soc_data->hw_init(pdev, soc_data, clk_data); +- if (r) +- return r; ++ err = soc_data->hw_init(pdev, soc_data, clk_data); ++ if (err) ++ return err; + +- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); ++ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, ++ clk_data); + } + + static const struct en_clk_soc_data en7523_data = { diff --git a/target/linux/airoha/patches-6.6/600-08-clk-en7523-add-support-for-probing-SCU-child.patch b/target/linux/airoha/patches-6.6/600-08-clk-en7523-add-support-for-probing-SCU-child.patch new file mode 100644 index 0000000000..4d57996a07 --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-08-clk-en7523-add-support-for-probing-SCU-child.patch @@ -0,0 +1,57 @@ +From 8f1aea6f4aa61e09eb29b41ff9fffeedd5b2fc0d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 17 Jun 2025 13:15:19 +0200 +Subject: [PATCH 08/10] clk: en7523: add support for probing SCU child + +On new Airoha SoC in the SCU register space additional pheriperal might +be present aside from the clock/reset. The Airoha AN7583 SoC is an +example of this where 2 MDIO controller are present. + +Introduce a bool "probe_child" to trigger probe of child node of the SCU +node. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -83,6 +84,7 @@ struct en_rst_data { + }; + + struct en_clk_soc_data { ++ bool probe_child; + u32 num_clocks; + const struct en_clk_desc *base_clks; + const struct clk_ops pcie_ops; +@@ -900,8 +902,19 @@ static int en7523_clk_probe(struct platf + if (err) + return err; + +- return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, +- clk_data); ++ err = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, ++ clk_data); ++ if (err) ++ return err; ++ ++ if (soc_data->probe_child) { ++ err = of_platform_populate(dev->of_node, NULL, NULL, ++ dev); ++ if (err) ++ return err; ++ } ++ ++ return 0; + } + + static const struct en_clk_soc_data en7523_data = { diff --git a/target/linux/airoha/patches-6.6/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch b/target/linux/airoha/patches-6.6/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch new file mode 100644 index 0000000000..7c3430bb95 --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch @@ -0,0 +1,122 @@ +From 12838dd20851a6eae67061c5f195f31981a4d8c1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 28 May 2025 02:39:35 +0200 +Subject: [PATCH 09/10] dt-bindings: clock: airoha: Document support for AN7583 + clock + +Document support for Airoha AN7583 clock. This is based on the EN7523 +clock schema with the new requirement of the "airoha,chip-scu" +(previously optional for EN7581). + +Add additional binding for additional clock and reset lines. + +Signed-off-by: Christian Marangi +--- + .../bindings/clock/airoha,en7523-scu.yaml | 9 +++ + include/dt-bindings/clock/en7523-clk.h | 3 + + .../dt-bindings/reset/airoha,an7583-reset.h | 61 +++++++++++++++++++ + 3 files changed, 73 insertions(+) + create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h + +# diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +# index bce77a14c938..be9759b86fdc 100644 +# --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +# +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +# @@ -32,6 +32,7 @@ properties: +# - enum: +# - airoha,en7523-scu +# - airoha,en7581-scu +# + - airoha,an7583-scu + +# reg: +# items: +# @@ -82,6 +83,14 @@ allOf: +# reg: +# maxItems: 1 + +# + - if: +# + properties: +# + compatible: +# + const: airoha,an7583-scu +# + then: +# + required: +# + - airoha,chip-scu +# + +# additionalProperties: false + +# examples: +--- a/include/dt-bindings/clock/en7523-clk.h ++++ b/include/dt-bindings/clock/en7523-clk.h +@@ -14,4 +14,7 @@ + + #define EN7581_CLK_EMMC 8 + ++#define AN7583_CLK_MDIO0 9 ++#define AN7583_CLK_MDIO1 10 ++ + #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ +--- /dev/null ++++ b/include/dt-bindings/reset/airoha,an7583-reset.h +@@ -0,0 +1,62 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++ ++#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ ++#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ ++ ++/* RST_CTRL2 */ ++#define AN7583_XPON_PHY_RST 0 ++#define AN7583_GPON_OLT_RST 1 ++#define AN7583_CPU_TIMER2_RST 2 ++#define AN7583_HSUART_RST 3 ++#define AN7583_UART4_RST 4 ++#define AN7583_UART5_RST 5 ++#define AN7583_I2C2_RST 6 ++#define AN7583_XSI_MAC_RST 7 ++#define AN7583_XSI_PHY_RST 8 ++#define AN7583_NPU_RST 9 ++#define AN7583_TRNG_MSTART_RST 10 ++#define AN7583_DUAL_HSI0_RST 11 ++#define AN7583_DUAL_HSI1_RST 12 ++#define AN7583_DUAL_HSI0_MAC_RST 13 ++#define AN7583_DUAL_HSI1_MAC_RST 14 ++#define AN7583_XPON_XFI_RST 15 ++#define AN7583_WDMA_RST 16 ++#define AN7583_WOE0_RST 17 ++#define AN7583_HSDMA_RST 18 ++#define AN7583_TDMA_RST 19 ++#define AN7583_EMMC_RST 20 ++#define AN7583_SOE_RST 21 ++#define AN7583_XFP_MAC_RST 22 ++#define AN7583_MDIO0 23 ++#define AN7583_MDIO1 24 ++/* RST_CTRL1 */ ++#define AN7583_PCM1_ZSI_ISI_RST 25 ++#define AN7583_FE_PDMA_RST 26 ++#define AN7583_FE_QDMA_RST 27 ++#define AN7583_PCM_SPIWP_RST 28 ++#define AN7583_CRYPTO_RST 29 ++#define AN7583_TIMER_RST 30 ++#define AN7583_PCM1_RST 31 ++#define AN7583_UART_RST 32 ++#define AN7583_GPIO_RST 33 ++#define AN7583_GDMA_RST 34 ++#define AN7583_I2C_MASTER_RST 35 ++#define AN7583_PCM2_ZSI_ISI_RST 36 ++#define AN7583_SFC_RST 37 ++#define AN7583_UART2_RST 38 ++#define AN7583_GDMP_RST 39 ++#define AN7583_FE_RST 40 ++#define AN7583_USB_HOST_P0_RST 41 ++#define AN7583_GSW_RST 42 ++#define AN7583_SFC2_PCM_RST 43 ++#define AN7583_PCIE0_RST 44 ++#define AN7583_PCIE1_RST 45 ++#define AN7583_CPU_TIMER_RST 46 ++#define AN7583_PCIE_HB_RST 47 ++#define AN7583_XPON_MAC_RST 48 ++ ++#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */ diff --git a/target/linux/airoha/patches-6.6/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch b/target/linux/airoha/patches-6.6/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch new file mode 100644 index 0000000000..0a57e8a9fb --- /dev/null +++ b/target/linux/airoha/patches-6.6/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch @@ -0,0 +1,328 @@ +From 3c5cd99f894c23650accf19fef18b5b9bbe83941 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 8 Feb 2025 00:43:27 +0100 +Subject: [PATCH 10/10] clk: en7523: add support for Airoha AN7583 clock + +Add support for Airoha AN7583 clock and reset. + +Airoha AN7583 SoC have the same register address of EN7581 but implement +different bits and additional base clocks. Also reset are different with +the introduction of 2 dedicated MDIO line and drop of some reset lines. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 264 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 264 insertions(+) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #define RST_NR_PER_BANK 32 + +@@ -104,6 +105,14 @@ static const u32 bus7581_base[] = { 6000 + static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; + static const u32 crypto_base[] = { 540000000, 480000000 }; + static const u32 emmc7581_base[] = { 200000000, 150000000 }; ++/* AN7583 */ ++static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 }; ++static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 }; ++static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 }; ++static const u32 spi7583_base[] = { 100000000, 12500000 }; ++static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 }; ++static const u32 crypto7583_base[] = { 540672000, 400000000 }; ++static const u32 emmc7583_base[] = { 150000000, 200000000 }; + + static const struct en_clk_desc en7523_base_clks[] = { + { +@@ -306,6 +315,138 @@ static const struct en_clk_desc en7581_b + } + }; + ++static const struct en_clk_desc an7583_base_clks[] = { ++ { ++ .id = EN7523_CLK_GSW, ++ .name = "gsw", ++ ++ .base_reg = REG_GSW_CLK_DIV_SEL, ++ .base_bits = 2, ++ .base_shift = 8, ++ .base_values = gsw7583_base, ++ .n_base_values = ARRAY_SIZE(gsw7583_base), ++ ++ .div_bits = 3, ++ .div_shift = 0, ++ .div_step = 1, ++ .div_offset = 1, ++ }, { ++ .id = EN7523_CLK_EMI, ++ .name = "emi", ++ ++ .base_reg = REG_EMI_CLK_DIV_SEL, ++ .base_bits = 2, ++ .base_shift = 8, ++ .base_values = emi7583_base, ++ .n_base_values = ARRAY_SIZE(emi7583_base), ++ ++ .div_bits = 3, ++ .div_shift = 0, ++ .div_step = 1, ++ .div_offset = 1, ++ }, { ++ .id = EN7523_CLK_BUS, ++ .name = "bus", ++ ++ .base_reg = REG_BUS_CLK_DIV_SEL, ++ .base_bits = 2, ++ .base_shift = 8, ++ .base_values = bus7583_base, ++ .n_base_values = ARRAY_SIZE(bus7583_base), ++ ++ .div_bits = 3, ++ .div_shift = 0, ++ .div_step = 1, ++ .div_offset = 1, ++ }, { ++ .id = EN7523_CLK_SLIC, ++ .name = "slic", ++ ++ .base_reg = REG_SPI_CLK_FREQ_SEL, ++ .base_bits = 1, ++ .base_shift = 0, ++ .base_values = slic_base, ++ .n_base_values = ARRAY_SIZE(slic_base), ++ ++ .div_reg = REG_SPI_CLK_DIV_SEL, ++ .div_bits = 5, ++ .div_shift = 24, ++ .div_val0 = 20, ++ .div_step = 2, ++ }, { ++ .id = EN7523_CLK_SPI, ++ .name = "spi", ++ ++ .base_reg = REG_SPI_CLK_FREQ_SEL, ++ .base_bits = 1, ++ .base_shift = 1, ++ .base_values = spi7583_base, ++ .n_base_values = ARRAY_SIZE(spi7583_base), ++ ++ .div_reg = REG_SPI_CLK_DIV_SEL, ++ .div_bits = 5, ++ .div_shift = 8, ++ .div_val0 = 40, ++ .div_step = 2, ++ }, { ++ .id = EN7523_CLK_NPU, ++ .name = "npu", ++ ++ .base_reg = REG_NPU_CLK_DIV_SEL, ++ .base_bits = 2, ++ .base_shift = 9, ++ .base_values = npu7583_base, ++ .n_base_values = ARRAY_SIZE(npu7583_base), ++ ++ .div_bits = 3, ++ .div_shift = 0, ++ .div_step = 1, ++ .div_offset = 1, ++ }, { ++ .id = EN7523_CLK_CRYPTO, ++ .name = "crypto", ++ ++ .base_reg = REG_CRYPTO_CLKSRC2, ++ .base_bits = 1, ++ .base_shift = 0, ++ .base_values = crypto7583_base, ++ .n_base_values = ARRAY_SIZE(crypto7583_base), ++ }, { ++ .id = EN7581_CLK_EMMC, ++ .name = "emmc", ++ ++ .base_reg = REG_CRYPTO_CLKSRC2, ++ .base_bits = 1, ++ .base_shift = 13, ++ .base_values = emmc7583_base, ++ .n_base_values = ARRAY_SIZE(emmc7583_base), ++ }, { ++ .id = AN7583_CLK_MDIO0, ++ .name = "mdio0", ++ ++ .base_reg = REG_CRYPTO_CLKSRC2, ++ ++ .base_value = 25000000, ++ ++ .div_bits = 4, ++ .div_shift = 15, ++ .div_step = 1, ++ .div_offset = 1, ++ }, { ++ .id = AN7583_CLK_MDIO1, ++ .name = "mdio1", ++ ++ .base_reg = REG_CRYPTO_CLKSRC2, ++ ++ .base_value = 25000000, ++ ++ .div_bits = 4, ++ .div_shift = 19, ++ .div_step = 1, ++ .div_offset = 1, ++ } ++}; ++ + static const u16 en7581_rst_ofs[] = { + REG_RST_CTRL2, + REG_RST_CTRL1, +@@ -369,6 +510,60 @@ static const u16 en7581_rst_map[] = { + [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, + }; + ++static const u16 an7583_rst_map[] = { ++ /* RST_CTRL2 */ ++ [AN7583_XPON_PHY_RST] = 0, ++ [AN7583_GPON_OLT_RST] = 1, ++ [AN7583_CPU_TIMER2_RST] = 2, ++ [AN7583_HSUART_RST] = 3, ++ [AN7583_UART4_RST] = 4, ++ [AN7583_UART5_RST] = 5, ++ [AN7583_I2C2_RST] = 6, ++ [AN7583_XSI_MAC_RST] = 7, ++ [AN7583_XSI_PHY_RST] = 8, ++ [AN7583_NPU_RST] = 9, ++ [AN7583_TRNG_MSTART_RST] = 12, ++ [AN7583_DUAL_HSI0_RST] = 13, ++ [AN7583_DUAL_HSI1_RST] = 14, ++ [AN7583_DUAL_HSI0_MAC_RST] = 16, ++ [AN7583_DUAL_HSI1_MAC_RST] = 17, ++ [AN7583_XPON_XFI_RST] = 18, ++ [AN7583_WDMA_RST] = 19, ++ [AN7583_WOE0_RST] = 20, ++ [AN7583_HSDMA_RST] = 22, ++ [AN7583_TDMA_RST] = 24, ++ [AN7583_EMMC_RST] = 25, ++ [AN7583_SOE_RST] = 26, ++ [AN7583_XFP_MAC_RST] = 28, ++ [AN7583_MDIO0] = 30, ++ [AN7583_MDIO1] = 31, ++ /* RST_CTRL1 */ ++ [AN7583_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, ++ [AN7583_FE_PDMA_RST] = RST_NR_PER_BANK + 1, ++ [AN7583_FE_QDMA_RST] = RST_NR_PER_BANK + 2, ++ [AN7583_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, ++ [AN7583_CRYPTO_RST] = RST_NR_PER_BANK + 6, ++ [AN7583_TIMER_RST] = RST_NR_PER_BANK + 8, ++ [AN7583_PCM1_RST] = RST_NR_PER_BANK + 11, ++ [AN7583_UART_RST] = RST_NR_PER_BANK + 12, ++ [AN7583_GPIO_RST] = RST_NR_PER_BANK + 13, ++ [AN7583_GDMA_RST] = RST_NR_PER_BANK + 14, ++ [AN7583_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, ++ [AN7583_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, ++ [AN7583_SFC_RST] = RST_NR_PER_BANK + 18, ++ [AN7583_UART2_RST] = RST_NR_PER_BANK + 19, ++ [AN7583_GDMP_RST] = RST_NR_PER_BANK + 20, ++ [AN7583_FE_RST] = RST_NR_PER_BANK + 21, ++ [AN7583_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, ++ [AN7583_GSW_RST] = RST_NR_PER_BANK + 23, ++ [AN7583_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, ++ [AN7583_PCIE0_RST] = RST_NR_PER_BANK + 26, ++ [AN7583_PCIE1_RST] = RST_NR_PER_BANK + 27, ++ [AN7583_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, ++ [AN7583_PCIE_HB_RST] = RST_NR_PER_BANK + 29, ++ [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31, ++}; ++ + static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) + { + if (!desc->base_bits) +@@ -881,6 +1076,62 @@ static int en7581_clk_hw_init(struct pla + return en7581_reset_register(&pdev->dev, clk_map); + } + ++static int an7583_reset_register(struct device *dev, struct regmap *map) ++{ ++ struct en_rst_data *rst_data; ++ ++ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); ++ if (!rst_data) ++ return -ENOMEM; ++ ++ rst_data->bank_ofs = en7581_rst_ofs; ++ rst_data->idx_map = an7583_rst_map; ++ rst_data->map = map; ++ ++ rst_data->rcdev.nr_resets = ARRAY_SIZE(an7583_rst_map); ++ rst_data->rcdev.of_xlate = en7523_reset_xlate; ++ rst_data->rcdev.ops = &en7581_reset_ops; ++ rst_data->rcdev.of_node = dev->of_node; ++ rst_data->rcdev.of_reset_n_cells = 1; ++ rst_data->rcdev.owner = THIS_MODULE; ++ rst_data->rcdev.dev = dev; ++ ++ return devm_reset_controller_register(dev, &rst_data->rcdev); ++} ++ ++static int an7583_clk_hw_init(struct platform_device *pdev, ++ const struct en_clk_soc_data *soc_data, ++ struct clk_hw_onecell_data *clk_data) ++{ ++ struct device *dev = &pdev->dev; ++ struct regmap *map, *clk_map; ++ void __iomem *base; ++ int err; ++ ++ map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu"); ++ if (IS_ERR(map)) ++ return PTR_ERR(map); ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config); ++ if (IS_ERR(clk_map)) ++ return PTR_ERR(clk_map); ++ ++ err = en75xx_register_clocks(dev, soc_data, clk_data, map, clk_map); ++ if (err) ++ return err; ++ ++ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, ++ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); ++ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, ++ FIELD_PREP(REG_PCIE_CTRL, 3)); ++ ++ return an7583_reset_register(dev, clk_map); ++} ++ + static int en7523_clk_probe(struct platform_device *pdev) + { + const struct en_clk_soc_data *soc_data; +@@ -940,9 +1191,23 @@ static const struct en_clk_soc_data en75 + .hw_init = en7581_clk_hw_init, + }; + ++static const struct en_clk_soc_data an7583_data = { ++ .probe_child = true, ++ .base_clks = an7583_base_clks, ++ /* We increment num_clocks by 1 to account for additional PCIe clock */ ++ .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1, ++ .pcie_ops = { ++ .is_enabled = en7581_pci_is_enabled, ++ .enable = en7581_pci_enable, ++ .disable = en7581_pci_disable, ++ }, ++ .hw_init = an7583_clk_hw_init, ++}; ++ + static const struct of_device_id of_match_clk_en7523[] = { + { .compatible = "airoha,en7523-scu", .data = &en7523_data }, + { .compatible = "airoha,en7581-scu", .data = &en7581_data }, ++ { .compatible = "airoha,an7583-scu", .data = &an7583_data }, + { /* sentinel */ } + }; + diff --git a/target/linux/airoha/patches-6.6/604-01-net-pcs-airoha-add-support-for-AN7583.patch b/target/linux/airoha/patches-6.6/604-01-net-pcs-airoha-add-support-for-AN7583.patch new file mode 100644 index 0000000000..6f0b3c9622 --- /dev/null +++ b/target/linux/airoha/patches-6.6/604-01-net-pcs-airoha-add-support-for-AN7583.patch @@ -0,0 +1,3002 @@ +From 500f525a21bfc18605b23e7b39fc1d8f74393b30 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 25 Jun 2025 00:00:59 +0200 +Subject: [PATCH 6/8] net: pcs: airoha: add support for Airoha AN7583 SoC + +Add support for Airoha AN7583 PCS. This use a new analog PHY +implementation that doesn't require manual calibration but makes use of +internal algo to lock to the center of the band EYE. + +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/airoha/Kconfig | 7 + + drivers/net/pcs/airoha/Makefile | 3 + + drivers/net/pcs/airoha/pcs-airoha-common.c | 50 +- + drivers/net/pcs/airoha/pcs-airoha.h | 430 ++++ + drivers/net/pcs/airoha/pcs-an7583.c | 2199 ++++++++++++++++++++ + 5 files changed, 2686 insertions(+), 3 deletions(-) + create mode 100644 drivers/net/pcs/airoha/pcs-an7583.c + +--- a/drivers/net/pcs/airoha/Kconfig ++++ b/drivers/net/pcs/airoha/Kconfig +@@ -9,3 +9,10 @@ config PCS_AIROHA_AN7581 + help + This module provides helper to phylink for managing the Airoha + AN7581 PCS for SoC Ethernet and PON SERDES. ++ ++config PCS_AIROHA_AN7583 ++ tristate "Airoha AN7583 PCS driver" ++ select PCS_AIROHA ++ help ++ This module provides helper to phylink for managing the Airoha ++ AN7583 PCS for SoC Ethernet and PON SERDES. +--- a/drivers/net/pcs/airoha/Makefile ++++ b/drivers/net/pcs/airoha/Makefile +@@ -5,3 +5,6 @@ pcs-airoha-objs := pcs-airoha-common.o + ifdef CONFIG_PCS_AIROHA_AN7581 + pcs-airoha-objs += pcs-an7581.o + endif ++ifdef CONFIG_PCS_AIROHA_AN7583 ++pcs-airoha-objs += pcs-an7583.o ++endif +--- a/drivers/net/pcs/airoha/pcs-airoha-common.c ++++ b/drivers/net/pcs/airoha/pcs-airoha-common.c +@@ -19,6 +19,7 @@ + static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv, + phy_interface_t interface) + { ++ struct device *dev = priv->dev; + u32 xsi_sel; + + switch (interface) { +@@ -36,6 +37,12 @@ static void airoha_pcs_setup_scu_eth(str + regmap_update_bits(priv->scu, AIROHA_SCU_SSR3, + AIROHA_SCU_ETH_XSI_SEL, + xsi_sel); ++ ++ /* AN7583 require additional setting */ ++ if (device_is_compatible(dev, "airoha,an7583-pcs-eth")) ++ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF, ++ AIROHA_SCU_ETH_MAC_SEL, ++ AIROHA_SCU_ETH_MAC_SEL_XFI); + } + + static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv, +@@ -100,16 +107,24 @@ static int airoha_pcs_setup_scu(struct a + + static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv) + { ++ const struct airoha_pcs_match_data *data = priv->data; ++ + regmap_set_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, + AIROHA_PCS_HSGMII_XFI_SEL); + + /* Disable Hibernation */ +- regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, +- AIROHA_PCS_USXGMII_SPEED_SEL_H); ++ if (data->hibernation_workaround) ++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, ++ AIROHA_PCS_USXGMII_SPEED_SEL_H); + + /* FIXME: wait Airoha */ + /* Avoid PCS sending garbage to MAC in some HW revision (E0) */ +- regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); ++ if (data->usxgmii_ber_time_fixup) ++ regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); ++ ++ if (data->usxgmii_rx_gb_out_vld_tweak) ++ regmap_clear_bits(priv->usxgmii_pcs, AN7583_PCS_USXGMII_RTL_MODIFIED, ++ AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD); + } + + static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv) +@@ -434,6 +449,13 @@ static int airoha_pcs_config(struct phyl + regmap_clear_bits(priv->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, + AIROHA_PCS_USXGMII_AN_ENABLE); ++ ++ if (data->usxgmii_xfi_mode_sel && ++ neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) ++ regmap_set_bits(priv->usxgmii_pcs, ++ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, ++ AIROHA_PCS_USXGMII_XFI_MODE_TX_SEL | ++ AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL); + } + + /* Clear any force bit that my be set by bootloader */ +@@ -985,7 +1007,8 @@ static int airoha_pcs_probe(struct platf + * manual rx calibration is needed. This is only limited to + * any SoC revision before E2. + */ +- if (data->port_type == AIROHA_PCS_ETH) { ++ if (device_is_compatible(dev, "airoha,an7581-pcs-eth") && ++ data->port_type == AIROHA_PCS_ETH) { + u32 val; + + ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val); +@@ -1003,6 +1026,8 @@ static int airoha_pcs_probe(struct platf + + static const struct airoha_pcs_match_data an7581_pcs_eth = { + .port_type = AIROHA_PCS_ETH, ++ .hibernation_workaround = true, ++ .usxgmii_ber_time_fixup = true, + .bringup = an7581_pcs_bringup, + .link_up = an7581_pcs_phya_link_up, + .rxlock_workaround = an7581_pcs_rxlock_workaround, +@@ -1010,13 +1035,33 @@ static const struct airoha_pcs_match_dat + + static const struct airoha_pcs_match_data an7581_pcs_pon = { + .port_type = AIROHA_PCS_PON, ++ .hibernation_workaround = true, ++ .usxgmii_ber_time_fixup = true, + .bringup = an7581_pcs_bringup, + .link_up = an7581_pcs_phya_link_up, + }; + ++static const struct airoha_pcs_match_data an7583_pcs_eth = { ++ .port_type = AIROHA_PCS_ETH, ++ .usxgmii_rx_gb_out_vld_tweak = true, ++ .usxgmii_xfi_mode_sel = true, ++ .bringup = an7583_pcs_common_phya_bringup, ++ .link_up = an7583_pcs_common_phya_link_up, ++}; ++ ++static const struct airoha_pcs_match_data an7583_pcs_pon = { ++ .port_type = AIROHA_PCS_PON, ++ .usxgmii_rx_gb_out_vld_tweak = true, ++ .usxgmii_xfi_mode_sel = true, ++ .bringup = an7583_pcs_common_phya_bringup, ++ .link_up = an7583_pcs_common_phya_link_up, ++}; ++ + static const struct of_device_id airoha_pcs_of_table[] = { + { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth }, + { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon }, ++ { .compatible = "airoha,an7583-pcs-eth", .data = &an7583_pcs_eth }, ++ { .compatible = "airoha,an7583-pcs-pon", .data = &an7583_pcs_pon }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, airoha_pcs_of_table); +--- a/drivers/net/pcs/airoha/pcs-airoha.h ++++ b/drivers/net/pcs/airoha/pcs-airoha.h +@@ -14,6 +14,9 @@ + #define AIROHA_SCU_PDIDR 0x5c + #define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0) + #define AIROHA_SCU_WAN_CONF 0x70 ++#define AIROHA_SCU_ETH_MAC_SEL BIT(24) ++#define AIROHA_SCU_ETH_MAC_SEL_XFI FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x0) ++#define AIROHA_SCU_ETH_MAC_SEL_PON FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x1) + #define AIROHA_SCU_WAN_SEL GENMASK(7, 0) + #define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10) + #define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11) +@@ -244,6 +247,8 @@ + #define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c + #define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0) + #define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320 ++#define AIROHA_PCS_USXGMII_XFI_MODE_TX_SEL BIT(20) ++#define AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL BIT(16) + #define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12) + #define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8) + #define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x0) +@@ -251,9 +256,27 @@ + #define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x2) + #define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x3) + #define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x4) ++#define AN7583_PCS_USXGMII_RTL_MODIFIED 0x334 ++#define AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD BIT(25) + + /* PMA_PHYA */ + #define AIROHA_PCS_ANA_PXP_CMN_EN 0x0 ++#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_8V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x0) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x1) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x2) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x3) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_9V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x4) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x5) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x6) ++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x7) ++#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16) ++/* GENMASK(2, 0) input selection from 0 to 7 ++ * BIT(3) OPAMP and path EN ++ * BIT(4) Current path measurement ++ * BIT(5) voltage/current path to PAD ++ */ ++#define AIROHA_PCS_ANA_CMN_MPXSELTOP_DC GENMASK(13, 8) + #define AIROHA_PCS_ANA_CMN_EN BIT(0) + #define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4 + #define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24) +@@ -347,6 +370,8 @@ + #define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16) + #define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8) + #define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5)) ++#define AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN 0x4c ++#define AIROHA_PCS_ANA_TXPLL_IB_EXT_EN BIT(24) + #define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50 + #define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24) + #define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16) +@@ -370,6 +395,9 @@ + #define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x3) + #define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8) + #define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN 0x60 ++#define AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN BIT(0) + #define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64 + #define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24) + #define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16) +@@ -435,16 +463,41 @@ + #define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24) + #define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16) + #define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0) ++#define AIROHA_PCS_ANA_PXP_TXPLL_VTP_EN 0x88 ++#define AIROHA_PCS_ANA_TXPLL_VTP GENMASK(10, 8) ++#define AIROHA_PCS_ANA_TXPLL_VTP_EN BIT(0) + #define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94 ++#define AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN BIT(25) /* 0: 128 1: 256 */ ++#define AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN BIT(24) ++#define AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN BIT(16) ++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL BIT(8) ++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x0) ++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_AVDD FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x1) + #define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) ++#define AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN 0x98 ++#define AIROHA_PCS_ANA_TXPLL_SPARE_L BIT(0) /* ICHP_DOUBLE */ ++#define AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL 0xa0 ++#define AIROHA_PCS_ANA_TDC_AUTOEN BIT(24) ++#define AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL 0xa8 ++#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL GENMASK(17, 16) ++#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN BIT(8) ++#define AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN 0xc0 ++#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_L GENMASK(26, 24) ++#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_H GENMASK(18, 16) + #define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4 + #define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24) + #define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0) ++#define AIROHA_PCS_ANA_PXP_TX_TERMCAL_SELPN 0xc8 ++#define AIROHA_PCS_ANA_TX_TDC_CK_SEL GENMASK(17, 16) + #define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc + #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24) + #define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) + #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_PR FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x0) + #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x1) ++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE BIT(8) ++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL BIT(0) ++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_8BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 0x0) ++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 0x1) + #define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4 + #define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16) + #define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) +@@ -452,6 +505,16 @@ + #define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) + #define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18) + #define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16) ++#define AIROHA_PCS_ANA_RX_REV_0 GENMASK(15, 0) ++#define AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) ++#define AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) ++#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) ++#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) ++#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) ++#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) ++#define AIROHA_PCS_ANA_REV_0_VOS_PNINV GENMASK(3, 2) ++#define AIROHA_PCS_ANA_REV_0_PLEYEBD4 BIT(1) ++#define AIROHA_PCS_ANA_REV_0_PLEYE_XOR_MON_EN BIT(0) + #define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8 + #define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24) + #define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16) +@@ -460,6 +523,8 @@ + #define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc + #define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8) + #define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0) ++#define AIROHA_PCS_ANA_PXP_CDR_LPF_BOT_LIM 0xe0 ++#define AIROHA_PCS_ANA_CDR_LPF_BOT_LIM GENMASK(18, 0) + #define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8 + #define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8) + #define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0) +@@ -475,6 +540,19 @@ + #define AIROHA_PCS_ANA_CDR_PR_DAC_BAND GENMASK(20, 16) + #define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8) + #define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV 0x100 ++#define AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS BIT(16) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV GENMASK(1, 0) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x0) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x1) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x2) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x3) ++#define AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL 0x108 ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1 GENMASK(25, 24) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x0) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x1) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x2) ++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x3) + #define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c + #define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24) + #define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19) +@@ -484,6 +562,7 @@ + #define AIROHA_PCS_ANA_CDR_PR_MONDPR_EN BIT(0) + #define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110 + #define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24) ++#define AIROHA_PCS_ANA_RX_DAC_RANGE_EYE GENMASK(9, 8) + #define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114 + #define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24) + #define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16) +@@ -532,7 +611,70 @@ + #define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0 + #define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24) + #define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4 ++#define AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER GENMASK(31, 24) ++#define AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER GENMASK(23, 16) ++#define AIROHA_PCS_PMA_LCPLL_EN_TIMER GENMASK(15, 8) + #define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0) ++#define AIROHA_PCS_PMA_LCPLL_TDC_PW_0 0x10 ++#define AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB BIT(0) ++#define AIROHA_PCS_PMA_LCPLL_TDC_PW_5 0x24 ++#define AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE BIT(24) ++#define AIROHA_PCS_PMA_LCPLL_AUTOK_TDC BIT(16) ++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_0 0x28 ++#define AIROHA_PCS_PMA_LCPLL_KI GENMASK(10, 8) ++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC GENMASK(1, 0) ++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x0) ++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x1) ++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x2) ++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x3) ++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_1 0x2c ++#define AIROHA_PCS_PMA_LCPLL_A_TDC GENMASK(11, 8) ++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL BIT(0) ++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x0) ++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_GPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x1) ++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_3 0x34 ++#define AIROHA_PCS_PMA_LCPLL_NCPO_LOAD BIT(8) ++#define AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT GENMASK(1, 0) ++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_5 0x3c ++#define AIROHA_PCS_PMA_LCPLL_TDC_AUTOPW_NCPO BIT(16) ++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_6 0x40 ++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY GENMASK(9, 8) ++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x0) ++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D1 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x1) ++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D2 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x2) ++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D3 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x3) ++#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_1 0x48 ++#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0) ++#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_2 0x4c ++#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON GENMASK(30, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0 0x68 ++#define AIROHA_PCS_PMA_X_MAX GENMASK(26, 16) ++#define AIROHA_PCS_PMA_X_MIN GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1 0x6c ++#define AIROHA_PCS_PMA_INDEX_MODE BIT(16) ++#define AIROHA_PCS_PMA_Y_MAX GENMASK(14, 8) ++#define AIROHA_PCS_PMA_Y_MIN GENMASK(6, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2 0x70 ++#define AIROHA_PCS_PMA_EYEDUR GENMASK(19, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3 0x74 ++#define AIROHA_PCS_PMA_EYE_NEXTPTS BIT(16) ++#define AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE BIT(8) ++#define AIROHA_PCS_PMA_EYE_NEXTPTS_SEL BIT(0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0 0x78 ++#define AIROHA_PCS_PMA_EYECNT_VTH GENMASK(15, 8) ++#define AIROHA_PCS_PMA_EYECNT_HTH GENMASK(7, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1 0x7c ++#define AIROHA_PCS_PMA_EO_VTH GENMASK(23, 16) ++#define AIROHA_PCS_PMA_EO_HTH GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0 0x80 ++#define AIROHA_PCS_PMA_EYE_MASK GENMASK(31, 24) ++#define AIROHA_PCS_PMA_CNTFOREVER BIT(16) ++#define AIROHA_PCS_PMA_CNTLEN GENMASK(9, 0) ++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1 0x84 ++#define AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B BIT(24) ++#define AIROHA_PCS_PMA_FORCE_EYEDUR_EN BIT(16) ++#define AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B BIT(8) ++#define AIROHA_PCS_PMA_DISB_EYEDUR_EN BIT(0) + #define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88 + #define AIROHA_PCS_PMA_DATA_SHIFT BIT(8) + #define AIROHA_PCS_PMA_EYECNT_FAST BIT(0) +@@ -564,14 +706,49 @@ + #define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0) + #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104 + #define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0 0x108 ++#define AIROHA_PCS_PMA_DISB_RX_FEOS_EN BIT(24) ++#define AIROHA_PCS_PMA_DISB_RX_PDOS_EN BIT(16) ++#define AIROHA_PCS_PMA_DISB_RX_PICAL_EN BIT(8) ++#define AIROHA_PCS_PMA_DISB_RX_OS_EN BIT(0) + #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c + #define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_DISB_RX_BLWC_EN BIT(16) ++#define AIROHA_PCS_PMA_DISB_RX_OS_RDY BIT(8) ++#define AIROHA_PCS_PMA_DISB_RX_SDCAL_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0 0x110 ++#define AIROHA_PCS_PMA_FORCE_RX_FEOS_EN BIT(24) ++#define AIROHA_PCS_PMA_FORCE_RX_PDOS_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_RX_PICAL_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_RX_OS_EN BIT(0) + #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114 + #define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24) ++#define AIROHA_PCS_PMA_FORCE_RX_BLWC_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_RX_OS_RDY BIT(8) ++#define AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN BIT(0) ++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_0 0x118 ++#define AIROHA_PCS_PMA_VEO_MASK GENMASK(31, 24) ++#define AIROHA_PCS_PMA_HEO_MASK GENMASK(18, 8) ++#define AIROHA_PCS_PMA_EQ_EN_DELAY GENMASK(7, 0) ++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_1 0x11c ++#define AIROHA_PCS_PMA_B_ZERO_SEL BIT(24) ++#define AIROHA_PCS_PMA_HEO_EMPHASIS BIT(16) ++#define AIROHA_PCS_PMA_A_MGAIN BIT(8) ++#define AIROHA_PCS_PMA_A_LGAIN BIT(0) + #define AIROHA_PCS_PMA_PHY_EQ_CTRL_2 0x120 + #define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16) + #define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8) + #define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_SS_RX_FEOS 0x144 ++#define AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE BIT(8) ++#define AIROHA_PCS_PMA_LFSEL GENMASK(7, 0) ++#define AIROHA_PCS_PMA_SS_RX_BLWC 0x148 ++#define AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM GENMASK(29, 23) ++#define AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM GENMASK(22, 16) ++#define AIROHA_PCS_PMA_EQ_BLWC_GAIN GENMASK(11, 8) ++#define AIROHA_PCS_PMA_EQ_BLWC_POL BIT(0) ++#define AIROHA_PCS_PMA_EQ_BLWC_POL_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x0) ++#define AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x1) + #define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c + #define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16) + #define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0) +@@ -590,31 +767,182 @@ + #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2) + #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3) + #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7) ++#define AIROHA_PCS_PMA_RX_PI_CAL 0x15c ++#define AIROHA_PCS_PMA_KPGAIN GENMASK(10, 8) ++#define AIROHA_PCS_PMA_RX_CAL1 0x160 ++#define AIROHA_PCS_PMA_CAL_CYC GENMASK(25, 24) ++#define AIROHA_PCS_PMA_CAL_CYC_63 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x0) ++#define AIROHA_PCS_PMA_CAL_CYC_15 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x1) ++#define AIROHA_PCS_PMA_CAL_CYC_31 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x2) ++#define AIROHA_PCS_PMA_CAL_CYC_127 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x3) ++#define AIROHA_PCS_PMA_CAL_STB GENMASK(17, 16) ++#define AIROHA_PCS_PMA_CAL_STB_5US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x0) ++#define AIROHA_PCS_PMA_CAL_STB_8US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x1) ++#define AIROHA_PCS_PMA_CAL_STB_16US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x2) ++#define AIROHA_PCS_PMA_CAL_STB_32US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x3) ++#define AIROHA_PCS_PMA_CAL_1US_SET GENMASK(15, 8) ++#define AIROHA_PCS_PMA_SIM_FAST_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_CAL2 0x164 ++#define AIROHA_PCS_PMA_CAL_CYC_TIME GENMASK(17, 16) ++#define AIROHA_PCS_PMA_CAL_OUT_OS GENMASK(11, 8) ++#define AIROHA_PCS_PMA_CAL_OS_PULSE BIT(0) + #define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c + #define AIROHA_PCS_PMA_SIGDET_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_FLL_0 0x170 ++#define AIROHA_PCS_PMA_KBAND_KFC GENMASK(25, 24) ++#define AIROHA_PCS_PMA_KBAND_KFC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x0) ++#define AIROHA_PCS_PMA_KBAND_KFC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x1) ++#define AIROHA_PCS_PMA_KBAND_KFC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x2) ++#define AIROHA_PCS_PMA_KBAND_KFC_64 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x3) ++#define AIROHA_PCS_PMA_FPKDIV GENMASK(18, 8) ++#define AIROHA_PCS_PMA_KBAND_PREDIV GENMASK(2, 0) ++#define AIROHA_PCS_PMA_KBAND_PREDIV_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x0) ++#define AIROHA_PCS_PMA_KBAND_PREDIV_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x1) ++#define AIROHA_PCS_PMA_KBAND_PREDIV_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x2) ++#define AIROHA_PCS_PMA_KBAND_PREDIV_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x3) + #define AIROHA_PCS_PMA_RX_FLL_1 0x174 ++#define AIROHA_PCS_PMA_SYMBOL_WD GENMASK(26, 24) ++#define AIROHA_PCS_PMA_SETTLE_TIME_SEL GENMASK(18, 16) + #define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0) + #define AIROHA_PCS_PMA_RX_FLL_2 0x178 + #define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16) + #define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0) + #define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1) + #define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2) ++#define AIROHA_PCS_PMA_AMP GENMASK(10, 8) ++#define AIROHA_PCS_PMA_PRBS_SEL GENMASK(2, 0) + #define AIROHA_PCS_PMA_RX_FLL_5 0x184 + #define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16) + #define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0) ++#define AIROHA_PCS_PMA_RX_FLL_6 0x188 ++#define AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN BIT(24) ++#define AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN BIT(16) ++#define AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN BIT(8) ++#define AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN BIT(0) + #define AIROHA_PCS_PMA_RX_FLL_B 0x19c + #define AIROHA_PCS_PMA_LOAD_EN BIT(0) ++#define AIROHA_PCS_PMA_RX_PDOS_CTRL_0 0x200 ++#define AIROHA_PCS_PMA_SAP_SEL GENMASK(18, 16) ++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x0) ++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x1) ++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x2) ++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x3) ++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x4) ++#define AIROHA_PCS_PMA_EYE_BLWC_ADD BIT(8) ++#define AIROHA_PCS_PMA_DATA_BLWC_ADD BIT(0) ++#define AIROHA_PCS_PMA_RX_RESET_0 0x204 ++#define AIROHA_PCS_PMA_CAL_RST_B BIT(24) ++#define AIROHA_PCS_PMA_EQ_PI_CAL_RST_B BIT(16) ++#define AIROHA_PCS_PMA_FEOS_RST_B BIT(8) + #define AIROHA_PCS_PMA_RX_RESET_1 0x208 + #define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8) ++#define AIROHA_PCS_PMA_PDOS_RST_B BIT(0) ++#define AIROHA_PCS_PMA_RX_DEBUG_0 0x20c ++#define AIROHA_PCS_PMA_RO_TOGGLE BIT(24) ++#define AIROHA_PCS_PMA_BISTCTL_CONTROL 0x210 ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL GENMASK(4, 0) ++/* AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x0) */ ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x1) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x2) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS15 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x3) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS23 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x4) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x5) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_HFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x6) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_MFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x7) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x8) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_5_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x9) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xa) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xb) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_8_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xc) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xd) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xe) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xf) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PROG_80 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x10) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x11) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x12) ++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x13) ++#define AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT 0x214 ++#define AIROHA_PCS_PMA_BISTCTL_POLLUTION 0x220 ++#define AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH BIT(16) ++#define AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED 0x224 ++#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD 0x230 ++#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK GENMASK(15, 0) ++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_2 0x23c ++#define AIROHA_PCS_PMA_PI_CAL_DATA_OUT GENMASK(22, 16) ++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_5 0x248 ++#define AIROHA_PCS_PMA_VEO_RDY BIT(24) ++#define AIROHA_PCS_PMA_HEO_RDY BIT(16) ++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_9 0x258 ++#define AIROHA_PCS_PMA_EO_Y_DONE BIT(24) ++#define AIROHA_PCS_PMA_EO_X_DONE BIT(16) ++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_10 0x25c ++#define AIROHA_PCS_PMA_EYE_EL GENMASK(26, 16) ++#define AIROHA_PCS_PMA_EYE_ER GENMASK(10, 0) + #define AIROHA_PCS_PMA_TX_RST_B 0x260 + #define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8) + #define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0) ++#define AIROHA_PCS_PMA_TX_CALIB_0 0x264 ++#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL GENMASK(25, 24) ++#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN BIT(16) ++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_11 0x290 ++#define AIROHA_PCS_PMA_EYE_EB GENMASK(14, 8) ++#define AIROHA_PCS_PMA_EYE_EU GENMASK(6, 0) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_0 0x294 ++#define AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_0 0x300 ++#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB BIT(24) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_1 0x304 ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0 BIT(24) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1 BIT(16) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0 BIT(8) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_2 0x308 ++#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE BIT(24) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS BIT(16) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE BIT(8) ++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1 BIT(0) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_3 0x30c ++#define AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY BIT(0) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_6 0x318 ++#define AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_EYECNT_RDY BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_3 0x31c ++#define AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY BIT(0) + #define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320 + #define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_5 0x324 ++#define AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN BIT(24) ++#define AIROHA_PCS_PMA_DISB_EYECNT_RDY BIT(16) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_7 0x328 ++#define AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B BIT(16) ++#define AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB BIT(8) ++#define AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB BIT(0) ++#define AIROHA_PCS_PMA_RX_FORCE_MODE_8 0x32c ++#define AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B BIT(24) ++#define AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B BIT(8) ++#define AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B BIT(0) + #define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330 ++#define AIROHA_PCS_PMA_FORCE_EYE_TOP_EN BIT(16) ++#define AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O BIT(8) + #define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_6 0x334 ++#define AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B BIT(16) ++#define AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB BIT(8) ++#define AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB BIT(0) ++#define AIROHA_PCS_PMA_RX_DISB_MODE_7 0x338 ++#define AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B BIT(24) ++#define AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B BIT(16) ++#define AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B BIT(8) ++#define AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B BIT(0) + #define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c ++#define AIROHA_PCS_PMA_DISB_EYE_TOP_EN BIT(16) ++#define AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O BIT(8) + #define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0) ++#define AIROHA_PCS_PMA_SS_BIST_1 0x344 ++#define AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL BIT(24) ++#define AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS BIT(0) + #define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c + #define AIROHA_PCS_PMA_XPON_CDR_PD_PWDB BIT(24) + #define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16) +@@ -637,7 +965,32 @@ + #define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0) + #define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c + #define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8) ++#define AIROHA_PCS_PMA_ADD_CLKPATH_RST_0 0x410 ++#define AIROHA_PCS_PMA_CLKPATH_RSTB_CK BIT(8) ++#define AIROHA_PCS_PMA_CLKPATH_RST_EN BIT(0) ++#define AIROHA_PCS_PMA_ADD_XPON_MODE_1 0x414 ++#define AIROHA_PCS_PMA_TX_BIST_GEN_EN BIT(16) ++#define AIROHA_PCS_PMA_R2T_MODE BIT(8) ++#define AIROHA_PCS_PMA_ADD_RX2ANA_1 0x424 ++#define AIROHA_PCS_PMA_RX_DAC_E0 GENMASK(30, 24) ++#define AIROHA_PCS_PMA_RX_DAC_D1 GENMASK(22, 16) ++#define AIROHA_PCS_PMA_RX_DAC_D0 GENMASK(14, 8) ++#define AIROHA_PCS_PMA_RX_DAC_EYE GENMASK(6, 0) ++#define AIROHA_PCS_PMA_ADD_RX2ANA_2 0x428 ++#define AIROHA_PCS_PMA_RX_FEOS_OUT GENMASK(13, 8) ++#define AIROHA_PCS_PMA_RX_DAC_E1 GENMASK(6, 0) ++#define AIROHA_PCS_PMA_PON_TX_COUNTER_0 0x440 ++#define AIROHA_PCS_PMA_TXCALIB_5US GENMASK(31, 16) ++#define AIROHA_PCS_PMA_TXCALIB_50US GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PON_TX_COUNTER_1 0x444 ++#define AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_TX_CK_EN_WAIT GENMASK(15, 0) ++#define AIROHA_PCS_PMA_PON_TX_COUNTER_2 0x448 ++#define AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT GENMASK(31, 16) ++#define AIROHA_PCS_PMA_TX_POWER_ON_WAIT GENMASK(15, 0) + #define AIROHA_PCS_PMA_SW_RST_SET 0x460 ++#define AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N BIT(17) ++#define AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N BIT(16) + #define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11) + #define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10) + #define AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N BIT(9) +@@ -650,17 +1003,32 @@ + #define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2) + #define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1) + #define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0) ++#define AIROHA_PCS_PMA_TX_DLY_CTRL 0x468 ++#define AIROHA_PCS_PMA_OUTBEN_DATA_MODE GENMASK(30, 28) ++#define AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE GENMASK(23, 16) ++#define AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE GENMASK(14, 8) ++#define AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE GENMASK(6, 0) + #define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474 + #define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16) + #define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c + #define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16) + #define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c ++/* 4ref_ck step: ++ * - 0x1 4ref_ck ++ * - 0x2 8ref_ck ++ * - 0x3 12ref_ck ++ * ... ++ */ ++#define AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME GENMASK(15, 8) ++#define AIROHA_PCS_PMA_OS_RDY_LATCH BIT(1) + #define AIROHA_PCS_PMA_DISB_LEQ BIT(0) + #define AIROHA_PCS_PMA_RX_FREQDET 0x530 + #define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16) + #define AIROHA_PCS_PMA_FBCK_LOCK BIT(0) + #define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580 + #define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_MD32_MEM_CLK_CTRL 0x60c ++#define AIROHA_PCS_PMA_MD32PM_CK_SEL GENMASK(31, 0) + #define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768 + #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL BIT(24) + #define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL GENMASK(19, 16) +@@ -683,8 +1051,13 @@ + #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8) + #define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0) + #define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE GENMASK(22, 16) + #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8) + #define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0) ++#define AIROHA_PCS_PMA_PXP_CDR_PR_FLL_COR 0x790 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE GENMASK(22, 16) + #define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794 + #define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24) + #define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16) +@@ -729,6 +1102,14 @@ + #define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16) + #define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8) + #define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB 0x83c ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON BIT(16) ++#define AIROHA_PCS_PMA_PXP_RX_OSCAL_EN 0x840 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB BIT(24) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB BIT(16) ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN BIT(0) + #define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c + #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24) + #define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16) +@@ -739,6 +1120,12 @@ + #define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16) + #define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8) + #define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_TXPLL_KBAND_LOAD_EN 0x858 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN BIT(0) ++#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG 0x864 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG BIT(0) + #define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874 + #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24) + #define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16) +@@ -750,10 +1137,31 @@ + #define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16) + #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8) + #define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0) ++#define AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN 0x898 ++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN BIT(8) ++#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN BIT(0) ++#define AIROHA_PCS_PMA_DIG_RESERVE_12 0x8b8 ++#define AIROHA_PCS_PMA_RESERVE_12_FEOS_0 BIT(0) ++#define AIROHA_PCS_PMA_DIG_RESERVE_24 0x8fc ++#define AIROHA_PCS_PMA_FORCE_RX_GEARBOX BIT(12) ++#define AIROHA_PCS_PMA_FORCE_SEL_RX_GEARBOX BIT(8) + + #define AIROHA_PCS_MAX_CALIBRATION_TRY 50 + #define AIROHA_PCS_MAX_NUM_RSTS 2 + ++enum pon_eo_buf_vals { ++ EYE_EU, ++ EYE_EB, ++ DAC_D0, ++ DAC_D1, ++ DAC_E0, ++ DAC_E1, ++ DAC_EYE, ++ FEOS, ++ ++ EO_BUF_MAX, ++}; ++ + enum xfi_port_type { + AIROHA_PCS_ETH, + AIROHA_PCS_PON, +@@ -790,6 +1198,11 @@ struct airoha_pcs_port { + struct airoha_pcs_match_data { + enum xfi_port_type port_type; + ++ bool hibernation_workaround; ++ bool usxgmii_ber_time_fixup; ++ bool usxgmii_rx_gb_out_vld_tweak; ++ bool usxgmii_xfi_mode_sel; ++ + int (*bringup)(struct airoha_pcs_priv *priv, + phy_interface_t interface); + void (*link_up)(struct airoha_pcs_priv *priv); +@@ -820,3 +1233,20 @@ static inline int an7581_pcs_rxlock_work + return 0; + } + #endif ++ ++#ifdef CONFIG_PCS_AIROHA_AN7583 ++int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface); ++ ++void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv); ++#else ++static inline int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv) ++{ ++} ++#endif +--- /dev/null ++++ b/drivers/net/pcs/airoha/pcs-an7583.c +@@ -0,0 +1,2199 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++#include ++#include ++ ++#include "pcs-airoha.h" ++ ++static void an7583_pcs_dig_reset_hold(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_PMA_RST_N); ++ ++ usleep_range(50, 100); ++} ++ ++static void an7583_pcs_dig_reset_release(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_TX_RST_N | ++ AIROHA_PCS_PMA_SW_RX_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_PMA_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N | ++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N); ++ ++ usleep_range(100, 200); ++} ++ ++static void an7583_pcs_common_phya_txpll(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 pcw, tdc_pcw; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: /* DS(RX)_1.25G / US(TX)_1.25G*/ ++ case PHY_INTERFACE_MODE_1000BASEX: ++ pcw = 0x32000000; ++ tdc_pcw = 0x64000000; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: /* DS(RX)_3.125G / US(TX)_3.125G */ ++ pcw = 0x3e800000; ++ tdc_pcw = 0x7d000000; ++ break; ++ case PHY_INTERFACE_MODE_5GBASER: /* DS(RX)_5.15625G / US(TX)_5.15625G */ ++ case PHY_INTERFACE_MODE_USXGMII: /* DS(RX)_10.31252G / US(TX)_10.3125G */ ++ case PHY_INTERFACE_MODE_10GBASER: ++ pcw = 0x33900000; ++ tdc_pcw = 0x67200000; ++ break; ++ default: ++ return; ++ } ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, ++ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_1, ++ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON, ++ tdc_pcw)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_2, ++ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON, ++ tdc_pcw)); ++} ++ ++static void an7583_pcs_common_phya_tx(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ u32 tx_rate_ctrl; ++ u32 ckin_divisor; ++ u32 fir_cn1, fir_c0b, fir_c1, fir_c2; ++ u32 tx_ben_exten_ftune; ++ u32 tx_dly_ben_ftune; ++ u32 tx_dly_data_ftune; ++ ++ if (data->port_type == AIROHA_PCS_ETH) ++ tx_ben_exten_ftune = 0x2; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ ckin_divisor = BIT(1); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 8; ++ fir_c1 = 0; ++ fir_c2 = 0; ++ ++ if (data->port_type == AIROHA_PCS_PON) { ++ tx_ben_exten_ftune = 0x7; ++ tx_dly_ben_ftune = 0x2; ++ tx_dly_data_ftune = 0x6; ++ } ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ ckin_divisor = BIT(2); ++ tx_rate_ctrl = BIT(0); ++ fir_cn1 = 0; ++ fir_c0b = 8; ++ fir_c1 = 1; ++ fir_c2 = 0; ++ if (data->port_type == AIROHA_PCS_PON) ++ tx_ben_exten_ftune = 0x2; ++ break; ++ case PHY_INTERFACE_MODE_5GBASER: ++ ckin_divisor = BIT(2); ++ tx_rate_ctrl = BIT(1); ++ fir_cn1 = 0; ++ fir_c0b = 14; ++ fir_c1 = 4; ++ fir_c2 = 0; ++ if (data->port_type == AIROHA_PCS_PON) ++ tx_ben_exten_ftune = 0x2; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ ckin_divisor = BIT(2) | BIT(0); ++ tx_rate_ctrl = BIT(1); ++ fir_cn1 = 0; ++ fir_c0b = 14; ++ fir_c1 = 4; ++ fir_c2 = 0; ++ ++ if (data->port_type == AIROHA_PCS_PON) { ++ tx_ben_exten_ftune = 0x16; ++ tx_dly_ben_ftune = 0xd; ++ tx_dly_data_ftune = 0x30; ++ } ++ ++ break; ++ default: ++ return; ++ } ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, ++ AIROHA_PCS_ANA_TX_DMEDGEGEN_EN | ++ AIROHA_PCS_ANA_TX_CKLDO_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CMN_EN, ++ AIROHA_PCS_ANA_CMN_VREFSEL | ++ AIROHA_PCS_ANA_CMN_MPXSELTOP_DC | ++ AIROHA_PCS_ANA_CMN_EN, ++ AIROHA_PCS_ANA_CMN_VREFSEL_9V | ++ FIELD_PREP(AIROHA_PCS_ANA_CMN_MPXSELTOP_DC, 0x1) | ++ AIROHA_PCS_ANA_CMN_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2, fir_c2) | ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, ++ ckin_divisor)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL, ++ tx_rate_ctrl)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, ++ AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE, ++ FIELD_PREP(AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE, tx_ben_exten_ftune)); ++ ++ if (data->port_type == AIROHA_PCS_PON) { ++ if (interface == PHY_INTERFACE_MODE_SGMII || interface == PHY_INTERFACE_MODE_1000BASEX || ++ interface == PHY_INTERFACE_MODE_USXGMII || interface == PHY_INTERFACE_MODE_10GBASER) ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, ++ AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE | ++ AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE, ++ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE, tx_dly_ben_ftune) | ++ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE, tx_dly_data_ftune)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_MD32_MEM_CLK_CTRL, ++ AIROHA_PCS_PMA_MD32PM_CK_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_MD32PM_CK_SEL, 0x3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, ++ AIROHA_PCS_PMA_OUTBEN_DATA_MODE, ++ FIELD_PREP(AIROHA_PCS_PMA_OUTBEN_DATA_MODE, 0x1)); ++ } ++} ++ ++static void an7583_pcs_common_phya_rx(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ ++ u32 rx_rev0; ++ u32 fe_gain_ctrl; ++ u32 dig_reserve_0; ++ u32 rx_force_mode_0; ++ u32 cdr_pr_beta_dac; ++ u32 phyck_sel; ++ u32 phyck_div; ++ u32 lpf_ratio; ++ u32 busbit_sel; ++ u32 rx_rate_ctrl; ++ u32 osr; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ dig_reserve_0 = 0x300; ++ cdr_pr_beta_dac = 0x8; ++ phyck_sel = 0x1; ++ phyck_div = 0x29; ++ lpf_ratio = 0x3; ++ osr = 0x3; ++ rx_rate_ctrl = 0x0; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ dig_reserve_0 = 0x300; ++ cdr_pr_beta_dac = 0x6; ++ phyck_sel = 0x1; ++ phyck_div = 0xb; ++ lpf_ratio = 0x1; ++ osr = 0x1; ++ rx_rate_ctrl = 0x0; ++ break; ++ case PHY_INTERFACE_MODE_5GBASER: ++ dig_reserve_0 = 0x400; ++ cdr_pr_beta_dac = 0x8; ++ phyck_sel = 0x2; ++ phyck_div = 0x42; ++ lpf_ratio = 0x1; ++ osr = 0x1; ++ rx_rate_ctrl = 0x2; ++ break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ dig_reserve_0 = 0x100; ++ cdr_pr_beta_dac = 0x8; ++ phyck_sel = 0x2; ++ phyck_div = 0x42; ++ lpf_ratio = 0x0; ++ osr = 0x0; ++ rx_rate_ctrl = 0x2; ++ break; ++ default: ++ return; ++ } ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, ++ AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL | ++ AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE, ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH | ++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, ++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS | ++ AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RESERVE_12, ++ AIROHA_PCS_PMA_RESERVE_12_FEOS_0); ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER) { ++ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3); ++ fe_gain_ctrl = 0x1; ++ rx_force_mode_0 = 0x1; ++ } else { ++ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) | ++ AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL | ++ BIT(7) | /* FIXME: Missing documentation for this BIT */ ++ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3); ++ fe_gain_ctrl = 0x3; ++ rx_force_mode_0 = 0x3; ++ } ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, ++ AIROHA_PCS_ANA_RX_REV_0, rx_rev0); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ fe_gain_ctrl)); ++ ++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RESERVE_0, ++ dig_reserve_0); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, ++ AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL, ++ rx_force_mode_0)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, ++ AIROHA_PCS_ANA_CDR_PR_BETA_DAC, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC, ++ cdr_pr_beta_dac)); ++ ++ if (data->port_type == AIROHA_PCS_ETH && ++ interface == PHY_INTERFACE_MODE_2500BASEX) ++ regmap_update_bits(priv->xfi_ana, ++ AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, ++ AIROHA_PCS_ANA_CDR_PR_DAC_BAND, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_DAC_BAND, ++ 0x6)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_PHYCK_SEL, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel)); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE | ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL, ++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ AIROHA_PCS_ANA_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_PHYCK_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, ++ AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ lpf_ratio)); ++ ++ if (interface == PHY_INTERFACE_MODE_5GBASER) ++ busbit_sel = AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE | ++ AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT; ++ else ++ busbit_sel = 0; ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, ++ AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE | ++ AIROHA_PCS_ANA_RX_BUSBIT_SEL, ++ busbit_sel); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1, ++ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl)); ++} ++ ++static void an7583_pcs_common_phya_ana(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ u32 txpll_chp_br, txpll_chp_ibias; ++ u32 lpf_bwr; ++ u32 vco_cfix; ++ u32 tcl_amp_vref; ++ bool sdm_ifm; ++ bool sdm_di; ++ bool sdm_hren; ++ bool vcodiv; ++ bool chp_double_en; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ if (data->port_type == AIROHA_PCS_PON) { ++ txpll_chp_br = 0xa; ++ txpll_chp_ibias = 0x18; ++ lpf_bwr = 0x16; ++ } else { ++ txpll_chp_br = 0x5; ++ txpll_chp_ibias = 0x31; ++ lpf_bwr = 0xb; ++ } ++ vco_cfix = 0x3; ++ tcl_amp_vref = 0xb; ++ vcodiv = false; ++ sdm_hren = data->port_type == AIROHA_PCS_PON; ++ sdm_ifm = data->port_type == AIROHA_PCS_PON; ++ sdm_di = data->port_type == AIROHA_PCS_PON; ++ chp_double_en = false; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ txpll_chp_br = 0x5; ++ txpll_chp_ibias = 0x1e; ++ lpf_bwr = 0xb; ++ vco_cfix = 0x0; ++ tcl_amp_vref = 0xe; ++ vcodiv = true; ++ sdm_hren = false; ++ sdm_ifm = false; ++ sdm_di = false; ++ chp_double_en = data->port_type == AIROHA_PCS_PON; ++ break; ++ case PHY_INTERFACE_MODE_5GBASER: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_USXGMII: ++ txpll_chp_br = 0xa; ++ txpll_chp_ibias = 0x18; ++ lpf_bwr = 0x16; ++ sdm_hren = true; ++ vco_cfix = 0x2; ++ tcl_amp_vref = 0xb; ++ vcodiv = false; ++ sdm_ifm = true; ++ sdm_di = true; ++ chp_double_en = false; ++ break; ++ default: ++ return; ++ } ++ ++ if (data->port_type == AIROHA_PCS_PON) ++ /* XPON TDC */ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL, ++ AIROHA_PCS_ANA_TDC_AUTOEN); ++ ++ /* TXPLL VCO LDO Out */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT | ++ AIROHA_PCS_ANA_TXPLL_LDO_OUT, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VTP_EN, ++ AIROHA_PCS_ANA_TXPLL_VTP | ++ AIROHA_PCS_ANA_TXPLL_VTP_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VTP, 0x0) | ++ AIROHA_PCS_ANA_TXPLL_VTP_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL, ++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL | ++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL, 0x1) | ++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN); ++ ++ /* Setup RSTB */ ++ /* FIXME: different order */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ AIROHA_PCS_ANA_TXPLL_RST_DLY | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV | ++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL, ++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) | ++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1); ++ ++ /* Setup SDM */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, ++ AIROHA_PCS_ANA_TXPLL_SDM_MODE | ++ AIROHA_PCS_ANA_TXPLL_SDM_IFM | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) | ++ (sdm_ifm ? AIROHA_PCS_ANA_TXPLL_SDM_IFM : 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 | ++ (sdm_di ? AIROHA_PCS_ANA_TXPLL_SDM_DI_EN : 0)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_SDM_HREN | ++ AIROHA_PCS_ANA_TXPLL_SDM_OUT | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD, ++ (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) | ++ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM); ++ ++ /* Setup SSC */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA | ++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, ++ AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN | ++ AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI | ++ AIROHA_PCS_ANA_TXPLL_SSC_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, ++ AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0)); ++ ++ regmap_update_bits(priv->xfi_ana, AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN, ++ AIROHA_PCS_ANA_TXPLL_SPARE_L, ++ chp_double_en ? AIROHA_PCS_ANA_TXPLL_SPARE_L : 0); ++ ++ /* Setup LPF */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, ++ AIROHA_PCS_ANA_TXPLL_LPF_BC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BR | ++ AIROHA_PCS_ANA_TXPLL_CHP_IOFST | ++ AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, txpll_chp_br) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, txpll_chp_ibias)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_LPF_BWC | ++ AIROHA_PCS_ANA_TXPLL_LPF_BWR | ++ AIROHA_PCS_ANA_TXPLL_LPF_BP, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, 0x18) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, 0x2)); ++ ++ /* Setup VCO */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_CFIX, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L | ++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H | ++ AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR | ++ AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) | ++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN); ++ ++ /* Setup KBand */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KF | ++ AIROHA_PCS_ANA_TXPLL_KBAND_KFC | ++ AIROHA_PCS_ANA_TXPLL_KBAND_DIV | ++ AIROHA_PCS_ANA_TXPLL_KBAND_CODE, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x2) | ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_KBAND_KS, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, ++ AIROHA_PCS_ANA_TXPLL_KBAND_OPTION); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_KBAND_LOAD_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE | ++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN, ++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 | ++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) | ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4); ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_VCODIV, ++ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : ++ AIROHA_PCS_ANA_TXPLL_VCODIV_1); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, ++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN, ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 | ++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, ++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN); ++ ++ /* Setup TX TermCal */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN, ++ AIROHA_PCS_ANA_TX_TERMCAL_VREF_L | ++ AIROHA_PCS_ANA_TX_TERMCAL_VREF_H, ++ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_L, 0x2) | ++ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_H, 0x2)); ++ ++ /* Setup XPON RX */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN | ++ AIROHA_PCS_ANA_RX_FE_EQ_HZEN, ++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | ++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, ++ AIROHA_PCS_ANA_FE_VCM_GEN_PWDB); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, ++ AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x8000)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_BOT_LIM, ++ AIROHA_PCS_ANA_CDR_LPF_BOT_LIM, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_BOT_LIM, 0x78000)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV, ++ AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, ++ AIROHA_PCS_ANA_RX_DAC_RANGE_EYE, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_RANGE_EYE, 0x2)); ++} ++ ++static void an7583_pcs_cfg_phy_type(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ ++ /* Enable PLL force selection and Force Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN); ++ ++ if (data->port_type == AIROHA_PCS_PON) { ++ /* TDC */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, ++ AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT, 0x1)); ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1, ++ AIROHA_PCS_PMA_LCPLL_A_TDC, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_A_TDC, 0x5)); ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_TERMCAL_SELPN, ++ AIROHA_PCS_ANA_TX_TDC_CK_SEL, ++ FIELD_PREP(AIROHA_PCS_ANA_TX_TDC_CK_SEL, 0x0)); ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, ++ AIROHA_PCS_ANA_RX_TDC_CK_SEL); ++ } ++ ++ /* PLL EN HW Mode */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, ++ AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER | ++ AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER | ++ AIROHA_PCS_PMA_LCPLL_EN_TIMER | ++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER, 0x1) | ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER, 0x10) | ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_EN_TIMER, 0xa) | ++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_1, ++ AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT | ++ AIROHA_PCS_PMA_TX_CK_EN_WAIT, ++ FIELD_PREP(AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT, 0x113) | ++ FIELD_PREP(AIROHA_PCS_PMA_TX_CK_EN_WAIT, 0xfa)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_2, ++ AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT | ++ AIROHA_PCS_PMA_TX_POWER_ON_WAIT, ++ FIELD_PREP(AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT, 0x9b) | ++ FIELD_PREP(AIROHA_PCS_PMA_TX_POWER_ON_WAIT, 0x210)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_0, ++ AIROHA_PCS_PMA_TXCALIB_5US | ++ AIROHA_PCS_PMA_TXCALIB_50US, ++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_5US, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_50US, 0x26)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_0, ++ AIROHA_PCS_PMA_LCPLL_KI, ++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_KI, 0x3)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_5, ++ AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE); ++ ++ an7583_pcs_common_phya_txpll(priv, interface); ++ an7583_pcs_common_phya_tx(priv, interface); ++ ++ /* RX HW mode counter */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, ++ AIROHA_PCS_PMA_RX_OS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6, ++ AIROHA_PCS_PMA_RX_OS_END, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, ++ AIROHA_PCS_PMA_OSC_SPEED_OPT, ++ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1, ++ AIROHA_PCS_PMA_RX_PICAL_END | ++ AIROHA_PCS_PMA_RX_PICAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x3e8) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4, ++ AIROHA_PCS_PMA_RX_SDCAL_END | ++ AIROHA_PCS_PMA_RX_SDCAL_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x3e8) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2, ++ AIROHA_PCS_PMA_RX_PDOS_END | ++ AIROHA_PCS_PMA_RX_PDOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x3e8) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3, ++ AIROHA_PCS_PMA_RX_FEOS_END | ++ AIROHA_PCS_PMA_RX_FEOS_START, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x3e8) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2)); ++ ++ /* RX Settings */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, ++ AIROHA_PCS_PMA_FOM_NUM_ORDER | ++ AIROHA_PCS_PMA_A_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) | ++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0, ++ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN, ++ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, 0x240) | ++ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, 0x1c0)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, ++ AIROHA_PCS_PMA_DATA_SHIFT); ++ ++ an7583_pcs_common_phya_rx(priv, interface); ++ an7583_pcs_common_phya_ana(priv, interface); ++ ++ /* Setup EYE */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, ++ AIROHA_PCS_PMA_EYECNT_FAST); ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3, ++ AIROHA_PCS_PMA_EYE_NEXTPTS); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0, ++ AIROHA_PCS_PMA_EYECNT_VTH | ++ AIROHA_PCS_PMA_EYECNT_HTH, ++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1, ++ AIROHA_PCS_PMA_EO_VTH | ++ AIROHA_PCS_PMA_EO_HTH, ++ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, ++ AIROHA_PCS_PMA_EYE_MASK | ++ AIROHA_PCS_PMA_CNTLEN, ++ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff) | ++ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xd0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, ++ AIROHA_PCS_PMA_VEO_MASK | ++ AIROHA_PCS_PMA_HEO_MASK | ++ AIROHA_PCS_PMA_EQ_EN_DELAY, ++ FIELD_PREP(AIROHA_PCS_PMA_VEO_MASK, 0x0) | ++ FIELD_PREP(AIROHA_PCS_PMA_HEO_MASK, 0x0) | ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x1)); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1, ++ AIROHA_PCS_PMA_A_LGAIN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CAL1, ++ AIROHA_PCS_PMA_CAL_CYC | ++ AIROHA_PCS_PMA_CAL_STB | ++ AIROHA_PCS_PMA_CAL_1US_SET | ++ AIROHA_PCS_PMA_SIM_FAST_EN, ++ AIROHA_PCS_PMA_CAL_CYC_15 | ++ AIROHA_PCS_PMA_CAL_STB_8US | ++ FIELD_PREP(AIROHA_PCS_PMA_CAL_1US_SET, 0x2e) | ++ AIROHA_PCS_PMA_SIM_FAST_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CAL2, ++ AIROHA_PCS_PMA_CAL_CYC_TIME | ++ AIROHA_PCS_PMA_CAL_OUT_OS | ++ AIROHA_PCS_PMA_CAL_OS_PULSE, ++ FIELD_PREP(AIROHA_PCS_PMA_CAL_CYC_TIME, 0x0) | ++ FIELD_PREP(AIROHA_PCS_PMA_CAL_OUT_OS, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5, ++ AIROHA_PCS_PMA_RX_RDY | ++ AIROHA_PCS_PMA_RX_BLWC_RDY_EN, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) | ++ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FEOS, ++ AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE | ++ AIROHA_PCS_PMA_LFSEL, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1, ++ AIROHA_PCS_PMA_INDEX_MODE | ++ AIROHA_PCS_PMA_Y_MAX | ++ AIROHA_PCS_PMA_Y_MIN, ++ AIROHA_PCS_PMA_INDEX_MODE | ++ FIELD_PREP(AIROHA_PCS_PMA_Y_MAX, 0x3f) | ++ FIELD_PREP(AIROHA_PCS_PMA_Y_MIN, 0x40)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2, ++ AIROHA_PCS_PMA_EYEDUR, ++ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x18)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, ++ AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME | ++ AIROHA_PCS_PMA_OS_RDY_LATCH | ++ AIROHA_PCS_PMA_DISB_LEQ, ++ FIELD_PREP(AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME, 0x2) | ++ AIROHA_PCS_PMA_OS_RDY_LATCH); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_0, ++ AIROHA_PCS_PMA_KBAND_KFC | ++ AIROHA_PCS_PMA_FPKDIV | ++ AIROHA_PCS_PMA_KBAND_PREDIV, ++ AIROHA_PCS_PMA_KBAND_KFC_8 | ++ FIELD_PREP(AIROHA_PCS_PMA_FPKDIV, 0xa5) | ++ AIROHA_PCS_PMA_KBAND_PREDIV_4); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_1, ++ AIROHA_PCS_PMA_SYMBOL_WD | ++ AIROHA_PCS_PMA_SETTLE_TIME_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_SYMBOL_WD, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_SETTLE_TIME_SEL, 0x1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_5, ++ AIROHA_PCS_PMA_FLL_IDAC_MIN | ++ AIROHA_PCS_PMA_FLL_IDAC_MAX, ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) | ++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x1ff)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_2, ++ AIROHA_PCS_PMA_AMP | ++ AIROHA_PCS_PMA_PRBS_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_AMP, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_PRBS_SEL, 0x3)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, ++ AIROHA_PCS_PMA_DISB_BLWC_OFFSET); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0, ++ AIROHA_PCS_PMA_EYE_BLWC_ADD | ++ AIROHA_PCS_PMA_DATA_BLWC_ADD, ++ AIROHA_PCS_PMA_DATA_BLWC_ADD); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_BLWC, ++ AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM | ++ AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM | ++ AIROHA_PCS_PMA_EQ_BLWC_GAIN | ++ AIROHA_PCS_PMA_EQ_BLWC_POL, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM, 0x10) | ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM, 0x70) | ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_GAIN, 0xa) | ++ AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION); ++} ++ ++static void an7583_pcs_common_phya_txpll_on(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0, ++ AIROHA_PCS_PMA_SW_LCPLL_EN); ++ ++ udelay(6); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN | ++ AIROHA_PCS_ANA_TXPLL_VREF_SEL, ++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN | ++ AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG); ++ ++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN, ++ AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN | ++ AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, ++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN, ++ AIROHA_PCS_ANA_TXPLL_IB_EXT_EN); ++ ++ usleep_range(500, 1000); ++} ++ ++static void an7583_pcs_common_phya_tx_on(struct airoha_pcs_priv *priv) ++{ ++ u32 xfi_tx_term_sel = 0x1; ++ // int efuse_valid; ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B, ++ AIROHA_PCS_PMA_TX_TOP_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_ADD_CLKPATH_RST_0, ++ AIROHA_PCS_PMA_CLKPATH_RSTB_CK | ++ AIROHA_PCS_PMA_CLKPATH_RST_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B, ++ AIROHA_PCS_PMA_TXCALIB_RST_B | ++ AIROHA_PCS_PMA_TX_TOP_RST_B); ++ ++ usleep_range(100, 200); ++ ++ /* TODO handle efuse */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_CALIB_0, ++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL | ++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN, ++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL, ++ xfi_tx_term_sel) | ++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN); ++} ++ ++static void an7583_pcs_common_phya_rx_preset(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 cdr_pr_buf_in_sr; ++ bool cdr_pr_cap_en; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_2500BASEX: ++ cdr_pr_cap_en = true; ++ cdr_pr_buf_in_sr = 0x6; ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_5GBASER: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_USXGMII: ++ cdr_pr_cap_en = false; ++ cdr_pr_buf_in_sr = 0x7; ++ break; ++ default: ++ return; ++ } ++ ++ /* Setup RX Precondition */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL | ++ AIROHA_PCS_ANA_RX_SIGDET_PEAK, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, 0x2) | ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, 0x2)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, ++ AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, 0x3)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, ++ AIROHA_PCS_ANA_CDR_PR_CAP_EN | ++ AIROHA_PCS_ANA_CDR_BUF_IN_SR, ++ (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_OS_RDY); ++ ++ /* Setup L2R */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++ ++ /* Setup LEQ setting */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0)); ++ ++ /* Keep EYE reset */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); ++ ++ /* Kepp BLWC reset */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_BLWC_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_BLWC_EN); ++} ++ ++static void an7583_pcs_common_phya_rx_on(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); ++ ++ /* RX SigDet Pwdb */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, ++ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | ++ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, ++ AIROHA_PCS_PMA_RX_SIDGET_PWDB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0, ++ AIROHA_PCS_PMA_RX_SYS_EN_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1)); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, ++ AIROHA_PCS_ANA_CDR_PR_FBKSEL | ++ AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL | ++ AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x5) | ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x5)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_PDOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_FEOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_OS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_BLWC_EN); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV, ++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, ++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1); ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL, ++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, ++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_RX_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++ ++ usleep_range(100, 200); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++} ++ ++static void an7583_pcs_common_phya_l2d(struct airoha_pcs_priv *priv) ++{ ++ /* Setup LPF L2D force and disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++ ++ usleep_range(200, 300); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++} ++ ++static void an7583_pcs_common_phya_tdc_off(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, ++ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, ++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1, ++ AIROHA_PCS_PMA_LCPLL_GPON_SEL, ++ AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_0, ++ AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB); ++ ++ usleep_range(100, 200); ++} ++ ++static void an7583_pcs_common_phya_rx_oscal(struct airoha_pcs_priv *priv) ++{ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_FBCK_LOCK); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_FBCK_LOCK); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN); ++ ++ usleep_range(200, 300); ++ ++ /* Set normal of force mode */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_OS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_OS_RDY); ++ ++ /* Disable force mode signal */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); ++ ++ /* Release reset enable */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++} ++ ++static void an7583_pcs_common_phya_pical(struct airoha_pcs_priv *priv) ++{ ++ /* Pre Condition */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, ++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL, ++ AIROHA_PCS_PMA_KPGAIN, ++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, ++ AIROHA_PCS_PMA_EQ_EN_DELAY, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x8)); ++ ++ /* Reset Block */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, ++ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, ++ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, ++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); ++ ++ /* Enable */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, ++ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, ++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); ++ ++ /* Release Reset and Enable */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); ++ ++ usleep_range(200, 300); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, ++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); ++} ++ ++static void an7583_pcs_common_phya_pdos(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN); ++ ++ /* Pre Condition */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_OS_RDY); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_EYEDUR_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0, ++ AIROHA_PCS_PMA_SAP_SEL, ++ AIROHA_PCS_PMA_SAP_SEL_SHIFT_8); ++ ++ /* Reset Block */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, ++ AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_1, ++ AIROHA_PCS_PMA_PDOS_RST_B); ++ ++ /* Disable */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_PDOS_EN); ++ ++ /* Release Reset and Enable */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_OS_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_1, ++ AIROHA_PCS_PMA_PDOS_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); ++ ++ usleep_range(200, 300); ++ ++ /* Disable (again) */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++ ++ /* Release EYE related */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_EYEDUR_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_EN); ++ ++ /* Disable PDOS */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN); ++} ++ ++static void an7583_pcs_common_phya_feos(struct airoha_pcs_priv *priv) ++{ ++ /* Pre Condition */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_OS_RDY); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); ++ ++ /* Setting */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FEOS, ++ AIROHA_PCS_PMA_LFSEL, ++ FIELD_PREP(AIROHA_PCS_PMA_LFSEL, 0x30)); ++ ++ /* Reset */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_FEOS_RST_B); ++ ++ /* Disable */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_FEOS_EN); ++ ++ /* Release Reset and Enable */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_OS_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_FEOS_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); ++ ++ usleep_range(1000, 1500); ++ ++ /* Disable */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_OS_EN); ++} ++ ++static void an7583_pcs_common_phya_sdcal(struct airoha_pcs_priv *priv) ++{ ++ /* Pre Condition */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN); ++ ++ /* Reset */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_CAL_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); ++ ++ /* Release Reset and Enable */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_CAL_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, ++ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); ++ ++ usleep_range(200, 300); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); ++ ++ /* SigDet Cal Disable */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | ++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN); ++} ++ ++static void an7583_pcs_common_phya_phy_status(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_OS_RDY); ++ udelay(1); ++} ++ ++static void an7583_pcs_common_phya_eye_setting(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ u32 x_min, x_max; ++ u32 cdr_lpf_ratio; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ x_min = 0x0; ++ x_max = 0x400; ++ cdr_lpf_ratio = 0x3; ++ break; ++ case PHY_INTERFACE_MODE_2500BASEX: ++ x_min = 0x140; ++ x_max = 0x2c0; ++ cdr_lpf_ratio = 0x0; ++ break; ++ case PHY_INTERFACE_MODE_5GBASER: ++ x_min = 0x180; ++ x_max = 0x280; ++ cdr_lpf_ratio = 0x1; ++ break; ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_USXGMII: ++ x_min = 0x1c0; ++ x_max = 0x234; ++ cdr_lpf_ratio = 0x0; ++ break; ++ default: ++ return; ++ } ++ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, ++ AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, ++ cdr_lpf_ratio)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, ++ AIROHA_PCS_PMA_EYE_MASK, ++ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0, ++ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN, ++ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, x_max) | ++ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, x_min)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, ++ AIROHA_PCS_PMA_CNTLEN, ++ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xf8)); ++ ++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, ++ AIROHA_PCS_PMA_CNTFOREVER); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, ++ AIROHA_PCS_PMA_DATA_SHIFT); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1, ++ AIROHA_PCS_PMA_INDEX_MODE); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2, ++ AIROHA_PCS_PMA_EYEDUR, ++ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x44c)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3, ++ AIROHA_PCS_PMA_EYE_NEXTPTS | ++ AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE | ++ AIROHA_PCS_PMA_EYE_NEXTPTS_SEL, ++ AIROHA_PCS_PMA_EYE_NEXTPTS); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0, ++ AIROHA_PCS_PMA_EYECNT_VTH | ++ AIROHA_PCS_PMA_EYECNT_HTH, ++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1, ++ AIROHA_PCS_PMA_EO_VTH | ++ AIROHA_PCS_PMA_EO_HTH, ++ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) | ++ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1, ++ AIROHA_PCS_PMA_B_ZERO_SEL | ++ AIROHA_PCS_PMA_HEO_EMPHASIS | ++ AIROHA_PCS_PMA_A_MGAIN | ++ AIROHA_PCS_PMA_A_LGAIN); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, ++ AIROHA_PCS_PMA_A_SEL, ++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x1)); ++} ++ ++static void an7583_pcs_common_phya_eye_cal(struct airoha_pcs_priv *priv) ++{ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE, 0x0)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_FLL_COR, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE | ++ AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE, 0x0)); ++ ++ /* Redo PICal and reset Block */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, ++ AIROHA_PCS_PMA_EQ_EN_DELAY, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL, ++ AIROHA_PCS_PMA_KPGAIN, ++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x1)); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, ++ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, ++ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB); ++ ++ /* Enable PICal */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, ++ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, ++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, ++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); ++ ++ /* Release Reset */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0, ++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, ++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ usleep_range(1000, 1500); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, ++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, ++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, ++ AIROHA_PCS_PMA_DISB_EYECNT_RDY); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_EYECNT_RDY); ++ ++ usleep_range(1000, 1500); ++} ++ ++static void an7583_pcs_common_phya_eye_eo_read(struct airoha_pcs_priv *priv, ++ u32 *heo, u32 *veo) ++{ ++ u32 eo_buf[EO_BUF_MAX]; ++ u32 eye_el, eye_er; ++ u32 feos; ++ u32 val; ++ int i; ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_6, ++ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN); ++ ++ usleep_range(50, 100); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_6, ++ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN | ++ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DEBUG_0, ++ AIROHA_PCS_PMA_RO_TOGGLE); ++ ++ usleep_range(100, 200); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DEBUG_0, ++ AIROHA_PCS_PMA_RO_TOGGLE); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_10, &val); ++ eye_el = FIELD_GET(AIROHA_PCS_PMA_EYE_EL, val); ++ eye_er = FIELD_GET(AIROHA_PCS_PMA_EYE_ER, val); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_11, &val); ++ eo_buf[EYE_EU] = FIELD_GET(AIROHA_PCS_PMA_EYE_EU, val); ++ eo_buf[EYE_EB] = FIELD_GET(AIROHA_PCS_PMA_EYE_EB, val); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_ADD_RX2ANA_1, &val); ++ eo_buf[DAC_EYE] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_EYE, val); ++ eo_buf[DAC_D0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D0, val); ++ eo_buf[DAC_D1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D1, val); ++ eo_buf[DAC_E0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E0, val); ++ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_ADD_RX2ANA_2, &val); ++ eo_buf[FEOS] = FIELD_GET(AIROHA_PCS_PMA_RX_FEOS_OUT, val); ++ eo_buf[DAC_E1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E1, val); ++ ++ feos = eo_buf[FEOS]; ++ ++ for (i = 0; i < ARRAY_SIZE(eo_buf); i++) { ++ if ((eo_buf[i] == feos) && (eo_buf[i] >= 32)) ++ eo_buf[i] = eo_buf[i] - 64; ++ else if (eo_buf[i] >= 64) ++ eo_buf[i] = eo_buf[i] - 128; ++ } ++ ++ /* Check if CLK unlocking happens (E0 result validity) */ ++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_5, &val); ++ if (!FIELD_GET(AIROHA_PCS_PMA_HEO_RDY, val)) { ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0, ++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, ++ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB); ++ ++ usleep_range(500, 700); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, ++ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB); ++ ++ usleep_range(500, 700); ++ } ++ ++ *heo = abs(eye_er - eye_el); ++ *veo = abs(eo_buf[EYE_EU] - eo_buf[EYE_EB]); ++} ++ ++static void an7583_pcs_common_phya_eye_eo(struct airoha_pcs_priv *priv, ++ phy_interface_t interface, ++ u32 *heo, u32 *veo) ++{ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); ++ ++ if (interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_USXGMII) ++ usleep_range(5500, 6000); ++ else ++ msleep(55); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, ++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE | ++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, ++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, ++ AIROHA_PCS_PMA_DISB_EYEDUR_EN); ++ ++ an7583_pcs_common_phya_eye_eo_read(priv, heo, veo); ++ ++ /* Clear Eye SW value */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, ++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, ++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); ++ ++ /* Reset PICal Rdy */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, ++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, ++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); ++ ++ /* Reset Eyecnt Rdy */ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, ++ AIROHA_PCS_PMA_DISB_EYECNT_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, ++ AIROHA_PCS_PMA_FORCE_EYECNT_RDY); ++} ++ ++static void an7583_pcs_common_phya_eo_scan(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ ++ u32 best_heo = 0, best_veo = 0; ++ u32 leq_gain, best_leq_gain; ++ u32 best_leq_peacking = 0; ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ case PHY_INTERFACE_MODE_5GBASER: ++ leq_gain = 3; ++ break; ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_USXGMII: ++ leq_gain = 1; ++ break; ++ default: ++ return; ++ } ++ ++ best_leq_gain = leq_gain; ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); ++ ++ an7583_pcs_common_phya_eye_setting(priv, interface); ++ ++ /* EYE Open */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, ++ AIROHA_PCS_PMA_EQ_EN_DELAY, ++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL, ++ AIROHA_PCS_PMA_KPGAIN, ++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4)); ++ ++ for (; leq_gain <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL); leq_gain++) { ++ u32 leq_peaking; ++ u32 heo, veo; ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, leq_gain)); ++ ++ for (leq_peaking = 0; leq_peaking <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL); leq_peaking++) { ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, leq_peaking)); ++ ++ usleep_range(500, 700); ++ ++ an7583_pcs_common_phya_eye_cal(priv); ++ an7583_pcs_common_phya_eye_eo(priv, interface, &heo, &veo); ++ ++ if (veo > 53 && best_veo > 53) { ++ if (heo > best_heo) { ++ best_heo = heo; ++ best_veo = veo; ++ best_leq_peacking = leq_peaking; ++ best_leq_gain = leq_gain; ++ } else if (heo == best_heo && veo > best_veo) { ++ best_heo = heo; ++ best_veo = veo; ++ best_leq_peacking = leq_peaking; ++ best_leq_gain = leq_gain; ++ } ++ } else { ++ if (veo > best_veo) { ++ best_heo = heo; ++ best_veo = veo; ++ best_leq_peacking = leq_peaking; ++ best_leq_gain = leq_gain; ++ } ++ } ++ } ++ } ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, best_leq_gain)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, ++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, ++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, best_leq_peacking)); ++} ++ ++static void an7583_pcs_common_phya_rxrdy(struct airoha_pcs_priv *priv) ++{ ++ u32 xfi_rx_term_sel = 0x1; ++ // int efuse_valid; ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_FORCE_RX_RDY); ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); ++ ++ /* TODO HANDLE EFUSE */ ++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, ++ AIROHA_PCS_ANA_RX_FE_50OHMS_SEL, ++ FIELD_PREP(AIROHA_PCS_ANA_RX_FE_50OHMS_SEL, ++ xfi_rx_term_sel)); ++} ++ ++static void an7583_pcs_common_phya_bist_setting(struct airoha_pcs_priv *priv) ++{ ++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT, ++ 0x8ff1fd53); ++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED, ++ 0xFF1FD53); ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD, ++ AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK, ++ FIELD_PREP(AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK, 0x1)); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_CONTROL, ++ AIROHA_PCS_PMA_BISTCTL_PAT_SEL, ++ AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_POLLUTION, ++ AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_BIST_1, ++ AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL | ++ AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS); ++} ++ ++static void an7583_pcs_first_plug_in(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ const struct airoha_pcs_match_data *data = priv->data; ++ ++ an7583_pcs_common_phya_rx_preset(priv, interface); ++ if (data->port_type == AIROHA_PCS_PON) ++ an7583_pcs_common_phya_tdc_off(priv); ++ an7583_pcs_common_phya_rx_on(priv); ++ an7583_pcs_common_phya_l2d(priv); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_REF_RST_N); ++ ++ an7583_pcs_common_phya_rx_oscal(priv); ++ an7583_pcs_common_phya_pical(priv); ++ an7583_pcs_common_phya_pdos(priv); ++ an7583_pcs_common_phya_feos(priv); ++ an7583_pcs_common_phya_sdcal(priv); ++ an7583_pcs_common_phya_phy_status(priv); ++ ++ an7583_pcs_dig_reset_release(priv); ++ ++ an7583_pcs_common_phya_l2d(priv); ++ ++ if (data->port_type == AIROHA_PCS_PON) ++ an7583_pcs_common_phya_eo_scan(priv, interface); ++ an7583_pcs_common_phya_rxrdy(priv); ++ if (data->port_type == AIROHA_PCS_PON) ++ an7583_pcs_common_phya_bist_setting(priv); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, ++ AIROHA_PCS_PMA_TX_BIST_GEN_EN | ++ AIROHA_PCS_PMA_R2T_MODE); ++} ++ ++static void an7583_pcs_ana_reset_release(struct airoha_pcs_priv *priv) ++{ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | ++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); ++ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET, ++ AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N | ++ AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N); ++} ++ ++int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, ++ phy_interface_t interface) ++{ ++ an7583_pcs_dig_reset_hold(priv); ++ ++ an7583_pcs_cfg_phy_type(priv, interface); ++ ++ an7583_pcs_common_phya_txpll_on(priv); ++ ++ an7583_pcs_common_phya_tx_on(priv); ++ ++ an7583_pcs_first_plug_in(priv, interface); ++ ++ an7583_pcs_ana_reset_release(priv); ++ ++ return 0; ++} ++ ++void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv) ++{ ++ /* First CDR reset */ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); ++ ++ usleep_range(700, 1000); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++ ++ usleep_range(100, 200); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); ++ ++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, ++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, ++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); ++ ++ /* Then RX Rdy reset */ ++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_RDY); ++ ++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, ++ AIROHA_PCS_PMA_DISB_RX_RDY); ++} diff --git a/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch new file mode 100644 index 0000000000..0fa14de3ee --- /dev/null +++ b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch @@ -0,0 +1,26 @@ +From 6548e580509397a622b7c504a79de93414771459 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 25 Jun 2025 00:04:36 +0200 +Subject: [PATCH 6/6] net: ethernet: airoha: define sport value for GDM3 + +On Airoha AN7583, the Serdes Ethernet goes through the GDM3 port. +To correctly receive packet for QDMA, add the sport value to identify +packet from GDM3 port. + +Signed-off-by: Christian Marangi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -616,6 +616,9 @@ static int airoha_qdma_get_gdm_port(stru + case 0x18: + port = 3; /* GDM4 */ + break; ++ case 0x16: ++ port = 2; /* GDM3 */ ++ break; + case 0x10 ... 0x14: + port = 0; /* GDM1 */ + break; diff --git a/target/linux/airoha/patches-6.6/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch b/target/linux/airoha/patches-6.6/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch new file mode 100644 index 0000000000..5f48c34753 --- /dev/null +++ b/target/linux/airoha/patches-6.6/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch @@ -0,0 +1,63 @@ +From 961800f3badd72e4efda39f219ac4cbec5791433 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 26 Jul 2025 22:58:10 +0200 +Subject: [PATCH 7/8] net: pcs: airoha: add support for optional xfi reset line + +On Airoha AN7583 there is a dedicated reset line for the PON XFI Serdes. +This is needed to permit changing the WAN sel register or the system +will stall on accessing the XFI register. + +Add support for this optional dedicated reset to permit correct +configuration of the PON Serdes. + +Signed-off-by: Christian Marangi +--- + drivers/net/pcs/airoha/pcs-airoha-common.c | 12 ++++++++++++ + drivers/net/pcs/airoha/pcs-airoha.h | 1 + + 2 files changed, 13 insertions(+) + +--- a/drivers/net/pcs/airoha/pcs-airoha-common.c ++++ b/drivers/net/pcs/airoha/pcs-airoha-common.c +@@ -82,6 +82,10 @@ static int airoha_pcs_setup_scu(struct a + const struct airoha_pcs_match_data *data = priv->data; + int ret; + ++ ret = reset_control_assert(priv->xfi_rst); ++ if (ret) ++ return ret; ++ + switch (data->port_type) { + case AIROHA_PCS_ETH: + airoha_pcs_setup_scu_eth(priv, interface); +@@ -91,6 +95,10 @@ static int airoha_pcs_setup_scu(struct a + break; + } + ++ ret = reset_control_deassert(priv->xfi_rst); ++ if (ret) ++ return ret; ++ + /* TODO better handle reset from MAC */ + ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts), + priv->rsts); +@@ -1003,6 +1011,10 @@ static int airoha_pcs_probe(struct platf + if (ret) + return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); + ++ priv->xfi_rst = devm_reset_control_get_optional_exclusive(dev, "xfi"); ++ if (IS_ERR(priv->xfi_rst)) ++ return dev_err_probe(dev, PTR_ERR(priv->xfi_rst), "failed to get xfi reset lines\n"); ++ + /* For Ethernet PCS, read the AN7581 SoC revision to check if + * manual rx calibration is needed. This is only limited to + * any SoC revision before E2. +--- a/drivers/net/pcs/airoha/pcs-airoha.h ++++ b/drivers/net/pcs/airoha/pcs-airoha.h +@@ -1184,6 +1184,7 @@ struct airoha_pcs_priv { + struct regmap *xfi_pma; + struct regmap *xfi_ana; + ++ struct reset_control *xfi_rst; + struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; + + bool manual_rx_calib; From 84944c0311a0d5ee382bd861a1c2ba6770b4a3c4 Mon Sep 17 00:00:00 2001 From: Chukun Pan Date: Tue, 9 Sep 2025 23:06:02 +0800 Subject: [PATCH 047/128] airoha: set default DEVICE_DTS/DEVICE_DTS_DIR All devices under airoha use dts directory under the target, so update the default DEVICE_DTS_DIR. Also set the default DEVICE_DTS based on the SoC name for non-dev boards. Signed-off-by: Chukun Pan Link: https://github.com/openwrt/openwrt/pull/20190 Signed-off-by: Christian Marangi (cherry picked from commit 866c4e5cdfeb7a09cbeb016885d54b1461350c67) --- target/linux/airoha/image/Makefile | 3 ++- target/linux/airoha/image/an7581.mk | 2 -- target/linux/airoha/image/an7583.mk | 2 -- target/linux/airoha/image/en7523.mk | 3 +-- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/target/linux/airoha/image/Makefile b/target/linux/airoha/image/Makefile index dd5878bfe1..f3547ae330 100644 --- a/target/linux/airoha/image/Makefile +++ b/target/linux/airoha/image/Makefile @@ -10,7 +10,8 @@ define Device/Default KERNEL_INITRAMFS = kernel-bin | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd FILESYSTEMS := squashfs - DEVICE_DTS_DIR := $(DTS_DIR) + DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1))) + DEVICE_DTS_DIR := ../dts IMAGES := sysupgrade.bin IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | \ pad-rootfs | append-metadata diff --git a/target/linux/airoha/image/an7581.mk b/target/linux/airoha/image/an7581.mk index 78918879f7..8f187b812c 100644 --- a/target/linux/airoha/image/an7581.mk +++ b/target/linux/airoha/image/an7581.mk @@ -10,7 +10,6 @@ define Device/airoha_an7581-evb DEVICE_MODEL := AN7581 Evaluation Board (SNAND) DEVICE_PACKAGES := kmod-leds-pwm kmod-i2c-an7581 kmod-pwm-airoha kmod-input-gpio-keys-polled DEVICE_DTS := an7581-evb - DEVICE_DTS_DIR := ../dts DEVICE_DTS_CONFIG := config@1 KERNEL_LOADADDR := 0x80088000 IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata @@ -21,7 +20,6 @@ define Device/airoha_an7581-evb-emmc DEVICE_VENDOR := Airoha DEVICE_MODEL := AN7581 Evaluation Board (EMMC) DEVICE_DTS := an7581-evb-emmc - DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-i2c-an7581 endef TARGET_DEVICES += airoha_an7581-evb-emmc diff --git a/target/linux/airoha/image/an7583.mk b/target/linux/airoha/image/an7583.mk index 6ebec7af1b..c8747a7913 100644 --- a/target/linux/airoha/image/an7583.mk +++ b/target/linux/airoha/image/an7583.mk @@ -30,7 +30,6 @@ define Device/airoha_an7583-evb DEVICE_MODEL := AN7583 Evaluation Board (SNAND) DEVICE_PACKAGES := kmod-leds-pwm kmod-input-gpio-keys-polled DEVICE_DTS := an7583-evb - DEVICE_DTS_DIR := ../dts DEVICE_DTS_CONFIG := config@1 KERNEL_LOADADDR := 0x80088000 IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata @@ -45,7 +44,6 @@ define Device/airoha_an7583-evb-emmc DEVICE_VENDOR := Airoha DEVICE_MODEL := AN7583 Evaluation Board (EMMC) DEVICE_DTS := an7583-evb-emmc - DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-i2c-an7581 ARTIFACT/preloader.bin := an7583-preloader rfb ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb diff --git a/target/linux/airoha/image/en7523.mk b/target/linux/airoha/image/en7523.mk index aca37a9923..e116ce9255 100644 --- a/target/linux/airoha/image/en7523.mk +++ b/target/linux/airoha/image/en7523.mk @@ -8,6 +8,5 @@ define Device/airoha_en7523-evb DEVICE_VENDOR := Airoha DEVICE_MODEL := EN7523 Evaluation Board DEVICE_DTS := en7523-evb - DEVICE_DTS_DIR := ../dts endef -TARGET_DEVICES += airoha_en7523-evb \ No newline at end of file +TARGET_DEVICES += airoha_en7523-evb From c56fbe156ed9e4cf71aef5bf816d4b46f1b660c0 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Fri, 26 Sep 2025 17:10:19 +0200 Subject: [PATCH 048/128] airoha: fix scuclk node for an7581 Add missing syscon compatible for scuclk node. Fix the unit-address of the scuclk node. This fixes the pcs driver error: airoha-pcs 1fa08000.pcs: probe with driver airoha-pcs failed with error -22 airoha-pcs 1fa09000.pcs: probe with driver airoha-pcs failed with error -22 Fixes: c3d70b1 ("airoha: en7581: Add support for external PHY") Signed-off-by: Aleksander Jan Bajkowski Signed-off-by: Chukun Pan Link: https://github.com/openwrt/openwrt/pull/20190 Signed-off-by: Christian Marangi (cherry picked from commit a30daf8a0b3f3c25a46320f5e7932d01c63301ef) --- target/linux/airoha/dts/an7581.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 1154cadd15..c00119cf2f 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -490,8 +490,8 @@ reg = <0x0 0x1fbe3400 0x0 0xff>; }; - scuclk: clock-controller@1fa20000 { - compatible = "airoha,en7581-scu"; + scuclk: clock-controller@1fb00000 { + compatible = "airoha,en7581-scu", "syscon"; reg = <0x0 0x1fb00000 0x0 0x970>; #clock-cells = <1>; #reset-cells = <1>; From 262b537f48e4bbd4b3b926796e0d1ea3b8340ac4 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 21 Oct 2025 23:12:07 +0200 Subject: [PATCH 049/128] airoha: backport upstream patch for AN7583 Ethernet support Backport upstream patch for AN7583 Ethernet support. While at it also backport some additional fixes required to apply the AN7583 patches cleanly. Refresh all affected patch automatically (aside from the XSI patch that changed the implementation) Link: https://github.com/openwrt/openwrt/pull/20489 (cherry picked from commit 46a454fb9b6684a2fccc3a1c3843ffc970393085) [ fix conflict errors ] Signed-off-by: Christian Marangi --- ...-Wflex-array-member-not-at-end-warni.patch | 45 +++ ...PE_IP_PROTO_CHK-register-definitions.patch | 29 ++ ...dd-a-NPU-callback-to-initialize-flow.patch | 159 ++++++++ ...oopback-mode-configuration-for-GDM2-.patch | 43 +++ ...issing-stats-to-ethtool_eth_mac_stat.patch | 34 ++ ...airoha-Add-get_link-ethtool-callback.patch | 25 ++ ...into-account-out-of-order-tx-complet.patch | 54 +++ ...ynamically-allocate-foe_check_time-a.patch | 43 +++ ...iroha_ppe_get_num_stats_entries-and-.patch | 239 ++++++++++++ ...iroha-Add-airoha_eth_soc_data-struct.patch | 152 ++++++++ ...alize-airoha_ppe2_is_enabled-routine.patch | 147 +++++++ ...ove-PPE-memory-info-in-airoha_eth_so.patch | 359 ++++++++++++++++++ ...emove-airoha_ppe_is_enabled-where-no.patch | 58 +++ ...onfigure-SRAM-PPE-entries-via-the-cp.patch | 65 ++++ ...lush-PPE-SRAM-table-during-PPE-setup.patch | 71 ++++ ...t-default-ppe-cpu-port-in-airoha_dev.patch | 91 +++++ ...tor-src-port-configuration-in-airhoh.patch | 202 ++++++++++ ...o-not-use-magic-numbers-in-airoha_pp.patch | 29 ++ ...19-net-airoha-Add-AN7583-SoC-support.patch | 185 +++++++++ ...-airoha-deassert-XSI-line-on-hw-init.patch | 4 +- ...eference-for-SPORT-GDM4-in-qdma_get_.patch | 2 +- ...-airoha-drop-redundant-GDM3-4-define.patch | 4 +- ...nitial-fixup-for-GDM3-4-port-support.patch | 4 +- ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 41 +- ...et-phylink-add-.pcs_link_down-PCS-OP.patch | 6 +- ...iroha-add-phylink-support-for-GDM2-4.patch | 20 +- ...t-airoha-define-sport-value-for-GDM3.patch | 2 +- 27 files changed, 2066 insertions(+), 47 deletions(-) create mode 100644 target/linux/airoha/patches-6.6/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch create mode 100644 target/linux/airoha/patches-6.6/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch create mode 100644 target/linux/airoha/patches-6.6/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch create mode 100644 target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch create mode 100644 target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch create mode 100644 target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch create mode 100644 target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch create mode 100644 target/linux/airoha/patches-6.6/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch create mode 100644 target/linux/airoha/patches-6.6/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch create mode 100644 target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch create mode 100644 target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch create mode 100644 target/linux/airoha/patches-6.6/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch create mode 100644 target/linux/airoha/patches-6.6/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch create mode 100644 target/linux/airoha/patches-6.6/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch create mode 100644 target/linux/airoha/patches-6.6/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch create mode 100644 target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch create mode 100644 target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch create mode 100644 target/linux/airoha/patches-6.6/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch create mode 100644 target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch diff --git a/target/linux/airoha/patches-6.6/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch b/target/linux/airoha/patches-6.6/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch new file mode 100644 index 0000000000..5e52a3b429 --- /dev/null +++ b/target/linux/airoha/patches-6.6/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch @@ -0,0 +1,45 @@ +From 09630ab91d840416b0178f3660afa4eebce24286 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Sep 2025 16:08:21 +0200 +Subject: [PATCH] net: airoha: Avoid -Wflex-array-member-not-at-end warning + +-Wflex-array-member-not-at-end was introduced in GCC-14, and we are +getting ready to enable it, globally. + +Move the conflicting declaration to the end of the corresponding +structure. Notice that `struct airoha_foe_entry` is a flexible +structure, this is a structure that contains a flexible-array +member. + +Fix the following warning: + +drivers/net/ethernet/airoha/airoha_eth.h:474:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/aNFYVYLXQDqm4yxb@kspp +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -471,7 +471,6 @@ struct airoha_flow_table_entry { + }; + }; + +- struct airoha_foe_entry data; + struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ + u32 hash; + +@@ -480,6 +479,9 @@ struct airoha_flow_table_entry { + + struct rhash_head node; + unsigned long cookie; ++ ++ /* Must be last --ends in a flexible-array member. */ ++ struct airoha_foe_entry data; + }; + + struct airoha_wdma_info { diff --git a/target/linux/airoha/patches-6.6/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch b/target/linux/airoha/patches-6.6/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch new file mode 100644 index 0000000000..31cd950437 --- /dev/null +++ b/target/linux/airoha/patches-6.6/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch @@ -0,0 +1,29 @@ +From e156dd6b856fa462430d875b0d4cd281ecd66c23 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 18 Sep 2025 08:59:41 +0200 +Subject: [PATCH] net: airoha: Fix PPE_IP_PROTO_CHK register definitions + +Fix typo in PPE_IP_PROTO_CHK_IPV4_MASK and PPE_IP_PROTO_CHK_IPV6_MASK +register mask definitions. This is not a real problem since this +register is not actually used in the current codebase. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_regs.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -237,8 +237,8 @@ + #define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) + + #define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) +-#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) +-#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) ++#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(31, 16) ++#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(15, 0) + + #define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) + #define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) diff --git a/target/linux/airoha/patches-6.6/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch b/target/linux/airoha/patches-6.6/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch new file mode 100644 index 0000000000..021ec0c8df --- /dev/null +++ b/target/linux/airoha/patches-6.6/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch @@ -0,0 +1,159 @@ +From 105ce7ad57e492b75ab40f2dc591db645fadbaa2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 24 Sep 2025 23:14:53 +0200 +Subject: [PATCH] net: airoha: npu: Add a NPU callback to initialize flow stats + +Introduce a NPU callback to initialize flow stats and remove NPU stats +initialization from airoha_npu_get routine. Add num_stats_entries to +airoha_npu_ppe_stats_setup routine. +This patch makes the code more readable since NPU statistic are now +initialized on demand by the NPU consumer (at the moment NPU statistic +are configured just by the airoha_eth driver). +Moreover this patch allows the NPU consumer (PPE module) to explicitly +enable/disable NPU flow stats. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250924-airoha-npu-init-stats-callback-v1-1-88bdf3c941b2@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 24 ++++++----------------- + drivers/net/ethernet/airoha/airoha_ppe.c | 19 ++++++++++++------ + include/linux/soc/airoha/airoha_offload.h | 7 ++++--- + 3 files changed, 23 insertions(+), 27 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -379,15 +379,13 @@ out: + return err; + } + +-static int airoha_npu_stats_setup(struct airoha_npu *npu, +- dma_addr_t foe_stats_addr) ++static int airoha_npu_ppe_stats_setup(struct airoha_npu *npu, ++ dma_addr_t foe_stats_addr, ++ u32 num_stats_entries) + { +- int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); ++ int err, size = num_stats_entries * sizeof(*npu->stats); + struct ppe_mbox_data *ppe_data; + +- if (!size) /* flow stats are disabled */ +- return 0; +- + ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); + if (!ppe_data) + return -ENOMEM; +@@ -542,7 +540,7 @@ static void airoha_npu_wlan_irq_disable( + regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); + } + +-struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) ++struct airoha_npu *airoha_npu_get(struct device *dev) + { + struct platform_device *pdev; + struct device_node *np; +@@ -580,17 +578,6 @@ struct airoha_npu *airoha_npu_get(struct + goto error_module_put; + } + +- if (stats_addr) { +- int err; +- +- err = airoha_npu_stats_setup(npu, *stats_addr); +- if (err) { +- dev_err(dev, "failed to allocate npu stats buffer\n"); +- npu = ERR_PTR(err); +- goto error_module_put; +- } +- } +- + return npu; + + error_module_put: +@@ -643,6 +630,7 @@ static int airoha_npu_probe(struct platf + npu->dev = dev; + npu->ops.ppe_init = airoha_npu_ppe_init; + npu->ops.ppe_deinit = airoha_npu_ppe_deinit; ++ npu->ops.ppe_init_stats = airoha_npu_ppe_stats_setup; + npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; + npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; + npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1243,12 +1243,11 @@ static int airoha_ppe_flush_sram_entries + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) + { +- struct airoha_npu *npu = airoha_npu_get(eth->dev, +- ð->ppe->foe_stats_dma); ++ struct airoha_npu *npu = airoha_npu_get(eth->dev); + + if (IS_ERR(npu)) { + request_module("airoha-npu"); +- npu = airoha_npu_get(eth->dev, ð->ppe->foe_stats_dma); ++ npu = airoha_npu_get(eth->dev); + } + + return npu; +@@ -1257,6 +1256,7 @@ static struct airoha_npu *airoha_ppe_npu + static int airoha_ppe_offload_setup(struct airoha_eth *eth) + { + struct airoha_npu *npu = airoha_ppe_npu_get(eth); ++ struct airoha_ppe *ppe = eth->ppe; + int err; + + if (IS_ERR(npu)) +@@ -1266,12 +1266,19 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + +- airoha_ppe_hw_init(eth->ppe); +- err = airoha_ppe_flush_sram_entries(eth->ppe, npu); ++ if (PPE_STATS_NUM_ENTRIES) { ++ err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, ++ PPE_STATS_NUM_ENTRIES); ++ if (err) ++ goto error_npu_put; ++ } ++ ++ airoha_ppe_hw_init(ppe); ++ err = airoha_ppe_flush_sram_entries(ppe, npu); + if (err) + goto error_npu_put; + +- airoha_ppe_foe_flow_stats_reset(eth->ppe, npu); ++ airoha_ppe_foe_flow_stats_reset(ppe, npu); + + rcu_assign_pointer(eth->npu, npu); + synchronize_rcu(); +--- a/include/linux/soc/airoha/airoha_offload.h ++++ b/include/linux/soc/airoha/airoha_offload.h +@@ -181,6 +181,8 @@ struct airoha_npu { + struct { + int (*ppe_init)(struct airoha_npu *npu); + int (*ppe_deinit)(struct airoha_npu *npu); ++ int (*ppe_init_stats)(struct airoha_npu *npu, ++ dma_addr_t addr, u32 num_stats_entries); + int (*ppe_flush_sram_entries)(struct airoha_npu *npu, + dma_addr_t foe_addr, + int sram_num_entries); +@@ -206,7 +208,7 @@ struct airoha_npu { + }; + + #if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) +-struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); ++struct airoha_npu *airoha_npu_get(struct device *dev); + void airoha_npu_put(struct airoha_npu *npu); + + static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) +@@ -256,8 +258,7 @@ static inline void airoha_npu_wlan_disab + npu->ops.wlan_disable_irq(npu, q); + } + #else +-static inline struct airoha_npu *airoha_npu_get(struct device *dev, +- dma_addr_t *foe_stats_addr) ++static inline struct airoha_npu *airoha_npu_get(struct device *dev) + { + return NULL; + } diff --git a/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch b/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch new file mode 100644 index 0000000000..5c3fcc0c20 --- /dev/null +++ b/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch @@ -0,0 +1,43 @@ +From fea8cdf6738a8b25fccbb7b109b440795a0892cb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Oct 2025 11:27:43 +0200 +Subject: [PATCH] net: airoha: Fix loopback mode configuration for GDM2 port + +Add missing configuration for loopback mode in airhoha_set_gdm2_loopback +routine. + +Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20251008-airoha-loopback-mode-fix-v2-1-045694fe7f60@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 +++- + drivers/net/ethernet/airoha/airoha_regs.h | 3 +++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1715,7 +1715,9 @@ static void airhoha_set_gdm2_loopback(st + airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); + airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, +- FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); ++ FIELD_PREP(LPBK_CHAN_MASK, chan) | ++ LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | ++ LBK_CHAN_MODE_MASK | LPBK_EN_MASK); + airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), + GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, + FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -151,6 +151,9 @@ + #define LPBK_LEN_MASK GENMASK(23, 10) + #define LPBK_CHAN_MASK GENMASK(8, 4) + #define LPBK_MODE_MASK GENMASK(3, 1) ++#define LBK_GAP_MODE_MASK BIT(3) ++#define LBK_LEN_MODE_MASK BIT(2) ++#define LBK_CHAN_MODE_MASK BIT(1) + #define LPBK_EN_MASK BIT(0) + + #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) diff --git a/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch b/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch new file mode 100644 index 0000000000..66d72ded83 --- /dev/null +++ b/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch @@ -0,0 +1,34 @@ +From 331f8a8bea22aecf99437f3561453a85f40026de Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 16:29:41 +0200 +Subject: [PATCH] net: airoha: Add missing stats to ethtool_eth_mac_stats + +Add the following stats to ethtool ethtool_eth_mac_stats stats: +- FramesTransmittedOK +- OctetsTransmittedOK +- FramesReceivedOK +- OctetsReceivedOK + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-1-fdd1c6fc9be1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2027,8 +2027,12 @@ static void airoha_ethtool_get_mac_stats + airoha_update_hw_stats(port); + do { + start = u64_stats_fetch_begin(&port->stats.syncp); ++ stats->FramesTransmittedOK = port->stats.tx_ok_pkts; ++ stats->OctetsTransmittedOK = port->stats.tx_ok_bytes; + stats->MulticastFramesXmittedOK = port->stats.tx_multicast; + stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; ++ stats->FramesReceivedOK = port->stats.rx_ok_pkts; ++ stats->OctetsReceivedOK = port->stats.rx_ok_bytes; + stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; + } while (u64_stats_fetch_retry(&port->stats.syncp, start)); + } diff --git a/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch b/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch new file mode 100644 index 0000000000..7d78bd6c03 --- /dev/null +++ b/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch @@ -0,0 +1,25 @@ +From fc4fed9054ef5b5269d4395dd9db36fe98fce9e3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 16:29:42 +0200 +Subject: [PATCH] net: airoha: Add get_link ethtool callback + +Set get_link ethtool callback to ethtool_op_get_link routine. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-2-fdd1c6fc9be1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2775,6 +2775,7 @@ static const struct ethtool_ops airoha_e + .get_drvinfo = airoha_ethtool_get_drvinfo, + .get_eth_mac_stats = airoha_ethtool_get_mac_stats, + .get_rmon_stats = airoha_ethtool_get_rmon_stats, ++ .get_link = ethtool_op_get_link, + }; + + static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) diff --git a/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch b/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch new file mode 100644 index 0000000000..46432b2480 --- /dev/null +++ b/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch @@ -0,0 +1,54 @@ +From bd5afca115f181c85f992d42a57cd497bc823ccb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sun, 12 Oct 2025 11:19:44 +0200 +Subject: [PATCH] net: airoha: Take into account out-of-order tx completions in + airoha_dev_xmit() + +Completion napi can free out-of-order tx descriptors if hw QoS is +enabled and packets with different priority are queued to same DMA ring. +Take into account possible out-of-order reports checking if the tx queue +is full using circular buffer head/tail pointer instead of the number of +queued packets. + +Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") +Suggested-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251012-airoha-tx-busy-queue-v2-1-a600b08bab2d@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1878,6 +1878,20 @@ static u32 airoha_get_dsa_tag(struct sk_ + #endif + } + ++static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags) ++{ ++ u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail; ++ u32 index = q->head + nr_frags; ++ ++ /* completion napi can free out-of-order tx descriptors if hw QoS is ++ * enabled and packets with different priorities are queued to the same ++ * DMA ring. Take into account possible out-of-order reports checking ++ * if the tx queue is full using circular buffer head/tail pointers ++ * instead of the number of queued packets. ++ */ ++ return index >= tail; ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +@@ -1931,7 +1945,7 @@ static netdev_tx_t airoha_dev_xmit(struc + txq = netdev_get_tx_queue(dev, qid); + nr_frags = 1 + skb_shinfo(skb)->nr_frags; + +- if (q->queued + nr_frags > q->ndesc) { ++ if (airoha_dev_tx_queue_busy(q, nr_frags)) { + /* not enough space in the queue */ + netif_tx_stop_queue(txq); + spin_unlock_bh(&q->lock); diff --git a/target/linux/airoha/patches-6.6/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch b/target/linux/airoha/patches-6.6/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch new file mode 100644 index 0000000000..3d4b0cfab0 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch @@ -0,0 +1,43 @@ +From 6d5b601d52a27aafff555b480e538507901c672c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:11 +0200 +Subject: [PATCH 01/12] net: airoha: ppe: Dynamically allocate foe_check_time + array in airoha_ppe struct + +This is a preliminary patch to properly enable PPE support for AN7583 +SoC. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-2-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 2 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -554,7 +554,7 @@ struct airoha_ppe { + struct rhashtable l2_flows; + + struct hlist_head *foe_flow; +- u16 foe_check_time[PPE_NUM_ENTRIES]; ++ u16 *foe_check_time; + + struct airoha_foe_stats *foe_stats; + dma_addr_t foe_stats_dma; +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1440,6 +1440,11 @@ int airoha_ppe_init(struct airoha_eth *e + return -ENOMEM; + } + ++ ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, ++ GFP_KERNEL); ++ if (!ppe->foe_check_time) ++ return -ENOMEM; ++ + err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); + if (err) + return err; diff --git a/target/linux/airoha/patches-6.6/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch b/target/linux/airoha/patches-6.6/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch new file mode 100644 index 0000000000..6733331f1f --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch @@ -0,0 +1,239 @@ +From 15f357cd4581ce6e02e5e97719320600783140ec Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:12 +0200 +Subject: [PATCH 02/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and + airoha_ppe_get_num_total_stats_entries() + +Introduce airoha_ppe_get_num_stats_entries and +airoha_ppe_get_num_total_stats_entries routines in order to make the +code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is +enabled or disabled. +Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on +airoha_ppe_get_num_total_stats_entries(). + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-3-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 10 +-- + drivers/net/ethernet/airoha/airoha_ppe.c | 101 ++++++++++++++++++----- + 2 files changed, 81 insertions(+), 30 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -50,15 +50,9 @@ + + #define PPE_NUM 2 + #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) +-#define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) +-#ifdef CONFIG_NET_AIROHA_FLOW_STATS ++#define PPE_SRAM_NUM_ENTRIES (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) + #define PPE1_STATS_NUM_ENTRIES (4 * 1024) +-#else +-#define PPE1_STATS_NUM_ENTRIES 0 +-#endif /* CONFIG_NET_AIROHA_FLOW_STATS */ +-#define PPE_STATS_NUM_ENTRIES (2 * PPE1_STATS_NUM_ENTRIES) +-#define PPE1_SRAM_NUM_DATA_ENTRIES (PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES) +-#define PPE_SRAM_NUM_DATA_ENTRIES (2 * PPE1_SRAM_NUM_DATA_ENTRIES) ++#define PPE_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_ENTRIES) + #define PPE_DRAM_NUM_ENTRIES (16 * 1024) + #define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) + #define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -32,6 +32,24 @@ static const struct rhashtable_params ai + .automatic_shrinking = true, + }; + ++static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe) ++{ ++ if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) ++ return -EOPNOTSUPP; ++ ++ return PPE1_STATS_NUM_ENTRIES; ++} ++ ++static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) ++{ ++ int num_stats = airoha_ppe_get_num_stats_entries(ppe); ++ ++ if (num_stats > 0) ++ num_stats = num_stats * PPE_NUM; ++ ++ return num_stats; ++} ++ + static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) + { + return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; +@@ -48,7 +66,7 @@ static void airoha_ppe_hw_init(struct ai + { + u32 sram_tb_size, sram_num_entries, dram_num_entries; + struct airoha_eth *eth = ppe->eth; +- int i; ++ int i, sram_num_stats_entries; + + sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); + dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); +@@ -103,8 +121,13 @@ static void airoha_ppe_hw_init(struct ai + } + + if (airoha_ppe2_is_enabled(eth)) { +- sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); ++ sram_num_entries = PPE1_SRAM_NUM_ENTRIES; ++ sram_num_stats_entries = ++ airoha_ppe_get_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ sram_num_entries -= sram_num_stats_entries; ++ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); ++ + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -120,8 +143,13 @@ static void airoha_ppe_hw_init(struct ai + FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, + dram_num_entries)); + } else { +- sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES); ++ sram_num_entries = PPE_SRAM_NUM_ENTRIES; ++ sram_num_stats_entries = ++ airoha_ppe_get_total_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ sram_num_entries -= sram_num_stats_entries; ++ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); ++ + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -480,13 +508,21 @@ static u32 airoha_ppe_foe_get_entry_hash + return hash; + } + +-static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) ++static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, ++ u32 hash, u32 *index) + { +- if (!airoha_ppe2_is_enabled(ppe->eth)) +- return hash; ++ int ppe_num_stats_entries; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return ppe_num_stats_entries; ++ ++ *index = hash; ++ if (airoha_ppe2_is_enabled(ppe->eth) && ++ hash >= ppe_num_stats_entries) ++ *index = *index - PPE_STATS_NUM_ENTRIES; + +- return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES +- : hash; ++ return 0; + } + + static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, +@@ -500,9 +536,13 @@ static void airoha_ppe_foe_flow_stat_ent + static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, + struct airoha_npu *npu) + { +- int i; ++ int i, ppe_num_stats_entries; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return; + +- for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) ++ for (i = 0; i < ppe_num_stats_entries; i++) + airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); + } + +@@ -513,10 +553,17 @@ static void airoha_ppe_foe_flow_stats_up + { + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); + u32 index, pse_port, val, *data, *ib2, *meter; ++ int ppe_num_stats_entries; + u8 nbq; + +- index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); +- if (index >= PPE_STATS_NUM_ENTRIES) ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return; ++ ++ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) ++ return; ++ ++ if (index >= ppe_num_stats_entries) + return; + + if (type == PPE_PKT_TYPE_BRIDGE) { +@@ -1158,11 +1205,19 @@ static int airoha_ppe_flow_offload_destr + void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, + struct airoha_foe_stats64 *stats) + { +- u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); + struct airoha_eth *eth = ppe->eth; ++ int ppe_num_stats_entries; + struct airoha_npu *npu; ++ u32 index; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return; + +- if (index >= PPE_STATS_NUM_ENTRIES) ++ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) ++ return; ++ ++ if (index >= ppe_num_stats_entries) + return; + + rcu_read_lock(); +@@ -1257,7 +1312,7 @@ static int airoha_ppe_offload_setup(stru + { + struct airoha_npu *npu = airoha_ppe_npu_get(eth); + struct airoha_ppe *ppe = eth->ppe; +- int err; ++ int err, ppe_num_stats_entries; + + if (IS_ERR(npu)) + return PTR_ERR(npu); +@@ -1266,9 +1321,10 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + +- if (PPE_STATS_NUM_ENTRIES) { ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries > 0) { + err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, +- PPE_STATS_NUM_ENTRIES); ++ ppe_num_stats_entries); + if (err) + goto error_npu_put; + } +@@ -1405,8 +1461,8 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); + + int airoha_ppe_init(struct airoha_eth *eth) + { ++ int foe_size, err, ppe_num_stats_entries; + struct airoha_ppe *ppe; +- int foe_size, err; + + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); + if (!ppe) +@@ -1431,8 +1487,9 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_flow) + return -ENOMEM; + +- foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); +- if (foe_size) { ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries > 0) { ++ foe_size = ppe_num_stats_entries * sizeof(*ppe->foe_stats); + ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size, + &ppe->foe_stats_dma, + GFP_KERNEL); diff --git a/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch b/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch new file mode 100644 index 0000000000..9035e21447 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch @@ -0,0 +1,152 @@ +From 5863b4e065e2253ef05684f728a04e4972046bcb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:13 +0200 +Subject: [PATCH 03/12] net: airoha: Add airoha_eth_soc_data struct + +Introduce airoha_eth_soc_data struct to contain differences between +various SoC. Move XSI reset names in airoha_eth_soc_data. This is a +preliminary patch to enable AN7583 ethernet controller support in +airoha-eth driver. + +Co-developed-by: Christian Marangi +Signed-off-by: Christian Marangi +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-4-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 42 +++++++++++++++++++----- + drivers/net/ethernet/airoha/airoha_eth.h | 17 ++++++++-- + 2 files changed, 48 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1392,8 +1392,7 @@ static int airoha_hw_init(struct platfor + int err, i; + + /* disable xsi */ +- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), +- eth->xsi_rsts); ++ err = reset_control_bulk_assert(eth->soc->num_xsi_rsts, eth->xsi_rsts); + if (err) + return err; + +@@ -2927,6 +2926,7 @@ free_metadata_dst: + + static int airoha_probe(struct platform_device *pdev) + { ++ struct reset_control_bulk_data *xsi_rsts; + struct device_node *np; + struct airoha_eth *eth; + int i, err; +@@ -2935,6 +2935,10 @@ static int airoha_probe(struct platform_ + if (!eth) + return -ENOMEM; + ++ eth->soc = of_device_get_match_data(&pdev->dev); ++ if (!eth->soc) ++ return -EINVAL; ++ + eth->dev = &pdev->dev; + + err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); +@@ -2959,13 +2963,18 @@ static int airoha_probe(struct platform_ + return err; + } + +- eth->xsi_rsts[0].id = "xsi-mac"; +- eth->xsi_rsts[1].id = "hsi0-mac"; +- eth->xsi_rsts[2].id = "hsi1-mac"; +- eth->xsi_rsts[3].id = "hsi-mac"; +- eth->xsi_rsts[4].id = "xfp-mac"; ++ xsi_rsts = devm_kzalloc(eth->dev, ++ eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), ++ GFP_KERNEL); ++ if (err) ++ return err; ++ ++ eth->xsi_rsts = xsi_rsts; ++ for (i = 0; i < eth->soc->num_xsi_rsts; i++) ++ eth->xsi_rsts[i].id = eth->soc->xsi_rsts_names[i]; ++ + err = devm_reset_control_bulk_get_exclusive(eth->dev, +- ARRAY_SIZE(eth->xsi_rsts), ++ eth->soc->num_xsi_rsts, + eth->xsi_rsts); + if (err) { + dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); +@@ -3052,8 +3061,23 @@ static void airoha_remove(struct platfor + platform_set_drvdata(pdev, NULL); + } + ++static const char * const en7581_xsi_rsts_names[] = { ++ "xsi-mac", ++ "hsi0-mac", ++ "hsi1-mac", ++ "hsi-mac", ++ "xfp-mac", ++}; ++ ++static const struct airoha_eth_soc_data en7581_soc_data = { ++ .version = 0x7581, ++ .xsi_rsts_names = en7581_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), ++ .num_ppe = 2, ++}; ++ + static const struct of_device_id of_airoha_match[] = { +- { .compatible = "airoha,en7581-eth" }, ++ { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_match); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -21,7 +21,6 @@ + #define AIROHA_MAX_NUM_IRQ_BANKS 4 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 +-#define AIROHA_MAX_NUM_XSI_RSTS 5 + #define AIROHA_MAX_MTU 9216 + #define AIROHA_MAX_PACKET_SIZE 2048 + #define AIROHA_NUM_QOS_CHANNELS 4 +@@ -556,9 +555,18 @@ struct airoha_ppe { + struct dentry *debugfs_dir; + }; + ++struct airoha_eth_soc_data { ++ u16 version; ++ const char * const *xsi_rsts_names; ++ int num_xsi_rsts; ++ int num_ppe; ++}; ++ + struct airoha_eth { + struct device *dev; + ++ const struct airoha_eth_soc_data *soc; ++ + unsigned long state; + void __iomem *fe_regs; + +@@ -568,7 +576,7 @@ struct airoha_eth { + struct rhashtable flow_table; + + struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; +- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; ++ struct reset_control_bulk_data *xsi_rsts; + + struct net_device *napi_dev; + +@@ -611,6 +619,11 @@ static inline bool airhoa_is_lan_gdm_por + return port->id == 1; + } + ++static inline bool airoha_is_7581(struct airoha_eth *eth) ++{ ++ return eth->soc->version == 0x7581; ++} ++ + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + diff --git a/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch b/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch new file mode 100644 index 0000000000..e82ce24e4f --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch @@ -0,0 +1,147 @@ +From ef9449f080b61920cdc3d3106f8ffc2d9ba8b861 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:14 +0200 +Subject: [PATCH 04/12] net: airoha: Generalize airoha_ppe2_is_enabled routine + +Rename airoha_ppe2_is_enabled() in airoha_ppe_is_enabled() and +generalize it in order to check if each PPE module is enabled. +Rely on airoha_ppe_is_enabled routine to properly initialize PPE for +AN7583 SoC since AN7583 does not support PPE2. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-5-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 32 ++++++++++++++++-------- + drivers/net/ethernet/airoha/airoha_eth.h | 1 + + drivers/net/ethernet/airoha/airoha_ppe.c | 17 +++++++------ + 3 files changed, 32 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -297,8 +297,11 @@ static void airoha_fe_pse_ports_init(str + int q; + + all_rsv = airoha_fe_get_pse_all_rsv(eth); +- /* hw misses PPE2 oq rsv */ +- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ /* hw misses PPE2 oq rsv */ ++ all_rsv += PSE_RSV_PAGES * ++ pse_port_num_queues[FE_PSE_PORT_PPE2]; ++ } + airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); + + /* CMD1 */ +@@ -335,13 +338,17 @@ static void airoha_fe_pse_ports_init(str + for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) + airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, + PSE_QUEUE_RSV_PAGES); +- /* PPE2 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { +- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, +- PSE_QUEUE_RSV_PAGES); +- else +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ /* PPE2 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { ++ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, ++ q, ++ PSE_QUEUE_RSV_PAGES); ++ else ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, ++ q, 0); ++ } + } + /* GMD4 */ + for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) +@@ -1767,8 +1774,11 @@ static int airoha_dev_init(struct net_de + airhoha_set_gdm2_loopback(port); + fallthrough; + case 2: +- pse_port = FE_PSE_PORT_PPE2; +- break; ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ pse_port = FE_PSE_PORT_PPE2; ++ break; ++ } ++ fallthrough; + default: + pse_port = FE_PSE_PORT_PPE1; + break; +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -627,6 +627,7 @@ static inline bool airoha_is_7581(struct + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + ++bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); + void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, + u16 hash, bool rx_wlan); + int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -50,9 +50,12 @@ static int airoha_ppe_get_total_num_stat + return num_stats; + } + +-static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) ++bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) + { +- return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; ++ if (index >= eth->soc->num_ppe) ++ return false; ++ ++ return airoha_fe_rr(eth, REG_PPE_GLO_CFG(index)) & PPE_GLO_CFG_EN_MASK; + } + + static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) +@@ -120,7 +123,7 @@ static void airoha_ppe_hw_init(struct ai + AIROHA_MAX_MTU)); + } + +- if (airoha_ppe2_is_enabled(eth)) { ++ if (airoha_ppe_is_enabled(eth, 1)) { + sram_num_entries = PPE1_SRAM_NUM_ENTRIES; + sram_num_stats_entries = + airoha_ppe_get_num_stats_entries(ppe); +@@ -518,7 +521,7 @@ static int airoha_ppe_foe_get_flow_stats + return ppe_num_stats_entries; + + *index = hash; +- if (airoha_ppe2_is_enabled(ppe->eth) && ++ if (airoha_ppe_is_enabled(ppe->eth, 1) && + hash >= ppe_num_stats_entries) + *index = *index - PPE_STATS_NUM_ENTRIES; + +@@ -613,7 +616,7 @@ airoha_ppe_foe_get_entry_locked(struct a + u32 val; + int i; + +- ppe2 = airoha_ppe2_is_enabled(ppe->eth) && ++ ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && + hash >= PPE1_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | +@@ -691,7 +694,7 @@ static int airoha_ppe_foe_commit_entry(s + + if (hash < PPE_SRAM_NUM_ENTRIES) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = airoha_ppe2_is_enabled(eth) && ++ bool ppe2 = airoha_ppe_is_enabled(eth, 1) && + hash >= PPE1_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), +@@ -1286,7 +1289,7 @@ static int airoha_ppe_flush_sram_entries + int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; + struct airoha_foe_entry *hwe = ppe->foe; + +- if (airoha_ppe2_is_enabled(ppe->eth)) ++ if (airoha_ppe_is_enabled(ppe->eth, 1)) + sram_num_entries = sram_num_entries / 2; + + for (i = 0; i < sram_num_entries; i++) diff --git a/target/linux/airoha/patches-6.6/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch b/target/linux/airoha/patches-6.6/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch new file mode 100644 index 0000000000..2382a21168 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch @@ -0,0 +1,359 @@ +From 5bd1d1fd48ea9f8300b211540d946899c7f96480 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:15 +0200 +Subject: [PATCH 05/12] net: airoha: ppe: Move PPE memory info in + airoha_eth_soc_data struct + +AN7583 SoC runs a single PPE device while EN7581 runs two of them. +Moreover PPE SRAM in AN7583 SoC is reduced to 8K (while SRAM is 16K on +EN7581). Take into account PPE memory layout during PPE configuration. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-6-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 10 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 133 +++++++++--------- + .../net/ethernet/airoha/airoha_ppe_debugfs.c | 3 +- + 3 files changed, 70 insertions(+), 76 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -47,14 +47,9 @@ + #define QDMA_METER_IDX(_n) ((_n) & 0xff) + #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) + +-#define PPE_NUM 2 +-#define PPE1_SRAM_NUM_ENTRIES (8 * 1024) +-#define PPE_SRAM_NUM_ENTRIES (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) +-#define PPE1_STATS_NUM_ENTRIES (4 * 1024) +-#define PPE_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_ENTRIES) ++#define PPE_SRAM_NUM_ENTRIES (8 * 1024) ++#define PPE_STATS_NUM_ENTRIES (4 * 1024) + #define PPE_DRAM_NUM_ENTRIES (16 * 1024) +-#define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) +-#define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) + #define PPE_ENTRY_SIZE 80 + #define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) + +@@ -634,6 +629,7 @@ int airoha_ppe_setup_tc_block_cb(struct + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); + void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); ++u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe); + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash); + void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -37,19 +37,36 @@ static int airoha_ppe_get_num_stats_entr + if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) + return -EOPNOTSUPP; + +- return PPE1_STATS_NUM_ENTRIES; ++ return PPE_STATS_NUM_ENTRIES; + } + + static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) + { + int num_stats = airoha_ppe_get_num_stats_entries(ppe); + +- if (num_stats > 0) +- num_stats = num_stats * PPE_NUM; ++ if (num_stats > 0) { ++ struct airoha_eth *eth = ppe->eth; ++ ++ num_stats = num_stats * eth->soc->num_ppe; ++ } + + return num_stats; + } + ++static u32 airoha_ppe_get_total_sram_num_entries(struct airoha_ppe *ppe) ++{ ++ struct airoha_eth *eth = ppe->eth; ++ ++ return PPE_SRAM_NUM_ENTRIES * eth->soc->num_ppe; ++} ++ ++u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe) ++{ ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ ++ return sram_num_entries + PPE_DRAM_NUM_ENTRIES; ++} ++ + bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) + { + if (index >= eth->soc->num_ppe) +@@ -67,14 +84,22 @@ static u32 airoha_ppe_get_timestamp(stru + + static void airoha_ppe_hw_init(struct airoha_ppe *ppe) + { +- u32 sram_tb_size, sram_num_entries, dram_num_entries; ++ u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; ++ u32 sram_tb_size, dram_num_entries; + struct airoha_eth *eth = ppe->eth; + int i, sram_num_stats_entries; + +- sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ sram_tb_size = sram_num_entries * sizeof(struct airoha_foe_entry); + dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); + +- for (i = 0; i < PPE_NUM; i++) { ++ sram_num_stats_entries = airoha_ppe_get_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ sram_ppe_num_data_entries -= sram_num_stats_entries; ++ sram_ppe_num_data_entries = ++ PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries); ++ ++ for (i = 0; i < eth->soc->num_ppe; i++) { + int p; + + airoha_fe_wr(eth, REG_PPE_TB_BASE(i), +@@ -106,10 +131,16 @@ static void airoha_ppe_hw_init(struct ai + + airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), + PPE_TB_CFG_SEARCH_MISS_MASK | ++ PPE_SRAM_TB_NUM_ENTRY_MASK | ++ PPE_DRAM_TB_NUM_ENTRY_MASK | + PPE_TB_CFG_KEEPALIVE_MASK | + PPE_TB_ENTRY_SIZE_MASK, + FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | +- FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); ++ FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0) | ++ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, ++ sram_ppe_num_data_entries) | ++ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, ++ dram_num_entries)); + + airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); + +@@ -122,45 +153,6 @@ static void airoha_ppe_hw_init(struct ai + FIELD_PREP(FP1_EGRESS_MTU_MASK, + AIROHA_MAX_MTU)); + } +- +- if (airoha_ppe_is_enabled(eth, 1)) { +- sram_num_entries = PPE1_SRAM_NUM_ENTRIES; +- sram_num_stats_entries = +- airoha_ppe_get_num_stats_entries(ppe); +- if (sram_num_stats_entries > 0) +- sram_num_entries -= sram_num_stats_entries; +- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); +- +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- } else { +- sram_num_entries = PPE_SRAM_NUM_ENTRIES; +- sram_num_stats_entries = +- airoha_ppe_get_total_num_stats_entries(ppe); +- if (sram_num_stats_entries > 0) +- sram_num_entries -= sram_num_stats_entries; +- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); +- +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- } + } + + static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) +@@ -459,9 +451,11 @@ static int airoha_ppe_foe_entry_set_ipv6 + return 0; + } + +-static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) ++static u32 airoha_ppe_foe_get_entry_hash(struct airoha_ppe *ppe, ++ struct airoha_foe_entry *hwe) + { + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; + u32 hash, hv1, hv2, hv3; + + switch (type) { +@@ -499,14 +493,14 @@ static u32 airoha_ppe_foe_get_entry_hash + case PPE_PKT_TYPE_IPV6_6RD: + default: + WARN_ON_ONCE(1); +- return PPE_HASH_MASK; ++ return ppe_hash_mask; + } + + hash = (hv1 & hv2) | ((~hv1) & hv3); + hash = (hash >> 24) | ((hash & 0xffffff) << 8); + hash ^= hv1 ^ hv2 ^ hv3; + hash ^= hash >> 16; +- hash &= PPE_NUM_ENTRIES - 1; ++ hash &= ppe_hash_mask; + + return hash; + } +@@ -607,9 +601,11 @@ static void airoha_ppe_foe_flow_stats_up + static struct airoha_foe_entry * + airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) + { ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ + lockdep_assert_held(&ppe_lock); + +- if (hash < PPE_SRAM_NUM_ENTRIES) { ++ if (hash < sram_num_entries) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); + struct airoha_eth *eth = ppe->eth; + bool ppe2; +@@ -617,7 +613,7 @@ airoha_ppe_foe_get_entry_locked(struct a + int i; + + ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= PPE1_SRAM_NUM_ENTRIES; ++ hash >= PPE_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | + PPE_SRAM_CTRL_REQ_MASK); +@@ -668,6 +664,7 @@ static int airoha_ppe_foe_commit_entry(s + struct airoha_foe_entry *e, + u32 hash, bool rx_wlan) + { ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); + u32 ts = airoha_ppe_get_timestamp(ppe); + struct airoha_eth *eth = ppe->eth; +@@ -692,10 +689,10 @@ static int airoha_ppe_foe_commit_entry(s + if (!rx_wlan) + airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); + +- if (hash < PPE_SRAM_NUM_ENTRIES) { ++ if (hash < sram_num_entries) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); + bool ppe2 = airoha_ppe_is_enabled(eth, 1) && +- hash >= PPE1_SRAM_NUM_ENTRIES; ++ hash >= PPE_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), + hash, ppe2); +@@ -822,7 +819,7 @@ static void airoha_ppe_foe_insert_entry( + if (state == AIROHA_FOE_STATE_BIND) + goto unlock; + +- index = airoha_ppe_foe_get_entry_hash(hwe); ++ index = airoha_ppe_foe_get_entry_hash(ppe, hwe); + hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { + if (e->type == FLOW_TYPE_L2_SUBFLOW) { + state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); +@@ -882,7 +879,7 @@ static int airoha_ppe_foe_flow_commit_en + if (type == PPE_PKT_TYPE_BRIDGE) + return airoha_ppe_foe_l2_flow_commit_entry(ppe, e); + +- hash = airoha_ppe_foe_get_entry_hash(&e->data); ++ hash = airoha_ppe_foe_get_entry_hash(ppe, &e->data); + e->type = FLOW_TYPE_L4; + e->hash = 0xffff; + +@@ -1286,17 +1283,15 @@ static int airoha_ppe_flow_offload_cmd(s + static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, + struct airoha_npu *npu) + { +- int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe; ++ int i; + +- if (airoha_ppe_is_enabled(ppe->eth, 1)) +- sram_num_entries = sram_num_entries / 2; +- +- for (i = 0; i < sram_num_entries; i++) ++ for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) + memset(&hwe[i], 0, sizeof(*hwe)); + + return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, +- PPE_SRAM_NUM_ENTRIES); ++ sram_num_entries); + } + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) +@@ -1372,9 +1367,10 @@ void airoha_ppe_check_skb(struct airoha_ + u16 hash, bool rx_wlan) + { + struct airoha_ppe *ppe = dev->priv; ++ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; + u16 now, diff; + +- if (hash > PPE_HASH_MASK) ++ if (hash > ppe_hash_mask) + return; + + now = (u16)jiffies; +@@ -1465,6 +1461,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); + int airoha_ppe_init(struct airoha_eth *eth) + { + int foe_size, err, ppe_num_stats_entries; ++ u32 ppe_num_entries; + struct airoha_ppe *ppe; + + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); +@@ -1474,18 +1471,18 @@ int airoha_ppe_init(struct airoha_eth *e + ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; + ppe->dev.ops.check_skb = airoha_ppe_check_skb; + ppe->dev.priv = ppe; ++ ppe->eth = eth; ++ eth->ppe = ppe; + +- foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); ++ foe_size = ppe_num_entries * sizeof(struct airoha_foe_entry); + ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, + GFP_KERNEL); + if (!ppe->foe) + return -ENOMEM; + +- ppe->eth = eth; +- eth->ppe = ppe; +- + ppe->foe_flow = devm_kzalloc(eth->dev, +- PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), ++ ppe_num_entries * sizeof(*ppe->foe_flow), + GFP_KERNEL); + if (!ppe->foe_flow) + return -ENOMEM; +@@ -1500,7 +1497,7 @@ int airoha_ppe_init(struct airoha_eth *e + return -ENOMEM; + } + +- ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, ++ ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries, + GFP_KERNEL); + if (!ppe->foe_check_time) + return -ENOMEM; +--- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c +@@ -53,9 +53,10 @@ static int airoha_ppe_debugfs_foe_show(s + [AIROHA_FOE_STATE_FIN] = "FIN", + }; + struct airoha_ppe *ppe = m->private; ++ u32 ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); + int i; + +- for (i = 0; i < PPE_NUM_ENTRIES; i++) { ++ for (i = 0; i < ppe_num_entries; i++) { + const char *state_str, *type_str = "UNKNOWN"; + void *src_addr = NULL, *dest_addr = NULL; + u16 *src_port = NULL, *dest_port = NULL; diff --git a/target/linux/airoha/patches-6.6/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch b/target/linux/airoha/patches-6.6/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch new file mode 100644 index 0000000000..18b92fb50d --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch @@ -0,0 +1,58 @@ +From 41139125f5c70e0f66f0cc4ac1b3a62f5801ab42 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:16 +0200 +Subject: [PATCH 06/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where + not necessary + +Now each PPE has always PPE_STATS_NUM_ENTRIES entries so we do not need +to run airoha_ppe_is_enabled routine to check if the hash refers to +PPE1 or PPE2. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-7-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -514,10 +514,8 @@ static int airoha_ppe_foe_get_flow_stats + if (ppe_num_stats_entries < 0) + return ppe_num_stats_entries; + +- *index = hash; +- if (airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= ppe_num_stats_entries) +- *index = *index - PPE_STATS_NUM_ENTRIES; ++ *index = hash >= ppe_num_stats_entries ? hash - PPE_STATS_NUM_ENTRIES ++ : hash; + + return 0; + } +@@ -607,13 +605,11 @@ airoha_ppe_foe_get_entry_locked(struct a + + if (hash < sram_num_entries) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; + struct airoha_eth *eth = ppe->eth; +- bool ppe2; + u32 val; + int i; + +- ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= PPE_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | + PPE_SRAM_CTRL_REQ_MASK); +@@ -691,8 +687,7 @@ static int airoha_ppe_foe_commit_entry(s + + if (hash < sram_num_entries) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = airoha_ppe_is_enabled(eth, 1) && +- hash >= PPE_SRAM_NUM_ENTRIES; ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), + hash, ppe2); diff --git a/target/linux/airoha/patches-6.6/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch b/target/linux/airoha/patches-6.6/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch new file mode 100644 index 0000000000..60b4ee1e44 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch @@ -0,0 +1,65 @@ +From 306b78f5035af4bd011753c5a6b12812515caa6c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:17 +0200 +Subject: [PATCH 07/12] net: airoha: ppe: Configure SRAM PPE entries via the + cpu + +Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure +the SRAM PPE entries directly via the CPU instead of using the NPU APIs. +This is a preliminary patch to enable netfilter flowtable hw offload for +AN7583 SoC. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-8-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 30 ++++++++++++++++++------ + 1 file changed, 23 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -656,6 +656,27 @@ static bool airoha_ppe_foe_compare_entry + return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); + } + ++static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash) ++{ ++ struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; ++ u32 *ptr = (u32 *)hwe, val; ++ int i; ++ ++ for (i = 0; i < sizeof(*hwe) / sizeof(*ptr); i++) ++ airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]); ++ ++ wmb(); ++ airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), ++ FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | ++ PPE_SRAM_CTRL_WR_MASK | PPE_SRAM_CTRL_REQ_MASK); ++ ++ return read_poll_timeout_atomic(airoha_fe_rr, val, ++ val & PPE_SRAM_CTRL_ACK_MASK, ++ 10, 100, false, ppe->eth, ++ REG_PPE_RAM_CTRL(ppe2)); ++} ++ + static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, + struct airoha_foe_entry *e, + u32 hash, bool rx_wlan) +@@ -685,13 +706,8 @@ static int airoha_ppe_foe_commit_entry(s + if (!rx_wlan) + airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); + +- if (hash < sram_num_entries) { +- dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; +- +- err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), +- hash, ppe2); +- } ++ if (hash < sram_num_entries) ++ err = airoha_ppe_foe_commit_sram_entry(ppe, hash); + unlock: + rcu_read_unlock(); + diff --git a/target/linux/airoha/patches-6.6/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch b/target/linux/airoha/patches-6.6/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch new file mode 100644 index 0000000000..24ecccabc8 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch @@ -0,0 +1,71 @@ +From 620d7b91aadbd4eb930895b07e34f0a155a9d3c1 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:18 +0200 +Subject: [PATCH 08/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup + +Rely on airoha_ppe_foe_commit_sram_entry routine to flush SRAM PPE table +entries. This patch allow moving PPE SRAM flush during PPE setup and +avoid dumping uninitialized values via the debugfs if no entries are +offloaded yet. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-9-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1291,18 +1291,22 @@ static int airoha_ppe_flow_offload_cmd(s + return -EOPNOTSUPP; + } + +-static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, +- struct airoha_npu *npu) ++static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe) + { + u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe; +- int i; ++ int i, err = 0; ++ ++ for (i = 0; i < sram_num_entries; i++) { ++ int err; + +- for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) + memset(&hwe[i], 0, sizeof(*hwe)); ++ err = airoha_ppe_foe_commit_sram_entry(ppe, i); ++ if (err) ++ break; ++ } + +- return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, +- sram_num_entries); ++ return err; + } + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) +@@ -1339,10 +1343,6 @@ static int airoha_ppe_offload_setup(stru + } + + airoha_ppe_hw_init(ppe); +- err = airoha_ppe_flush_sram_entries(ppe, npu); +- if (err) +- goto error_npu_put; +- + airoha_ppe_foe_flow_stats_reset(ppe, npu); + + rcu_assign_pointer(eth->npu, npu); +@@ -1513,6 +1513,10 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_check_time) + return -ENOMEM; + ++ err = airoha_ppe_flush_sram_entries(ppe); ++ if (err) ++ return err; ++ + err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); + if (err) + return err; diff --git a/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch b/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch new file mode 100644 index 0000000000..c6ecbdb829 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch @@ -0,0 +1,91 @@ +From c71a7a861ef02aa2bebb18c2f3385aa3f19094e0 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:19 +0200 +Subject: [PATCH 09/12] net: airoha: Select default ppe cpu port in + airoha_dev_init() + +Select the PPE default cpu port in airoha_dev_init routine. +This patch allows to distribute the load between the two available cpu +ports (FE_PSE_PORT_CDM1 and FE_PSE_PORT_CDM2) if the device is running a +single PPE module (e.g. 7583) selecting the cpu port based on the use +QDMA device. For multi-PPE device (e.g. 7581) assign FE_PSE_PORT_CDM1 to +PPE1 and FE_PSE_PORT_CDM2 to PPE2. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-10-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 38 ++++++++++-------------- + 1 file changed, 16 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -531,25 +531,6 @@ static int airoha_fe_init(struct airoha_ + /* disable IFC by default */ + airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); + +- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), +- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1)); +- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1), +- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2)); +- + /* enable 1:N vlan action, init vlan table */ + airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); + +@@ -1761,8 +1742,10 @@ static void airhoha_set_gdm2_loopback(st + static int airoha_dev_init(struct net_device *dev) + { + struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_eth *eth = port->qdma->eth; +- u32 pse_port; ++ struct airoha_qdma *qdma = port->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ u32 pse_port, fe_cpu_port; ++ u8 ppe_id; + + airoha_set_macaddr(port, dev->dev_addr); + +@@ -1775,16 +1758,27 @@ static int airoha_dev_init(struct net_de + fallthrough; + case 2: + if (airoha_ppe_is_enabled(eth, 1)) { ++ /* For PPE2 always use secondary cpu port. */ ++ fe_cpu_port = FE_PSE_PORT_CDM2; + pse_port = FE_PSE_PORT_PPE2; + break; + } + fallthrough; +- default: ++ default: { ++ u8 qdma_id = qdma - ð->qdma[0]; ++ ++ /* For PPE1 select cpu port according to the running QDMA. */ ++ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; + pse_port = FE_PSE_PORT_PPE1; + break; + } ++ } + + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); ++ ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0; ++ airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), ++ DFT_CPORT_MASK(port->id), ++ fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id))); + + return 0; + } diff --git a/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch b/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch new file mode 100644 index 0000000000..cec079845c --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch @@ -0,0 +1,202 @@ +From 9d5b5219f672c80bed4d4e15f0068e648cdca43b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:20 +0200 +Subject: [PATCH 10/12] net: airoha: Refactor src port configuration in + airhoha_set_gdm2_loopback + +AN7583 chipset relies on different definitions for source-port +identifier used for hw offloading. In order to support hw offloading +in AN7583 controller, refactor src port configuration in +airhoha_set_gdm2_loopback routine and introduce get_src_port_id +callback. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-11-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 82 ++++++++++++++++------- + drivers/net/ethernet/airoha/airoha_eth.h | 18 +++-- + drivers/net/ethernet/airoha/airoha_regs.h | 6 +- + 3 files changed, 73 insertions(+), 33 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1687,13 +1687,17 @@ static int airoha_dev_set_macaddr(struct + return 0; + } + +-static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) ++static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { +- u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; ++ u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; +- u32 chan = port->id == 3 ? 4 : 0; ++ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ ++ u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; ++ int src_port; + + /* Forward the traffic to the proper GDM port */ ++ pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 ++ : FE_PSE_PORT_GDM4; + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); + airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); + +@@ -1714,29 +1718,25 @@ static void airhoha_set_gdm2_loopback(st + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); + +- if (port->id == 3) { +- /* FIXME: handle XSI_PCE1_PORT */ +- airoha_fe_rmw(eth, REG_FE_WAN_PORT, +- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, +- FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); +- airoha_fe_rmw(eth, +- REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), +- SP_CPORT_PCIE0_MASK, +- FIELD_PREP(SP_CPORT_PCIE0_MASK, +- FE_PSE_PORT_CDM2)); +- } else { +- /* FIXME: handle XSI_USB_PORT */ ++ src_port = eth->soc->ops.get_src_port_id(port, nbq); ++ if (src_port < 0) ++ return src_port; ++ ++ airoha_fe_rmw(eth, REG_FE_WAN_PORT, ++ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, ++ FIELD_PREP(WAN0_MASK, src_port)); ++ val = src_port & SP_CPORT_DFT_MASK; ++ airoha_fe_rmw(eth, ++ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), ++ SP_CPORT_MASK(val), ++ FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); ++ ++ if (port->id != AIROHA_GDM3_IDX) + airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, + FC_ID_OF_SRC_PORT24_MASK, + FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); +- airoha_fe_rmw(eth, REG_FE_WAN_PORT, +- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, +- FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); +- airoha_fe_rmw(eth, +- REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), +- SP_CPORT_ETH_MASK, +- FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); +- } ++ ++ return 0; + } + + static int airoha_dev_init(struct net_device *dev) +@@ -1753,8 +1753,13 @@ static int airoha_dev_init(struct net_de + case 3: + case 4: + /* If GDM2 is active we can't enable loopback */ +- if (!eth->ports[1]) +- airhoha_set_gdm2_loopback(port); ++ if (!eth->ports[1]) { ++ int err; ++ ++ err = airhoha_set_gdm2_loopback(port); ++ if (err) ++ return err; ++ } + fallthrough; + case 2: + if (airoha_ppe_is_enabled(eth, 1)) { +@@ -3073,11 +3078,38 @@ static const char * const en7581_xsi_rst + "xfp-mac", + }; + ++static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case 3: ++ /* 7581 SoC supports PCIe serdes on GDM3 port */ ++ if (nbq == 4) ++ return HSGMII_LAN_7581_PCIE0_SRCPORT; ++ if (nbq == 5) ++ return HSGMII_LAN_7581_PCIE1_SRCPORT; ++ break; ++ case 4: ++ /* 7581 SoC supports eth and usb serdes on GDM4 port */ ++ if (!nbq) ++ return HSGMII_LAN_7581_ETH_SRCPORT; ++ if (nbq == 1) ++ return HSGMII_LAN_7581_USB_SRCPORT; ++ break; ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + static const struct airoha_eth_soc_data en7581_soc_data = { + .version = 0x7581, + .xsi_rsts_names = en7581_xsi_rsts_names, + .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), + .num_ppe = 2, ++ .ops = { ++ .get_src_port_id = airoha_en7581_get_src_port_id, ++ }, + }; + + static const struct of_device_id of_airoha_match[] = { +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -67,10 +67,10 @@ enum { + }; + + enum { +- HSGMII_LAN_PCIE0_SRCPORT = 0x16, +- HSGMII_LAN_PCIE1_SRCPORT, +- HSGMII_LAN_ETH_SRCPORT, +- HSGMII_LAN_USB_SRCPORT, ++ HSGMII_LAN_7581_PCIE0_SRCPORT = 0x16, ++ HSGMII_LAN_7581_PCIE1_SRCPORT, ++ HSGMII_LAN_7581_ETH_SRCPORT, ++ HSGMII_LAN_7581_USB_SRCPORT, + }; + + enum { +@@ -99,6 +99,13 @@ enum { + CRSN_25 = 0x19, + }; + ++enum airoha_gdm_index { ++ AIROHA_GDM1_IDX = 1, ++ AIROHA_GDM2_IDX = 2, ++ AIROHA_GDM3_IDX = 3, ++ AIROHA_GDM4_IDX = 4, ++}; ++ + enum { + FE_PSE_PORT_CDM1, + FE_PSE_PORT_GDM1, +@@ -555,6 +562,9 @@ struct airoha_eth_soc_data { + const char * const *xsi_rsts_names; + int num_xsi_rsts; + int num_ppe; ++ struct { ++ int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); ++ } ops; + }; + + struct airoha_eth { +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -383,10 +383,8 @@ + #define REG_MC_VLAN_DATA 0x2108 + + #define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) +-#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) +-#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) +-#define SP_CPORT_USB_MASK GENMASK(7, 4) +-#define SP_CPORT_ETH_MASK GENMASK(7, 4) ++#define SP_CPORT_DFT_MASK GENMASK(2, 0) ++#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) + + #define REG_SRC_PORT_FC_MAP6 0x2298 + #define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) diff --git a/target/linux/airoha/patches-6.6/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch b/target/linux/airoha/patches-6.6/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch new file mode 100644 index 0000000000..93e7f5e592 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch @@ -0,0 +1,29 @@ +From 63f283d36b1fb06b55ae609a1f679544f5f66057 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:21 +0200 +Subject: [PATCH 11/12] net: airoha: ppe: Do not use magic numbers in + airoha_ppe_foe_get_entry_locked() + +Explicit the size of entries pointed by hwe pointer in +airoha_ppe_foe_get_entry_locked routine + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-12-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -619,7 +619,8 @@ airoha_ppe_foe_get_entry_locked(struct a + REG_PPE_RAM_CTRL(ppe2))) + return NULL; + +- for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) ++ for (i = 0; i < sizeof(struct airoha_foe_entry) / sizeof(*hwe); ++ i++) + hwe[i] = airoha_fe_rr(eth, + REG_PPE_RAM_ENTRY(ppe2, i)); + } diff --git a/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch b/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch new file mode 100644 index 0000000000..7f34a05ab5 --- /dev/null +++ b/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch @@ -0,0 +1,185 @@ +From e4e5ce823bdd4601bd75ae7c206ae35e7c2fa60b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:22 +0200 +Subject: [PATCH 12/12] net: airoha: Add AN7583 SoC support + +Introduce support for AN7583 ethernet controller to airoha-eth dirver. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-13-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 68 ++++++++++++++++++++++-- + drivers/net/ethernet/airoha/airoha_eth.h | 11 ++++ + drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++ + 3 files changed, 77 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1689,10 +1689,8 @@ static int airoha_dev_set_macaddr(struct + + static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { +- u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; +- /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ +- u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; ++ u32 val, pse_port, chan, nbq; + int src_port; + + /* Forward the traffic to the proper GDM port */ +@@ -1704,6 +1702,8 @@ static int airhoha_set_gdm2_loopback(str + /* Enable GDM2 loopback */ + airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); + airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); ++ ++ chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0; + airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, + FIELD_PREP(LPBK_CHAN_MASK, chan) | +@@ -1718,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); + ++ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ ++ nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; + src_port = eth->soc->ops.get_src_port_id(port, nbq); + if (src_port < 0) + return src_port; +@@ -1731,7 +1733,7 @@ static int airhoha_set_gdm2_loopback(str + SP_CPORT_MASK(val), + FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); + +- if (port->id != AIROHA_GDM3_IDX) ++ if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth)) + airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, + FC_ID_OF_SRC_PORT24_MASK, + FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); +@@ -1900,6 +1902,22 @@ static bool airoha_dev_tx_queue_busy(str + return index >= tail; + } + ++static int airoha_get_fe_port(struct airoha_gdm_port *port) ++{ ++ struct airoha_qdma *qdma = port->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ ++ switch (eth->soc->version) { ++ case 0x7583: ++ return port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 ++ : port->id; ++ case 0x7581: ++ default: ++ return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 ++ : port->id; ++ } ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +@@ -1940,7 +1958,7 @@ static netdev_tx_t airoha_dev_xmit(struc + } + } + +- fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ fport = airoha_get_fe_port(port); + msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | + FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); + +@@ -3102,6 +3120,35 @@ static int airoha_en7581_get_src_port_id + return -EINVAL; + } + ++static const char * const an7583_xsi_rsts_names[] = { ++ "xsi-mac", ++ "hsi0-mac", ++ "hsi1-mac", ++ "xfp-mac", ++}; ++ ++static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case 3: ++ /* 7583 SoC supports eth serdes on GDM3 port */ ++ if (!nbq) ++ return HSGMII_LAN_7583_ETH_SRCPORT; ++ break; ++ case 4: ++ /* 7583 SoC supports PCIe and USB serdes on GDM4 port */ ++ if (!nbq) ++ return HSGMII_LAN_7583_PCIE_SRCPORT; ++ if (nbq == 1) ++ return HSGMII_LAN_7583_USB_SRCPORT; ++ break; ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + static const struct airoha_eth_soc_data en7581_soc_data = { + .version = 0x7581, + .xsi_rsts_names = en7581_xsi_rsts_names, +@@ -3112,8 +3159,19 @@ static const struct airoha_eth_soc_data + }, + }; + ++static const struct airoha_eth_soc_data an7583_soc_data = { ++ .version = 0x7583, ++ .xsi_rsts_names = an7583_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), ++ .num_ppe = 1, ++ .ops = { ++ .get_src_port_id = airoha_an7583_get_src_port_id, ++ }, ++}; ++ + static const struct of_device_id of_airoha_match[] = { + { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, ++ { .compatible = "airoha,an7583-eth", .data = &an7583_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_match); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -74,6 +74,12 @@ enum { + }; + + enum { ++ HSGMII_LAN_7583_ETH_SRCPORT = 0x16, ++ HSGMII_LAN_7583_PCIE_SRCPORT = 0x18, ++ HSGMII_LAN_7583_USB_SRCPORT, ++}; ++ ++enum { + XSI_PCIE0_VIP_PORT_MASK = BIT(22), + XSI_PCIE1_VIP_PORT_MASK = BIT(23), + XSI_USB_VIP_PORT_MASK = BIT(25), +@@ -629,6 +635,11 @@ static inline bool airoha_is_7581(struct + return eth->soc->version == 0x7581; + } + ++static inline bool airoha_is_7583(struct airoha_eth *eth) ++{ ++ return eth->soc->version == 0x7583; ++} ++ + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -37,6 +37,9 @@ static int airoha_ppe_get_num_stats_entr + if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) + return -EOPNOTSUPP; + ++ if (airoha_is_7583(ppe->eth)) ++ return -EOPNOTSUPP; ++ + return PPE_STATS_NUM_ENTRIES; + } + diff --git a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch index 7537f659f9..85af65e3b4 100644 --- a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -13,11 +13,11 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1401,6 +1401,10 @@ static int airoha_hw_init(struct platfor +@@ -1388,6 +1388,10 @@ static int airoha_hw_init(struct platfor if (err) return err; -+ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts); ++ err = reset_control_bulk_deassert(eth->soc->num_xsi_rsts, eth->xsi_rsts); + if (err) + return err; + diff --git a/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch index b620ec62b9..cf6520dd53 100644 --- a/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch +++ b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch @@ -16,7 +16,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -605,8 +605,11 @@ static int airoha_qdma_get_gdm_port(stru +@@ -593,8 +593,11 @@ static int airoha_qdma_get_gdm_port(stru sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); switch (sport) { diff --git a/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch b/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch index 4cc1d6c6fc..a52ee91ed9 100644 --- a/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch +++ b/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -507,8 +507,8 @@ static int airoha_fe_init(struct airoha_ +@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); @@ -36,7 +36,7 @@ Signed-off-by: Christian Marangi #define GDM_DROP_CRC_ERR BIT(23) #define GDM_IP4_CKSUM BIT(22) #define GDM_TCP_CKSUM BIT(21) -@@ -349,13 +350,6 @@ +@@ -352,13 +353,6 @@ #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index 4af0275688..7e3ee7a9e8 100644 --- a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -507,8 +507,10 @@ static int airoha_fe_init(struct airoha_ +@@ -514,8 +514,10 @@ static int airoha_fe_init(struct airoha_ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); @@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi airoha_fe_crsn_qsel_init(eth); -@@ -1643,7 +1645,8 @@ static int airoha_dev_open(struct net_de +@@ -1630,7 +1632,8 @@ static int airoha_dev_open(struct net_de if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index 3e9a92db6b..be23e27ce0 100644 --- a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,30 +15,19 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2948,11 +2948,10 @@ static int airoha_probe(struct platform_ - return err; - } +@@ -3099,7 +3099,6 @@ static void airoha_remove(struct platfor + } -- eth->xsi_rsts[0].id = "xsi-mac"; -- eth->xsi_rsts[1].id = "hsi0-mac"; -- eth->xsi_rsts[2].id = "hsi1-mac"; -- eth->xsi_rsts[3].id = "hsi-mac"; -- eth->xsi_rsts[4].id = "xfp-mac"; -+ eth->xsi_rsts[0].id = "hsi0-mac"; -+ eth->xsi_rsts[1].id = "hsi1-mac"; -+ eth->xsi_rsts[2].id = "hsi-mac"; -+ eth->xsi_rsts[3].id = "xfp-mac"; - err = devm_reset_control_bulk_get_exclusive(eth->dev, - ARRAY_SIZE(eth->xsi_rsts), - eth->xsi_rsts); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -21,7 +21,7 @@ - #define AIROHA_MAX_NUM_IRQ_BANKS 4 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 --#define AIROHA_MAX_NUM_XSI_RSTS 5 -+#define AIROHA_MAX_NUM_XSI_RSTS 4 - #define AIROHA_MAX_MTU 9216 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 + static const char * const en7581_xsi_rsts_names[] = { +- "xsi-mac", + "hsi0-mac", + "hsi1-mac", + "hsi-mac", +@@ -3131,7 +3130,6 @@ static int airoha_en7581_get_src_port_id + } + + static const char * const an7583_xsi_rsts_names[] = { +- "xsi-mac", + "hsi0-mac", + "hsi1-mac", + "xfp-mac", diff --git a/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch index 7accd73775..e6a39b4680 100644 --- a/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch +++ b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch @@ -22,8 +22,8 @@ Signed-off-by: Christian Marangi --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -1041,6 +1041,12 @@ static void phylink_pcs_link_up(struct p - pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); +@@ -1088,6 +1088,12 @@ static unsigned int phylink_inband_caps( + return phylink_pcs_inband_caps(pcs, interface); } +static void phylink_pcs_link_down(struct phylink_pcs *pcs) @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void phylink_pcs_poll_stop(struct phylink *pl) { if (pl->cfg_link_an_mode == MLO_AN_INBAND) -@@ -1454,6 +1460,8 @@ static void phylink_link_down(struct phy +@@ -1642,6 +1648,8 @@ static void phylink_link_down(struct phy if (ndev) netif_carrier_off(ndev); diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index 68671eb496..fd01dcda99 100644 --- a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { struct airoha_eth *eth = port->qdma->eth; -@@ -1640,6 +1646,17 @@ static int airoha_dev_open(struct net_de +@@ -1627,6 +1633,17 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); if (err) -@@ -1693,6 +1710,11 @@ static int airoha_dev_stop(struct net_de +@@ -1680,6 +1697,11 @@ static int airoha_dev_stop(struct net_de } } @@ -65,8 +65,8 @@ Signed-off-by: Christian Marangi return 0; } -@@ -2781,6 +2803,20 @@ static const struct ethtool_ops airoha_e - .get_rmon_stats = airoha_ethtool_get_rmon_stats, +@@ -2828,6 +2850,20 @@ static const struct ethtool_ops airoha_e + .get_link = ethtool_op_get_link, }; +static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config, @@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { int i; -@@ -2825,6 +2861,99 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2872,6 +2908,99 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { -@@ -2903,6 +3032,12 @@ static int airoha_alloc_gdm_port(struct +@@ -2950,6 +3079,12 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3006,6 +3141,10 @@ error_hw_cleanup: +@@ -3064,6 +3199,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3033,6 +3172,10 @@ static void airoha_remove(struct platfor +@@ -3091,6 +3230,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -528,6 +528,10 @@ struct airoha_gdm_port { +@@ -531,6 +531,10 @@ struct airoha_gdm_port { struct net_device *dev; int id; @@ -236,7 +236,7 @@ Signed-off-by: Christian Marangi DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -361,6 +361,18 @@ +@@ -364,6 +364,18 @@ #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) diff --git a/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch index 0fa14de3ee..5270c26e99 100644 --- a/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch +++ b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch @@ -14,7 +14,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -616,6 +616,9 @@ static int airoha_qdma_get_gdm_port(stru +@@ -604,6 +604,9 @@ static int airoha_qdma_get_gdm_port(stru case 0x18: port = 3; /* GDM4 */ break; From 4d4fd4d1258ba9ba645175faa1c16765a1f3abd1 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Oct 2025 15:37:00 +0200 Subject: [PATCH 050/128] airoha: an7583: add additional comments on EVB board On the Airoha AN7583 EVB there are 2 Aeonsemi AS21xxx PHY but only the one connected to Serdes Ethernet is usable as the other connected to Serdes PON is not actually HW connected (as the serdes is connected to the BOSA port) Add comments and disable the relevant PHY. Signed-off-by: Christian Marangi (cherry picked from commit ea850b5a18a7b5041000bfd77ed1be6f29ba7b75) --- target/linux/airoha/dts/an7583-evb.dts | 83 ++++++++++++++------------ 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/target/linux/airoha/dts/an7583-evb.dts b/target/linux/airoha/dts/an7583-evb.dts index fdd5b2aa92..30f1cf0800 100644 --- a/target/linux/airoha/dts/an7583-evb.dts +++ b/target/linux/airoha/dts/an7583-evb.dts @@ -135,37 +135,41 @@ pinctrl-names = "default"; pinctrl-0 = <&mdio0_pins>; - as21xx_0: ethernet-phy@1d { - reg = <0x1d>; - compatible = "ethernet-phy-ieee802.3-c45"; - - firmware-name = "as21x1x_fw.bin"; - - reset-deassert-us = <350000>; - reset-assert-us = <200000>; - reset-gpios = <&an7583_pinctrl 34 GPIO_ACTIVE_LOW>; - - leds { - #address-cells = <1>; - #size-cells = <0>; - - led@0 { - reg = <0>; - color = ; - function = LED_FUNCTION_LAN; - function-enumerator = <0>; - default-state = "keep"; - }; - - led@1 { - reg = <1>; - color = ; - function = LED_FUNCTION_LAN; - function-enumerator = <1>; - default-state = "keep"; - }; - }; - }; + /* Present but not HW connected to GDM port */ + /* + * as21xx_0: ethernet-phy@1d { + * reg = <0x1d>; + * compatible = "ethernet-phy-ieee802.3-c45"; + * status = "disabled"; + * + * firmware-name = "as21x1x_fw.bin"; + * + * reset-deassert-us = <350000>; + * reset-assert-us = <200000>; + * reset-gpios = <&an7583_pinctrl 34 GPIO_ACTIVE_LOW>; + * + * leds { + * #address-cells = <1>; + * #size-cells = <0>; + * + * led@0 { + * reg = <0>; + * color = ; + * function = LED_FUNCTION_LAN; + * function-enumerator = <0>; + * default-state = "keep"; + * }; + * + * led@1 { + * reg = <1>; + * color = ; + * function = LED_FUNCTION_LAN; + * function-enumerator = <1>; + * default-state = "keep"; + * }; + * }; + * }; + */ as21xx_1: ethernet-phy@1f { reg = <0x1f>; @@ -200,16 +204,19 @@ }; }; +/* GDM2 seems to be connected to PON */ +/* + *&gdm2 { + * status = "disabled"; + * + * phy-handle = <&as21xx_0>; + * phy-mode = "usxgmii"; + *}; + */ + &gdm3 { status = "okay"; phy-handle = <&as21xx_1>; phy-mode = "usxgmii"; }; - -&gdm2 { - status = "okay"; - - phy-handle = <&as21xx_0>; - phy-mode = "usxgmii"; -}; From 89cee1bf3f72336b6137931118c600a6b4947325 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Oct 2025 15:38:36 +0200 Subject: [PATCH 051/128] airoha: an7583: Add missing DTS for EMMC RFB board While adding support for Airoha AN7583, it was forget to push the EMMC DTS while defining the variant in the image Makefile. Add the missing DTS to fix image creation error. Signed-off-by: Christian Marangi (cherry picked from commit 6fe65d404bdd1236d16d9278a5d50c0af541d1f9) --- target/linux/airoha/dts/an7583-evb-emmc.dts | 293 ++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 target/linux/airoha/dts/an7583-evb-emmc.dts diff --git a/target/linux/airoha/dts/an7583-evb-emmc.dts b/target/linux/airoha/dts/an7583-evb-emmc.dts new file mode 100644 index 0000000000..df5ee5bde0 --- /dev/null +++ b/target/linux/airoha/dts/an7583-evb-emmc.dts @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/dts-v1/; + +#include +#include +#include +#include "an7583.dtsi" + +/ { + model = "Airoha AN7583 Evaluation Board"; + compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583"; + + aliases { + serial0 = &uart1; + }; + + chosen { + bootargs = "console=ttyS0,115200 earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x2 0x00000000>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + btn-reset { + label = "reset"; + linux,code = ; + gpios = <&an7583_pinctrl 0 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-1 { + label = "pon"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&an7583_pinctrl 12 GPIO_ACTIVE_LOW>; + }; + + led-2 { + label = "internet"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&an7583_pinctrl 26 GPIO_ACTIVE_LOW>; + }; + + led-3 { + label = "wps"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&an7583_pinctrl 31 GPIO_ACTIVE_LOW>; + }; + + led-4 { + label = "los"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&an7583_pinctrl 27 GPIO_ACTIVE_LOW>; + }; + + led-5 { + label = "voip_hook"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&an7583_pinctrl 29 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&an7583_pinctrl { + gpio-ranges = <&an7583_pinctrl 0 2 53>; + + mdio0_pins: mdio0-pins { + conf { + pins = "mdio_0"; + output-high; + }; + }; + + pcie0_rst_pins: pcie0-rst-pins { + conf { + pins = "pcie_reset0"; + drive-open-drain = <1>; + }; + }; + + pcie1_rst_pins: pcie1-rst-pins { + conf { + pins = "pcie_reset1"; + drive-open-drain = <1>; + }; + }; + + gswp1_led0_pins: gswp1-led0-pins { + mux { + function = "phy1_led0"; + pins = "gpio1"; + }; + }; + + gswp2_led0_pins: gswp2-led0-pins { + mux { + function = "phy2_led0"; + pins = "gpio2"; + }; + }; + + gswp3_led0_pins: gswp3-led0-pins { + mux { + function = "phy3_led0"; + pins = "gpio3"; + }; + }; + + gswp4_led0_pins: gswp4-led0-pins { + mux { + function = "phy4_led0"; + pins = "gpio4"; + }; + }; + + mmc_pins: mmc-pins { + mux { + function = "emmc"; + groups = "emmc"; + }; + }; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc_pins>; + pinctrl-1 = <&mmc_pins>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + card@0 { + compatible = "mmc-card"; + reg = <0>; + + block { + compatible = "block-device"; + partitions { + block-partition-factory { + partname = "art"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x40000 0x1e00>; + }; + + mac_factory_2c0000: mac@2c0000 { + reg = <0x2c0000 0x6>; + }; + + pon_mac_factory_2c0006: pon_mac@2c0006 { + reg = <0x2c0006 0x6>; + }; + + onu_type_factory_2e0000: onu_type@2e0000 { + reg = <0x2e0000 0x10>; + }; + + board_config_factory_2e0010: board_config@2e0010 { + reg = <0x2e0010 0x8>; + }; + }; + }; + }; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&mdio_0 { + pinctrl-names = "default"; + pinctrl-0 = <&mdio0_pins>; + + en8811: ethernet-phy@f { + reg = <0xf>; + + reset-gpios = <&an7583_pinctrl 28 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <20000>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + function = LED_FUNCTION_LAN; + color = ; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + function = LED_FUNCTION_LAN; + color = ; + function-enumerator = <1>; + default-state = "keep"; + }; + }; + }; +}; + +ð { + status = "okay"; + nvmem-cells = <&mac_factory_2c0000>; + nvmem-cell-names = "mac"; +}; + +&gdm1 { + status = "okay"; +}; + +&gdm3 { + status = "okay"; + + phy-handle = <&en8811>; + phy-mode = "2500base-x"; +}; + +&switch { + status = "okay"; +}; + +&gsw_phy1 { + pinctrl-names = "gbe-led"; + pinctrl-0 = <&gswp1_led0_pins>; + status = "okay"; +}; + +&gsw_phy1_led0 { + status = "okay"; + active-low; +}; + +&gsw_phy2 { + pinctrl-names = "gbe-led"; + pinctrl-0 = <&gswp2_led0_pins>; + status = "okay"; +}; + +&gsw_phy2_led0 { + status = "okay"; + active-low; +}; + +&gsw_phy3 { + pinctrl-names = "gbe-led"; + pinctrl-0 = <&gswp3_led0_pins>; + status = "okay"; +}; + +&gsw_phy3_led0 { + status = "okay"; + active-low; +}; + +&gsw_phy4 { + pinctrl-names = "gbe-led"; + pinctrl-0 = <&gswp4_led0_pins>; + status = "okay"; +}; + +&gsw_phy4_led0 { + status = "okay"; + active-low; +}; From ed8ba06cedeaa70108e2c6a8060374d0c15056ba Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Oct 2025 15:42:21 +0200 Subject: [PATCH 052/128] airoha: an7583: drop bootloader artifacts entry and add default pkg Fix the current image Makefile for Airoha AN7583 by dropping the artifacts entry for bootloader and add default PKG for the PHY mounted on the RFB boards. The artifacts for the bootloader will be readded later once ATF-A support will be pushed mainline. Signed-off-by: Christian Marangi (cherry picked from commit a7964f0893f27e4c47491f9d76748d800216f49d) --- target/linux/airoha/image/an7583.mk | 32 ++--------------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/target/linux/airoha/image/an7583.mk b/target/linux/airoha/image/an7583.mk index c8747a7913..bbc78c65ae 100644 --- a/target/linux/airoha/image/an7583.mk +++ b/target/linux/airoha/image/an7583.mk @@ -1,23 +1,3 @@ -define Build/an7583-bl2-bl31-uboot - head -c $$((0x800)) /dev/zero > $@ - cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ - dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-uboot.img of=$@ bs=1 seek=$$((0x20000)) conv=notrunc -endef - -define Build/an7583-emmc-bl2-bl31-uboot - head -c $$((0x800)) /dev/zero > $@ - cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ - dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip of=$@ bs=1 seek=$$((0x20000)) conv=notrunc -endef - -define Build/an7583-preloader - cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@ -endef - -define Build/an7583-bl31-uboot - cat $(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip >> $@ -endef - define Device/FitImageLzma KERNEL_SUFFIX := -uImage.itb KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb @@ -28,15 +8,11 @@ define Device/airoha_an7583-evb $(call Device/FitImageLzma) DEVICE_VENDOR := Airoha DEVICE_MODEL := AN7583 Evaluation Board (SNAND) - DEVICE_PACKAGES := kmod-leds-pwm kmod-input-gpio-keys-polled + DEVICE_PACKAGES := kmod-phy-aeonsemi-as21xxx kmod-leds-pwm kmod-pwm-airoha kmod-input-gpio-keys-polled DEVICE_DTS := an7583-evb DEVICE_DTS_CONFIG := config@1 KERNEL_LOADADDR := 0x80088000 IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata - ARTIFACT/bl2-bl31-uboot.bin := an7583-bl2-bl31-uboot rfb - ARTIFACT/preloader.bin := an7583-preloader rfb - ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb - ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip endef TARGET_DEVICES += airoha_an7583-evb @@ -44,10 +20,6 @@ define Device/airoha_an7583-evb-emmc DEVICE_VENDOR := Airoha DEVICE_MODEL := AN7583 Evaluation Board (EMMC) DEVICE_DTS := an7583-evb-emmc - DEVICE_PACKAGES := kmod-i2c-an7581 - ARTIFACT/preloader.bin := an7583-preloader rfb - ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb - ARTIFACT/bl2-bl31-uboot.bin := an7583-emmc-bl2-bl31-uboot rfb - ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip + DEVICE_PACKAGES := kmod-phy-airoha-en8811h kmod-i2c-an7581 endef TARGET_DEVICES += airoha_an7583-evb-emmc From 4391bf8729afe24c2d0ff1c7bfa17b1780e96fa6 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Oct 2025 16:23:42 +0200 Subject: [PATCH 053/128] airoha: an7583: add NPU nodes and enable kernel config Add relevant nodes for NPU support for Airoha AN7583 and enable the kernel config to enable support in the Airoha Ethernet driver. NPU firmware is scheduled to be upstreamed to linux-firmware and will be added once present upstream. Signed-off-by: Christian Marangi (cherry picked from commit 8758b58f25dac29a9cbf60e153143bdc124e582c) --- target/linux/airoha/an7583/config-6.6 | 1 + target/linux/airoha/dts/an7583-evb-emmc.dts | 4 ++++ target/linux/airoha/dts/an7583-evb.dts | 4 ++++ target/linux/airoha/dts/an7583.dtsi | 26 +++++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/target/linux/airoha/an7583/config-6.6 b/target/linux/airoha/an7583/config-6.6 index b95bfa67c6..4d137e2202 100644 --- a/target/linux/airoha/an7583/config-6.6 +++ b/target/linux/airoha/an7583/config-6.6 @@ -242,6 +242,7 @@ CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NET_AIROHA=y CONFIG_NET_AIROHA_FLOW_STATS=y +CONFIG_NET_AIROHA_NPU=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_MT7530=y diff --git a/target/linux/airoha/dts/an7583-evb-emmc.dts b/target/linux/airoha/dts/an7583-evb-emmc.dts index df5ee5bde0..6477832a20 100644 --- a/target/linux/airoha/dts/an7583-evb-emmc.dts +++ b/target/linux/airoha/dts/an7583-evb-emmc.dts @@ -227,6 +227,10 @@ }; }; +&npu { + status = "okay"; +}; + ð { status = "okay"; nvmem-cells = <&mac_factory_2c0000>; diff --git a/target/linux/airoha/dts/an7583-evb.dts b/target/linux/airoha/dts/an7583-evb.dts index 30f1cf0800..95ac20e727 100644 --- a/target/linux/airoha/dts/an7583-evb.dts +++ b/target/linux/airoha/dts/an7583-evb.dts @@ -84,6 +84,10 @@ status = "okay"; }; +&npu { + status = "okay"; +}; + ð { status = "okay"; }; diff --git a/target/linux/airoha/dts/an7583.dtsi b/target/linux/airoha/dts/an7583.dtsi index 43e60ebf66..49a0616a39 100644 --- a/target/linux/airoha/dts/an7583.dtsi +++ b/target/linux/airoha/dts/an7583.dtsi @@ -546,6 +546,30 @@ interrupts = ; }; + npu: npu@1e900000 { + compatible = "airoha,an7583-npu"; + reg = <0x0 0x1e900000 0x0 0x313000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + memory-region = <&npu_binary>; + memory-region-names = "binary"; + + status = "disabled"; + }; + pon_pcs: pcs@1fa08000 { compatible = "airoha,an7583-pcs-pon"; reg = <0x0 0x1fa08000 0x0 0x1000>, @@ -620,6 +644,8 @@ memory-region = <&qdma0_buf>, <&qdma1_buf>; memory-region-names = "qdma0-buf", "qdma1-buf"; + airoha,npu = <&npu>; + status = "disabled"; #address-cells = <1>; From 1f7de3311cc6b550d236152134340ee689466466 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Oct 2025 16:52:53 +0200 Subject: [PATCH 054/128] airoha: backport additional upstream patch for NPU support for AN7583 Backport additional patch required for NPU support of Airoha AN7583. These are specific for the NPU module with some minor fixes and to adds upport for loading the specific Airoha AN7583 NPU firmware. (cherry picked from commit 8b4adfbb87af1ea9d483a670bb7b1d7e85bba23e) [ fix conflict errors ] Signed-off-by: Christian Marangi --- ...u-Add-missing-MODULE_FIRMWARE-macros.patch | 27 ++++ ...-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch | 31 ++++ ...a-npu-Add-airoha_npu_soc_data-struct.patch | 136 ++++++++++++++++++ ...-net-airoha-npu-Add-7583-SoC-support.patch | 56 ++++++++ 4 files changed, 250 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch create mode 100644 target/linux/airoha/patches-6.6/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch create mode 100644 target/linux/airoha/patches-6.6/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch create mode 100644 target/linux/airoha/patches-6.6/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch diff --git a/target/linux/airoha/patches-6.6/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch b/target/linux/airoha/patches-6.6/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch new file mode 100644 index 0000000000..7e86417f9d --- /dev/null +++ b/target/linux/airoha/patches-6.6/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch @@ -0,0 +1,27 @@ +From 4e7e471e2e3f9085fe1dbe821c4dd904a917c66a Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 1 Aug 2025 09:12:25 +0200 +Subject: [PATCH] net: airoha: npu: Add missing MODULE_FIRMWARE macros + +Introduce missing MODULE_FIRMWARE definitions for firmware autoload. + +Fixes: 23290c7bc190d ("net: airoha: Introduce Airoha NPU support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250801-airoha-npu-missing-module-firmware-v2-1-e860c824d515@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -741,6 +741,8 @@ static struct platform_driver airoha_npu + }; + module_platform_driver(airoha_npu_driver); + ++MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); ++MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Lorenzo Bianconi "); + MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); diff --git a/target/linux/airoha/patches-6.6/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch b/target/linux/airoha/patches-6.6/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch new file mode 100644 index 0000000000..71453fd57f --- /dev/null +++ b/target/linux/airoha/patches-6.6/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch @@ -0,0 +1,31 @@ +From 1e5e40f2558c07f6bc60a8983000309cc0a9d600 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 15 Jul 2025 18:01:10 -0500 +Subject: [PATCH] net: airoha: Fix a NULL vs IS_ERR() bug in + airoha_npu_run_firmware() + +The devm_ioremap_resource() function returns error pointers. It never +returns NULL. Update the check to match. + +Fixes: e27dba1951ce ("net: Use of_reserved_mem_region_to_resource{_byname}() for "memory-region"") +Signed-off-by: Dan Carpenter +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/fc6d194e-6bf5-49ca-bc77-3fdfda62c434@sabinyo.mountain +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -201,8 +201,8 @@ static int airoha_npu_run_firmware(struc + } + + addr = devm_ioremap(dev, rmem->base, rmem->size); +- if (!addr) { +- ret = -ENOMEM; ++ if (IS_ERR(addr)) { ++ ret = PTR_ERR(addr); + goto out; + } + diff --git a/target/linux/airoha/patches-6.6/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch b/target/linux/airoha/patches-6.6/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch new file mode 100644 index 0000000000..09972a9b62 --- /dev/null +++ b/target/linux/airoha/patches-6.6/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch @@ -0,0 +1,136 @@ +From 0850ae496d534847ec2c26744521c1bce04ec59d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 15:58:50 +0200 +Subject: [PATCH 2/3] net: airoha: npu: Add airoha_npu_soc_data struct + +Introduce airoha_npu_soc_data structure in order to generalize per-SoC +NPU firmware info. Introduce airoha_npu_load_firmware utility routine. +This is a preliminary patch in order to introduce AN7583 NPU support. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251013-airoha-npu-7583-v3-2-00f748b5a0c7@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 77 ++++++++++++++++-------- + 1 file changed, 51 insertions(+), 26 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -103,6 +103,16 @@ enum { + QDMA_WAN_PON_XDSL, + }; + ++struct airoha_npu_fw { ++ const char *name; ++ int max_size; ++}; ++ ++struct airoha_npu_soc_data { ++ struct airoha_npu_fw fw_rv32; ++ struct airoha_npu_fw fw_data; ++}; ++ + #define MBOX_MSG_FUNC_ID GENMASK(14, 11) + #define MBOX_MSG_STATIC_BUF BIT(5) + #define MBOX_MSG_STATUS GENMASK(4, 2) +@@ -182,49 +192,53 @@ static int airoha_npu_send_msg(struct ai + return ret; + } + +-static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, +- struct reserved_mem *rmem) ++static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, ++ const struct airoha_npu_fw *fw_info) + { + const struct firmware *fw; +- void __iomem *addr; + int ret; + +- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); ++ ret = request_firmware(&fw, fw_info->name, dev); + if (ret) + return ret == -ENOENT ? -EPROBE_DEFER : ret; + +- if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { ++ if (fw->size > fw_info->max_size) { + dev_err(dev, "%s: fw size too overlimit (%zu)\n", +- NPU_EN7581_FIRMWARE_RV32, fw->size); ++ fw_info->name, fw->size); + ret = -E2BIG; + goto out; + } + +- addr = devm_ioremap(dev, rmem->base, rmem->size); +- if (IS_ERR(addr)) { +- ret = PTR_ERR(addr); +- goto out; +- } +- + memcpy_toio(addr, fw->data, fw->size); ++out: + release_firmware(fw); + +- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); +- if (ret) +- return ret == -ENOENT ? -EPROBE_DEFER : ret; ++ return ret; ++} + +- if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { +- dev_err(dev, "%s: fw size too overlimit (%zu)\n", +- NPU_EN7581_FIRMWARE_DATA, fw->size); +- ret = -E2BIG; +- goto out; +- } ++static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, ++ struct reserved_mem *rmem) ++{ ++ const struct airoha_npu_soc_data *soc; ++ void __iomem *addr; ++ int ret; + +- memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); +-out: +- release_firmware(fw); ++ soc = of_device_get_match_data(dev); ++ if (!soc) ++ return -EINVAL; + +- return ret; ++ addr = devm_ioremap(dev, rmem->base, rmem->size); ++ if (IS_ERR(addr)) ++ return PTR_ERR(addr); ++ ++ /* Load rv32 npu firmware */ ++ ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); ++ if (ret) ++ return ret; ++ ++ /* Load data npu firmware */ ++ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, ++ &soc->fw_data); + } + + static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) +@@ -596,8 +610,19 @@ void airoha_npu_put(struct airoha_npu *n + } + EXPORT_SYMBOL_GPL(airoha_npu_put); + ++static const struct airoha_npu_soc_data en7581_npu_soc_data = { ++ .fw_rv32 = { ++ .name = NPU_EN7581_FIRMWARE_RV32, ++ .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, ++ }, ++ .fw_data = { ++ .name = NPU_EN7581_FIRMWARE_DATA, ++ .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, ++ }, ++}; ++ + static const struct of_device_id of_airoha_npu_match[] = { +- { .compatible = "airoha,en7581-npu" }, ++ { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_npu_match); diff --git a/target/linux/airoha/patches-6.6/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch b/target/linux/airoha/patches-6.6/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch new file mode 100644 index 0000000000..a628d09b77 --- /dev/null +++ b/target/linux/airoha/patches-6.6/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch @@ -0,0 +1,56 @@ +From 4478596f71d92060c9093bdf1d2d940881f41bcc Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 15:58:51 +0200 +Subject: [PATCH 3/3] net: airoha: npu: Add 7583 SoC support + +Introduce support for Airoha 7583 SoC NPU selecting proper firmware images. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251013-airoha-npu-7583-v3-3-00f748b5a0c7@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -16,6 +16,8 @@ + + #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" + #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" ++#define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" ++#define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" + #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 + #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 + #define NPU_DUMP_SIZE 512 +@@ -621,8 +623,20 @@ static const struct airoha_npu_soc_data + }, + }; + ++static const struct airoha_npu_soc_data an7583_npu_soc_data = { ++ .fw_rv32 = { ++ .name = NPU_AN7583_FIRMWARE_RV32, ++ .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, ++ }, ++ .fw_data = { ++ .name = NPU_AN7583_FIRMWARE_DATA, ++ .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, ++ }, ++}; ++ + static const struct of_device_id of_airoha_npu_match[] = { + { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data }, ++ { .compatible = "airoha,an7583-npu", .data = &an7583_npu_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_npu_match); +@@ -768,6 +782,8 @@ module_platform_driver(airoha_npu_driver + + MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); + MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); ++MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); ++MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Lorenzo Bianconi "); + MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); From fda425adf43acf176e1b23eac563f6a414cc454d Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 24 Oct 2025 09:49:57 +0200 Subject: [PATCH 055/128] airoha: an7581: add BL2 and BL31+U-Boot Artifacts for RFB board Pack the BL2 and BL31+U-Boot artifacts as Airoha AN7581 is currently supported in upstream U-Boot and bootloader files can be used for unfused boards. Signed-off-by: Christian Marangi (cherry picked from commit 17cb69fe7f91f5560c793020281b236812b71489) --- target/linux/airoha/image/an7581.mk | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/target/linux/airoha/image/an7581.mk b/target/linux/airoha/image/an7581.mk index 8f187b812c..fcd19e413c 100644 --- a/target/linux/airoha/image/an7581.mk +++ b/target/linux/airoha/image/an7581.mk @@ -1,3 +1,17 @@ +define Build/an7581-emmc-bl2-bl31-uboot + head -c $$((0x800)) /dev/zero > $@ + cat $(STAGING_DIR_IMAGE)/an7581_$1-bl2.fip >> $@ + dd if=$(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip of=$@ bs=1 seek=$$((0x20000)) conv=notrunc +endef + +define Build/an7581-preloader + cat $(STAGING_DIR_IMAGE)/an7581_$1-bl2.fip >> $@ +endef + +define Build/an7581-bl31-uboot + cat $(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip >> $@ +endef + define Device/FitImageLzma KERNEL_SUFFIX := -uImage.itb KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb @@ -13,6 +27,9 @@ define Device/airoha_an7581-evb DEVICE_DTS_CONFIG := config@1 KERNEL_LOADADDR := 0x80088000 IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata + ARTIFACT/preloader.bin := an7581-preloader rfb + ARTIFACT/bl31-uboot.fip := an7581-bl31-uboot rfb + ARTIFACTS := preloader.bin bl31-uboot.fip endef TARGET_DEVICES += airoha_an7581-evb @@ -21,5 +38,8 @@ define Device/airoha_an7581-evb-emmc DEVICE_MODEL := AN7581 Evaluation Board (EMMC) DEVICE_DTS := an7581-evb-emmc DEVICE_PACKAGES := kmod-i2c-an7581 + ARTIFACT/preloader.bin := an7581-preloader rfb + ARTIFACT/bl31-uboot.fip := an7581-bl31-uboot rfb + ARTIFACTS := preloader.bin bl31-uboot.fip endef TARGET_DEVICES += airoha_an7581-evb-emmc From 9babe16bd28bd9ad700526d5d17d299721db24f9 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 24 Oct 2025 11:48:13 +0200 Subject: [PATCH 056/128] airoha: an7581: add Aeonsemi AS21xxx PHY to RFB eMMC board Airoha AN7581 eMMC RFB board mount 2 Aeonsemi AS21xxx PHY. One is usually connected to GDM4 and the other is optionally connected to GDM2. Add the relevant nodes to support the one connected to GDM4. Signed-off-by: Christian Marangi (cherry picked from commit 26da4bf552bacd2ca606c50859fa2ebb8867266d) --- target/linux/airoha/dts/an7581-evb-emmc.dts | 41 +++++++++++++++++++++ target/linux/airoha/dts/an7581.dtsi | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/target/linux/airoha/dts/an7581-evb-emmc.dts b/target/linux/airoha/dts/an7581-evb-emmc.dts index 26d446e2a1..f7540f79e3 100644 --- a/target/linux/airoha/dts/an7581-evb-emmc.dts +++ b/target/linux/airoha/dts/an7581-evb-emmc.dts @@ -156,6 +156,40 @@ status = "okay"; }; +&mdio { + as21xx_1: ethernet-phy@1d { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x1d>; + + firmware-name = "as21x1x_fw.bin"; + + reset-deassert-us = <1000000>; + reset-assert-us = <1000000>; + reset-gpios = <&en7581_pinctrl 31 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + default-state = "keep"; + }; + }; + }; +}; + ð { status = "okay"; }; @@ -164,6 +198,13 @@ status = "okay"; }; +&gdm4 { + status = "okay"; + + phy-handle = <&as21xx_1>; + phy-mode = "usxgmii"; +}; + &switch { pinctrl-names = "default"; pinctrl-0 = <&mdio_pins>; diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index c00119cf2f..1477b63c74 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -874,7 +874,7 @@ }; }; - mdio { + mdio: mdio { #address-cells = <1>; #size-cells = <0>; From 518f3c61715e45b4c5f8e41f873568d51e81cc17 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 24 Oct 2025 12:15:27 +0200 Subject: [PATCH 057/128] airoha: backport cleanup patch for Airoha Ethernet driver Backport cleanup patch for Airoha Ethernet patch to permit easier backport in the future. Automatically refresh all affected patch. (cherry picked from commit 2f3ea18f9163ce2d287f76e0079f10580e01bd59) [ fix conflict errors, drop upstream patch ] Signed-off-by: Christian Marangi --- ...ve-code-duplication-in-airoha_regs.h.patch | 342 ++++++++++++++++++ ...-airoha-drop-redundant-GDM3-4-define.patch | 52 --- ...nitial-fixup-for-GDM3-4-port-support.patch | 8 +- ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 4 +- ...iroha-add-phylink-support-for-GDM2-4.patch | 6 +- 5 files changed, 351 insertions(+), 61 deletions(-) create mode 100644 target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch delete mode 100644 target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch diff --git a/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch b/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch new file mode 100644 index 0000000000..654f287b14 --- /dev/null +++ b/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch @@ -0,0 +1,342 @@ +From 99ad2b6815f41acbec15ab051ccc79b11b05710a Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 22 Oct 2025 09:11:12 +0200 +Subject: [PATCH] net: airoha: Remove code duplication in airoha_regs.h + +This patch does not introduce any logical change, it just removes +duplicated code in airoha_regs.h. +Fix naming conventions in airoha_regs.h. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251022-airoha-regs-cosmetics-v2-1-e0425b3f2c2c@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 102 ++++++++++---------- + drivers/net/ethernet/airoha/airoha_regs.h | 109 ++++++++++------------ + 2 files changed, 100 insertions(+), 111 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -137,11 +137,11 @@ static void airoha_fe_maccr_init(struct + + for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) + airoha_fe_set(eth, REG_GDM_FWD_CFG(p), +- GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | +- GDM_DROP_CRC_ERR); ++ GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK | ++ GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK); + +- airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, +- FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); ++ airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK, ++ FIELD_PREP(CDM_VLAN_MASK, 0x8100)); + + airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); + } +@@ -403,46 +403,46 @@ static int airoha_fe_mc_vlan_clear(struc + static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) + { + /* CDM1_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), + CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), + CDM_CRSN_QSEL_Q1)); + /* CDM2_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), + CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), + CDM_CRSN_QSEL_Q1)); + } + +@@ -462,18 +462,18 @@ static int airoha_fe_init(struct airoha_ + airoha_fe_wr(eth, REG_FE_PCE_CFG, + PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); + /* set vip queue selection to ring 1 */ +- airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, +- FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, +- FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK, ++ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK, ++ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); + /* set GDM4 source interface offset to 8 */ +- airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, +- GDM4_SPORT_OFF2_MASK | +- GDM4_SPORT_OFF1_MASK | +- GDM4_SPORT_OFF0_MASK, +- FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); ++ airoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4), ++ GDM_SPORT_OFF2_MASK | ++ GDM_SPORT_OFF1_MASK | ++ GDM_SPORT_OFF0_MASK, ++ FIELD_PREP(GDM_SPORT_OFF2_MASK, 8) | ++ FIELD_PREP(GDM_SPORT_OFF1_MASK, 8) | ++ FIELD_PREP(GDM_SPORT_OFF0_MASK, 8)); + + /* set PSE Page as 128B */ + airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, +@@ -499,8 +499,8 @@ static int airoha_fe_init(struct airoha_ + airoha_fe_set(eth, REG_GDM_MISC_CFG, + GDM2_RDM_ACK_WAIT_PREF_MASK | + GDM2_CHN_VLD_MODE_MASK); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, +- FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK, ++ FIELD_PREP(CDM_OAM_QSEL_MASK, 15)); + + /* init fragment and assemble Force Port */ + /* NPU Core-3, NPU Bridge Channel-3 */ +@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ + FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | + FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); + +- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); + + airoha_fe_crsn_qsel_init(eth); + +@@ -523,7 +523,7 @@ static int airoha_fe_init(struct airoha_ + airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); + + /* default aging mode for mbi unlock issue */ +- airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, ++ airoha_fe_rmw(eth, REG_GDM_CHN_RLS(2), + MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, + FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | + FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); +@@ -1697,7 +1697,7 @@ static int airhoha_set_gdm2_loopback(str + pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 + : FE_PSE_PORT_GDM4; + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); +- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); ++ airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); + + /* Enable GDM2 loopback */ + airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -23,6 +23,8 @@ + #define GDM3_BASE 0x1100 + #define GDM4_BASE 0x2500 + ++#define CDM_BASE(_n) \ ++ ((_n) == 2 ? CDM2_BASE : CDM1_BASE) + #define GDM_BASE(_n) \ + ((_n) == 4 ? GDM4_BASE : \ + (_n) == 3 ? GDM3_BASE : \ +@@ -109,30 +111,24 @@ + #define PATN_DP_MASK GENMASK(31, 16) + #define PATN_SP_MASK GENMASK(15, 0) + +-#define REG_CDM1_VLAN_CTRL CDM1_BASE +-#define CDM1_VLAN_MASK GENMASK(31, 16) ++#define REG_CDM_VLAN_CTRL(_n) CDM_BASE(_n) ++#define CDM_VLAN_MASK GENMASK(31, 16) + +-#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) +-#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) ++#define REG_CDM_FWD_CFG(_n) (CDM_BASE(_n) + 0x08) ++#define CDM_OAM_QSEL_MASK GENMASK(31, 27) ++#define CDM_VIP_QSEL_MASK GENMASK(24, 20) + +-#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) +-#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) +-#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) +-#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) +-#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ ++#define REG_CDM_CRSN_QSEL(_n, _m) (CDM_BASE(_n) + 0x10 + ((_m) << 2)) ++#define CDM_CRSN_QSEL_REASON_MASK(_n) \ + GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) + + #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) +-#define GDM_DROP_CRC_ERR BIT(23) +-#define GDM_IP4_CKSUM BIT(22) +-#define GDM_TCP_CKSUM BIT(21) +-#define GDM_UDP_CKSUM BIT(20) +-#define GDM_STRIP_CRC BIT(16) ++#define GDM_PAD_EN_MASK BIT(28) ++#define GDM_DROP_CRC_ERR_MASK BIT(23) ++#define GDM_IP4_CKSUM_MASK BIT(22) ++#define GDM_TCP_CKSUM_MASK BIT(21) ++#define GDM_UDP_CKSUM_MASK BIT(20) ++#define GDM_STRIP_CRC_MASK BIT(16) + #define GDM_UCFQ_MASK GENMASK(15, 12) + #define GDM_BCFQ_MASK GENMASK(11, 8) + #define GDM_MCFQ_MASK GENMASK(7, 4) +@@ -156,6 +152,10 @@ + #define LBK_CHAN_MODE_MASK BIT(1) + #define LPBK_EN_MASK BIT(0) + ++#define REG_GDM_CHN_RLS(_n) (GDM_BASE(_n) + 0x20) ++#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) ++#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) ++ + #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) + #define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) + +@@ -168,10 +168,10 @@ + #define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) + #define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) + +-#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) ++#define REG_FE_GDM_MIB_CFG(_n) (GDM_BASE(_n) + 0xf4) + #define FE_STRICT_RFC2819_MODE_MASK BIT(31) +-#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) +-#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) ++#define FE_GDM_TX_MIB_SPLIT_EN_MASK BIT(17) ++#define FE_GDM_RX_MIB_SPLIT_EN_MASK BIT(16) + #define FE_TX_MIB_ID_MASK GENMASK(15, 8) + #define FE_RX_MIB_ID_MASK GENMASK(7, 0) + +@@ -214,6 +214,33 @@ + #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) + #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) + ++#define REG_GDM_SRC_PORT_SET(_n) (GDM_BASE(_n) + 0x23c) ++#define GDM_SPORT_OFF2_MASK GENMASK(19, 16) ++#define GDM_SPORT_OFF1_MASK GENMASK(15, 12) ++#define GDM_SPORT_OFF0_MASK GENMASK(11, 8) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) ++#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) ++#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) ++#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) ++#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) ++#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) ++#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) ++#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) ++#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) ++#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) ++#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) ++ + #define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) + #define PPE_GLO_CFG_BUSY_MASK BIT(31) + #define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) +@@ -326,44 +353,6 @@ + + #define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374) + +-#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) +-#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) +-#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) +-#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) +-#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) +-#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) +-#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) +-#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) +-#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) +-#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) +-#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) +- +-#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) +-#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) +-#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) +- +-#define REG_GDM3_FWD_CFG GDM3_BASE +-#define GDM3_PAD_EN_MASK BIT(28) +- +-#define REG_GDM4_FWD_CFG GDM4_BASE +-#define GDM4_PAD_EN_MASK BIT(28) +-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) +- +-#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) +-#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) +-#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) +-#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) +- + #define REG_IP_FRAG_FP 0x2010 + #define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) + #define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) diff --git a/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch b/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch deleted file mode 100644 index a52ee91ed9..0000000000 --- a/target/linux/airoha/patches-6.6/116-05-net-airoha-drop-redundant-GDM3-4-define.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 6fbb7d72520393a3d447399799d436f17c03ff24 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 10:29:52 +0100 -Subject: [PATCH 5/9] net: airoha: drop redundant GDM3/4 define - -The GDM FWD register are all the same hence it's redundant to have -specific define for GDM3 and GDM4. Drop the redundant define and use the -generic macro. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 ++-- - drivers/net/ethernet/airoha/airoha_regs.h | 8 +------- - 2 files changed, 3 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ - FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | - FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); - -- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); -- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN); - - airoha_fe_crsn_qsel_init(eth); - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -128,6 +128,7 @@ - GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) - - #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) -+#define GDM_PAD_EN BIT(28) - #define GDM_DROP_CRC_ERR BIT(23) - #define GDM_IP4_CKSUM BIT(22) - #define GDM_TCP_CKSUM BIT(21) -@@ -352,13 +353,6 @@ - #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) - #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) - --#define REG_GDM3_FWD_CFG GDM3_BASE --#define GDM3_PAD_EN_MASK BIT(28) -- --#define REG_GDM4_FWD_CFG GDM4_BASE --#define GDM4_PAD_EN_MASK BIT(28) --#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -- - #define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) - #define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) - #define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index 7e3ee7a9e8..f56e3b9356 100644 --- a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -19,12 +19,12 @@ Signed-off-by: Christian Marangi FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); -- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN); -- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN); +- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); + airoha_fe_set(eth, REG_GDM_FWD_CFG(3), -+ GDM_PAD_EN | GDM_STRIP_CRC); ++ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); + airoha_fe_set(eth, REG_GDM_FWD_CFG(4), -+ GDM_PAD_EN | GDM_STRIP_CRC); ++ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); airoha_fe_crsn_qsel_init(eth); diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index be23e27ce0..a8a9e64802 100644 --- a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3099,7 +3099,6 @@ static void airoha_remove(struct platfor +@@ -3100,7 +3100,6 @@ static void airoha_remove(struct platfor } static const char * const en7581_xsi_rsts_names[] = { @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi "hsi0-mac", "hsi1-mac", "hsi-mac", -@@ -3131,7 +3130,6 @@ static int airoha_en7581_get_src_port_id +@@ -3132,7 +3131,6 @@ static int airoha_en7581_get_src_port_id } static const char * const an7583_xsi_rsts_names[] = { diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index fd01dcda99..eb6b249b21 100644 --- a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3064,6 +3199,10 @@ error_hw_cleanup: +@@ -3065,6 +3200,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3091,6 +3230,10 @@ static void airoha_remove(struct platfor +@@ -3092,6 +3231,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -236,7 +236,7 @@ Signed-off-by: Christian Marangi DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -364,6 +364,18 @@ +@@ -359,6 +359,18 @@ #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) From 7af48fdcd34d4aa0fa5619df598dc9feefd1d7fc Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 24 Oct 2025 12:16:11 +0200 Subject: [PATCH 058/128] airoha: backport fix for Airoha offload support with airoha_hw_init fail Backport a patch fixing a kernel panic on airoha_hw_init fail. This should better handle scenario with NPU load Probe deferring. (cherry picked from commit c3c75d0e685b90fdcb9f1cf79a6e2c6949cce9ac) [ fix conflict error ] Signed-off-by: Christian Marangi --- ...n-error-handling-path-in-airoha_prob.patch | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch diff --git a/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch b/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch new file mode 100644 index 0000000000..58e48cb8d0 --- /dev/null +++ b/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch @@ -0,0 +1,29 @@ +From 3ef07434c7dbfba302df477bb6c70e082965f232 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 5 Jul 2025 10:34:32 +0200 +Subject: [PATCH] net: airoha: Fix an error handling path in airoha_probe() + +If an error occurs after a successful airoha_hw_init() call, +airoha_ppe_deinit() needs to be called as already done in the remove +function. + +Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") +Signed-off-by: Christophe JAILLET +Reviewed-by: Simon Horman +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/1c940851b4fa3c3ed2a142910c821493a136f121.1746715755.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -3044,6 +3044,7 @@ static int airoha_probe(struct platform_ + error_napi_stop: + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) + airoha_qdma_stop_napi(ð->qdma[i]); ++ airoha_ppe_deinit(eth); + error_hw_cleanup: + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) + airoha_hw_cleanup(ð->qdma[i]); From 9097d73cbbb6760a508eed9e46e1dfc84ce546e9 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 27 Oct 2025 11:08:46 +0100 Subject: [PATCH 059/128] airoha: add nodes for 3rd PCIe line for AN7581 Some SoC might use the Serdes for the second USB port as a 3rd PCIe line (with the SSTR register correctly setup). Add the node for the 3rd PCIe card and enable for the eMMC RFB board. Signed-off-by: Christian Marangi (cherry picked from commit 2fae199953b025449d4143e85f2ab278b27afe3d) --- target/linux/airoha/dts/an7581-evb-emmc.dts | 13 +++++++ target/linux/airoha/dts/an7581.dtsi | 43 +++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/target/linux/airoha/dts/an7581-evb-emmc.dts b/target/linux/airoha/dts/an7581-evb-emmc.dts index f7540f79e3..b814834c28 100644 --- a/target/linux/airoha/dts/an7581-evb-emmc.dts +++ b/target/linux/airoha/dts/an7581-evb-emmc.dts @@ -57,6 +57,13 @@ }; }; + pcie2_rst_pins: pcie2-rst-pins { + conf { + pins = "pcie_reset2"; + drive-open-drain = <1>; + }; + }; + gswp1_led0_pins: gswp1-led0-pins { mux { function = "phy1_led0"; @@ -156,6 +163,12 @@ status = "okay"; }; +&pcie2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie2_rst_pins>; + status = "okay"; +}; + &mdio { as21xx_1: ethernet-phy@1d { compatible = "ethernet-phy-ieee802.3-c45"; diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 1477b63c74..46c8480111 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -718,6 +718,49 @@ }; }; + pcie2: pcie@1fc40000 { + compatible = "airoha,en7581-pcie"; + device_type = "pci"; + linux,pci-domain = <2>; + #address-cells = <3>; + #size-cells = <2>; + + reg = <0x0 0x1fc40000 0x0 0x1670>; + reg-names = "pcie-mac"; + + clocks = <&scuclk EN7523_CLK_PCIE>; + clock-names = "sys-ck"; + + phys = <&pciephy>; + phy-names = "pcie-phy"; + + ranges = <0x02000000 0 0x28000000 0x0 0x28000000 0 0x4000000>; + + resets = <&scuclk EN7581_PCIE0_RST>, + <&scuclk EN7581_PCIE1_RST>, + <&scuclk EN7581_PCIE2_RST>; + reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + + mediatek,pbus-csr = <&pbus_csr 0x10 0x14>; + + interrupts = ; + bus-range = <0x00 0xff>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc2 0>, + <0 0 0 2 &pcie_intc2 1>, + <0 0 0 3 &pcie_intc2 2>, + <0 0 0 4 &pcie_intc2 3>; + + status = "disabled"; + + pcie_intc2: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + npu: npu@1e900000 { compatible = "airoha,en7581-npu"; reg = <0x0 0x1e900000 0x0 0x313000>; From 9aeda89c05c84cefb0e31cc82784c0b29c4917b5 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 28 Oct 2025 13:14:56 +0100 Subject: [PATCH 060/128] airoha: add pending patch for USB support on AN7581 Add pending patch for USB support on AN7581 SoC. This is also required to make operational the 3rd PCIe line that use the USB2 Serdes for PCIe operations. (cherry picked from commit 7afc2da3fcc01a3932829ed4fb3ced6876b71846) [ fix conflict errors, add missing Kconfig flag ] Signed-off-by: Christian Marangi --- target/linux/airoha/an7581/config-6.6 | 1 + ...Add-bindings-for-Airoha-SCU-Serdes-l.patch | 35 + ...Add-documentation-for-Airoha-AN7581-.patch | 141 ++ ...PCIe-PHY-driver-to-dedicated-directo.patch | 1885 +++++++++++++++++ ...dd-support-for-Airoha-AN7581-USB-PHY.patch | 667 ++++++ ...d-ARCH_AIROHA-in-XHCI-MTK-dependency.patch | 25 + ...-gen3-set-PHY-mode-for-Airoha-EN7581.patch | 34 + 7 files changed, 2788 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch create mode 100644 target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch create mode 100644 target/linux/airoha/patches-6.6/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch create mode 100644 target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch create mode 100644 target/linux/airoha/patches-6.6/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch create mode 100644 target/linux/airoha/patches-6.6/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 8d253214f7..9d2251c5c8 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -458,6 +458,7 @@ CONFIG_PHYLIB_LEDS=y CONFIG_PHYLINK=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHY_AIROHA_PCIE=y +CONFIG_PHY_AIROHA_USB=y CONFIG_PID_NS=y CONFIG_PINCTRL=y CONFIG_PINCTRL_AIROHA=y diff --git a/target/linux/airoha/patches-6.6/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch b/target/linux/airoha/patches-6.6/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch new file mode 100644 index 0000000000..3fa8d6d590 --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch @@ -0,0 +1,35 @@ +From 39537b6b334dfac001aba395229adb9318627463 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 28 Oct 2025 12:09:57 +0100 +Subject: [PATCH 04/10] dt-bindings: soc: Add bindings for Airoha SCU Serdes + lines + +The Airoha AN7581 SoC have can configure the SCU serdes lines for +multiple purpose. For example the Serdes for the USB1 port can be both +used for USB 3.0 operation or for Ethernet. Or the USB2 serdes can both +used for USB 3.0 operation or for PCIe. + +Add bindings to permit correct reference of the different ports in DT, +mostly to differenciate the different supported modes internally to the +drivers. + +Signed-off-by: Christian Marangi +--- + include/dt-bindings/soc/airoha,scu-ssr.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h + +--- /dev/null ++++ b/include/dt-bindings/soc/airoha,scu-ssr.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ ++ ++#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H ++#define __DT_BINDINGS_AIROHA_SCU_SSR_H ++ ++#define AIROHA_SCU_SERDES_WIFI1 0 ++#define AIROHA_SCU_SERDES_WIFI2 1 ++#define AIROHA_SCU_SERDES_USB1 2 ++#define AIROHA_SCU_SERDES_USB2 3 ++ ++#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ diff --git a/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch b/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch new file mode 100644 index 0000000000..3fc0ba7dc7 --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch @@ -0,0 +1,141 @@ +From e0095e21dd9179250c304d6df2643e9a50d48edb Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 7 Feb 2025 13:25:28 +0100 +Subject: [PATCH 05/10] dt-bindings: phy: Add documentation for Airoha AN7581 + USB PHY + +Add documentation for Airoha AN7581 USB PHY that describe the USB PHY +for the USB controller. + +Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is +always supported. The USB 3.0 mode is optional and depends on the Serdes +mode currently configured on the system for the USB port. + +If the airoha,serdes-port property is not declared, it's assumed USB 3.0 +mode is not supported, as the Serdes mode can't be validated. + +Signed-off-by: Christian Marangi +--- + .../bindings/phy/airoha,an7581-usb-phy.yaml | 83 +++++++++++++++++++ + MAINTAINERS | 7 ++ + .../dt-bindings/phy/airoha,an7581-usb-phy.h | 11 +++ + 3 files changed, 101 insertions(+) + create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml + create mode 100644 include/dt-bindings/phy/airoha,an7581-usb-phy.h + +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml +@@ -0,0 +1,83 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Airoha AN7581 SoC USB PHY ++ ++maintainers: ++ - Christian Marangi ++ ++description: > ++ The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controller. ++ ++ Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is ++ always supported. The USB 3.0 mode is optional and depends on the Serdes ++ mode currently configured on the system for the USB port. ++ ++ If the airoha,serdes-port property is not declared, it's assumed USB 3.0 ++ mode is not supported, as the Serdes mode can't be validated. ++ ++properties: ++ compatible: ++ const: airoha,an7581-usb-phy ++ ++ reg: ++ maxItems: 1 ++ ++ ++ airoha,usb2-monitor-clk-sel: ++ description: Describe what oscillator across the available 4 ++ should be selected for USB 2.0 Slew Rate calibration. ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [0, 1, 2, 3] ++ ++ airoha,serdes-port: ++ description: Describe what Serdes Port is attached to the USB 3.0 port. ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [0, 1, 2, 3] ++ ++ airoha,scu: ++ description: Phandle to the SCU node for USB 3.0 Serdes mode validation. ++ $ref: /schemas/types.yaml#/definitions/phandle ++ ++ '#phy-cells': ++ const: 1 ++ ++required: ++ - compatible ++ - reg ++ - airoha,usb2-monitor-clk-sel ++ - '#phy-cells' ++ ++dependentRequired: ++ airoha,serdes-port: [ 'airoha,scu' ] ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ ++ phy@1fac0000 { ++ compatible = "airoha,an7581-usb-phy"; ++ reg = <0x1fac0000 0x10000>; ++ ++ airoha,usb2-monitor-clk-sel = ; ++ airoha,scu = <&scu>; ++ airoha,serdes-port = ; ++ ++ #phy-cells = <1>; ++ }; ++ ++ phy@1fae0000 { ++ compatible = "airoha,an7581-usb-phy"; ++ reg = <0x1fae0000 0x10000>; ++ ++ airoha,usb2-monitor-clk-sel = ; ++ ++ #phy-cells = <1>; ++ }; ++ +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -737,6 +737,13 @@ S: Maintained + F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml + F: drivers/spi/spi-airoha-snfi.c + ++AIROHA USB PHY DRIVER ++M: Christian Marangi ++L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ++S: Maintained ++F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml ++F: include/dt-bindings/phy/airoha,an7581-usb-phy.h ++ + AIRSPY MEDIA DRIVER + L: linux-media@vger.kernel.org + S: Orphan +--- /dev/null ++++ b/include/dt-bindings/phy/airoha,an7581-usb-phy.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ ++ ++#ifndef _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ ++#define _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ ++ ++#define AIROHA_USB2_MONCLK_SEL0 0 ++#define AIROHA_USB2_MONCLK_SEL1 1 ++#define AIROHA_USB2_MONCLK_SEL2 2 ++#define AIROHA_USB2_MONCLK_SEL3 3 ++ ++#endif diff --git a/target/linux/airoha/patches-6.6/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch b/target/linux/airoha/patches-6.6/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch new file mode 100644 index 0000000000..e61de0441e --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch @@ -0,0 +1,1885 @@ +From 1bfe1cc581ffba2462580496507497840aa018aa Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Mar 2025 15:23:50 +0100 +Subject: [PATCH 06/10] phy: move Airoha PCIe PHY driver to dedicated directory + +To keep the generic PHY directory tidy, move the PCIe PHY driver to a +dedicated directory. + +This is also in preparation for support of the Airoha USB PHY driver. + +Signed-off-by: Christian Marangi +--- + MAINTAINERS | 4 +- + drivers/phy/Kconfig | 11 +- + drivers/phy/Makefile | 5 +- + drivers/phy/airoha/Kconfig | 13 + + drivers/phy/airoha/Makefile | 3 + + drivers/phy/airoha/phy-airoha-pcie-regs.h | 494 ++++++++ + drivers/phy/airoha/phy-airoha-pcie.c | 1290 +++++++++++++++++++++ + 7 files changed, 1806 insertions(+), 14 deletions(-) + create mode 100644 drivers/phy/airoha/Kconfig + create mode 100644 drivers/phy/airoha/Makefile + create mode 100644 drivers/phy/airoha/phy-airoha-pcie-regs.h + create mode 100644 drivers/phy/airoha/phy-airoha-pcie.c + +# diff --git a/MAINTAINERS b/MAINTAINERS +# index 2468f4fea5b7..3f930a613658 100644 +# --- a/MAINTAINERS +# +++ b/MAINTAINERS +# @@ -733,8 +733,8 @@ M: Lorenzo Bianconi +# L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +# S: Maintained +# F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml +# -F: drivers/phy/phy-airoha-pcie-regs.h +# -F: drivers/phy/phy-airoha-pcie.c +# +F: drivers/phy/airoha/phy-airoha-pcie-regs.h +# +F: drivers/phy/airoha/phy-airoha-pcie.c + +# AIROHA SPI SNFI DRIVER +# M: Lorenzo Bianconi +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -72,16 +72,7 @@ config PHY_CAN_TRANSCEIVER + functional modes using gpios and sets the attribute max link + rate, for CAN drivers. + +-config PHY_AIROHA_PCIE +- tristate "Airoha PCIe-PHY Driver" +- depends on ARCH_AIROHA || COMPILE_TEST +- depends on OF +- select GENERIC_PHY +- help +- Say Y here to add support for Airoha PCIe PHY driver. +- This driver create the basic PHY instance and provides initialize +- callback for PCIe GEN3 port. +- ++source "drivers/phy/airoha/Kconfig" + source "drivers/phy/allwinner/Kconfig" + source "drivers/phy/amlogic/Kconfig" + source "drivers/phy/broadcom/Kconfig" +--- a/drivers/phy/Makefile ++++ b/drivers/phy/Makefile +@@ -10,8 +10,8 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy + obj-$(CONFIG_PHY_XGENE) += phy-xgene.o + obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o + obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o +-obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o +-obj-y += allwinner/ \ ++obj-y += airoha/ \ ++ allwinner/ \ + amlogic/ \ + broadcom/ \ + cadence/ \ +--- /dev/null ++++ b/drivers/phy/airoha/Kconfig +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Phy drivers for Airoha devices ++# ++config PHY_AIROHA_PCIE ++ tristate "Airoha PCIe-PHY Driver" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ depends on OF ++ select GENERIC_PHY ++ help ++ Say Y here to add support for Airoha PCIe PHY driver. ++ This driver create the basic PHY instance and provides initialize ++ callback for PCIe GEN3 port. +--- /dev/null ++++ b/drivers/phy/airoha/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o +--- /dev/null ++++ b/drivers/phy/airoha/phy-airoha-pcie-regs.h +@@ -0,0 +1,494 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#ifndef _PHY_AIROHA_PCIE_H ++#define _PHY_AIROHA_PCIE_H ++ ++/* CSR_2L */ ++#define REG_CSR_2L_CMN 0x0000 ++#define CSR_2L_PXP_CMN_LANE_EN BIT(0) ++#define CSR_2L_PXP_CMN_TRIM_MASK GENMASK(28, 24) ++ ++#define REG_CSR_2L_JCPLL_IB_EXT 0x0004 ++#define REG_CSR_2L_JCPLL_LPF_SHCK_EN BIT(8) ++#define CSR_2L_PXP_JCPLL_CHP_IBIAS GENMASK(21, 16) ++#define CSR_2L_PXP_JCPLL_CHP_IOFST GENMASK(29, 24) ++ ++#define REG_CSR_2L_JCPLL_LPF_BR 0x0008 ++#define CSR_2L_PXP_JCPLL_LPF_BR GENMASK(4, 0) ++#define CSR_2L_PXP_JCPLL_LPF_BC GENMASK(12, 8) ++#define CSR_2L_PXP_JCPLL_LPF_BP GENMASK(20, 16) ++#define CSR_2L_PXP_JCPLL_LPF_BWR GENMASK(28, 24) ++ ++#define REG_CSR_2L_JCPLL_LPF_BWC 0x000c ++#define CSR_2L_PXP_JCPLL_LPF_BWC GENMASK(4, 0) ++#define CSR_2L_PXP_JCPLL_KBAND_CODE GENMASK(23, 16) ++#define CSR_2L_PXP_JCPLL_KBAND_DIV GENMASK(26, 24) ++ ++#define REG_CSR_2L_JCPLL_KBAND_KFC 0x0010 ++#define CSR_2L_PXP_JCPLL_KBAND_KFC GENMASK(1, 0) ++#define CSR_2L_PXP_JCPLL_KBAND_KF GENMASK(9, 8) ++#define CSR_2L_PXP_JCPLL_KBAND_KS GENMASK(17, 16) ++#define CSR_2L_PXP_JCPLL_POSTDIV_EN BIT(24) ++ ++#define REG_CSR_2L_JCPLL_MMD_PREDIV_MODE 0x0014 ++#define CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) ++#define CSR_2L_PXP_JCPLL_POSTDIV_D2 BIT(16) ++#define CSR_2L_PXP_JCPLL_POSTDIV_D5 BIT(24) ++ ++#define CSR_2L_PXP_JCPLL_MONCK 0x0018 ++#define CSR_2L_PXP_JCPLL_REFIN_DIV GENMASK(25, 24) ++ ++#define REG_CSR_2L_JCPLL_RST_DLY 0x001c ++#define CSR_2L_PXP_JCPLL_RST_DLY GENMASK(2, 0) ++#define CSR_2L_PXP_JCPLL_RST BIT(8) ++#define CSR_2L_PXP_JCPLL_SDM_DI_EN BIT(16) ++#define CSR_2L_PXP_JCPLL_SDM_DI_LS GENMASK(25, 24) ++ ++#define REG_CSR_2L_JCPLL_SDM_IFM 0x0020 ++#define CSR_2L_PXP_JCPLL_SDM_IFM BIT(0) ++ ++#define REG_CSR_2L_JCPLL_SDM_HREN 0x0024 ++#define CSR_2L_PXP_JCPLL_SDM_HREN BIT(0) ++#define CSR_2L_PXP_JCPLL_TCL_AMP_EN BIT(8) ++#define CSR_2L_PXP_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) ++#define CSR_2L_PXP_JCPLL_TCL_AMP_VREF GENMASK(28, 24) ++ ++#define REG_CSR_2L_JCPLL_TCL_CMP 0x0028 ++#define CSR_2L_PXP_JCPLL_TCL_LPF_EN BIT(16) ++#define CSR_2L_PXP_JCPLL_TCL_LPF_BW GENMASK(26, 24) ++ ++#define REG_CSR_2L_JCPLL_VCODIV 0x002c ++#define CSR_2L_PXP_JCPLL_VCO_CFIX GENMASK(9, 8) ++#define CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN BIT(16) ++#define CSR_2L_PXP_JCPLL_VCO_SCAPWR GENMASK(26, 24) ++ ++#define REG_CSR_2L_JCPLL_VCO_TCLVAR 0x0030 ++#define CSR_2L_PXP_JCPLL_VCO_TCLVAR GENMASK(2, 0) ++ ++#define REG_CSR_2L_JCPLL_SSC 0x0038 ++#define CSR_2L_PXP_JCPLL_SSC_EN BIT(0) ++#define CSR_2L_PXP_JCPLL_SSC_PHASE_INI BIT(8) ++#define CSR_2L_PXP_JCPLL_SSC_TRI_EN BIT(16) ++ ++#define REG_CSR_2L_JCPLL_SSC_DELTA1 0x003c ++#define CSR_2L_PXP_JCPLL_SSC_DELTA1 GENMASK(15, 0) ++#define CSR_2L_PXP_JCPLL_SSC_DELTA GENMASK(31, 16) ++ ++#define REG_CSR_2L_JCPLL_SSC_PERIOD 0x0040 ++#define CSR_2L_PXP_JCPLL_SSC_PERIOD GENMASK(15, 0) ++ ++#define REG_CSR_2L_JCPLL_TCL_VTP_EN 0x004c ++#define CSR_2L_PXP_JCPLL_SPARE_LOW GENMASK(31, 24) ++ ++#define REG_CSR_2L_JCPLL_TCL_KBAND_VREF 0x0050 ++#define CSR_2L_PXP_JCPLL_TCL_KBAND_VREF GENMASK(4, 0) ++#define CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN BIT(24) ++ ++#define REG_CSR_2L_750M_SYS_CK 0x0054 ++#define CSR_2L_PXP_TXPLL_LPF_SHCK_EN BIT(16) ++#define CSR_2L_PXP_TXPLL_CHP_IBIAS GENMASK(29, 24) ++ ++#define REG_CSR_2L_TXPLL_CHP_IOFST 0x0058 ++#define CSR_2L_PXP_TXPLL_CHP_IOFST GENMASK(5, 0) ++#define CSR_2L_PXP_TXPLL_LPF_BR GENMASK(12, 8) ++#define CSR_2L_PXP_TXPLL_LPF_BC GENMASK(20, 16) ++#define CSR_2L_PXP_TXPLL_LPF_BP GENMASK(28, 24) ++ ++#define REG_CSR_2L_TXPLL_LPF_BWR 0x005c ++#define CSR_2L_PXP_TXPLL_LPF_BWR GENMASK(4, 0) ++#define CSR_2L_PXP_TXPLL_LPF_BWC GENMASK(12, 8) ++#define CSR_2L_PXP_TXPLL_KBAND_CODE GENMASK(31, 24) ++ ++#define REG_CSR_2L_TXPLL_KBAND_DIV 0x0060 ++#define CSR_2L_PXP_TXPLL_KBAND_DIV GENMASK(2, 0) ++#define CSR_2L_PXP_TXPLL_KBAND_KFC GENMASK(9, 8) ++#define CSR_2L_PXP_TXPLL_KBAND_KF GENMASK(17, 16) ++#define CSR_2L_PXP_txpll_KBAND_KS GENMASK(25, 24) ++ ++#define REG_CSR_2L_TXPLL_POSTDIV 0x0064 ++#define CSR_2L_PXP_TXPLL_POSTDIV_EN BIT(0) ++#define CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8) ++#define CSR_2L_PXP_TXPLL_PHY_CK1_EN BIT(24) ++ ++#define REG_CSR_2L_TXPLL_PHY_CK2 0x0068 ++#define CSR_2L_PXP_TXPLL_REFIN_INTERNAL BIT(24) ++ ++#define REG_CSR_2L_TXPLL_REFIN_DIV 0x006c ++#define CSR_2L_PXP_TXPLL_REFIN_DIV GENMASK(1, 0) ++#define CSR_2L_PXP_TXPLL_RST_DLY GENMASK(10, 8) ++#define CSR_2L_PXP_TXPLL_PLL_RSTB BIT(16) ++ ++#define REG_CSR_2L_TXPLL_SDM_DI_LS 0x0070 ++#define CSR_2L_PXP_TXPLL_SDM_DI_LS GENMASK(1, 0) ++#define CSR_2L_PXP_TXPLL_SDM_IFM BIT(8) ++#define CSR_2L_PXP_TXPLL_SDM_ORD GENMASK(25, 24) ++ ++#define REG_CSR_2L_TXPLL_SDM_OUT 0x0074 ++#define CSR_2L_PXP_TXPLL_TCL_AMP_EN BIT(16) ++#define CSR_2L_PXP_TXPLL_TCL_AMP_GAIN GENMASK(26, 24) ++ ++#define REG_CSR_2L_TXPLL_TCL_AMP_VREF 0x0078 ++#define CSR_2L_PXP_TXPLL_TCL_AMP_VREF GENMASK(4, 0) ++#define CSR_2L_PXP_TXPLL_TCL_LPF_EN BIT(24) ++ ++#define REG_CSR_2L_TXPLL_TCL_LPF_BW 0x007c ++#define CSR_2L_PXP_TXPLL_TCL_LPF_BW GENMASK(2, 0) ++#define CSR_2L_PXP_TXPLL_VCO_CFIX GENMASK(17, 16) ++#define CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN BIT(24) ++ ++#define REG_CSR_2L_TXPLL_VCO_SCAPWR 0x0080 ++#define CSR_2L_PXP_TXPLL_VCO_SCAPWR GENMASK(2, 0) ++ ++#define REG_CSR_2L_TXPLL_SSC 0x0084 ++#define CSR_2L_PXP_TXPLL_SSC_EN BIT(0) ++#define CSR_2L_PXP_TXPLL_SSC_PHASE_INI BIT(8) ++ ++#define REG_CSR_2L_TXPLL_SSC_DELTA1 0x0088 ++#define CSR_2L_PXP_TXPLL_SSC_DELTA1 GENMASK(15, 0) ++#define CSR_2L_PXP_TXPLL_SSC_DELTA GENMASK(31, 16) ++ ++#define REG_CSR_2L_TXPLL_SSC_PERIOD 0x008c ++#define CSR_2L_PXP_txpll_SSC_PERIOD GENMASK(15, 0) ++ ++#define REG_CSR_2L_TXPLL_VTP 0x0090 ++#define CSR_2L_PXP_TXPLL_VTP_EN BIT(0) ++ ++#define REG_CSR_2L_TXPLL_TCL_VTP 0x0098 ++#define CSR_2L_PXP_TXPLL_SPARE_L GENMASK(31, 24) ++ ++#define REG_CSR_2L_TXPLL_TCL_KBAND_VREF 0x009c ++#define CSR_2L_PXP_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) ++#define CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN BIT(24) ++ ++#define REG_CSR_2L_TXPLL_POSTDIV_D256 0x00a0 ++#define CSR_2L_PXP_CLKTX0_AMP GENMASK(10, 8) ++#define CSR_2L_PXP_CLKTX0_OFFSET GENMASK(17, 16) ++#define CSR_2L_PXP_CLKTX0_SR GENMASK(25, 24) ++ ++#define REG_CSR_2L_CLKTX0_FORCE_OUT1 0x00a4 ++#define CSR_2L_PXP_CLKTX0_HZ BIT(8) ++#define CSR_2L_PXP_CLKTX0_IMP_SEL GENMASK(20, 16) ++#define CSR_2L_PXP_CLKTX1_AMP GENMASK(26, 24) ++ ++#define REG_CSR_2L_CLKTX1_OFFSET 0x00a8 ++#define CSR_2L_PXP_CLKTX1_OFFSET GENMASK(1, 0) ++#define CSR_2L_PXP_CLKTX1_SR GENMASK(9, 8) ++#define CSR_2L_PXP_CLKTX1_HZ BIT(24) ++ ++#define REG_CSR_2L_CLKTX1_IMP_SEL 0x00ac ++#define CSR_2L_PXP_CLKTX1_IMP_SEL GENMASK(4, 0) ++ ++#define REG_CSR_2L_PLL_CMN_RESERVE0 0x00b0 ++#define CSR_2L_PXP_PLL_RESERVE_MASK GENMASK(15, 0) ++ ++#define REG_CSR_2L_TX0_CKLDO 0x00cc ++#define CSR_2L_PXP_TX0_CKLDO_EN BIT(0) ++#define CSR_2L_PXP_TX0_DMEDGEGEN_EN BIT(24) ++ ++#define REG_CSR_2L_TX1_CKLDO 0x00e8 ++#define CSR_2L_PXP_TX1_CKLDO_EN BIT(0) ++#define CSR_2L_PXP_TX1_DMEDGEGEN_EN BIT(24) ++ ++#define REG_CSR_2L_TX1_MULTLANE 0x00ec ++#define CSR_2L_PXP_TX1_MULTLANE_EN BIT(0) ++ ++#define REG_CSR_2L_RX0_REV0 0x00fc ++#define CSR_2L_PXP_VOS_PNINV GENMASK(19, 18) ++#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE GENMASK(22, 20) ++#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE GENMASK(26, 24) ++ ++#define REG_CSR_2L_RX0_PHYCK_DIV 0x0100 ++#define CSR_2L_PXP_RX0_PHYCK_SEL GENMASK(9, 8) ++#define CSR_2L_PXP_RX0_PHYCK_RSTB BIT(16) ++#define CSR_2L_PXP_RX0_TDC_CK_SEL BIT(24) ++ ++#define REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV 0x0104 ++#define CSR_2L_PXP_CDR0_PD_EDGE_DISABLE BIT(8) ++ ++#define REG_CSR_2L_CDR0_LPF_RATIO 0x0110 ++#define CSR_2L_PXP_CDR0_LPF_TOP_LIM GENMASK(26, 8) ++ ++#define REG_CSR_2L_CDR0_PR_INJ_MODE 0x011c ++#define CSR_2L_PXP_CDR0_INJ_FORCE_OFF BIT(24) ++ ++#define REG_CSR_2L_CDR0_PR_BETA_DAC 0x0120 ++#define CSR_2L_PXP_CDR0_PR_BETA_SEL GENMASK(19, 16) ++#define CSR_2L_PXP_CDR0_PR_KBAND_DIV GENMASK(26, 24) ++ ++#define REG_CSR_2L_CDR0_PR_VREG_IBAND 0x0124 ++#define CSR_2L_PXP_CDR0_PR_VREG_IBAND GENMASK(2, 0) ++#define CSR_2L_PXP_CDR0_PR_VREG_CKBUF GENMASK(10, 8) ++ ++#define REG_CSR_2L_CDR0_PR_CKREF_DIV 0x0128 ++#define CSR_2L_PXP_CDR0_PR_CKREF_DIV GENMASK(1, 0) ++ ++#define REG_CSR_2L_CDR0_PR_MONCK 0x012c ++#define CSR_2L_PXP_CDR0_PR_MONCK_ENABLE BIT(0) ++#define CSR_2L_PXP_CDR0_PR_RESERVE0 GENMASK(19, 16) ++ ++#define REG_CSR_2L_CDR0_PR_COR_HBW 0x0130 ++#define CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON BIT(8) ++#define CSR_2L_PXP_CDR0_PR_CKREF_DIV1 GENMASK(17, 16) ++ ++#define REG_CSR_2L_CDR0_PR_MONPI 0x0134 ++#define CSR_2L_PXP_CDR0_PR_XFICK_EN BIT(8) ++ ++#define REG_CSR_2L_RX0_SIGDET_DCTEST 0x0140 ++#define CSR_2L_PXP_RX0_SIGDET_LPF_CTRL GENMASK(9, 8) ++#define CSR_2L_PXP_RX0_SIGDET_PEAK GENMASK(25, 24) ++ ++#define REG_CSR_2L_RX0_SIGDET_VTH_SEL 0x0144 ++#define CSR_2L_PXP_RX0_SIGDET_VTH_SEL GENMASK(4, 0) ++#define CSR_2L_PXP_RX0_FE_VB_EQ1_EN BIT(24) ++ ++#define REG_CSR_2L_PXP_RX0_FE_VB_EQ2 0x0148 ++#define CSR_2L_PXP_RX0_FE_VB_EQ2_EN BIT(0) ++#define CSR_2L_PXP_RX0_FE_VB_EQ3_EN BIT(8) ++#define CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB BIT(16) ++ ++#define REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS 0x0158 ++#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS GENMASK(29, 24) ++ ++#define REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS 0x015c ++#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS GENMASK(5, 0) ++#define CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS GENMASK(13, 8) ++ ++#define REG_CSR_2L_RX1_REV0 0x01b4 ++ ++#define REG_CSR_2L_RX1_PHYCK_DIV 0x01b8 ++#define CSR_2L_PXP_RX1_PHYCK_SEL GENMASK(9, 8) ++#define CSR_2L_PXP_RX1_PHYCK_RSTB BIT(16) ++#define CSR_2L_PXP_RX1_TDC_CK_SEL BIT(24) ++ ++#define REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV 0x01bc ++#define CSR_2L_PXP_CDR1_PD_EDGE_DISABLE BIT(8) ++ ++#define REG_CSR_2L_CDR1_PR_BETA_DAC 0x01d8 ++#define CSR_2L_PXP_CDR1_PR_BETA_SEL GENMASK(19, 16) ++#define CSR_2L_PXP_CDR1_PR_KBAND_DIV GENMASK(26, 24) ++ ++#define REG_CSR_2L_CDR1_PR_MONCK 0x01e4 ++#define CSR_2L_PXP_CDR1_PR_MONCK_ENABLE BIT(0) ++#define CSR_2L_PXP_CDR1_PR_RESERVE0 GENMASK(19, 16) ++ ++#define REG_CSR_2L_CDR1_LPF_RATIO 0x01c8 ++#define CSR_2L_PXP_CDR1_LPF_TOP_LIM GENMASK(26, 8) ++ ++#define REG_CSR_2L_CDR1_PR_INJ_MODE 0x01d4 ++#define CSR_2L_PXP_CDR1_INJ_FORCE_OFF BIT(24) ++ ++#define REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL 0x01dc ++#define CSR_2L_PXP_CDR1_PR_VREG_IBAND GENMASK(2, 0) ++#define CSR_2L_PXP_CDR1_PR_VREG_CKBUF GENMASK(10, 8) ++ ++#define REG_CSR_2L_CDR1_PR_CKREF_DIV 0x01e0 ++#define CSR_2L_PXP_CDR1_PR_CKREF_DIV GENMASK(1, 0) ++ ++#define REG_CSR_2L_CDR1_PR_COR_HBW 0x01e8 ++#define CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON BIT(8) ++#define CSR_2L_PXP_CDR1_PR_CKREF_DIV1 GENMASK(17, 16) ++ ++#define REG_CSR_2L_CDR1_PR_MONPI 0x01ec ++#define CSR_2L_PXP_CDR1_PR_XFICK_EN BIT(8) ++ ++#define REG_CSR_2L_RX1_DAC_RANGE_EYE 0x01f4 ++#define CSR_2L_PXP_RX1_SIGDET_LPF_CTRL GENMASK(25, 24) ++ ++#define REG_CSR_2L_RX1_SIGDET_NOVTH 0x01f8 ++#define CSR_2L_PXP_RX1_SIGDET_PEAK GENMASK(9, 8) ++#define CSR_2L_PXP_RX1_SIGDET_VTH_SEL GENMASK(20, 16) ++ ++#define REG_CSR_2L_RX1_FE_VB_EQ1 0x0200 ++#define CSR_2L_PXP_RX1_FE_VB_EQ1_EN BIT(0) ++#define CSR_2L_PXP_RX1_FE_VB_EQ2_EN BIT(8) ++#define CSR_2L_PXP_RX1_FE_VB_EQ3_EN BIT(16) ++#define CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB BIT(24) ++ ++#define REG_CSR_2L_RX1_OSCAL_VGA1IOS 0x0214 ++#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS GENMASK(5, 0) ++#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS GENMASK(13, 8) ++#define CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS GENMASK(21, 16) ++ ++/* PMA */ ++#define REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1 0x0004 ++#define PCIE_LCPLL_MAN_PWDB BIT(0) ++ ++#define REG_PCIE_PMA_SEQUENCE_DISB_CTRL1 0x010c ++#define PCIE_DISB_RX_SDCAL_EN BIT(0) ++ ++#define REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1 0x0114 ++#define PCIE_FORCE_RX_SDCAL_EN BIT(0) ++ ++#define REG_PCIE_PMA_SS_RX_FREQ_DET1 0x014c ++#define PCIE_PLL_FT_LOCK_CYCLECNT GENMASK(15, 0) ++#define PCIE_PLL_FT_UNLOCK_CYCLECNT GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_SS_RX_FREQ_DET2 0x0150 ++#define PCIE_LOCK_TARGET_BEG GENMASK(15, 0) ++#define PCIE_LOCK_TARGET_END GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_SS_RX_FREQ_DET3 0x0154 ++#define PCIE_UNLOCK_TARGET_BEG GENMASK(15, 0) ++#define PCIE_UNLOCK_TARGET_END GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_SS_RX_FREQ_DET4 0x0158 ++#define PCIE_FREQLOCK_DET_EN GENMASK(2, 0) ++#define PCIE_LOCK_LOCKTH GENMASK(11, 8) ++#define PCIE_UNLOCK_LOCKTH GENMASK(15, 12) ++ ++#define REG_PCIE_PMA_SS_RX_CAL1 0x0160 ++#define REG_PCIE_PMA_SS_RX_CAL2 0x0164 ++#define PCIE_CAL_OUT_OS GENMASK(11, 8) ++ ++#define REG_PCIE_PMA_SS_RX_SIGDET0 0x0168 ++#define PCIE_SIGDET_WIN_NONVLD_TIMES GENMASK(28, 24) ++ ++#define REG_PCIE_PMA_TX_RESET 0x0260 ++#define PCIE_TX_TOP_RST BIT(0) ++#define PCIE_TX_CAL_RST BIT(8) ++ ++#define REG_PCIE_PMA_RX_FORCE_MODE0 0x0294 ++#define PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0) ++ ++#define REG_PCIE_PMA_SS_DA_XPON_PWDB0 0x034c ++#define PCIE_DA_XPON_CDR_PR_PWDB BIT(8) ++ ++#define REG_PCIE_PMA_SW_RESET 0x0460 ++#define PCIE_SW_RX_FIFO_RST BIT(0) ++#define PCIE_SW_RX_RST BIT(1) ++#define PCIE_SW_TX_RST BIT(2) ++#define PCIE_SW_PMA_RST BIT(3) ++#define PCIE_SW_ALLPCS_RST BIT(4) ++#define PCIE_SW_REF_RST BIT(5) ++#define PCIE_SW_TX_FIFO_RST BIT(6) ++#define PCIE_SW_XFI_TXPCS_RST BIT(7) ++#define PCIE_SW_XFI_RXPCS_RST BIT(8) ++#define PCIE_SW_XFI_RXPCS_BIST_RST BIT(9) ++#define PCIE_SW_HSG_TXPCS_RST BIT(10) ++#define PCIE_SW_HSG_RXPCS_RST BIT(11) ++#define PCIE_PMA_SW_RST (PCIE_SW_RX_FIFO_RST | \ ++ PCIE_SW_RX_RST | \ ++ PCIE_SW_TX_RST | \ ++ PCIE_SW_PMA_RST | \ ++ PCIE_SW_ALLPCS_RST | \ ++ PCIE_SW_REF_RST | \ ++ PCIE_SW_TX_FIFO_RST | \ ++ PCIE_SW_XFI_TXPCS_RST | \ ++ PCIE_SW_XFI_RXPCS_RST | \ ++ PCIE_SW_XFI_RXPCS_BIST_RST | \ ++ PCIE_SW_HSG_TXPCS_RST | \ ++ PCIE_SW_HSG_RXPCS_RST) ++ ++#define REG_PCIE_PMA_RO_RX_FREQDET 0x0530 ++#define PCIE_RO_FBCK_LOCK BIT(0) ++#define PCIE_RO_FL_OUT GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC 0x0794 ++#define PCIE_FORCE_DA_PXP_CDR_PR_IDAC GENMASK(10, 0) ++#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW BIT(24) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW 0x0798 ++#define PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW GENMASK(30, 0) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS 0x079c ++#define PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW BIT(16) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW 0x0800 ++#define PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW GENMASK(30, 0) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB 0x081c ++#define PCIE_FORCE_DA_PXP_CDR_PD_PWDB BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB BIT(8) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C 0x0820 ++#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN BIT(8) ++#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN BIT(24) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB 0x0824 ++#define PCIE_FORCE_DA_PXP_CDR_PR_PWDB BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB BIT(24) ++ ++#define REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT 0x0828 ++#define PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN BIT(8) ++#define PCIE_FORCE_DA_PXP_JCPLL_EN BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_JCPLL_EN BIT(24) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST 0x0084c ++#define PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB BIT(24) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT 0x0854 ++#define PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN BIT(8) ++#define PCIE_FORCE_DA_PXP_TXPLL_EN BIT(16) ++#define PCIE_FORCE_SEL_DA_PXP_TXPLL_EN BIT(24) ++ ++#define REG_PCIE_PMA_SCAN_MODE 0x0884 ++#define PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(8) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_13 0x08bc ++#define PCIE_FLL_IDAC_PCIEG1 GENMASK(10, 0) ++#define PCIE_FLL_IDAC_PCIEG2 GENMASK(26, 16) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_14 0x08c0 ++#define PCIE_FLL_IDAC_PCIEG3 GENMASK(10, 0) ++#define PCIE_FLL_LOAD_EN BIT(16) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL 0x088c ++#define PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL GENMASK(1, 0) ++#define PCIE_FORCE_SEL_DA_PXP_RX_FE_GAIN_CTRL BIT(8) ++ ++#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB 0x0894 ++#define PCIE_FORCE_DA_PXP_RX_FE_PWDB BIT(0) ++#define PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB BIT(8) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_12 0x08b8 ++#define PCIE_FORCE_PMA_RX_SPEED GENMASK(7, 4) ++#define PCIE_FORCE_SEL_PMA_RX_SPEED BIT(7) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_17 0x08e0 ++ ++#define REG_PCIE_PMA_DIG_RESERVE_18 0x08e4 ++#define PCIE_PXP_RX_VTH_SEL_PCIE_G1 GENMASK(4, 0) ++#define PCIE_PXP_RX_VTH_SEL_PCIE_G2 GENMASK(12, 8) ++#define PCIE_PXP_RX_VTH_SEL_PCIE_G3 GENMASK(20, 16) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_19 0x08e8 ++#define PCIE_PCP_RX_REV0_PCIE_GEN1 GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_20 0x08ec ++#define PCIE_PCP_RX_REV0_PCIE_GEN2 GENMASK(15, 0) ++#define PCIE_PCP_RX_REV0_PCIE_GEN3 GENMASK(31, 16) ++ ++#define REG_PCIE_PMA_DIG_RESERVE_21 0x08f0 ++#define REG_PCIE_PMA_DIG_RESERVE_22 0x08f4 ++#define REG_PCIE_PMA_DIG_RESERVE_27 0x0908 ++#define REG_PCIE_PMA_DIG_RESERVE_30 0x0914 ++ ++/* DTIME */ ++#define REG_PCIE_PEXTP_DIG_GLB44 0x00 ++#define PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL GENMASK(7, 0) ++#define PCIE_XTP_RXDET_EN_STB_T_SEL GENMASK(15, 8) ++#define PCIE_XTP_RXDET_FINISH_STB_T_SEL GENMASK(23, 16) ++#define PCIE_XTP_TXPD_TX_DATA_EN_DLY GENMASK(27, 24) ++#define PCIE_XTP_TXPD_RXDET_DONE_CDT BIT(28) ++#define PCIE_XTP_RXDET_LATCH_STB_T_SEL GENMASK(31, 29) ++ ++/* RX AEQ */ ++#define REG_PCIE_PEXTP_DIG_LN_RX30_P0 0x0000 ++#define PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT GENMASK(7, 0) ++#define PCIE_XTP_LN_RX_PDOWN_T2RLB_DIG_EN BIT(8) ++#define PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT GENMASK(31, 16) ++ ++#define REG_PCIE_PEXTP_DIG_LN_RX30_P1 0x0100 ++ ++#endif /* _PHY_AIROHA_PCIE_H */ +--- /dev/null ++++ b/drivers/phy/airoha/phy-airoha-pcie.c +@@ -0,0 +1,1290 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "phy-airoha-pcie-regs.h" ++ ++#define LEQ_LEN_CTRL_MAX_VAL 7 ++#define FREQ_LOCK_MAX_ATTEMPT 10 ++ ++/* PCIe-PHY initialization time in ms needed by the hw to complete */ ++#define PHY_HW_INIT_TIME_MS 30 ++ ++enum airoha_pcie_port_gen { ++ PCIE_PORT_GEN1 = 1, ++ PCIE_PORT_GEN2, ++ PCIE_PORT_GEN3, ++}; ++ ++/** ++ * struct airoha_pcie_phy - PCIe phy driver main structure ++ * @dev: pointer to device ++ * @phy: pointer to generic phy ++ * @csr_2l: Analogic lane IO mapped register base address ++ * @pma0: IO mapped register base address of PMA0-PCIe ++ * @pma1: IO mapped register base address of PMA1-PCIe ++ * @p0_xr_dtime: IO mapped register base address of port0 Tx-Rx detection time ++ * @p1_xr_dtime: IO mapped register base address of port1 Tx-Rx detection time ++ * @rx_aeq: IO mapped register base address of Rx AEQ training ++ */ ++struct airoha_pcie_phy { ++ struct device *dev; ++ struct phy *phy; ++ void __iomem *csr_2l; ++ void __iomem *pma0; ++ void __iomem *pma1; ++ void __iomem *p0_xr_dtime; ++ void __iomem *p1_xr_dtime; ++ void __iomem *rx_aeq; ++}; ++ ++static void airoha_phy_clear_bits(void __iomem *reg, u32 mask) ++{ ++ u32 val = readl(reg) & ~mask; ++ ++ writel(val, reg); ++} ++ ++static void airoha_phy_set_bits(void __iomem *reg, u32 mask) ++{ ++ u32 val = readl(reg) | mask; ++ ++ writel(val, reg); ++} ++ ++static void airoha_phy_update_bits(void __iomem *reg, u32 mask, u32 val) ++{ ++ u32 tmp = readl(reg); ++ ++ tmp &= ~mask; ++ tmp |= val & mask; ++ writel(tmp, reg); ++} ++ ++#define airoha_phy_update_field(reg, mask, val) \ ++ do { \ ++ BUILD_BUG_ON_MSG(!__builtin_constant_p((mask)), \ ++ "mask is not constant"); \ ++ airoha_phy_update_bits((reg), (mask), \ ++ FIELD_PREP((mask), (val))); \ ++ } while (0) ++ ++#define airoha_phy_csr_2l_clear_bits(pcie_phy, reg, mask) \ ++ airoha_phy_clear_bits((pcie_phy)->csr_2l + (reg), (mask)) ++#define airoha_phy_csr_2l_set_bits(pcie_phy, reg, mask) \ ++ airoha_phy_set_bits((pcie_phy)->csr_2l + (reg), (mask)) ++#define airoha_phy_csr_2l_update_field(pcie_phy, reg, mask, val) \ ++ airoha_phy_update_field((pcie_phy)->csr_2l + (reg), (mask), (val)) ++#define airoha_phy_pma0_clear_bits(pcie_phy, reg, mask) \ ++ airoha_phy_clear_bits((pcie_phy)->pma0 + (reg), (mask)) ++#define airoha_phy_pma1_clear_bits(pcie_phy, reg, mask) \ ++ airoha_phy_clear_bits((pcie_phy)->pma1 + (reg), (mask)) ++#define airoha_phy_pma0_set_bits(pcie_phy, reg, mask) \ ++ airoha_phy_set_bits((pcie_phy)->pma0 + (reg), (mask)) ++#define airoha_phy_pma1_set_bits(pcie_phy, reg, mask) \ ++ airoha_phy_set_bits((pcie_phy)->pma1 + (reg), (mask)) ++#define airoha_phy_pma0_update_field(pcie_phy, reg, mask, val) \ ++ airoha_phy_update_field((pcie_phy)->pma0 + (reg), (mask), (val)) ++#define airoha_phy_pma1_update_field(pcie_phy, reg, mask, val) \ ++ airoha_phy_update_field((pcie_phy)->pma1 + (reg), (mask), (val)) ++ ++static void ++airoha_phy_init_lane0_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, ++ enum airoha_pcie_port_gen gen) ++{ ++ u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; ++ u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; ++ u32 pr_idac, val, cdr_pr_idac_tmp = 0; ++ int i; ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, ++ PCIE_LCPLL_MAN_PWDB); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, ++ PCIE_LOCK_TARGET_BEG, ++ fl_out_target - 100); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, ++ PCIE_LOCK_TARGET_END, ++ fl_out_target + 100); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, ++ PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_LOCK_LOCKTH, 0x3); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, ++ PCIE_UNLOCK_TARGET_BEG, ++ fl_out_target - 100); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, ++ PCIE_UNLOCK_TARGET_END, ++ fl_out_target + 100); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, ++ PCIE_PLL_FT_UNLOCK_CYCLECNT, ++ lock_cyclecnt); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_UNLOCK_LOCKTH, 0x3); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, ++ CSR_2L_PXP_CDR0_INJ_FORCE_OFF); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); ++ ++ for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = FIELD_GET(PCIE_RO_FL_OUT, ++ readl(pcie_phy->pma0 + ++ REG_PCIE_PMA_RO_RX_FREQDET)); ++ if (val > fl_out_target) ++ cdr_pr_idac_tmp = i << 8; ++ } ++ ++ for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { ++ pr_idac = cdr_pr_idac_tmp | (0x1 << i); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = FIELD_GET(PCIE_RO_FL_OUT, ++ readl(pcie_phy->pma0 + ++ REG_PCIE_PMA_RO_RX_FREQDET)); ++ if (val < fl_out_target) ++ pr_idac &= ~(0x1 << i); ++ ++ cdr_pr_idac_tmp = pr_idac; ++ } ++ ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, ++ cdr_pr_idac_tmp); ++ ++ for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { ++ u32 val; ++ ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = readl(pcie_phy->pma0 + REG_PCIE_PMA_RO_RX_FREQDET); ++ if (val & PCIE_RO_FBCK_LOCK) ++ break; ++ } ++ ++ /* turn off force mode and update band values */ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, ++ CSR_2L_PXP_CDR0_INJ_FORCE_OFF); ++ ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); ++ if (gen == PCIE_PORT_GEN3) { ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_14, ++ PCIE_FLL_IDAC_PCIEG3, ++ cdr_pr_idac_tmp); ++ } else { ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_13, ++ PCIE_FLL_IDAC_PCIEG1, ++ cdr_pr_idac_tmp); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_13, ++ PCIE_FLL_IDAC_PCIEG2, ++ cdr_pr_idac_tmp); ++ } ++} ++ ++static void ++airoha_phy_init_lane1_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, ++ enum airoha_pcie_port_gen gen) ++{ ++ u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; ++ u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; ++ u32 pr_idac, val, cdr_pr_idac_tmp = 0; ++ int i; ++ ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, ++ PCIE_LCPLL_MAN_PWDB); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, ++ PCIE_LOCK_TARGET_BEG, ++ fl_out_target - 100); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, ++ PCIE_LOCK_TARGET_END, ++ fl_out_target + 100); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, ++ PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_LOCK_LOCKTH, 0x3); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, ++ PCIE_UNLOCK_TARGET_BEG, ++ fl_out_target - 100); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, ++ PCIE_UNLOCK_TARGET_END, ++ fl_out_target + 100); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, ++ PCIE_PLL_FT_UNLOCK_CYCLECNT, ++ lock_cyclecnt); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_UNLOCK_LOCKTH, 0x3); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, ++ CSR_2L_PXP_CDR1_INJ_FORCE_OFF); ++ ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); ++ ++ for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = FIELD_GET(PCIE_RO_FL_OUT, ++ readl(pcie_phy->pma1 + ++ REG_PCIE_PMA_RO_RX_FREQDET)); ++ if (val > fl_out_target) ++ cdr_pr_idac_tmp = i << 8; ++ } ++ ++ for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { ++ pr_idac = cdr_pr_idac_tmp | (0x1 << i); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = FIELD_GET(PCIE_RO_FL_OUT, ++ readl(pcie_phy->pma1 + ++ REG_PCIE_PMA_RO_RX_FREQDET)); ++ if (val < fl_out_target) ++ pr_idac &= ~(0x1 << i); ++ ++ cdr_pr_idac_tmp = pr_idac; ++ } ++ ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, ++ cdr_pr_idac_tmp); ++ ++ for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { ++ u32 val; ++ ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_SS_RX_FREQ_DET4, ++ PCIE_FREQLOCK_DET_EN, 0x3); ++ ++ usleep_range(10000, 15000); ++ ++ val = readl(pcie_phy->pma1 + REG_PCIE_PMA_RO_RX_FREQDET); ++ if (val & PCIE_RO_FBCK_LOCK) ++ break; ++ } ++ ++ /* turn off force mode and update band values */ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, ++ CSR_2L_PXP_CDR1_INJ_FORCE_OFF); ++ ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); ++ if (gen == PCIE_PORT_GEN3) { ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_14, ++ PCIE_FLL_IDAC_PCIEG3, ++ cdr_pr_idac_tmp); ++ } else { ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_13, ++ PCIE_FLL_IDAC_PCIEG1, ++ cdr_pr_idac_tmp); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_DIG_RESERVE_13, ++ PCIE_FLL_IDAC_PCIEG2, ++ cdr_pr_idac_tmp); ++ } ++} ++ ++static void airoha_pcie_phy_init_default(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CMN, ++ CSR_2L_PXP_CMN_TRIM_MASK, 0x10); ++ writel(0xcccbcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_21); ++ writel(0xcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_22); ++ writel(0xcccbcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_21); ++ writel(0xcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_22); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CMN, ++ CSR_2L_PXP_CMN_LANE_EN); ++} ++ ++static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_TXPLL_POSTDIV_D256, ++ CSR_2L_PXP_CLKTX0_AMP, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_CLKTX0_FORCE_OUT1, ++ CSR_2L_PXP_CLKTX1_AMP, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_TXPLL_POSTDIV_D256, ++ CSR_2L_PXP_CLKTX0_OFFSET, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, ++ CSR_2L_PXP_CLKTX1_OFFSET, 0x2); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX0_FORCE_OUT1, ++ CSR_2L_PXP_CLKTX0_HZ); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, ++ CSR_2L_PXP_CLKTX1_HZ); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_CLKTX0_FORCE_OUT1, ++ CSR_2L_PXP_CLKTX0_IMP_SEL, 0x12); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_IMP_SEL, ++ CSR_2L_PXP_CLKTX1_IMP_SEL, 0x12); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV_D256, ++ CSR_2L_PXP_CLKTX0_SR); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, ++ CSR_2L_PXP_CLKTX1_SR); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0, ++ CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d); ++} ++ ++static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | ++ PCIE_SW_RX_RST); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | ++ PCIE_SW_RX_RST); ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, ++ PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, ++ PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); ++} ++ ++static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy) ++{ ++ writel(0x2a00090b, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_17); ++ writel(0x2a00090b, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_17); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONPI, ++ CSR_2L_PXP_CDR0_PR_XFICK_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONPI, ++ CSR_2L_PXP_CDR1_PR_XFICK_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, ++ REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV, ++ CSR_2L_PXP_CDR0_PD_EDGE_DISABLE); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, ++ REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV, ++ CSR_2L_PXP_CDR1_PD_EDGE_DISABLE); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, ++ CSR_2L_PXP_RX0_PHYCK_SEL, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, ++ CSR_2L_PXP_RX1_PHYCK_SEL, 0x1); ++} ++ ++static void airoha_pcie_phy_init_jcpll(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_VTP_EN, ++ CSR_2L_PXP_JCPLL_SPARE_LOW, 0x20); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, ++ CSR_2L_PXP_JCPLL_RST); ++ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_JCPLL_SSC_DELTA1); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, ++ CSR_2L_PXP_JCPLL_SSC_PERIOD); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_PHASE_INI); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_TRI_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, ++ CSR_2L_PXP_JCPLL_LPF_BR, 0xa); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, ++ CSR_2L_PXP_JCPLL_LPF_BP, 0xc); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, ++ CSR_2L_PXP_JCPLL_LPF_BC, 0x1f); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, ++ CSR_2L_PXP_JCPLL_LPF_BWC, 0x1e); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, ++ CSR_2L_PXP_JCPLL_LPF_BWR, 0xa); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, ++ CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, ++ 0x1); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, CSR_2L_PXP_JCPLL_MONCK, ++ CSR_2L_PXP_JCPLL_REFIN_DIV); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, ++ PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, ++ 0x50000000); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, ++ PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, ++ 0x50000000); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, ++ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, ++ CSR_2L_PXP_JCPLL_POSTDIV_D5); ++ airoha_phy_csr_2l_set_bits(pcie_phy, ++ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, ++ CSR_2L_PXP_JCPLL_POSTDIV_D2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, ++ CSR_2L_PXP_JCPLL_RST_DLY, 0x4); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, ++ CSR_2L_PXP_JCPLL_SDM_DI_LS); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_KBAND_VREF, ++ CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, ++ CSR_2L_PXP_JCPLL_CHP_IOFST); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, ++ CSR_2L_PXP_JCPLL_CHP_IBIAS, 0xc); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, ++ CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, ++ 0x1); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, ++ CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, ++ CSR_2L_PXP_JCPLL_VCO_CFIX, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, ++ CSR_2L_PXP_JCPLL_VCO_SCAPWR, 0x4); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, ++ REG_CSR_2L_JCPLL_LPF_SHCK_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, ++ CSR_2L_PXP_JCPLL_POSTDIV_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, ++ CSR_2L_PXP_JCPLL_KBAND_KFC); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, ++ CSR_2L_PXP_JCPLL_KBAND_KF, 0x3); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, ++ CSR_2L_PXP_JCPLL_KBAND_KS); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, ++ CSR_2L_PXP_JCPLL_KBAND_DIV, 0x1); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, ++ PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, ++ CSR_2L_PXP_JCPLL_KBAND_CODE, 0xe4); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, ++ CSR_2L_PXP_JCPLL_TCL_AMP_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, ++ CSR_2L_PXP_JCPLL_TCL_LPF_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_JCPLL_TCL_KBAND_VREF, ++ CSR_2L_PXP_JCPLL_TCL_KBAND_VREF, 0xf); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, ++ CSR_2L_PXP_JCPLL_TCL_AMP_GAIN, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, ++ CSR_2L_PXP_JCPLL_TCL_AMP_VREF, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, ++ CSR_2L_PXP_JCPLL_TCL_LPF_BW, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCO_TCLVAR, ++ CSR_2L_PXP_JCPLL_VCO_TCLVAR, 0x3); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_JCPLL_EN); ++} ++ ++static void airoha_pcie_phy_txpll(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_EN); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, ++ CSR_2L_PXP_TXPLL_PLL_RSTB); ++ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC_PERIOD, ++ CSR_2L_PXP_txpll_SSC_PERIOD); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, ++ CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, ++ CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, ++ CSR_2L_PXP_TXPLL_REFIN_DIV); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, ++ CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, ++ PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, ++ 0xc800000); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, ++ PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, ++ 0xc800000); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, ++ CSR_2L_PXP_TXPLL_SDM_IFM); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, ++ CSR_2L_PXP_TXPLL_SSC_PHASE_INI); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, ++ CSR_2L_PXP_TXPLL_RST_DLY, 0x4); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, ++ CSR_2L_PXP_TXPLL_SDM_DI_LS); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, ++ CSR_2L_PXP_TXPLL_SDM_ORD, 0x3); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, ++ CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); ++ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, ++ CSR_2L_PXP_TXPLL_LPF_BP, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, ++ CSR_2L_PXP_TXPLL_LPF_BC, 0x18); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, ++ CSR_2L_PXP_TXPLL_LPF_BR, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, ++ CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, ++ CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_VTP, ++ CSR_2L_PXP_TXPLL_SPARE_L, 0x1); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, ++ CSR_2L_PXP_TXPLL_LPF_BWC); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, ++ CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, ++ CSR_2L_PXP_TXPLL_REFIN_DIV); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, ++ CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_VCO_SCAPWR, ++ CSR_2L_PXP_TXPLL_VCO_SCAPWR, 0x7); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, ++ CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, ++ CSR_2L_PXP_TXPLL_SSC_PHASE_INI); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, ++ CSR_2L_PXP_TXPLL_LPF_BWR); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, ++ CSR_2L_PXP_TXPLL_REFIN_INTERNAL); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, ++ CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_VTP, ++ CSR_2L_PXP_TXPLL_VTP_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, ++ CSR_2L_PXP_TXPLL_PHY_CK1_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, ++ CSR_2L_PXP_TXPLL_REFIN_INTERNAL); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, ++ CSR_2L_PXP_TXPLL_SSC_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_750M_SYS_CK, ++ CSR_2L_PXP_TXPLL_LPF_SHCK_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, ++ CSR_2L_PXP_TXPLL_POSTDIV_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, ++ CSR_2L_PXP_TXPLL_KBAND_KFC); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, ++ CSR_2L_PXP_TXPLL_KBAND_KF, 0x3); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, ++ CSR_2L_PXP_txpll_KBAND_KS, 0x1); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, ++ CSR_2L_PXP_TXPLL_KBAND_DIV, 0x4); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, ++ CSR_2L_PXP_TXPLL_KBAND_CODE, 0xe4); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, ++ CSR_2L_PXP_TXPLL_TCL_AMP_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_AMP_VREF, ++ CSR_2L_PXP_TXPLL_TCL_LPF_EN); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_TXPLL_TCL_KBAND_VREF, ++ CSR_2L_PXP_TXPLL_TCL_KBAND_VREF, 0xf); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, ++ CSR_2L_PXP_TXPLL_TCL_AMP_GAIN, 0x3); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_TXPLL_TCL_AMP_VREF, ++ CSR_2L_PXP_TXPLL_TCL_AMP_VREF, 0xb); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, ++ CSR_2L_PXP_TXPLL_TCL_LPF_BW, 0x3); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, ++ PCIE_FORCE_DA_PXP_TXPLL_EN); ++} ++ ++static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, ++ CSR_2L_PXP_JCPLL_SSC_DELTA1, 0x106); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, ++ CSR_2L_PXP_JCPLL_SSC_DELTA, 0x106); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, ++ CSR_2L_PXP_JCPLL_SSC_PERIOD, 0x31b); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_PHASE_INI); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM, ++ CSR_2L_PXP_JCPLL_SDM_IFM); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, ++ CSR_2L_PXP_JCPLL_SDM_HREN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, ++ CSR_2L_PXP_JCPLL_SDM_DI_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_TRI_EN); ++} ++ ++static void ++airoha_pcie_phy_set_rxlan0_signal_detect(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, ++ CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON); ++ ++ usleep_range(100, 200); ++ ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, ++ PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, ++ PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, ++ PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, ++ CSR_2L_PXP_RX0_SIGDET_PEAK, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, ++ CSR_2L_PXP_RX0_SIGDET_VTH_SEL, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, ++ CSR_2L_PXP_VOS_PNINV, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, ++ CSR_2L_PXP_RX0_SIGDET_LPF_CTRL, 0x1); ++ ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, ++ PCIE_CAL_OUT_OS, 0x0); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, ++ CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, ++ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); ++ airoha_phy_pma0_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, ++ PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, ++ PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, ++ PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); ++ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, ++ PCIE_DISB_RX_SDCAL_EN); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, ++ PCIE_FORCE_RX_SDCAL_EN); ++ usleep_range(150, 200); ++ airoha_phy_pma0_clear_bits(pcie_phy, ++ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, ++ PCIE_FORCE_RX_SDCAL_EN); ++} ++ ++static void ++airoha_pcie_phy_set_rxlan1_signal_detect(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, ++ CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON); ++ ++ usleep_range(100, 200); ++ ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, ++ PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, ++ PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, ++ PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, ++ CSR_2L_PXP_RX1_SIGDET_PEAK, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, ++ CSR_2L_PXP_RX1_SIGDET_VTH_SEL, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, ++ CSR_2L_PXP_VOS_PNINV, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_DAC_RANGE_EYE, ++ CSR_2L_PXP_RX1_SIGDET_LPF_CTRL, 0x1); ++ ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, ++ PCIE_CAL_OUT_OS, 0x0); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, ++ CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB); ++ ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, ++ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); ++ airoha_phy_pma1_update_field(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, ++ PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, ++ PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, ++ PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); ++ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, ++ PCIE_DISB_RX_SDCAL_EN); ++ ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, ++ PCIE_FORCE_RX_SDCAL_EN); ++ usleep_range(150, 200); ++ airoha_phy_pma1_clear_bits(pcie_phy, ++ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, ++ PCIE_FORCE_RX_SDCAL_EN); ++} ++ ++static void airoha_pcie_phy_set_rxflow(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, ++ PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, ++ PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PD_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); ++ airoha_phy_pma0_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, ++ PCIE_FORCE_DA_PXP_RX_FE_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, ++ PCIE_FORCE_DA_PXP_CDR_PD_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); ++ airoha_phy_pma1_set_bits(pcie_phy, ++ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, ++ PCIE_FORCE_DA_PXP_RX_FE_PWDB | ++ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, ++ CSR_2L_PXP_RX0_PHYCK_RSTB | ++ CSR_2L_PXP_RX0_TDC_CK_SEL); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, ++ CSR_2L_PXP_RX1_PHYCK_RSTB | ++ CSR_2L_PXP_RX1_TDC_CK_SEL); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | ++ PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | ++ PCIE_SW_TX_FIFO_RST); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | ++ PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | ++ PCIE_SW_TX_FIFO_RST); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, ++ CSR_2L_PXP_RX0_FE_VB_EQ2_EN | ++ CSR_2L_PXP_RX0_FE_VB_EQ3_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, ++ CSR_2L_PXP_RX0_FE_VB_EQ1_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, ++ CSR_2L_PXP_RX1_FE_VB_EQ1_EN | ++ CSR_2L_PXP_RX1_FE_VB_EQ2_EN | ++ CSR_2L_PXP_RX1_FE_VB_EQ3_EN); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, ++ CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, ++ CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, ++ CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, ++ CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); ++} ++ ++static void airoha_pcie_phy_set_pr(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, ++ CSR_2L_PXP_CDR0_PR_VREG_IBAND, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, ++ CSR_2L_PXP_CDR0_PR_VREG_CKBUF, 0x5); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_CKREF_DIV, ++ CSR_2L_PXP_CDR0_PR_CKREF_DIV); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, ++ CSR_2L_PXP_CDR0_PR_CKREF_DIV1); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, ++ CSR_2L_PXP_CDR1_PR_VREG_IBAND, 0x5); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, ++ CSR_2L_PXP_CDR1_PR_VREG_CKBUF, 0x5); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_CKREF_DIV, ++ CSR_2L_PXP_CDR1_PR_CKREF_DIV); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, ++ CSR_2L_PXP_CDR1_PR_CKREF_DIV1); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_LPF_RATIO, ++ CSR_2L_PXP_CDR0_LPF_TOP_LIM, 0x20000); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_LPF_RATIO, ++ CSR_2L_PXP_CDR1_LPF_TOP_LIM, 0x20000); ++ ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, ++ CSR_2L_PXP_CDR0_PR_BETA_SEL, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, ++ CSR_2L_PXP_CDR1_PR_BETA_SEL, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, ++ CSR_2L_PXP_CDR0_PR_KBAND_DIV, 0x4); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, ++ CSR_2L_PXP_CDR1_PR_KBAND_DIV, 0x4); ++} ++ ++static void airoha_pcie_phy_set_txflow(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, ++ CSR_2L_PXP_TX0_CKLDO_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, ++ CSR_2L_PXP_TX1_CKLDO_EN); ++ ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, ++ CSR_2L_PXP_TX0_DMEDGEGEN_EN); ++ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, ++ CSR_2L_PXP_TX1_DMEDGEGEN_EN); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TX1_MULTLANE, ++ CSR_2L_PXP_TX1_MULTLANE_EN); ++} ++ ++static void airoha_pcie_phy_set_rx_mode(struct airoha_pcie_phy *pcie_phy) ++{ ++ writel(0x804000, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_27); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, ++ 0x77700); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, ++ CSR_2L_PXP_CDR0_PR_MONCK_ENABLE); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, ++ CSR_2L_PXP_CDR0_PR_RESERVE0, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS, ++ CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS, 0x19); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, ++ CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS, 0x19); ++ airoha_phy_csr_2l_update_field(pcie_phy, ++ REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, ++ CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS, 0x14); ++ ++ writel(0x804000, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_27); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, ++ PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); ++ ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, ++ 0x77700); ++ ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, ++ CSR_2L_PXP_CDR1_PR_MONCK_ENABLE); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, ++ CSR_2L_PXP_CDR1_PR_RESERVE0, 0x2); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, ++ CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS, 0x19); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, ++ CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS, 0x19); ++ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, ++ CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS, 0x14); ++} ++ ++static void airoha_pcie_phy_load_kflow(struct airoha_pcie_phy *pcie_phy) ++{ ++ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, ++ PCIE_FORCE_PMA_RX_SPEED, 0xa); ++ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, ++ PCIE_FORCE_PMA_RX_SPEED, 0xa); ++ airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); ++ airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); ++ ++ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, ++ PCIE_FORCE_PMA_RX_SPEED); ++ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, ++ PCIE_FORCE_PMA_RX_SPEED); ++ usleep_range(100, 200); ++ ++ airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); ++ airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); ++} ++ ++/** ++ * airoha_pcie_phy_init() - Initialize the phy ++ * @phy: the phy to be initialized ++ * ++ * Initialize the phy registers. ++ * The hardware settings will be reset during suspend, it should be ++ * reinitialized when the consumer calls phy_init() again on resume. ++ */ ++static int airoha_pcie_phy_init(struct phy *phy) ++{ ++ struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); ++ u32 val; ++ ++ /* Setup Tx-Rx detection time */ ++ val = FIELD_PREP(PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL, 0x33) | ++ FIELD_PREP(PCIE_XTP_RXDET_EN_STB_T_SEL, 0x1) | ++ FIELD_PREP(PCIE_XTP_RXDET_FINISH_STB_T_SEL, 0x2) | ++ FIELD_PREP(PCIE_XTP_TXPD_TX_DATA_EN_DLY, 0x3) | ++ FIELD_PREP(PCIE_XTP_RXDET_LATCH_STB_T_SEL, 0x1); ++ writel(val, pcie_phy->p0_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); ++ writel(val, pcie_phy->p1_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); ++ /* Setup Rx AEQ training time */ ++ val = FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT, 0x32) | ++ FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT, 0x5050); ++ writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P0); ++ writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P1); ++ ++ /* enable load FLL-K flow */ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, ++ PCIE_FLL_LOAD_EN); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, ++ PCIE_FLL_LOAD_EN); ++ ++ airoha_pcie_phy_init_default(pcie_phy); ++ airoha_pcie_phy_init_clk_out(pcie_phy); ++ airoha_pcie_phy_init_csr_2l(pcie_phy); ++ ++ usleep_range(100, 200); ++ ++ airoha_pcie_phy_init_rx(pcie_phy); ++ /* phase 1, no ssc for K TXPLL */ ++ airoha_pcie_phy_init_jcpll(pcie_phy); ++ ++ usleep_range(500, 600); ++ ++ /* TX PLL settings */ ++ airoha_pcie_phy_txpll(pcie_phy); ++ ++ usleep_range(200, 300); ++ ++ /* SSC JCPLL setting */ ++ airoha_pcie_phy_init_ssc_jcpll(pcie_phy); ++ ++ usleep_range(100, 200); ++ ++ /* Rx lan0 signal detect */ ++ airoha_pcie_phy_set_rxlan0_signal_detect(pcie_phy); ++ /* Rx lan1 signal detect */ ++ airoha_pcie_phy_set_rxlan1_signal_detect(pcie_phy); ++ /* RX FLOW */ ++ airoha_pcie_phy_set_rxflow(pcie_phy); ++ ++ usleep_range(100, 200); ++ ++ airoha_pcie_phy_set_pr(pcie_phy); ++ /* TX FLOW */ ++ airoha_pcie_phy_set_txflow(pcie_phy); ++ ++ usleep_range(100, 200); ++ /* RX mode setting */ ++ airoha_pcie_phy_set_rx_mode(pcie_phy); ++ /* Load K-Flow */ ++ airoha_pcie_phy_load_kflow(pcie_phy); ++ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, ++ PCIE_DA_XPON_CDR_PR_PWDB); ++ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, ++ PCIE_DA_XPON_CDR_PR_PWDB); ++ ++ usleep_range(100, 200); ++ ++ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, ++ PCIE_DA_XPON_CDR_PR_PWDB); ++ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, ++ PCIE_DA_XPON_CDR_PR_PWDB); ++ ++ /* Wait for the PCIe PHY to complete initialization before returning */ ++ msleep(PHY_HW_INIT_TIME_MS); ++ ++ return 0; ++} ++ ++static int airoha_pcie_phy_exit(struct phy *phy) ++{ ++ struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); ++ ++ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_PMA_SW_RST); ++ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, ++ PCIE_PMA_SW_RST); ++ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, ++ CSR_2L_PXP_JCPLL_SSC_PHASE_INI | ++ CSR_2L_PXP_JCPLL_SSC_TRI_EN | ++ CSR_2L_PXP_JCPLL_SSC_EN); ++ ++ return 0; ++} ++ ++static const struct phy_ops airoha_pcie_phy_ops = { ++ .init = airoha_pcie_phy_init, ++ .exit = airoha_pcie_phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static int airoha_pcie_phy_probe(struct platform_device *pdev) ++{ ++ struct airoha_pcie_phy *pcie_phy; ++ struct device *dev = &pdev->dev; ++ struct phy_provider *provider; ++ ++ pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL); ++ if (!pcie_phy) ++ return -ENOMEM; ++ ++ pcie_phy->csr_2l = devm_platform_ioremap_resource_byname(pdev, "csr-2l"); ++ if (IS_ERR(pcie_phy->csr_2l)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->csr_2l), ++ "Failed to map phy-csr-2l base\n"); ++ ++ pcie_phy->pma0 = devm_platform_ioremap_resource_byname(pdev, "pma0"); ++ if (IS_ERR(pcie_phy->pma0)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->pma0), ++ "Failed to map phy-pma0 base\n"); ++ ++ pcie_phy->pma1 = devm_platform_ioremap_resource_byname(pdev, "pma1"); ++ if (IS_ERR(pcie_phy->pma1)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->pma1), ++ "Failed to map phy-pma1 base\n"); ++ ++ pcie_phy->phy = devm_phy_create(dev, dev->of_node, &airoha_pcie_phy_ops); ++ if (IS_ERR(pcie_phy->phy)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), ++ "Failed to create PCIe phy\n"); ++ ++ pcie_phy->p0_xr_dtime = ++ devm_platform_ioremap_resource_byname(pdev, "p0-xr-dtime"); ++ if (IS_ERR(pcie_phy->p0_xr_dtime)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->p0_xr_dtime), ++ "Failed to map P0 Tx-Rx dtime base\n"); ++ ++ pcie_phy->p1_xr_dtime = ++ devm_platform_ioremap_resource_byname(pdev, "p1-xr-dtime"); ++ if (IS_ERR(pcie_phy->p1_xr_dtime)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->p1_xr_dtime), ++ "Failed to map P1 Tx-Rx dtime base\n"); ++ ++ pcie_phy->rx_aeq = devm_platform_ioremap_resource_byname(pdev, "rx-aeq"); ++ if (IS_ERR(pcie_phy->rx_aeq)) ++ return dev_err_probe(dev, PTR_ERR(pcie_phy->rx_aeq), ++ "Failed to map Rx AEQ base\n"); ++ ++ pcie_phy->dev = dev; ++ phy_set_drvdata(pcie_phy->phy, pcie_phy); ++ ++ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ if (IS_ERR(provider)) ++ return dev_err_probe(dev, PTR_ERR(provider), ++ "PCIe phy probe failed\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id airoha_pcie_phy_of_match[] = { ++ { .compatible = "airoha,en7581-pcie-phy" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, airoha_pcie_phy_of_match); ++ ++static struct platform_driver airoha_pcie_phy_driver = { ++ .probe = airoha_pcie_phy_probe, ++ .driver = { ++ .name = "airoha-pcie-phy", ++ .of_match_table = airoha_pcie_phy_of_match, ++ }, ++}; ++module_platform_driver(airoha_pcie_phy_driver); ++ ++MODULE_DESCRIPTION("Airoha PCIe PHY driver"); ++MODULE_AUTHOR("Lorenzo Bianconi "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch b/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch new file mode 100644 index 0000000000..609df08285 --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch @@ -0,0 +1,667 @@ +From fadd22890b239e5a251dbe47367cfbeb1ea105f7 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 7 Feb 2025 13:28:40 +0100 +Subject: [PATCH 07/10] phy: airoha: Add support for Airoha AN7581 USB PHY + +Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2 +USB port with USB 2.0 mode always supported and USB 3.0 mode available +only if the Serdes port is correctly configured for USB 3.0. + +The second USB port on the SoC can be both used for USB 3.0 operation or +PCIe. (toggled by the SCU SSR register and configured by the USB PHY +driver) + +If the USB 3.0 mode is not configured, the modes needs to be also +disabled in the xHCI node or the driver will report unsable clock and +fail probe. + +Also USB 3.0 PHY instance are provided only if the airoha,serdes-port +and airoha,scu property is defined in DT, if it's not then USB 3.0 PHY +is assumed not supported. + +For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is +mandatory and is used to select the monitor clock for calibration. + +Normally it's 1 for USB port 1 and 2 for USB port 2. + +Signed-off-by: Christian Marangi +--- + MAINTAINERS | 1 + + drivers/phy/airoha/Kconfig | 10 + + drivers/phy/airoha/Makefile | 1 + + drivers/phy/airoha/phy-airoha-usb.c | 597 ++++++++++++++++++++++++++++ + 4 files changed, 609 insertions(+) + create mode 100644 drivers/phy/airoha/phy-airoha-usb.c + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -742,6 +742,7 @@ M: Christian Marangi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SCU */ ++#define AIROHA_SCU_SSTR 0x9c ++#define AIROHA_SCU_SSTR_USB_PCIE_SEL BIT(3) ++#define AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x0) ++#define AIROHA_SCU_SSTR_USB_PCIE_SEL_USB FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x1) ++ ++/* U2PHY */ ++#define AIROHA_USB_PHY_FMCR0 0x100 ++#define AIROHA_USB_PHY_MONCLK_SEL GENMASK(27, 26) ++#define AIROHA_USB_PHY_MONCLK_SEL0 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0) ++#define AIROHA_USB_PHY_MONCLK_SEL1 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1) ++#define AIROHA_USB_PHY_MONCLK_SEL2 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2) ++#define AIROHA_USB_PHY_MONCLK_SEL3 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3) ++#define AIROHA_USB_PHY_FREQDET_EN BIT(24) ++#define AIROHA_USB_PHY_CYCLECNT GENMASK(23, 0) ++#define AIROHA_USB_PHY_FMMONR0 0x10c ++#define AIROHA_USB_PHY_USB_FM_OUT GENMASK(31, 0) ++#define AIROHA_USB_PHY_FMMONR1 0x110 ++#define AIROHA_USB_PHY_FRCK_EN BIT(8) ++ ++#define AIROHA_USB_PHY_USBPHYACR4 0x310 ++#define AIROHA_USB_PHY_USB20_FS_CR GENMASK(10, 8) ++#define AIROHA_USB_PHY_USB20_FS_CR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0) ++#define AIROHA_USB_PHY_USB20_FS_CR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2) ++#define AIROHA_USB_PHY_USB20_FS_CR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4) ++#define AIROHA_USB_PHY_USB20_FS_CR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6) ++#define AIROHA_USB_PHY_USB20_FS_SR GENMASK(2, 0) ++#define AIROHA_USB_PHY_USB20_FS_SR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0) ++#define AIROHA_USB_PHY_USB20_FS_SR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2) ++#define AIROHA_USB_PHY_USB20_FS_SR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4) ++#define AIROHA_USB_PHY_USB20_FS_SR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6) ++#define AIROHA_USB_PHY_USBPHYACR5 0x314 ++#define AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN BIT(15) ++#define AIROHA_USB_PHY_USB20_HSTX_SRCTRL GENMASK(14, 12) ++#define AIROHA_USB_PHY_USBPHYACR6 0x318 ++#define AIROHA_USB_PHY_USB20_BC11_SW_EN BIT(23) ++#define AIROHA_USB_PHY_USB20_DISCTH GENMASK(7, 4) ++#define AIROHA_USB_PHY_USB20_DISCTH_400 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0) ++#define AIROHA_USB_PHY_USB20_DISCTH_420 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1) ++#define AIROHA_USB_PHY_USB20_DISCTH_440 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2) ++#define AIROHA_USB_PHY_USB20_DISCTH_460 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3) ++#define AIROHA_USB_PHY_USB20_DISCTH_480 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4) ++#define AIROHA_USB_PHY_USB20_DISCTH_500 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5) ++#define AIROHA_USB_PHY_USB20_DISCTH_520 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6) ++#define AIROHA_USB_PHY_USB20_DISCTH_540 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7) ++#define AIROHA_USB_PHY_USB20_DISCTH_560 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8) ++#define AIROHA_USB_PHY_USB20_DISCTH_580 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9) ++#define AIROHA_USB_PHY_USB20_DISCTH_600 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa) ++#define AIROHA_USB_PHY_USB20_DISCTH_620 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb) ++#define AIROHA_USB_PHY_USB20_DISCTH_640 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc) ++#define AIROHA_USB_PHY_USB20_DISCTH_660 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd) ++#define AIROHA_USB_PHY_USB20_DISCTH_680 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe) ++#define AIROHA_USB_PHY_USB20_DISCTH_700 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf) ++#define AIROHA_USB_PHY_USB20_SQTH GENMASK(3, 0) ++#define AIROHA_USB_PHY_USB20_SQTH_85 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0) ++#define AIROHA_USB_PHY_USB20_SQTH_90 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1) ++#define AIROHA_USB_PHY_USB20_SQTH_95 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2) ++#define AIROHA_USB_PHY_USB20_SQTH_100 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3) ++#define AIROHA_USB_PHY_USB20_SQTH_105 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4) ++#define AIROHA_USB_PHY_USB20_SQTH_110 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5) ++#define AIROHA_USB_PHY_USB20_SQTH_115 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6) ++#define AIROHA_USB_PHY_USB20_SQTH_120 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7) ++#define AIROHA_USB_PHY_USB20_SQTH_125 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8) ++#define AIROHA_USB_PHY_USB20_SQTH_130 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9) ++#define AIROHA_USB_PHY_USB20_SQTH_135 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa) ++#define AIROHA_USB_PHY_USB20_SQTH_140 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb) ++#define AIROHA_USB_PHY_USB20_SQTH_145 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc) ++#define AIROHA_USB_PHY_USB20_SQTH_150 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd) ++#define AIROHA_USB_PHY_USB20_SQTH_155 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe) ++#define AIROHA_USB_PHY_USB20_SQTH_160 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf) ++ ++#define AIROHA_USB_PHY_U2PHYDTM1 0x36c ++#define AIROHA_USB_PHY_FORCE_IDDIG BIT(9) ++#define AIROHA_USB_PHY_IDDIG BIT(1) ++ ++#define AIROHA_USB_PHY_GPIO_CTLD 0x80c ++#define AIROHA_USB_PHY_C60802_GPIO_CTLD GENMASK(31, 0) ++#define AIROHA_USB_PHY_SSUSB_IP_SW_RST BIT(31) ++#define AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN BIT(30) ++#define AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29) ++#define AIROHA_USB_PHY_SSUSB_SW_RST BIT(28) ++ ++#define AIROHA_USB_PHY_U3_PHYA_REG0 0xb00 ++#define AIROHA_USB_PHY_SSUSB_BG_DIV GENMASK(29, 28) ++#define AIROHA_USB_PHY_SSUSB_BG_DIV_2 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0) ++#define AIROHA_USB_PHY_SSUSB_BG_DIV_4 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1) ++#define AIROHA_USB_PHY_SSUSB_BG_DIV_8 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2) ++#define AIROHA_USB_PHY_SSUSB_BG_DIV_16 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3) ++#define AIROHA_USB_PHY_U3_PHYA_REG1 0xb04 ++#define AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) ++#define AIROHA_USB_PHY_U3_PHYA_REG6 0xb18 ++#define AIROHA_USB_PHY_SSUSB_CDR_RESERVE GENMASK(31, 24) ++#define AIROHA_USB_PHY_U3_PHYA_REG8 0xb20 ++#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY GENMASK(7, 6) ++#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0) ++#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1) ++#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2) ++#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3) ++ ++#define AIROHA_USB_PHY_U3_PHYA_DA_REG19 0xc38 ++#define AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0) ++ ++#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT 1024 ++#define AIROHA_USB_PHY_REF_CK 20 ++#define AIROHA_USB_PHY_U2_SR_COEF 28 ++#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR 1000 ++ ++#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION 0x5 ++#define AIROHA_USB_PHY_FREQDET_SLEEP 1000 /* 1ms */ ++#define AIROHA_USB_PHY_FREQDET_TIMEOUT (AIROHA_USB_PHY_FREQDET_SLEEP * 10) ++ ++struct airoha_usb_phy_instance { ++ struct phy *phy; ++ u32 type; ++}; ++ ++enum airoha_usb_phy_instance_type { ++ AIROHA_PHY_USB2, ++ AIROHA_PHY_USB3, ++ ++ AIROHA_PHY_USB_MAX, ++}; ++ ++struct airoha_usb_phy_priv { ++ struct device *dev; ++ struct regmap *regmap; ++ struct regmap *scu; ++ ++ unsigned int monclk_sel; ++ unsigned int serdes_port; ++ ++ struct airoha_usb_phy_instance *phys[AIROHA_PHY_USB_MAX]; ++}; ++ ++static void airoha_usb_phy_u2_slew_rate_calibration(struct airoha_usb_phy_priv *priv) ++{ ++ u32 fm_out; ++ u32 srctrl; ++ ++ /* Enable HS TX SR calibration */ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, ++ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); ++ ++ usleep_range(1000, 1500); ++ ++ /* Enable Free run clock */ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, ++ AIROHA_USB_PHY_FRCK_EN); ++ ++ /* Select Monitor Clock */ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, ++ AIROHA_USB_PHY_MONCLK_SEL, ++ FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL, ++ priv->monclk_sel)); ++ ++ /* Set cyclecnt */ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, ++ AIROHA_USB_PHY_CYCLECNT, ++ FIELD_PREP(AIROHA_USB_PHY_CYCLECNT, ++ AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT)); ++ ++ /* Enable Frequency meter */ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, ++ AIROHA_USB_PHY_FREQDET_EN); ++ ++ /* Timeout can happen and we will apply workaround at the end */ ++ regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out, ++ fm_out, AIROHA_USB_PHY_FREQDET_SLEEP, ++ AIROHA_USB_PHY_FREQDET_TIMEOUT); ++ ++ /* Disable Frequency meter */ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, ++ AIROHA_USB_PHY_FREQDET_EN); ++ ++ /* Disable Free run clock */ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, ++ AIROHA_USB_PHY_FRCK_EN); ++ ++ /* Disable HS TX SR calibration */ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, ++ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); ++ ++ usleep_range(1000, 1500); ++ ++ /* Frequency was not detected, use default SR calibration value */ ++ if (!fm_out) { ++ srctrl = AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION; ++ dev_err(priv->dev, "Frequency not detected, using default SR calibration.\n"); ++ } else { ++ /* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */ ++ srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF; ++ srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out; ++ srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR); ++ dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl); ++ } ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, ++ AIROHA_USB_PHY_USB20_HSTX_SRCTRL, ++ FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl)); ++} ++ ++static void airoha_usb_phy_u2_init(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, ++ AIROHA_USB_PHY_USB20_FS_CR, ++ AIROHA_USB_PHY_USB20_FS_CR_MIN); ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, ++ AIROHA_USB_PHY_USB20_FS_SR, ++ AIROHA_USB_PHY_USB20_FS_SR_NORMAL); ++ ++ /* FIXME: evaluate if needed */ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_SQTH, ++ AIROHA_USB_PHY_USB20_SQTH_130); ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_DISCTH, ++ AIROHA_USB_PHY_USB20_DISCTH_600); ++ ++ /* Enable the USB port and then disable after calibration */ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_BC11_SW_EN); ++ ++ airoha_usb_phy_u2_slew_rate_calibration(priv); ++ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_BC11_SW_EN); ++ ++ usleep_range(1000, 1500); ++} ++ ++/* ++ * USB 3.0 mode can only work if USB serdes is correctly set. ++ * This is validated in xLate function. ++ */ ++static void airoha_usb_phy_u3_init(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8, ++ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, ++ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32); ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6, ++ AIROHA_USB_PHY_SSUSB_CDR_RESERVE, ++ FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe)); ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0, ++ AIROHA_USB_PHY_SSUSB_BG_DIV, ++ AIROHA_USB_PHY_SSUSB_BG_DIV_4); ++ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1, ++ FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600)); ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19, ++ AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, ++ FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43)); ++} ++ ++static int airoha_usb_phy_init(struct phy *phy) ++{ ++ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); ++ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); ++ ++ switch (instance->type) { ++ case PHY_TYPE_USB2: ++ airoha_usb_phy_u2_init(priv); ++ break; ++ case PHY_TYPE_USB3: ++ if (phy_get_mode(phy) == PHY_MODE_PCIE) ++ return 0; ++ ++ airoha_usb_phy_u3_init(priv); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u2_power_on(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_BC11_SW_EN); ++ ++ usleep_range(1000, 1500); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u3_power_on(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, ++ AIROHA_USB_PHY_SSUSB_IP_SW_RST | ++ AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN | ++ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST | ++ AIROHA_USB_PHY_SSUSB_SW_RST); ++ ++ usleep_range(1000, 1500); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_power_on(struct phy *phy) ++{ ++ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); ++ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); ++ ++ switch (instance->type) { ++ case PHY_TYPE_USB2: ++ airoha_usb_phy_u2_power_on(priv); ++ break; ++ case PHY_TYPE_USB3: ++ if (phy_get_mode(phy) == PHY_MODE_PCIE) ++ return 0; ++ ++ airoha_usb_phy_u3_power_on(priv); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u2_power_off(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, ++ AIROHA_USB_PHY_USB20_BC11_SW_EN); ++ ++ usleep_range(1000, 1500); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u3_power_off(struct airoha_usb_phy_priv *priv) ++{ ++ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, ++ AIROHA_USB_PHY_SSUSB_IP_SW_RST | ++ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST); ++ ++ usleep_range(1000, 1500); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_power_off(struct phy *phy) ++{ ++ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); ++ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); ++ ++ switch (instance->type) { ++ case PHY_TYPE_USB2: ++ airoha_usb_phy_u2_power_off(priv); ++ break; ++ case PHY_TYPE_USB3: ++ if (phy_get_mode(phy) == PHY_MODE_PCIE) ++ return 0; ++ ++ airoha_usb_phy_u3_power_off(priv); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u2_set_mode(struct airoha_usb_phy_priv *priv, ++ enum phy_mode mode) ++{ ++ u32 val; ++ ++ /* ++ * For Device and Host mode, enable force IDDIG. ++ * For Device set IDDIG, for Host clear IDDIG. ++ * For OTG disable force and clear IDDIG bit while at it. ++ */ ++ switch (mode) { ++ case PHY_MODE_USB_DEVICE: ++ val = AIROHA_USB_PHY_IDDIG; ++ break; ++ case PHY_MODE_USB_HOST: ++ val = AIROHA_USB_PHY_FORCE_IDDIG | ++ AIROHA_USB_PHY_FORCE_IDDIG; ++ break; ++ case PHY_MODE_USB_OTG: ++ val = 0; ++ break; ++ default: ++ return 0; ++ } ++ ++ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1, ++ AIROHA_USB_PHY_FORCE_IDDIG | ++ AIROHA_USB_PHY_IDDIG, val); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_u3_set_mode(struct airoha_usb_phy_priv *priv, ++ enum phy_mode mode) ++{ ++ u32 sel; ++ ++ /* Only USB2 supports PCIe mode */ ++ if (mode == PHY_MODE_PCIE && ++ priv->serdes_port != AIROHA_SCU_SERDES_USB2) ++ return -EINVAL; ++ ++ if (mode == PHY_MODE_PCIE) ++ sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE; ++ else ++ sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_USB; ++ ++ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, ++ AIROHA_SCU_SSTR_USB_PCIE_SEL, sel); ++ ++ return 0; ++} ++ ++static int airoha_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) ++{ ++ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); ++ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); ++ ++ switch (instance->type) { ++ case PHY_TYPE_USB2: ++ return airoha_usb_phy_u2_set_mode(priv, mode); ++ case PHY_TYPE_USB3: ++ return airoha_usb_phy_u3_set_mode(priv, mode); ++ default: ++ return 0; ++ } ++} ++ ++static struct phy *airoha_usb_phy_xlate(struct device *dev, ++ struct of_phandle_args *args) ++{ ++ struct airoha_usb_phy_priv *priv = dev_get_drvdata(dev); ++ struct airoha_usb_phy_instance *instance = NULL; ++ unsigned int index, phy_type; ++ ++ if (args->args_count != 1) { ++ dev_err(dev, "invalid number of cells in 'phy' property\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ phy_type = args->args[0]; ++ if (!(phy_type == PHY_TYPE_USB2 || phy_type == PHY_TYPE_USB3)) { ++ dev_err(dev, "unsupported device type: %d\n", phy_type); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ for (index = 0; index < AIROHA_PHY_USB_MAX; index++) ++ if (priv->phys[index] && ++ phy_type == priv->phys[index]->type) { ++ instance = priv->phys[index]; ++ break; ++ } ++ ++ if (!instance) { ++ dev_err(dev, "failed to find appropriate phy\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ return instance->phy; ++} ++ ++static const struct phy_ops airoha_phy = { ++ .init = airoha_usb_phy_init, ++ .power_on = airoha_usb_phy_power_on, ++ .power_off = airoha_usb_phy_power_off, ++ .set_mode = airoha_usb_phy_set_mode, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct regmap_config airoha_usb_phy_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ ++static int airoha_usb_phy_probe(struct platform_device *pdev) ++{ ++ struct phy_provider *phy_provider; ++ struct airoha_usb_phy_priv *priv; ++ struct device *dev = &pdev->dev; ++ unsigned int index; ++ void *base; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->dev = dev; ++ ++ ret = of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel", ++ &priv->monclk_sel); ++ if (ret) ++ return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for USB PHY calibration.\n"); ++ ++ if (priv->monclk_sel > 3) ++ return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable on the SoC.\n"); ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ priv->regmap = devm_regmap_init_mmio(dev, base, &airoha_usb_phy_regmap_config); ++ if (IS_ERR(priv->regmap)) ++ return PTR_ERR(priv->regmap); ++ ++ platform_set_drvdata(pdev, priv); ++ ++ for (index = 0; index < AIROHA_PHY_USB_MAX; index++) { ++ enum airoha_usb_phy_instance_type phy_type; ++ struct airoha_usb_phy_instance *instance; ++ ++ switch (index) { ++ case AIROHA_PHY_USB2: ++ phy_type = PHY_TYPE_USB2; ++ break; ++ case AIROHA_PHY_USB3: ++ phy_type = PHY_TYPE_USB3; ++ break; ++ } ++ ++ /* Skip registering USB3 instance if not supported */ ++ if (phy_type == PHY_TYPE_USB3) { ++ ret = of_property_read_u32(dev->of_node, "airoha,serdes-port", ++ &priv->serdes_port); ++ if (ret) ++ continue; ++ ++ /* With Serdes Port property, SCU is required */ ++ priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "airoha,scu"); ++ if (IS_ERR(priv->scu)) ++ return dev_err_probe(dev, PTR_ERR(priv->scu), "failed to get SCU syscon.\n"); ++ } ++ ++ instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); ++ if (!instance) ++ return -ENOMEM; ++ ++ instance->type = phy_type; ++ priv->phys[index] = instance; ++ ++ instance->phy = devm_phy_create(dev, NULL, &airoha_phy); ++ if (IS_ERR(instance->phy)) ++ return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n"); ++ ++ phy_set_drvdata(instance->phy, instance); ++ } ++ ++ phy_provider = devm_of_phy_provider_register(&pdev->dev, airoha_usb_phy_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static const struct of_device_id airoha_phy_id_table[] = { ++ { .compatible = "airoha,an7581-usb-phy" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, airoha_phy_id_table); ++ ++static struct platform_driver airoha_usb_driver = { ++ .probe = airoha_usb_phy_probe, ++ .driver = { ++ .name = "airoha-usb-phy", ++ .of_match_table = airoha_phy_id_table, ++ }, ++}; ++ ++module_platform_driver(airoha_usb_driver); ++ ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Airoha USB PHY driver"); diff --git a/target/linux/airoha/patches-6.6/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch b/target/linux/airoha/patches-6.6/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch new file mode 100644 index 0000000000..3756f7643a --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch @@ -0,0 +1,25 @@ +From 3d3a406dea89b789dfb550bd05d0eba5ae926755 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 7 Feb 2025 14:17:06 +0100 +Subject: [PATCH 08/10] usb: host: add ARCH_AIROHA in XHCI MTK dependency + +Airoha SoC use the same register map a logic of the Mediatek xHCI +driver, hence add it to the dependency list to permit compilation also +on this ARCH. + +Signed-off-by: Christian Marangi +--- + drivers/usb/host/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -71,7 +71,7 @@ config USB_XHCI_HISTB + config USB_XHCI_MTK + tristate "xHCI support for MediaTek SoCs" + select MFD_SYSCON +- depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST ++ depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || ARCH_AIROHA || COMPILE_TEST + help + Say 'Y' to enable the support for the xHCI host controller + found in MediaTek SoCs. diff --git a/target/linux/airoha/patches-6.6/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch b/target/linux/airoha/patches-6.6/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch new file mode 100644 index 0000000000..19d168db64 --- /dev/null +++ b/target/linux/airoha/patches-6.6/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch @@ -0,0 +1,34 @@ +From 112c6ea7ac356dab16e11084f2183e653a289e91 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 28 Oct 2025 12:35:41 +0100 +Subject: [PATCH 10/10] PCI: mediatek-gen3: set PHY mode for Airoha EN7581 + +For the Airoha EN7581 SoC, the 3rd PCIe line is attached to a special +PHY that can be both used for USB 3.0 operation or PCIe. + +Configure the PHY for PCIe operation before init it to correctly +configure the SCU Serdes register. + +This permits correct functionality and enumeration of PCIe devices on +the 3rd PCIe line present on the SoC. + +Signed-off-by: Christian Marangi +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -925,6 +925,12 @@ static int mtk_pcie_en7581_power_up(stru + size = lower_32_bits(resource_size(entry->res)); + regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); + ++ err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); ++ if (err) { ++ dev_err(dev, "failed to set PHY mode\n"); ++ return err; ++ } ++ + /* + * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 + * requires PHY initialization and power-on before PHY reset deassert. From 64ad16e3ed0fb6a966ca0e428b06e493e95bbbbe Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 28 Oct 2025 13:16:18 +0100 Subject: [PATCH 061/128] airoha: an7581: add USB nodes Add USB nodes to AN7581 DTSI, disabled by default. Signed-off-by: Christian Marangi (cherry picked from commit 3db72b71d1929e27068bf927e8e09200e190464d) --- target/linux/airoha/dts/an7581.dtsi | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 46c8480111..7956d1de3b 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -503,6 +506,52 @@ interrupts = ; }; + usb0: usb@1fab0000 { + compatible = "mediatek,mtk-xhci"; + reg = <0x0 0x1fab0000 0x0 0x3e00>, + <0x0 0x1fab3e00 0x0 0x100>; + reg-names = "mac", "ippc"; + interrupts = ; + + phys = <&usb0_phy PHY_TYPE_USB2>, <&usb0_phy PHY_TYPE_USB3>; + + status = "disabled"; + }; + + usb0_phy: phy@1fac0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x0 0x1fac0000 0x0 0x10000>; + + airoha,scu = <&scuclk>; + airoha,usb2-monitor-clk-sel = ; + airoha,serdes-port = ; + + #phy-cells = <1>; + }; + + usb1: usb@1fad0000 { + compatible = "mediatek,mtk-xhci"; + reg = <0x0 0x1fad0000 0x0 0x3e00>, + <0x0 0x1fad3e00 0x0 0x100>; + reg-names = "mac", "ippc"; + interrupts = ; + + phys = <&usb1_phy PHY_TYPE_USB2>, <&usb1_phy PHY_TYPE_USB3>; + + status = "disabled"; + }; + + usb1_phy: phy@1fae0000 { + compatible = "airoha,an7581-usb-phy"; + reg = <0x0 0x1fae0000 0x0 0x10000>; + + airoha,scu = <&scuclk>; + airoha,usb2-monitor-clk-sel = ; + airoha,serdes-port = ; + + #phy-cells = <1>; + }; + crypto@1e004000 { compatible = "inside-secure,safexcel-eip93ies"; reg = <0x0 0x1fb70000 0x0 0x1000>; From b5a66740c28af721cfbea7eb6edfc275cfec1107 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 28 Oct 2025 13:17:38 +0100 Subject: [PATCH 062/128] airoha: an7581: correctly attach the USB2 PHY for 3rd PCIe line The 3rd PCIe line use the USB2 serdes for PCIe operation. Correctly set it to the DT node so that the mode can be correctly set in the PHY driver. Signed-off-by: Christian Marangi (cherry picked from commit 3ba92e0e3268c07859859968368602d2dc758148) --- target/linux/airoha/dts/an7581.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 7956d1de3b..880063341f 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -780,7 +780,7 @@ clocks = <&scuclk EN7523_CLK_PCIE>; clock-names = "sys-ck"; - phys = <&pciephy>; + phys = <&usb1_phy PHY_TYPE_USB3>; phy-names = "pcie-phy"; ranges = <0x02000000 0 0x28000000 0x0 0x28000000 0 0x4000000>; From e905c45b059b4058bf2df2bd433de813b1248377 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 28 Oct 2025 13:19:24 +0100 Subject: [PATCH 063/128] airoha: an7581: enable USB node on eMMC RFB board Enable USB node on eMMC RFB board and disable USB2 3.0 port to make the 3rd PCIe line correctly work. This is needed to prevent the xHCI driver to mess with PCIe by configuring the USB2 3.0 port. Port will still be detected but won't be configureed by the driver and won't have PHY to configure for. Signed-off-by: Christian Marangi (cherry picked from commit 6d51c80424b93b6aebacf4c47ad74597e450c8bd) --- target/linux/airoha/dts/an7581-evb-emmc.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/target/linux/airoha/dts/an7581-evb-emmc.dts b/target/linux/airoha/dts/an7581-evb-emmc.dts index b814834c28..25d9b87af0 100644 --- a/target/linux/airoha/dts/an7581-evb-emmc.dts +++ b/target/linux/airoha/dts/an7581-evb-emmc.dts @@ -106,6 +106,17 @@ }; }; +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; + + mediatek,u3p-dis-msk = <0x1>; + phys = <&usb1_phy PHY_TYPE_USB2>; +}; + &mmc0 { pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&mmc_pins>; From 9d218f08536c02b019dcbdf50ea7a6bf80904516 Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Mon, 20 Oct 2025 23:10:19 +0800 Subject: [PATCH 064/128] airoha: adjust and default the loadaddr Similar to e92b153e99 ("mediatek: introduce KERNEL_LOADADDR to Device/Default template"), let's move the default loadaddr to Device/Default. What's more, use 0x80200000 instead of the SDK default value 0x80088000 to avoid the following error which may overwrite TZ memory and cause crash: [ 0.000000] [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader! [ 0.000000] OF: reserved mem: Reserved memory: failed to reserve memory for node 'atf@80000000': base 0x0000000080000000, size 2 MiB Signed-off-by: Ziyang Huang [ fix spelling mistake ] Link: https://github.com/openwrt/openwrt/pull/20470 (cherry picked from commit fed2d313436e76eb1c1d7ac9f49e09dc1e611008) [ fix conflict error ] Signed-off-by: Christian Marangi --- target/linux/airoha/image/Makefile | 5 +++++ target/linux/airoha/image/an7581.mk | 1 - target/linux/airoha/image/en7523.mk | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/target/linux/airoha/image/Makefile b/target/linux/airoha/image/Makefile index f3547ae330..542a61db2a 100644 --- a/target/linux/airoha/image/Makefile +++ b/target/linux/airoha/image/Makefile @@ -1,6 +1,10 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk +loadaddr-$(CONFIG_TARGET_airoha_an7581) := 0x80200000 +loadaddr-$(CONFIG_TARGET_airoha_an7583) := 0x80200000 +loadaddr-$(CONFIG_TARGET_airoha_en7523) := 0x80200000 + # default all platform image(fit) build define Device/Default PROFILES = Default $$(DEVICE_NAME) @@ -9,6 +13,7 @@ define Device/Default fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb KERNEL_INITRAMFS = kernel-bin | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd + KERNEL_LOADADDR = $(loadaddr-y) FILESYSTEMS := squashfs DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1))) DEVICE_DTS_DIR := ../dts diff --git a/target/linux/airoha/image/an7581.mk b/target/linux/airoha/image/an7581.mk index fcd19e413c..497c7acacf 100644 --- a/target/linux/airoha/image/an7581.mk +++ b/target/linux/airoha/image/an7581.mk @@ -25,7 +25,6 @@ define Device/airoha_an7581-evb DEVICE_PACKAGES := kmod-leds-pwm kmod-i2c-an7581 kmod-pwm-airoha kmod-input-gpio-keys-polled DEVICE_DTS := an7581-evb DEVICE_DTS_CONFIG := config@1 - KERNEL_LOADADDR := 0x80088000 IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata ARTIFACT/preloader.bin := an7581-preloader rfb ARTIFACT/bl31-uboot.fip := an7581-bl31-uboot rfb diff --git a/target/linux/airoha/image/en7523.mk b/target/linux/airoha/image/en7523.mk index e116ce9255..9cbe7594df 100644 --- a/target/linux/airoha/image/en7523.mk +++ b/target/linux/airoha/image/en7523.mk @@ -1,5 +1,3 @@ -KERNEL_LOADADDR := 0x80208000 - define Target/Description Build firmware images for Airoha EN7523 ARM based boards. endef From dcced671e2a7124fe51875e87a8495109dab2f30 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 26 Oct 2025 17:46:42 +0100 Subject: [PATCH 065/128] airoha: Add missing board files for EN7581 Add missing leds and network board files for EN7581 SoC. Signed-off-by: Lorenzo Bianconi [ drop reference to downstream 10g RFB board ] Link: https://github.com/openwrt/openwrt/pull/20556 Signed-off-by: Christian Marangi (cherry picked from commit 738eacb9a00dc813e0c81691f1ca757de0e01e6b) --- .../an7581/base-files/etc/board.d/01_leds | 20 +++++++++++++ .../an7581/base-files/etc/board.d/02_network | 28 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 target/linux/airoha/an7581/base-files/etc/board.d/01_leds create mode 100644 target/linux/airoha/an7581/base-files/etc/board.d/02_network diff --git a/target/linux/airoha/an7581/base-files/etc/board.d/01_leds b/target/linux/airoha/an7581/base-files/etc/board.d/01_leds new file mode 100644 index 0000000000..2eac5c6f15 --- /dev/null +++ b/target/linux/airoha/an7581/base-files/etc/board.d/01_leds @@ -0,0 +1,20 @@ +# +# Copyright (C) 2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh + +board_config_update + +board=$(board_name) + +case "$board" in +airoha,an7581-evb) + ucidef_set_led_usbport "usb1" "USB 1" "green:usb-1" "usb1-port1" "usb2-port1" + ucidef_set_led_usbport "usb2" "USB 2" "green:usb-2" "usb3-port1" "usb4-port1" + ;; +esac + +board_config_flush + +exit 0 diff --git a/target/linux/airoha/an7581/base-files/etc/board.d/02_network b/target/linux/airoha/an7581/base-files/etc/board.d/02_network new file mode 100644 index 0000000000..7f03fdc512 --- /dev/null +++ b/target/linux/airoha/an7581/base-files/etc/board.d/02_network @@ -0,0 +1,28 @@ +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# Copyright (c) 2011-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +an7581_setup_interfaces() +{ + local board="$1" + + case "$board" in + airoha,an7581-evb) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth1" + ;; + *) + echo "Unsupported hardware. Network interfaces not initialized" + ;; + esac +} + +board_config_update +board=$(board_name) +an7581_setup_interfaces $board +board_config_flush + +exit 0 From b3e90139ce9d9372fa147f97aedff8ffb7735d0f Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 29 Oct 2025 15:15:53 +0100 Subject: [PATCH 066/128] airoha: backport minor fixes for NPU handling Backport upstream minor fixed for NPU handling that might result in kernel panic or handle leak. (cherry picked from commit 83eacb6ab0596634131aa90510e52159cef08b93) [ fix conflict errors ] Signed-off-by: Christian Marangi --- ...ha-Fix-a-copy-and-paste-bug-in-probe.patch | 37 +++++++++++++++++ ...id-of-dma_sync_single_for_device-in-.patch | 40 ++++++++++++++++++ ...otential-use-after-free-in-airoha_np.patch | 41 +++++++++++++++++++ ...-airoha-deassert-XSI-line-on-hw-init.patch | 2 +- ...eference-for-SPORT-GDM4-in-qdma_get_.patch | 2 +- ...nitial-fixup-for-GDM3-4-port-support.patch | 2 +- ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 4 +- ...iroha-add-phylink-support-for-GDM2-4.patch | 14 +++---- ...t-airoha-define-sport-value-for-GDM3.patch | 2 +- 9 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch create mode 100644 target/linux/airoha/patches-6.6/105-6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch create mode 100644 target/linux/airoha/patches-6.6/106-6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch diff --git a/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch b/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch new file mode 100644 index 0000000000..e87035ec54 --- /dev/null +++ b/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch @@ -0,0 +1,37 @@ +From 05e090620bacf317020f9591cfff8926093380bd Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 24 Oct 2025 14:23:35 +0300 +Subject: [PATCH] net: airoha: Fix a copy and paste bug in probe() + +This code has a copy and paste bug where it accidentally checks "if (err)" +instead of checking if "xsi_rsts" is NULL. Also, as a free bonus, I +changed the allocation from kzalloc() to kcalloc() which is a kernel +hardening measure to protect against integer overflows. + +Fixes: 5863b4e065e2 ("net: airoha: Add airoha_eth_soc_data struct") +Signed-off-by: Dan Carpenter +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/aPtht6y5DRokn9zv@stanley.mountain +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2990,11 +2990,11 @@ static int airoha_probe(struct platform_ + return err; + } + +- xsi_rsts = devm_kzalloc(eth->dev, +- eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), ++ xsi_rsts = devm_kcalloc(eth->dev, ++ eth->soc->num_xsi_rsts, sizeof(*xsi_rsts), + GFP_KERNEL); +- if (err) +- return err; ++ if (!xsi_rsts) ++ return -ENOMEM; + + eth->xsi_rsts = xsi_rsts; + for (i = 0; i < eth->soc->num_xsi_rsts; i++) diff --git a/target/linux/airoha/patches-6.6/105-6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch b/target/linux/airoha/patches-6.6/105-6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch new file mode 100644 index 0000000000..0c690b0d65 --- /dev/null +++ b/target/linux/airoha/patches-6.6/105-6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch @@ -0,0 +1,40 @@ +From 4cd9d227ab838b3590c4b27e3707b8c3ef14d7e9 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 25 Jun 2025 16:43:15 +0200 +Subject: [PATCH] net: airoha: Get rid of dma_sync_single_for_device() in + airoha_qdma_fill_rx_queue() + +Since the page_pool for airoha_eth driver is created with +PP_FLAG_DMA_SYNC_DEV flag, we do not need to sync_for_device each page +received from the pool since it is already done by the page_pool codebase. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Alexander Lobakin +Link: https://patch.msgid.link/20250625-airoha-sync-for-device-v1-1-923741deaabf@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -539,9 +539,7 @@ static int airoha_fe_init(struct airoha_ + + static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) + { +- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); + struct airoha_qdma *qdma = q->qdma; +- struct airoha_eth *eth = qdma->eth; + int qid = q - &qdma->q_rx[0]; + int nframes = 0; + +@@ -565,9 +563,6 @@ static int airoha_qdma_fill_rx_queue(str + e->dma_addr = page_pool_get_dma_addr(page) + offset; + e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); + +- dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, +- dir); +- + val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); + WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); + WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); diff --git a/target/linux/airoha/patches-6.6/106-6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch b/target/linux/airoha/patches-6.6/106-6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch new file mode 100644 index 0000000000..251395c751 --- /dev/null +++ b/target/linux/airoha/patches-6.6/106-6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch @@ -0,0 +1,41 @@ +From 3cd582e7d0787506990ef0180405eb6224fa90a6 Mon Sep 17 00:00:00 2001 +From: Alok Tiwari +Date: Tue, 15 Jul 2025 07:30:58 -0700 +Subject: [PATCH] net: airoha: fix potential use-after-free in airoha_npu_get() + +np->name was being used after calling of_node_put(np), which +releases the node and can lead to a use-after-free bug. +Previously, of_node_put(np) was called unconditionally after +of_find_device_by_node(np), which could result in a use-after-free if +pdev is NULL. + +This patch moves of_node_put(np) after the error check to ensure +the node is only released after both the error and success cases +are handled appropriately, preventing potential resource issues. + +Fixes: 23290c7bc190 ("net: airoha: Introduce Airoha NPU support") +Signed-off-by: Alok Tiwari +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250715143102.3458286-1-alok.a.tiwari@oracle.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -567,12 +567,13 @@ struct airoha_npu *airoha_npu_get(struct + return ERR_PTR(-ENODEV); + + pdev = of_find_device_by_node(np); +- of_node_put(np); + + if (!pdev) { + dev_err(dev, "cannot find device node %s\n", np->name); ++ of_node_put(np); + return ERR_PTR(-ENODEV); + } ++ of_node_put(np); + + if (!try_module_get(THIS_MODULE)) { + dev_err(dev, "failed to get the device driver module\n"); diff --git a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch index 85af65e3b4..d7e312dfcf 100644 --- a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1388,6 +1388,10 @@ static int airoha_hw_init(struct platfor +@@ -1383,6 +1383,10 @@ static int airoha_hw_init(struct platfor if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch index cf6520dd53..2407246861 100644 --- a/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch +++ b/target/linux/airoha/patches-6.6/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch @@ -16,7 +16,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -593,8 +593,11 @@ static int airoha_qdma_get_gdm_port(stru +@@ -588,8 +588,11 @@ static int airoha_qdma_get_gdm_port(stru sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); switch (sport) { diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index f56e3b9356..7b395bfcb7 100644 --- a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi airoha_fe_crsn_qsel_init(eth); -@@ -1630,7 +1632,8 @@ static int airoha_dev_open(struct net_de +@@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index a8a9e64802..508ae97154 100644 --- a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3100,7 +3100,6 @@ static void airoha_remove(struct platfor +@@ -3095,7 +3095,6 @@ static void airoha_remove(struct platfor } static const char * const en7581_xsi_rsts_names[] = { @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi "hsi0-mac", "hsi1-mac", "hsi-mac", -@@ -3132,7 +3131,6 @@ static int airoha_en7581_get_src_port_id +@@ -3127,7 +3126,6 @@ static int airoha_en7581_get_src_port_id } static const char * const an7583_xsi_rsts_names[] = { diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index eb6b249b21..8ce66b706a 100644 --- a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { struct airoha_eth *eth = port->qdma->eth; -@@ -1627,6 +1633,17 @@ static int airoha_dev_open(struct net_de +@@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); if (err) -@@ -1680,6 +1697,11 @@ static int airoha_dev_stop(struct net_de +@@ -1675,6 +1692,11 @@ static int airoha_dev_stop(struct net_de } } @@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi return 0; } -@@ -2828,6 +2850,20 @@ static const struct ethtool_ops airoha_e +@@ -2823,6 +2845,20 @@ static const struct ethtool_ops airoha_e .get_link = ethtool_op_get_link, }; @@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { int i; -@@ -2872,6 +2908,99 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2867,6 +2903,99 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { -@@ -2950,6 +3079,12 @@ static int airoha_alloc_gdm_port(struct +@@ -2945,6 +3074,12 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3065,6 +3200,10 @@ error_hw_cleanup: +@@ -3060,6 +3195,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3092,6 +3231,10 @@ static void airoha_remove(struct platfor +@@ -3087,6 +3226,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); diff --git a/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch index 5270c26e99..db0e9b4f48 100644 --- a/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch +++ b/target/linux/airoha/patches-6.6/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch @@ -14,7 +14,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -604,6 +604,9 @@ static int airoha_qdma_get_gdm_port(stru +@@ -599,6 +599,9 @@ static int airoha_qdma_get_gdm_port(stru case 0x18: port = 3; /* GDM4 */ break; From 81929a31af406e2b5926b46865a5f207579fa32f Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 4 Nov 2025 20:40:15 +0100 Subject: [PATCH 067/128] airoha: replace PWM patch with upstream version Replace Airoha AN7581 PWM patch with upstream version and add kernel version tag. (cherry picked from commit 2352de96c1c2fea34d31da24f8cbfc2faf6d820a) [ fix conflict error ] Signed-off-by: Christian Marangi --- ...wm-airoha-Add-support-for-EN7581-SoC.patch | 689 ++++++++++++++++++ ...wm-airoha-Add-support-for-EN7581-SoC.patch | 439 ----------- 2 files changed, 689 insertions(+), 439 deletions(-) create mode 100644 target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch delete mode 100644 target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch diff --git a/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch new file mode 100644 index 0000000000..253fa37913 --- /dev/null +++ b/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch @@ -0,0 +1,689 @@ +From 61d7c2f94d391594de08d8a52a7c2630d2f3d263 Mon Sep 17 00:00:00 2001 +From: Benjamin Larsson +Date: Mon, 13 Oct 2025 12:34:03 +0200 +Subject: [PATCH] pwm: airoha: Add support for EN7581 SoC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce driver for PWM module available on EN7581 SoC. + +Limitations: +- Only 8 concurrent waveform generators are available for 8 combinations of + duty_cycle and period. Waveform generators are shared between 16 GPIO + pins and 17 SIPO GPIO pins. +- Supports only normal polarity. +- On configuration the currently running period is completed. +- Minimum supported period is 4 ms +- Maximum supported period is 1s + +Signed-off-by: Benjamin Larsson +Reviewed-by: AngeloGioacchino Del Regno +Co-developed-by: Lorenzo Bianconi +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andy Shevchenko +Co-developed-by: Christian Marangi +Signed-off-by: Christian Marangi +Link: https://patch.msgid.link/20251013103408.14724-1-ansuelsmth@gmail.com +Signed-off-by: Uwe Kleine-König +--- + drivers/pwm/Kconfig | 10 + + drivers/pwm/Makefile | 1 + + drivers/pwm/pwm-airoha.c | 622 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 633 insertions(+) + create mode 100644 drivers/pwm/pwm-airoha.c + +--- a/drivers/pwm/Kconfig ++++ b/drivers/pwm/Kconfig +@@ -54,6 +54,16 @@ config PWM_ADP5585 + This option enables support for the PWM function found in the Analog + Devices ADP5585. + ++config PWM_AIROHA ++ tristate "Airoha PWM support" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ select REGMAP_MMIO ++ help ++ Generic PWM framework driver for Airoha SoC. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called pwm-airoha. ++ + config PWM_APPLE + tristate "Apple SoC PWM support" + depends on ARCH_APPLE || COMPILE_TEST +--- a/drivers/pwm/Makefile ++++ b/drivers/pwm/Makefile +@@ -2,6 +2,7 @@ + obj-$(CONFIG_PWM) += core.o + obj-$(CONFIG_PWM_SYSFS) += sysfs.o + obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o ++obj-$(CONFIG_PWM_AIROHA) += pwm-airoha.o + obj-$(CONFIG_PWM_APPLE) += pwm-apple.o + obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o + obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o +--- /dev/null ++++ b/drivers/pwm/pwm-airoha.c +@@ -0,0 +1,622 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright 2022 Markus Gothe ++ * Copyright 2025 Christian Marangi ++ * ++ * Limitations: ++ * - Only 8 concurrent waveform generators are available for 8 combinations of ++ * duty_cycle and period. Waveform generators are shared between 16 GPIO ++ * pins and 17 SIPO GPIO pins. ++ * - Supports only normal polarity. ++ * - On configuration the currently running period is completed. ++ * - Minimum supported period is 4 ms ++ * - Maximum supported period is 1s ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AIROHA_PWM_REG_SGPIO_LED_DATA 0x0024 ++#define AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG BIT(31) ++#define AIROHA_PWM_SGPIO_LED_DATA_DATA GENMASK(16, 0) ++ ++#define AIROHA_PWM_REG_SGPIO_CLK_DIVR 0x0028 ++#define AIROHA_PWM_SGPIO_CLK_DIVR GENMASK(1, 0) ++#define AIROHA_PWM_SGPIO_CLK_DIVR_32 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 3) ++#define AIROHA_PWM_SGPIO_CLK_DIVR_16 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 2) ++#define AIROHA_PWM_SGPIO_CLK_DIVR_8 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 1) ++#define AIROHA_PWM_SGPIO_CLK_DIVR_4 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 0) ++ ++#define AIROHA_PWM_REG_SGPIO_CLK_DLY 0x002c ++ ++#define AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG 0x0030 ++#define AIROHA_PWM_SERIAL_GPIO_FLASH_MODE BIT(1) ++#define AIROHA_PWM_SERIAL_GPIO_MODE_74HC164 BIT(0) ++ ++#define AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(_n) (0x003c + (4 * (_n))) ++#define AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(_n) (16 * (_n)) ++#define AIROHA_PWM_GPIO_FLASH_PRD_LOW GENMASK(15, 8) ++#define AIROHA_PWM_GPIO_FLASH_PRD_HIGH GENMASK(7, 0) ++ ++#define AIROHA_PWM_REG_GPIO_FLASH_MAP(_n) (0x004c + (4 * (_n))) ++#define AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(_n) (4 * (_n)) ++#define AIROHA_PWM_GPIO_FLASH_EN BIT(3) ++#define AIROHA_PWM_GPIO_FLASH_SET_ID GENMASK(2, 0) ++ ++/* Register map is equal to GPIO flash map */ ++#define AIROHA_PWM_REG_SIPO_FLASH_MAP(_n) (0x0054 + (4 * (_n))) ++ ++#define AIROHA_PWM_REG_CYCLE_CFG_VALUE(_n) (0x0098 + (4 * (_n))) ++#define AIROHA_PWM_REG_CYCLE_CFG_SHIFT(_n) (8 * (_n)) ++#define AIROHA_PWM_WAVE_GEN_CYCLE GENMASK(7, 0) ++ ++/* GPIO/SIPO flash map handles 8 pins in one register */ ++#define AIROHA_PWM_PINS_PER_FLASH_MAP 8 ++/* Cycle(Period) registers handles 4 generators in one 32-bit register */ ++#define AIROHA_PWM_BUCKET_PER_CYCLE_CFG 4 ++/* Flash(Duty) producer handles 2 generators in one 32-bit register */ ++#define AIROHA_PWM_BUCKET_PER_FLASH_PROD 2 ++ ++#define AIROHA_PWM_NUM_BUCKETS 8 ++/* ++ * The first 16 GPIO pins, GPIO0-GPIO15, are mapped into 16 PWM channels, 0-15. ++ * The SIPO GPIO pins are 17 pins which are mapped into 17 PWM channels, 16-32. ++ * However, we've only got 8 concurrent waveform generators and can therefore ++ * only use up to 8 different combinations of duty cycle and period at a time. ++ */ ++#define AIROHA_PWM_NUM_GPIO 16 ++#define AIROHA_PWM_NUM_SIPO 17 ++#define AIROHA_PWM_MAX_CHANNELS (AIROHA_PWM_NUM_GPIO + AIROHA_PWM_NUM_SIPO) ++ ++struct airoha_pwm_bucket { ++ /* Concurrent access protected by PWM core */ ++ int used; ++ u32 period_ticks; ++ u32 duty_ticks; ++}; ++ ++struct airoha_pwm { ++ struct regmap *regmap; ++ ++ DECLARE_BITMAP(initialized, AIROHA_PWM_MAX_CHANNELS); ++ ++ struct airoha_pwm_bucket buckets[AIROHA_PWM_NUM_BUCKETS]; ++ ++ /* Cache bucket used by each pwm channel */ ++ u8 channel_bucket[AIROHA_PWM_MAX_CHANNELS]; ++}; ++ ++/* The PWM hardware supports periods between 4 ms and 1 s */ ++#define AIROHA_PWM_PERIOD_TICK_NS (4 * NSEC_PER_MSEC) ++#define AIROHA_PWM_PERIOD_MAX_NS (1 * NSEC_PER_SEC) ++/* It is represented internally as 1/250 s between 1 and 250. Unit is ticks. */ ++#define AIROHA_PWM_PERIOD_MIN 1 ++#define AIROHA_PWM_PERIOD_MAX 250 ++/* Duty cycle is relative with 255 corresponding to 100% */ ++#define AIROHA_PWM_DUTY_FULL 255 ++ ++static void airoha_pwm_get_flash_map_addr_and_shift(unsigned int hwpwm, ++ u32 *addr, u32 *shift) ++{ ++ unsigned int offset, hwpwm_bit; ++ ++ if (hwpwm >= AIROHA_PWM_NUM_GPIO) { ++ unsigned int sipohwpwm = hwpwm - AIROHA_PWM_NUM_GPIO; ++ ++ offset = sipohwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP; ++ hwpwm_bit = sipohwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP; ++ ++ /* One FLASH_MAP register handles 8 pins */ ++ *shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit); ++ *addr = AIROHA_PWM_REG_SIPO_FLASH_MAP(offset); ++ } else { ++ offset = hwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP; ++ hwpwm_bit = hwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP; ++ ++ /* One FLASH_MAP register handles 8 pins */ ++ *shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit); ++ *addr = AIROHA_PWM_REG_GPIO_FLASH_MAP(offset); ++ } ++} ++ ++static u32 airoha_pwm_get_period_ticks_from_ns(u32 period_ns) ++{ ++ return period_ns / AIROHA_PWM_PERIOD_TICK_NS; ++} ++ ++static u32 airoha_pwm_get_duty_ticks_from_ns(u32 period_ns, u32 duty_ns) ++{ ++ return mul_u64_u32_div(duty_ns, AIROHA_PWM_DUTY_FULL, period_ns); ++} ++ ++static u32 airoha_pwm_get_period_ns_from_ticks(u32 period_tick) ++{ ++ return period_tick * AIROHA_PWM_PERIOD_TICK_NS; ++} ++ ++static u32 airoha_pwm_get_duty_ns_from_ticks(u32 period_tick, u32 duty_tick) ++{ ++ u32 period_ns = period_tick * AIROHA_PWM_PERIOD_TICK_NS; ++ ++ /* ++ * Overflow can't occur in multiplication as duty_tick is just 8 bit ++ * and period_ns is clamped to AIROHA_PWM_PERIOD_MAX_NS and fit in a ++ * u64. ++ */ ++ return DIV_U64_ROUND_UP(duty_tick * period_ns, AIROHA_PWM_DUTY_FULL); ++} ++ ++static int airoha_pwm_get_bucket(struct airoha_pwm *pc, int bucket, ++ u64 *period_ns, u64 *duty_ns) ++{ ++ struct regmap *map = pc->regmap; ++ u32 period_tick, duty_tick; ++ unsigned int offset; ++ u32 shift, val; ++ int ret; ++ ++ offset = bucket / AIROHA_PWM_BUCKET_PER_CYCLE_CFG; ++ shift = bucket % AIROHA_PWM_BUCKET_PER_CYCLE_CFG; ++ shift = AIROHA_PWM_REG_CYCLE_CFG_SHIFT(shift); ++ ++ ret = regmap_read(map, AIROHA_PWM_REG_CYCLE_CFG_VALUE(offset), &val); ++ if (ret) ++ return ret; ++ ++ period_tick = FIELD_GET(AIROHA_PWM_WAVE_GEN_CYCLE, val >> shift); ++ *period_ns = airoha_pwm_get_period_ns_from_ticks(period_tick); ++ ++ offset = bucket / AIROHA_PWM_BUCKET_PER_FLASH_PROD; ++ shift = bucket % AIROHA_PWM_BUCKET_PER_FLASH_PROD; ++ shift = AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(shift); ++ ++ ret = regmap_read(map, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), ++ &val); ++ if (ret) ++ return ret; ++ ++ duty_tick = FIELD_GET(AIROHA_PWM_GPIO_FLASH_PRD_HIGH, val >> shift); ++ *duty_ns = airoha_pwm_get_duty_ns_from_ticks(period_tick, duty_tick); ++ ++ return 0; ++} ++ ++static int airoha_pwm_get_generator(struct airoha_pwm *pc, u32 duty_ticks, ++ u32 period_ticks) ++{ ++ int best = -ENOENT, unused = -ENOENT; ++ u32 duty_ns, best_duty_ns = 0; ++ u32 best_period_ticks = 0; ++ unsigned int i; ++ ++ duty_ns = airoha_pwm_get_duty_ns_from_ticks(period_ticks, duty_ticks); ++ ++ for (i = 0; i < ARRAY_SIZE(pc->buckets); i++) { ++ struct airoha_pwm_bucket *bucket = &pc->buckets[i]; ++ u32 bucket_period_ticks = bucket->period_ticks; ++ u32 bucket_duty_ticks = bucket->duty_ticks; ++ ++ /* If found, save an unused bucket to return it later */ ++ if (!bucket->used) { ++ unused = i; ++ continue; ++ } ++ ++ /* We found a matching bucket, exit early */ ++ if (duty_ticks == bucket_duty_ticks && ++ period_ticks == bucket_period_ticks) ++ return i; ++ ++ /* ++ * Unlike duty cycle zero, which can be handled by ++ * disabling PWM, a generator is needed for full duty ++ * cycle but it can be reused regardless of period ++ */ ++ if (duty_ticks == AIROHA_PWM_DUTY_FULL && ++ bucket_duty_ticks == AIROHA_PWM_DUTY_FULL) ++ return i; ++ ++ /* ++ * With an unused bucket available, skip searching for ++ * a bucket to recycle (closer to the requested period/duty) ++ */ ++ if (unused >= 0) ++ continue; ++ ++ /* Ignore bucket with invalid period */ ++ if (bucket_period_ticks > period_ticks) ++ continue; ++ ++ /* ++ * Search for a bucket closer to the requested period ++ * that has the maximal possible period that isn't bigger ++ * than the requested period. For that period pick the maximal ++ * duty cycle that isn't bigger than the requested duty_cycle. ++ */ ++ if (bucket_period_ticks >= best_period_ticks) { ++ u32 bucket_duty_ns = airoha_pwm_get_duty_ns_from_ticks(bucket_period_ticks, ++ bucket_duty_ticks); ++ ++ /* Skip bucket that goes over the requested duty */ ++ if (bucket_duty_ns > duty_ns) ++ continue; ++ ++ if (bucket_duty_ns > best_duty_ns) { ++ best_period_ticks = bucket_period_ticks; ++ best_duty_ns = bucket_duty_ns; ++ best = i; ++ } ++ } ++ } ++ ++ /* Return an unused bucket or the best one found (if ever) */ ++ return unused >= 0 ? unused : best; ++} ++ ++static void airoha_pwm_release_bucket_config(struct airoha_pwm *pc, ++ unsigned int hwpwm) ++{ ++ int bucket; ++ ++ /* Nothing to clear, PWM channel never used */ ++ if (!test_bit(hwpwm, pc->initialized)) ++ return; ++ ++ bucket = pc->channel_bucket[hwpwm]; ++ pc->buckets[bucket].used--; ++} ++ ++static int airoha_pwm_apply_bucket_config(struct airoha_pwm *pc, unsigned int bucket, ++ u32 duty_ticks, u32 period_ticks) ++{ ++ u32 mask, shift, val; ++ u32 offset; ++ int ret; ++ ++ offset = bucket / AIROHA_PWM_BUCKET_PER_CYCLE_CFG; ++ shift = bucket % AIROHA_PWM_BUCKET_PER_CYCLE_CFG; ++ shift = AIROHA_PWM_REG_CYCLE_CFG_SHIFT(shift); ++ ++ /* Configure frequency divisor */ ++ mask = AIROHA_PWM_WAVE_GEN_CYCLE << shift; ++ val = FIELD_PREP(AIROHA_PWM_WAVE_GEN_CYCLE, period_ticks) << shift; ++ ret = regmap_update_bits(pc->regmap, AIROHA_PWM_REG_CYCLE_CFG_VALUE(offset), ++ mask, val); ++ if (ret) ++ return ret; ++ ++ offset = bucket / AIROHA_PWM_BUCKET_PER_FLASH_PROD; ++ shift = bucket % AIROHA_PWM_BUCKET_PER_FLASH_PROD; ++ shift = AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(shift); ++ ++ /* Configure duty cycle */ ++ mask = AIROHA_PWM_GPIO_FLASH_PRD_HIGH << shift; ++ val = FIELD_PREP(AIROHA_PWM_GPIO_FLASH_PRD_HIGH, duty_ticks) << shift; ++ ret = regmap_update_bits(pc->regmap, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), ++ mask, val); ++ if (ret) ++ return ret; ++ ++ mask = AIROHA_PWM_GPIO_FLASH_PRD_LOW << shift; ++ val = FIELD_PREP(AIROHA_PWM_GPIO_FLASH_PRD_LOW, ++ AIROHA_PWM_DUTY_FULL - duty_ticks) << shift; ++ return regmap_update_bits(pc->regmap, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), ++ mask, val); ++} ++ ++static int airoha_pwm_consume_generator(struct airoha_pwm *pc, ++ u32 duty_ticks, u32 period_ticks, ++ unsigned int hwpwm) ++{ ++ bool config_bucket = false; ++ int bucket, ret; ++ ++ /* ++ * Search for a bucket that already satisfies duty and period ++ * or an unused one. ++ * If not found, -ENOENT is returned. ++ */ ++ bucket = airoha_pwm_get_generator(pc, duty_ticks, period_ticks); ++ if (bucket < 0) ++ return bucket; ++ ++ /* Release previous used bucket (if any) */ ++ airoha_pwm_release_bucket_config(pc, hwpwm); ++ ++ if (!pc->buckets[bucket].used) ++ config_bucket = true; ++ pc->buckets[bucket].used++; ++ ++ if (config_bucket) { ++ pc->buckets[bucket].period_ticks = period_ticks; ++ pc->buckets[bucket].duty_ticks = duty_ticks; ++ ret = airoha_pwm_apply_bucket_config(pc, bucket, ++ duty_ticks, ++ period_ticks); ++ if (ret) { ++ pc->buckets[bucket].used--; ++ return ret; ++ } ++ } ++ ++ return bucket; ++} ++ ++static int airoha_pwm_sipo_init(struct airoha_pwm *pc) ++{ ++ u32 val; ++ int ret; ++ ++ ret = regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, ++ AIROHA_PWM_SERIAL_GPIO_MODE_74HC164); ++ if (ret) ++ return ret; ++ ++ /* Configure shift register chip clock timings, use 32x divisor */ ++ ret = regmap_write(pc->regmap, AIROHA_PWM_REG_SGPIO_CLK_DIVR, ++ AIROHA_PWM_SGPIO_CLK_DIVR_32); ++ if (ret) ++ return ret; ++ ++ /* ++ * Configure the shift register chip clock delay. This needs ++ * to be configured based on the chip characteristics when the SoC ++ * apply the shift register configuration. ++ * This doesn't affect actual PWM operation and is only specific to ++ * the shift register chip. ++ * ++ * For 74HC164 we set it to 0. ++ * ++ * For reference, the actual delay applied is the internal clock ++ * feed to the SGPIO chip + 1. ++ * ++ * From documentation is specified that clock delay should not be ++ * greater than (AIROHA_PWM_REG_SGPIO_CLK_DIVR / 2) - 1. ++ */ ++ ret = regmap_write(pc->regmap, AIROHA_PWM_REG_SGPIO_CLK_DLY, 0); ++ if (ret) ++ return ret; ++ ++ /* ++ * It is necessary to explicitly shift out all zeros after muxing ++ * to initialize the shift register before enabling PWM ++ * mode because in PWM mode SIPO will not start shifting until ++ * it needs to output a non-zero value (bit 31 of led_data ++ * indicates shifting in progress and it must return to zero ++ * before led_data can be written or PWM mode can be set). ++ */ ++ ret = regmap_read_poll_timeout(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, val, ++ !(val & AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG), ++ 10, 200 * USEC_PER_MSEC); ++ if (ret) ++ return ret; ++ ++ ret = regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, ++ AIROHA_PWM_SGPIO_LED_DATA_DATA); ++ if (ret) ++ return ret; ++ ret = regmap_read_poll_timeout(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, val, ++ !(val & AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG), ++ 10, 200 * USEC_PER_MSEC); ++ if (ret) ++ return ret; ++ ++ /* Set SIPO in PWM mode */ ++ return regmap_set_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, ++ AIROHA_PWM_SERIAL_GPIO_FLASH_MODE); ++} ++ ++static int airoha_pwm_config_flash_map(struct airoha_pwm *pc, ++ unsigned int hwpwm, int index) ++{ ++ unsigned int addr; ++ u32 shift; ++ int ret; ++ ++ airoha_pwm_get_flash_map_addr_and_shift(hwpwm, &addr, &shift); ++ ++ /* negative index means disable PWM channel */ ++ if (index < 0) { ++ /* ++ * If we need to disable the PWM, we just put low the ++ * GPIO. No need to setup buckets. ++ */ ++ return regmap_clear_bits(pc->regmap, addr, ++ AIROHA_PWM_GPIO_FLASH_EN << shift); ++ } ++ ++ ret = regmap_update_bits(pc->regmap, addr, ++ AIROHA_PWM_GPIO_FLASH_SET_ID << shift, ++ FIELD_PREP(AIROHA_PWM_GPIO_FLASH_SET_ID, index) << shift); ++ if (ret) ++ return ret; ++ ++ return regmap_set_bits(pc->regmap, addr, AIROHA_PWM_GPIO_FLASH_EN << shift); ++} ++ ++static int airoha_pwm_config(struct airoha_pwm *pc, struct pwm_device *pwm, ++ u32 period_ticks, u32 duty_ticks) ++{ ++ unsigned int hwpwm = pwm->hwpwm; ++ int bucket, ret; ++ ++ bucket = airoha_pwm_consume_generator(pc, duty_ticks, period_ticks, ++ hwpwm); ++ if (bucket < 0) ++ return bucket; ++ ++ ret = airoha_pwm_config_flash_map(pc, hwpwm, bucket); ++ if (ret) { ++ pc->buckets[bucket].used--; ++ return ret; ++ } ++ ++ __set_bit(hwpwm, pc->initialized); ++ pc->channel_bucket[hwpwm] = bucket; ++ ++ /* ++ * SIPO are special GPIO attached to a shift register chip. The handling ++ * of this chip is internal to the SoC that takes care of applying the ++ * values based on the flash map. To apply a new flash map, it's needed ++ * to trigger a refresh on the shift register chip. ++ * If a SIPO is getting configuring , always reinit the shift register ++ * chip to make sure the correct flash map is applied. ++ * Skip reconfiguring the shift register if the related hwpwm ++ * is disabled (as it doesn't need to be mapped). ++ */ ++ if (hwpwm >= AIROHA_PWM_NUM_GPIO) { ++ ret = airoha_pwm_sipo_init(pc); ++ if (ret) { ++ airoha_pwm_release_bucket_config(pc, hwpwm); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static void airoha_pwm_disable(struct airoha_pwm *pc, struct pwm_device *pwm) ++{ ++ /* Disable PWM and release the bucket */ ++ airoha_pwm_config_flash_map(pc, pwm->hwpwm, -1); ++ airoha_pwm_release_bucket_config(pc, pwm->hwpwm); ++ ++ __clear_bit(pwm->hwpwm, pc->initialized); ++ ++ /* If no SIPO is used, disable the shift register chip */ ++ if (!bitmap_read(pc->initialized, ++ AIROHA_PWM_NUM_GPIO, AIROHA_PWM_NUM_SIPO)) ++ regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, ++ AIROHA_PWM_SERIAL_GPIO_FLASH_MODE); ++} ++ ++static int airoha_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ++ const struct pwm_state *state) ++{ ++ struct airoha_pwm *pc = pwmchip_get_drvdata(chip); ++ u32 period_ticks, duty_ticks; ++ u32 period_ns, duty_ns; ++ ++ if (!state->enabled) { ++ airoha_pwm_disable(pc, pwm); ++ return 0; ++ } ++ ++ /* Only normal polarity is supported */ ++ if (state->polarity == PWM_POLARITY_INVERSED) ++ return -EINVAL; ++ ++ /* Exit early if period is less than minimum supported */ ++ if (state->period < AIROHA_PWM_PERIOD_TICK_NS) ++ return -EINVAL; ++ ++ /* Clamp period to MAX supported value */ ++ if (state->period > AIROHA_PWM_PERIOD_MAX_NS) ++ period_ns = AIROHA_PWM_PERIOD_MAX_NS; ++ else ++ period_ns = state->period; ++ ++ /* Validate duty to configured period */ ++ if (state->duty_cycle > period_ns) ++ duty_ns = period_ns; ++ else ++ duty_ns = state->duty_cycle; ++ ++ /* Convert period ns to ticks */ ++ period_ticks = airoha_pwm_get_period_ticks_from_ns(period_ns); ++ /* Convert period ticks to ns again for cosistent duty tick calculation */ ++ period_ns = airoha_pwm_get_period_ns_from_ticks(period_ticks); ++ duty_ticks = airoha_pwm_get_duty_ticks_from_ns(period_ns, duty_ns); ++ ++ return airoha_pwm_config(pc, pwm, period_ticks, duty_ticks); ++} ++ ++static int airoha_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, ++ struct pwm_state *state) ++{ ++ struct airoha_pwm *pc = pwmchip_get_drvdata(chip); ++ int ret, hwpwm = pwm->hwpwm; ++ u32 addr, shift, val; ++ u8 bucket; ++ ++ airoha_pwm_get_flash_map_addr_and_shift(hwpwm, &addr, &shift); ++ ++ ret = regmap_read(pc->regmap, addr, &val); ++ if (ret) ++ return ret; ++ ++ state->enabled = FIELD_GET(AIROHA_PWM_GPIO_FLASH_EN, val >> shift); ++ if (!state->enabled) ++ return 0; ++ ++ state->polarity = PWM_POLARITY_NORMAL; ++ ++ bucket = FIELD_GET(AIROHA_PWM_GPIO_FLASH_SET_ID, val >> shift); ++ return airoha_pwm_get_bucket(pc, bucket, &state->period, ++ &state->duty_cycle); ++} ++ ++static const struct pwm_ops airoha_pwm_ops = { ++ .apply = airoha_pwm_apply, ++ .get_state = airoha_pwm_get_state, ++}; ++ ++static int airoha_pwm_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct airoha_pwm *pc; ++ struct pwm_chip *chip; ++ int ret; ++ ++ chip = devm_pwmchip_alloc(dev, AIROHA_PWM_MAX_CHANNELS, sizeof(*pc)); ++ if (IS_ERR(chip)) ++ return PTR_ERR(chip); ++ ++ chip->ops = &airoha_pwm_ops; ++ pc = pwmchip_get_drvdata(chip); ++ ++ pc->regmap = device_node_to_regmap(dev_of_node(dev->parent)); ++ if (IS_ERR(pc->regmap)) ++ return dev_err_probe(dev, PTR_ERR(pc->regmap), "Failed to get PWM regmap\n"); ++ ++ ret = devm_pwmchip_add(dev, chip); ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id airoha_pwm_of_match[] = { ++ { .compatible = "airoha,en7581-pwm" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, airoha_pwm_of_match); ++ ++static struct platform_driver airoha_pwm_driver = { ++ .driver = { ++ .name = "pwm-airoha", ++ .probe_type = PROBE_PREFER_ASYNCHRONOUS, ++ .of_match_table = airoha_pwm_of_match, ++ }, ++ .probe = airoha_pwm_probe, ++}; ++module_platform_driver(airoha_pwm_driver); ++ ++MODULE_AUTHOR("Lorenzo Bianconi "); ++MODULE_AUTHOR("Markus Gothe "); ++MODULE_AUTHOR("Benjamin Larsson "); ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_DESCRIPTION("Airoha EN7581 PWM driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch deleted file mode 100644 index 0b114d5f53..0000000000 --- a/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch +++ /dev/null @@ -1,439 +0,0 @@ -From 97e4e7b106b08373f90ff1b8c4daf6c2254386a8 Mon Sep 17 00:00:00 2001 -From: Benjamin Larsson -Date: Wed, 23 Oct 2024 01:20:06 +0200 -Subject: [PATCH] pwm: airoha: Add support for EN7581 SoC - -Introduce driver for PWM module available on EN7581 SoC. - -Signed-off-by: Benjamin Larsson -Reviewed-by: AngeloGioacchino Del Regno -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi ---- - drivers/pwm/Kconfig | 11 ++ - drivers/pwm/Makefile | 1 + - drivers/pwm/pwm-airoha.c | 386 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 398 insertions(+) - create mode 100644 drivers/pwm/pwm-airoha.c - ---- a/drivers/pwm/Kconfig -+++ b/drivers/pwm/Kconfig -@@ -51,6 +51,17 @@ config PWM_AB8500 - To compile this driver as a module, choose M here: the module - will be called pwm-ab8500. - -+config PWM_AIROHA -+ tristate "Airoha PWM support" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ depends on OF -+ select REGMAP_MMIO -+ help -+ Generic PWM framework driver for Airoha SoC. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-airoha. -+ - config PWM_APPLE - tristate "Apple SoC PWM support" - depends on ARCH_APPLE || COMPILE_TEST ---- a/drivers/pwm/Makefile -+++ b/drivers/pwm/Makefile -@@ -2,6 +2,7 @@ - obj-$(CONFIG_PWM) += core.o - obj-$(CONFIG_PWM_SYSFS) += sysfs.o - obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o -+obj-$(CONFIG_PWM_AIROHA) += pwm-airoha.o - obj-$(CONFIG_PWM_APPLE) += pwm-apple.o - obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o - obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o ---- /dev/null -+++ b/drivers/pwm/pwm-airoha.c -@@ -0,0 +1,388 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright 2022 Markus Gothe -+ * -+ * Limitations: -+ * - No disable bit, so a disabled PWM is simulated by setting duty_cycle to 0 -+ * - Only 8 concurrent waveform generators are available for 8 combinations of -+ * duty_cycle and period. Waveform generators are shared between 16 GPIO -+ * pins and 17 SIPO GPIO pins. -+ * - Supports only normal polarity. -+ * - On configuration the currently running period is completed. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define REG_SGPIO_LED_DATA 0x0024 -+#define SGPIO_LED_DATA_SHIFT_FLAG BIT(31) -+#define SGPIO_LED_DATA_DATA GENMASK(16, 0) -+ -+#define REG_SGPIO_CLK_DIVR 0x0028 -+#define REG_SGPIO_CLK_DIVR_MASK GENMASK(1, 0) -+#define REG_SGPIO_CLK_DLY 0x002c -+ -+#define REG_SIPO_FLASH_MODE_CFG 0x0030 -+#define SERIAL_GPIO_FLASH_MODE BIT(1) -+#define SERIAL_GPIO_MODE_74HC164 BIT(0) -+ -+#define REG_GPIO_FLASH_PRD_SET(_n) (0x003c + ((_n) << 2)) -+#define GPIO_FLASH_PRD_MASK(_n) GENMASK(15 + ((_n) << 4), ((_n) << 4)) -+ -+#define REG_GPIO_FLASH_MAP(_n) (0x004c + ((_n) << 2)) -+#define GPIO_FLASH_SETID_MASK(_n) GENMASK(2 + ((_n) << 2), ((_n) << 2)) -+#define GPIO_FLASH_EN(_n) BIT(3 + ((_n) << 2)) -+ -+#define REG_SIPO_FLASH_MAP(_n) (0x0054 + ((_n) << 2)) -+ -+#define REG_CYCLE_CFG_VALUE(_n) (0x0098 + ((_n) << 2)) -+#define WAVE_GEN_CYCLE_MASK(_n) GENMASK(7 + ((_n) << 3), ((_n) << 3)) -+ -+#define PWM_NUM_BUCKETS 8 -+ -+struct airoha_pwm_bucket { -+ /* Bitmask of PWM channels using this bucket */ -+ u64 used; -+ u64 period_ns; -+ u64 duty_ns; -+}; -+ -+struct airoha_pwm { -+ struct pwm_chip chip; -+ -+ struct regmap *regmap; -+ -+ struct device_node *np; -+ u64 initialized; -+ -+ struct airoha_pwm_bucket bucket[PWM_NUM_BUCKETS]; -+}; -+ -+/* -+ * The first 16 GPIO pins, GPIO0-GPIO15, are mapped into 16 PWM channels, 0-15. -+ * The SIPO GPIO pins are 17 pins which are mapped into 17 PWM channels, 16-32. -+ * However, we've only got 8 concurrent waveform generators and can therefore -+ * only use up to 8 different combinations of duty cycle and period at a time. -+ */ -+#define PWM_NUM_GPIO 16 -+#define PWM_NUM_SIPO 17 -+ -+/* The PWM hardware supports periods between 4 ms and 1 s */ -+#define PERIOD_MIN_NS (4 * NSEC_PER_MSEC) -+#define PERIOD_MAX_NS (1 * NSEC_PER_SEC) -+/* It is represented internally as 1/250 s between 1 and 250 */ -+#define PERIOD_MIN 1 -+#define PERIOD_MAX 250 -+/* Duty cycle is relative with 255 corresponding to 100% */ -+#define DUTY_FULL 255 -+ -+static int airoha_pwm_get_generator(struct airoha_pwm *pc, u64 duty_ns, -+ u64 period_ns) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(pc->bucket); i++) { -+ if (!pc->bucket[i].used) -+ continue; -+ -+ if (duty_ns == pc->bucket[i].duty_ns && -+ period_ns == pc->bucket[i].period_ns) -+ return i; -+ -+ /* -+ * Unlike duty cycle zero, which can be handled by -+ * disabling PWM, a generator is needed for full duty -+ * cycle but it can be reused regardless of period -+ */ -+ if (duty_ns == DUTY_FULL && pc->bucket[i].duty_ns == DUTY_FULL) -+ return i; -+ } -+ -+ return -1; -+} -+ -+static void airoha_pwm_release_bucket_config(struct airoha_pwm *pc, -+ unsigned int hwpwm) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(pc->bucket); i++) -+ pc->bucket[i].used &= ~BIT_ULL(hwpwm); -+} -+ -+static int airoha_pwm_consume_generator(struct airoha_pwm *pc, -+ u64 duty_ns, u64 period_ns, -+ unsigned int hwpwm) -+{ -+ int id = airoha_pwm_get_generator(pc, duty_ns, period_ns); -+ -+ if (id < 0) { -+ int i; -+ -+ /* find an unused waveform generator */ -+ for (i = 0; i < ARRAY_SIZE(pc->bucket); i++) { -+ if (!(pc->bucket[i].used & ~BIT_ULL(hwpwm))) { -+ id = i; -+ break; -+ } -+ } -+ } -+ -+ if (id >= 0) { -+ airoha_pwm_release_bucket_config(pc, hwpwm); -+ pc->bucket[id].used |= BIT_ULL(hwpwm); -+ pc->bucket[id].period_ns = period_ns; -+ pc->bucket[id].duty_ns = duty_ns; -+ } -+ -+ return id; -+} -+ -+static int airoha_pwm_sipo_init(struct airoha_pwm *pc) -+{ -+ u32 val; -+ -+ if (!(pc->initialized >> PWM_NUM_GPIO)) -+ return 0; -+ -+ regmap_clear_bits(pc->regmap, REG_SIPO_FLASH_MODE_CFG, -+ SERIAL_GPIO_MODE_74HC164); -+ -+ /* Configure shift register timings, use 32x divisor */ -+ regmap_write(pc->regmap, REG_SGPIO_CLK_DIVR, -+ FIELD_PREP(REG_SGPIO_CLK_DIVR_MASK, 0x3)); -+ -+ /* -+ * The actual delay is clock + 1. -+ * Notice that clock delay should not be greater -+ * than (divisor / 2) - 1. -+ * Set to 0 by default. (aka 1) -+ */ -+ regmap_write(pc->regmap, REG_SGPIO_CLK_DLY, 0x0); -+ -+ /* -+ * It it necessary to after muxing explicitly shift out all -+ * zeroes to initialize the shift register before enabling PWM -+ * mode because in PWM mode SIPO will not start shifting until -+ * it needs to output a non-zero value (bit 31 of led_data -+ * indicates shifting in progress and it must return to zero -+ * before led_data can be written or PWM mode can be set) -+ */ -+ if (regmap_read_poll_timeout(pc->regmap, REG_SGPIO_LED_DATA, val, -+ !(val & SGPIO_LED_DATA_SHIFT_FLAG), 10, -+ 200 * USEC_PER_MSEC)) -+ return -ETIMEDOUT; -+ -+ regmap_clear_bits(pc->regmap, REG_SGPIO_LED_DATA, SGPIO_LED_DATA_DATA); -+ if (regmap_read_poll_timeout(pc->regmap, REG_SGPIO_LED_DATA, val, -+ !(val & SGPIO_LED_DATA_SHIFT_FLAG), 10, -+ 200 * USEC_PER_MSEC)) -+ return -ETIMEDOUT; -+ -+ /* Set SIPO in PWM mode */ -+ regmap_set_bits(pc->regmap, REG_SIPO_FLASH_MODE_CFG, -+ SERIAL_GPIO_FLASH_MODE); -+ -+ return 0; -+} -+ -+static void airoha_pwm_calc_bucket_config(struct airoha_pwm *pc, int index, -+ u64 duty_ns, u64 period_ns) -+{ -+ u32 period, duty, mask, val; -+ u64 tmp; -+ -+ tmp = duty_ns * DUTY_FULL; -+ duty = clamp_val(div64_u64(tmp, period_ns), 0, DUTY_FULL); -+ tmp = period_ns * 25; -+ period = clamp_val(div64_u64(tmp, 100000000), PERIOD_MIN, PERIOD_MAX); -+ -+ /* Configure frequency divisor */ -+ mask = WAVE_GEN_CYCLE_MASK(index % 4); -+ val = (period << __ffs(mask)) & mask; -+ regmap_update_bits(pc->regmap, REG_CYCLE_CFG_VALUE(index / 4), -+ mask, val); -+ -+ /* Configure duty cycle */ -+ duty = ((DUTY_FULL - duty) << 8) | duty; -+ mask = GPIO_FLASH_PRD_MASK(index % 2); -+ val = (duty << __ffs(mask)) & mask; -+ regmap_update_bits(pc->regmap, REG_GPIO_FLASH_PRD_SET(index / 2), -+ mask, val); -+} -+ -+static void airoha_pwm_config_flash_map(struct airoha_pwm *pc, -+ unsigned int hwpwm, int index) -+{ -+ u32 addr, mask, val; -+ -+ if (hwpwm < PWM_NUM_GPIO) { -+ addr = REG_GPIO_FLASH_MAP(hwpwm / 8); -+ } else { -+ addr = REG_SIPO_FLASH_MAP(hwpwm / 8); -+ hwpwm -= PWM_NUM_GPIO; -+ } -+ -+ if (index < 0) { -+ /* -+ * Change of waveform takes effect immediately but -+ * disabling has some delay so to prevent glitching -+ * only the enable bit is touched when disabling -+ */ -+ regmap_clear_bits(pc->regmap, addr, GPIO_FLASH_EN(hwpwm % 8)); -+ return; -+ } -+ -+ mask = GPIO_FLASH_SETID_MASK(hwpwm % 8); -+ val = ((index & 7) << __ffs(mask)) & mask; -+ regmap_update_bits(pc->regmap, addr, mask, val); -+ regmap_set_bits(pc->regmap, addr, GPIO_FLASH_EN(hwpwm % 8)); -+} -+ -+static int airoha_pwm_config(struct airoha_pwm *pc, struct pwm_device *pwm, -+ u64 duty_ns, u64 period_ns) -+{ -+ int index = -1; -+ -+ index = airoha_pwm_consume_generator(pc, duty_ns, period_ns, -+ pwm->hwpwm); -+ if (index < 0) -+ return -EBUSY; -+ -+ if (!(pc->initialized & BIT_ULL(pwm->hwpwm)) && -+ pwm->hwpwm >= PWM_NUM_GPIO) -+ airoha_pwm_sipo_init(pc); -+ -+ if (index >= 0) { -+ airoha_pwm_calc_bucket_config(pc, index, duty_ns, period_ns); -+ airoha_pwm_config_flash_map(pc, pwm->hwpwm, index); -+ } else { -+ airoha_pwm_config_flash_map(pc, pwm->hwpwm, index); -+ airoha_pwm_release_bucket_config(pc, pwm->hwpwm); -+ } -+ -+ pc->initialized |= BIT_ULL(pwm->hwpwm); -+ -+ return 0; -+} -+ -+static void airoha_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct airoha_pwm *pc = container_of(chip, struct airoha_pwm, chip); -+ -+ /* Disable PWM and release the waveform */ -+ airoha_pwm_config_flash_map(pc, pwm->hwpwm, -1); -+ airoha_pwm_release_bucket_config(pc, pwm->hwpwm); -+ -+ pc->initialized &= ~BIT_ULL(pwm->hwpwm); -+ if (!(pc->initialized >> PWM_NUM_GPIO)) -+ regmap_clear_bits(pc->regmap, REG_SIPO_FLASH_MODE_CFG, -+ SERIAL_GPIO_FLASH_MODE); -+} -+ -+static int airoha_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, -+ const struct pwm_state *state) -+{ -+ struct airoha_pwm *pc = container_of(chip, struct airoha_pwm, chip); -+ u64 duty = state->enabled ? state->duty_cycle : 0; -+ u64 period = state->period; -+ -+ /* Only normal polarity is supported */ -+ if (state->polarity == PWM_POLARITY_INVERSED) -+ return -EINVAL; -+ -+ if (!state->enabled) { -+ airoha_pwm_disable(chip, pwm); -+ return 0; -+ } -+ -+ if (period < PERIOD_MIN_NS) -+ return -EINVAL; -+ -+ if (period > PERIOD_MAX_NS) -+ period = PERIOD_MAX_NS; -+ -+ return airoha_pwm_config(pc, pwm, duty, period); -+} -+ -+static int airoha_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_state *state) -+{ -+ struct airoha_pwm *pc = container_of(chip, struct airoha_pwm, chip); -+ int i; -+ -+ /* find hwpwm in waveform generator bucket */ -+ for (i = 0; i < ARRAY_SIZE(pc->bucket); i++) { -+ if (pc->bucket[i].used & BIT_ULL(pwm->hwpwm)) { -+ state->enabled = pc->initialized & BIT_ULL(pwm->hwpwm); -+ state->polarity = PWM_POLARITY_NORMAL; -+ state->period = pc->bucket[i].period_ns; -+ state->duty_cycle = pc->bucket[i].duty_ns; -+ break; -+ } -+ } -+ -+ if (i == ARRAY_SIZE(pc->bucket)) -+ state->enabled = false; -+ -+ return 0; -+} -+ -+static const struct pwm_ops airoha_pwm_ops = { -+ .get_state = airoha_pwm_get_state, -+ .apply = airoha_pwm_apply, -+ .owner = THIS_MODULE, -+}; -+ -+static int airoha_pwm_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct airoha_pwm *pc; -+ -+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); -+ if (!pc) -+ return -ENOMEM; -+ -+ pc->np = dev->of_node; -+ pc->chip.dev = dev; -+ pc->chip.ops = &airoha_pwm_ops; -+ pc->chip.npwm = PWM_NUM_GPIO + PWM_NUM_SIPO; -+ -+ pc->regmap = device_node_to_regmap(dev->parent->of_node); -+ if (IS_ERR(pc->regmap)) -+ return PTR_ERR(pc->regmap); -+ -+ return devm_pwmchip_add(&pdev->dev, &pc->chip); -+} -+ -+static const struct of_device_id airoha_pwm_of_match[] = { -+ { .compatible = "airoha,en7581-pwm" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, airoha_pwm_of_match); -+ -+static struct platform_driver airoha_pwm_driver = { -+ .driver = { -+ .name = "pwm-airoha", -+ .of_match_table = airoha_pwm_of_match, -+ }, -+ .probe = airoha_pwm_probe, -+}; -+module_platform_driver(airoha_pwm_driver); -+ -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_AUTHOR("Markus Gothe "); -+MODULE_AUTHOR("Benjamin Larsson "); -+MODULE_DESCRIPTION("Airoha EN7581 PWM driver"); -+MODULE_LICENSE("GPL"); From 2d05923d2ec6733e4cb0d6291b30b5d91be6c0d7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 10 Nov 2025 18:24:16 +0100 Subject: [PATCH 068/128] airona: an7583: fix typo for CONFIG_PHY_AIROHA_USB KConfig flag have an extra whitespace for CONFIG_PHY_AIROHA_USB and value is not ignored. Drop the extra whitespace to correctly ignore the value on kernel compilation. Fixes: c5b12fc02ab1 ("airoha: Introduce support for Airoha AN7583 SoC") Signed-off-by: Christian Marangi (cherry picked from commit eedc7b3b79efed157636312e255b825d507a7182) --- target/linux/airoha/an7583/config-6.6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/airoha/an7583/config-6.6 b/target/linux/airoha/an7583/config-6.6 index 4d137e2202..a8036f6d92 100644 --- a/target/linux/airoha/an7583/config-6.6 +++ b/target/linux/airoha/an7583/config-6.6 @@ -300,7 +300,7 @@ CONFIG_PHYLIB_LEDS=y CONFIG_PHYLINK=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHY_AIROHA_PCIE=y -# CONFIG_PHY_AIROHA_USB is not set +# CONFIG_PHY_AIROHA_USB is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_AIROHA=y # CONFIG_PINCTRL_MT2712 is not set From ae51d0098efe0712a3405fb3c913fe9baaef4473 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 10 Nov 2025 18:29:44 +0100 Subject: [PATCH 069/128] airoha: refresh kernel patches After all the backports, automatically refresh all the patches for Airoha target. Signed-off-by: Christian Marangi --- ...atek-add-Airoha-PHY-ID-to-SoC-driver.patch | 14 +++---- ...oopback-mode-configuration-for-GDM2-.patch | 2 +- ...issing-stats-to-ethtool_eth_mac_stat.patch | 2 +- ...airoha-Add-get_link-ethtool-callback.patch | 2 +- ...into-account-out-of-order-tx-complet.patch | 4 +- ...iroha-Add-airoha_eth_soc_data-struct.patch | 10 ++--- ...alize-airoha_ppe2_is_enabled-routine.patch | 2 +- ...t-default-ppe-cpu-port-in-airoha_dev.patch | 4 +- ...tor-src-port-configuration-in-airhoh.patch | 8 ++-- ...19-net-airoha-Add-AN7583-SoC-support.patch | 16 ++++---- ...ve-code-duplication-in-airoha_regs.h.patch | 2 +- ...ha-Fix-a-copy-and-paste-bug-in-probe.patch | 2 +- ...n-error-handling-path-in-airoha_prob.patch | 2 +- ...wm-airoha-Add-support-for-EN7581-SoC.patch | 6 +-- ...-airoha-deassert-XSI-line-on-hw-init.patch | 2 +- ...nitial-fixup-for-GDM3-4-port-support.patch | 2 +- ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 4 +- ...et-phylink-add-.pcs_link_down-PCS-OP.patch | 10 ++--- ...airoha-add-PCS-driver-for-Airoha-SoC.patch | 2 +- ...iroha-add-phylink-support-for-GDM2-4.patch | 14 +++---- ...-airoha-generalize-pins-group-functi.patch | 40 +++++++++---------- ...airoha-convert-PHY-LED-GPIO-to-macro.patch | 2 +- ...trl-airoha-convert-PWM-GPIO-to-macro.patch | 2 +- ...a-add-support-for-Airoha-AN7583-PINs.patch | 40 +++++++++---------- ...k-move-some-header-to-global-include.patch | 4 +- ...AFE-and-I2S-driver-for-Airoha-AN7581.patch | 4 +- ...Add-documentation-for-Airoha-AN7581-.patch | 8 ++-- ...dd-support-for-Airoha-AN7581-USB-PHY.patch | 2 +- ...-gen3-set-PHY-mode-for-Airoha-EN7581.patch | 2 +- 29 files changed, 107 insertions(+), 107 deletions(-) diff --git a/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch b/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch index 5d8e14aeea..03bb46bb89 100644 --- a/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch +++ b/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch @@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -15,8 +15,9 @@ config MEDIATEK_GE_PHY +@@ -320,8 +320,9 @@ config MEDIATEK_GE_PHY config MEDIATEK_GE_SOC_PHY tristate "MediaTek SoC Ethernet PHYs" @@ -36,9 +36,9 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/phy/mediatek-ge-soc.c +++ b/drivers/net/phy/mediatek-ge-soc.c -@@ -10,8 +10,11 @@ - - #include "mtk.h" +@@ -8,8 +8,11 @@ + #include + #include +#define MTK_PHY_MAX_LEDS 2 + @@ -48,7 +48,7 @@ Signed-off-by: Jakub Kicinski #define MTK_EXT_PAGE_ACCESS 0x1f #define MTK_PHY_PAGE_STANDARD 0x0000 -@@ -1405,6 +1408,53 @@ static int mt7981_phy_probe(struct phy_d +@@ -1502,6 +1505,53 @@ static int mt7981_phy_probe(struct phy_d return mt798x_phy_calibration(phydev); } @@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski static struct phy_driver mtk_socphy_driver[] = { { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), -@@ -1440,6 +1490,17 @@ static struct phy_driver mtk_socphy_driv +@@ -1537,6 +1587,17 @@ static struct phy_driver mtk_socphy_driv .led_hw_control_set = mt798x_phy_led_hw_control_set, .led_hw_control_get = mt798x_phy_led_hw_control_get, }, @@ -120,7 +120,7 @@ Signed-off-by: Jakub Kicinski }; module_phy_driver(mtk_socphy_driver); -@@ -1447,6 +1508,7 @@ module_phy_driver(mtk_socphy_driver); +@@ -1544,6 +1605,7 @@ module_phy_driver(mtk_socphy_driver); static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) }, { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) }, diff --git a/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch b/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch index 5c3fcc0c20..95200a910a 100644 --- a/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch +++ b/target/linux/airoha/patches-6.6/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch @@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1715,7 +1715,9 @@ static void airhoha_set_gdm2_loopback(st +@@ -1716,7 +1716,9 @@ static void airhoha_set_gdm2_loopback(st airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, diff --git a/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch b/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch index 66d72ded83..0ffeb5867d 100644 --- a/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch +++ b/target/linux/airoha/patches-6.6/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2027,8 +2027,12 @@ static void airoha_ethtool_get_mac_stats +@@ -2028,8 +2028,12 @@ static void airoha_ethtool_get_mac_stats airoha_update_hw_stats(port); do { start = u64_stats_fetch_begin(&port->stats.syncp); diff --git a/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch b/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch index 7d78bd6c03..b990297a42 100644 --- a/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch +++ b/target/linux/airoha/patches-6.6/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch @@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2775,6 +2775,7 @@ static const struct ethtool_ops airoha_e +@@ -2776,6 +2776,7 @@ static const struct ethtool_ops airoha_e .get_drvinfo = airoha_ethtool_get_drvinfo, .get_eth_mac_stats = airoha_ethtool_get_mac_stats, .get_rmon_stats = airoha_ethtool_get_rmon_stats, diff --git a/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch b/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch index 46432b2480..4ff6daf033 100644 --- a/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch +++ b/target/linux/airoha/patches-6.6/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch @@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1878,6 +1878,20 @@ static u32 airoha_get_dsa_tag(struct sk_ +@@ -1879,6 +1879,20 @@ static u32 airoha_get_dsa_tag(struct sk_ #endif } @@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, struct net_device *dev) { -@@ -1931,7 +1945,7 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1932,7 +1946,7 @@ static netdev_tx_t airoha_dev_xmit(struc txq = netdev_get_tx_queue(dev, qid); nr_frags = 1 + skb_shinfo(skb)->nr_frags; diff --git a/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch b/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch index 9035e21447..2c94dccb1a 100644 --- a/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch +++ b/target/linux/airoha/patches-6.6/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch @@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1392,8 +1392,7 @@ static int airoha_hw_init(struct platfor +@@ -1393,8 +1393,7 @@ static int airoha_hw_init(struct platfor int err, i; /* disable xsi */ @@ -31,7 +31,7 @@ Signed-off-by: Paolo Abeni if (err) return err; -@@ -2927,6 +2926,7 @@ free_metadata_dst: +@@ -2928,6 +2927,7 @@ free_metadata_dst: static int airoha_probe(struct platform_device *pdev) { @@ -39,7 +39,7 @@ Signed-off-by: Paolo Abeni struct device_node *np; struct airoha_eth *eth; int i, err; -@@ -2935,6 +2935,10 @@ static int airoha_probe(struct platform_ +@@ -2936,6 +2936,10 @@ static int airoha_probe(struct platform_ if (!eth) return -ENOMEM; @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni eth->dev = &pdev->dev; err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); -@@ -2959,13 +2963,18 @@ static int airoha_probe(struct platform_ +@@ -2960,13 +2964,18 @@ static int airoha_probe(struct platform_ return err; } @@ -75,7 +75,7 @@ Signed-off-by: Paolo Abeni eth->xsi_rsts); if (err) { dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); -@@ -3052,8 +3061,23 @@ static void airoha_remove(struct platfor +@@ -3053,8 +3062,23 @@ static void airoha_remove(struct platfor platform_set_drvdata(pdev, NULL); } diff --git a/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch b/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch index e82ce24e4f..cbed7ffc94 100644 --- a/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch +++ b/target/linux/airoha/patches-6.6/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni } /* GMD4 */ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) -@@ -1767,8 +1774,11 @@ static int airoha_dev_init(struct net_de +@@ -1768,8 +1775,11 @@ static int airoha_dev_init(struct net_de airhoha_set_gdm2_loopback(port); fallthrough; case 2: diff --git a/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch b/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch index c6ecbdb829..08bfcaf587 100644 --- a/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch +++ b/target/linux/airoha/patches-6.6/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch @@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni /* enable 1:N vlan action, init vlan table */ airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); -@@ -1761,8 +1742,10 @@ static void airhoha_set_gdm2_loopback(st +@@ -1762,8 +1743,10 @@ static void airhoha_set_gdm2_loopback(st static int airoha_dev_init(struct net_device *dev) { struct airoha_gdm_port *port = netdev_priv(dev); @@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni airoha_set_macaddr(port, dev->dev_addr); -@@ -1775,16 +1758,27 @@ static int airoha_dev_init(struct net_de +@@ -1776,16 +1759,27 @@ static int airoha_dev_init(struct net_de fallthrough; case 2: if (airoha_ppe_is_enabled(eth, 1)) { diff --git a/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch b/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch index cec079845c..b7fafc52ad 100644 --- a/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch +++ b/target/linux/airoha/patches-6.6/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch @@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1687,13 +1687,17 @@ static int airoha_dev_set_macaddr(struct +@@ -1688,13 +1688,17 @@ static int airoha_dev_set_macaddr(struct return 0; } @@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); -@@ -1714,29 +1718,25 @@ static void airhoha_set_gdm2_loopback(st +@@ -1715,29 +1719,25 @@ static void airhoha_set_gdm2_loopback(st airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); @@ -89,7 +89,7 @@ Signed-off-by: Paolo Abeni } static int airoha_dev_init(struct net_device *dev) -@@ -1753,8 +1753,13 @@ static int airoha_dev_init(struct net_de +@@ -1754,8 +1754,13 @@ static int airoha_dev_init(struct net_de case 3: case 4: /* If GDM2 is active we can't enable loopback */ @@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni fallthrough; case 2: if (airoha_ppe_is_enabled(eth, 1)) { -@@ -3073,11 +3078,38 @@ static const char * const en7581_xsi_rst +@@ -3074,11 +3079,38 @@ static const char * const en7581_xsi_rst "xfp-mac", }; diff --git a/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch b/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch index 7f34a05ab5..5c7d3bf903 100644 --- a/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch +++ b/target/linux/airoha/patches-6.6/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch @@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1689,10 +1689,8 @@ static int airoha_dev_set_macaddr(struct +@@ -1690,10 +1690,8 @@ static int airoha_dev_set_macaddr(struct static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) { @@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni int src_port; /* Forward the traffic to the proper GDM port */ -@@ -1704,6 +1702,8 @@ static int airhoha_set_gdm2_loopback(str +@@ -1705,6 +1703,8 @@ static int airhoha_set_gdm2_loopback(str /* Enable GDM2 loopback */ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); @@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, FIELD_PREP(LPBK_CHAN_MASK, chan) | -@@ -1718,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str +@@ -1719,6 +1719,8 @@ static int airhoha_set_gdm2_loopback(str airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); @@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni src_port = eth->soc->ops.get_src_port_id(port, nbq); if (src_port < 0) return src_port; -@@ -1731,7 +1733,7 @@ static int airhoha_set_gdm2_loopback(str +@@ -1732,7 +1734,7 @@ static int airhoha_set_gdm2_loopback(str SP_CPORT_MASK(val), FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); @@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, FC_ID_OF_SRC_PORT24_MASK, FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); -@@ -1900,6 +1902,22 @@ static bool airoha_dev_tx_queue_busy(str +@@ -1901,6 +1903,22 @@ static bool airoha_dev_tx_queue_busy(str return index >= tail; } @@ -79,7 +79,7 @@ Signed-off-by: Paolo Abeni static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, struct net_device *dev) { -@@ -1940,7 +1958,7 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1941,7 +1959,7 @@ static netdev_tx_t airoha_dev_xmit(struc } } @@ -88,7 +88,7 @@ Signed-off-by: Paolo Abeni msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); -@@ -3102,6 +3120,35 @@ static int airoha_en7581_get_src_port_id +@@ -3103,6 +3121,35 @@ static int airoha_en7581_get_src_port_id return -EINVAL; } @@ -124,7 +124,7 @@ Signed-off-by: Paolo Abeni static const struct airoha_eth_soc_data en7581_soc_data = { .version = 0x7581, .xsi_rsts_names = en7581_xsi_rsts_names, -@@ -3112,8 +3159,19 @@ static const struct airoha_eth_soc_data +@@ -3113,8 +3160,19 @@ static const struct airoha_eth_soc_data }, }; diff --git a/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch b/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch index 654f287b14..68f22a5af4 100644 --- a/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch +++ b/target/linux/airoha/patches-6.6/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch @@ -172,7 +172,7 @@ Signed-off-by: Jakub Kicinski MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); -@@ -1697,7 +1697,7 @@ static int airhoha_set_gdm2_loopback(str +@@ -1698,7 +1698,7 @@ static int airhoha_set_gdm2_loopback(str pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); diff --git a/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch b/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch index e87035ec54..0002556fe0 100644 --- a/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch +++ b/target/linux/airoha/patches-6.6/104-6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2990,11 +2990,11 @@ static int airoha_probe(struct platform_ +@@ -2991,11 +2991,11 @@ static int airoha_probe(struct platform_ return err; } diff --git a/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch b/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch index 58e48cb8d0..fd1c9f0dc3 100644 --- a/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch +++ b/target/linux/airoha/patches-6.6/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3044,6 +3044,7 @@ static int airoha_probe(struct platform_ +@@ -3045,6 +3045,7 @@ static int airoha_probe(struct platform_ error_napi_stop: for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) airoha_qdma_stop_napi(ð->qdma[i]); diff --git a/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch index 253fa37913..6774803057 100644 --- a/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch +++ b/target/linux/airoha/patches-6.6/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch @@ -35,9 +35,9 @@ Signed-off-by: Uwe Kleine-König --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig -@@ -54,6 +54,16 @@ config PWM_ADP5585 - This option enables support for the PWM function found in the Analog - Devices ADP5585. +@@ -51,6 +51,16 @@ config PWM_AB8500 + To compile this driver as a module, choose M here: the module + will be called pwm-ab8500. +config PWM_AIROHA + tristate "Airoha PWM support" diff --git a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch index d7e312dfcf..e1e6baed40 100644 --- a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1383,6 +1383,10 @@ static int airoha_hw_init(struct platfor +@@ -1384,6 +1384,10 @@ static int airoha_hw_init(struct platfor if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index 7b395bfcb7..5750bc3dbb 100644 --- a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi airoha_fe_crsn_qsel_init(eth); -@@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de +@@ -1626,7 +1628,8 @@ static int airoha_dev_open(struct net_de if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index 508ae97154..5da8a24a7e 100644 --- a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3095,7 +3095,6 @@ static void airoha_remove(struct platfor +@@ -3096,7 +3096,6 @@ static void airoha_remove(struct platfor } static const char * const en7581_xsi_rsts_names[] = { @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi "hsi0-mac", "hsi1-mac", "hsi-mac", -@@ -3127,7 +3126,6 @@ static int airoha_en7581_get_src_port_id +@@ -3128,7 +3127,6 @@ static int airoha_en7581_get_src_port_id } static const char * const an7583_xsi_rsts_names[] = { diff --git a/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch index e6a39b4680..c16d4c8686 100644 --- a/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch +++ b/target/linux/airoha/patches-6.6/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch @@ -22,8 +22,8 @@ Signed-off-by: Christian Marangi --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -1088,6 +1088,12 @@ static unsigned int phylink_inband_caps( - return phylink_pcs_inband_caps(pcs, interface); +@@ -1106,6 +1106,12 @@ static void phylink_pcs_link_up(struct p + pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); } +static void phylink_pcs_link_down(struct phylink_pcs *pcs) @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void phylink_pcs_poll_stop(struct phylink *pl) { if (pl->cfg_link_an_mode == MLO_AN_INBAND) -@@ -1642,6 +1648,8 @@ static void phylink_link_down(struct phy +@@ -1437,6 +1443,8 @@ static void phylink_link_down(struct phy if (ndev) netif_carrier_off(ndev); @@ -46,7 +46,7 @@ Signed-off-by: Christian Marangi phylink_info(pl, "Link is Down\n"); --- a/include/linux/phylink.h +++ b/include/linux/phylink.h -@@ -430,6 +430,7 @@ struct phylink_pcs { +@@ -507,6 +507,7 @@ struct phylink_pcs { * @pcs_an_restart: restart 802.3z BaseX autonegotiation. * @pcs_link_up: program the PCS for the resolved link configuration * (where necessary). @@ -54,7 +54,7 @@ Signed-off-by: Christian Marangi */ struct phylink_pcs_ops { int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, -@@ -450,6 +451,7 @@ struct phylink_pcs_ops { +@@ -526,6 +527,7 @@ struct phylink_pcs_ops { void (*pcs_an_restart)(struct phylink_pcs *pcs); void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); diff --git a/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch b/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch index 5bd7da4a43..cde7048967 100644 --- a/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch +++ b/target/linux/airoha/patches-6.6/116-09-net-pcs-airoha-add-PCS-driver-for-Airoha-SoC.patch @@ -40,7 +40,7 @@ Signed-off-by: Christian Marangi endmenu --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile -@@ -9,3 +9,5 @@ obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o +@@ -8,3 +8,5 @@ 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 diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index 8ce66b706a..ac17676436 100644 --- a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { struct airoha_eth *eth = port->qdma->eth; -@@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de +@@ -1623,6 +1629,17 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); if (err) -@@ -1675,6 +1692,11 @@ static int airoha_dev_stop(struct net_de +@@ -1676,6 +1693,11 @@ static int airoha_dev_stop(struct net_de } } @@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi return 0; } -@@ -2823,6 +2845,20 @@ static const struct ethtool_ops airoha_e +@@ -2824,6 +2846,20 @@ static const struct ethtool_ops airoha_e .get_link = ethtool_op_get_link, }; @@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { int i; -@@ -2867,6 +2903,99 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2868,6 +2904,99 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { -@@ -2945,6 +3074,12 @@ static int airoha_alloc_gdm_port(struct +@@ -2946,6 +3075,12 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3060,6 +3195,10 @@ error_hw_cleanup: +@@ -3061,6 +3196,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3087,6 +3226,10 @@ static void airoha_remove(struct platfor +@@ -3088,6 +3227,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); diff --git a/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch b/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch index b7940f0603..65f21aa6ac 100644 --- a/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch +++ b/target/linux/airoha/patches-6.6/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch @@ -39,7 +39,7 @@ Signed-off-by: Christian Marangi } #define PINCTRL_CONF_DESC(p, offset, mask) \ -@@ -362,16 +362,46 @@ struct airoha_pinctrl_gpiochip { +@@ -356,16 +356,46 @@ struct airoha_pinctrl_gpiochip { u32 irq_type[AIROHA_NUM_PINS]; }; @@ -87,7 +87,7 @@ Signed-off-by: Christian Marangi PINCTRL_PIN(0, "uart1_txd"), PINCTRL_PIN(1, "uart1_rxd"), PINCTRL_PIN(2, "i2c_scl"), -@@ -432,172 +462,172 @@ static struct pinctrl_pin_desc airoha_pi +@@ -426,172 +456,172 @@ static struct pinctrl_pin_desc airoha_pi PINCTRL_PIN(63, "pcie_reset2"), }; @@ -426,7 +426,7 @@ Signed-off-by: Christian Marangi }; static const char *const pon_groups[] = { "pon" }; -@@ -1960,33 +1990,33 @@ static const struct airoha_pinctrl_func_ +@@ -1954,33 +1984,33 @@ static const struct airoha_pinctrl_func_ }, }; @@ -485,7 +485,7 @@ Signed-off-by: Christian Marangi PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), -@@ -2047,7 +2077,7 @@ static const struct airoha_pinctrl_conf +@@ -2041,7 +2071,7 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), }; @@ -494,7 +494,7 @@ Signed-off-by: Christian Marangi PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), -@@ -2108,7 +2138,7 @@ static const struct airoha_pinctrl_conf +@@ -2102,7 +2132,7 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), }; @@ -503,7 +503,7 @@ Signed-off-by: Christian Marangi PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), -@@ -2169,7 +2199,7 @@ static const struct airoha_pinctrl_conf +@@ -2163,7 +2193,7 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), }; @@ -512,7 +512,7 @@ Signed-off-by: Christian Marangi PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), -@@ -2230,7 +2260,7 @@ static const struct airoha_pinctrl_conf +@@ -2224,7 +2254,7 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), }; @@ -521,7 +521,7 @@ Signed-off-by: Christian Marangi PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), -@@ -2552,12 +2582,17 @@ airoha_pinctrl_get_conf_reg(const struct +@@ -2551,12 +2581,17 @@ airoha_pinctrl_get_conf_reg(const struct } static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl, @@ -542,7 +542,7 @@ Signed-off-by: Christian Marangi if (!reg) return -EINVAL; -@@ -2570,12 +2605,17 @@ static int airoha_pinctrl_get_conf(struc +@@ -2569,12 +2604,17 @@ static int airoha_pinctrl_get_conf(struc } static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl, @@ -563,7 +563,7 @@ Signed-off-by: Christian Marangi if (!reg) return -EINVAL; -@@ -2588,44 +2628,34 @@ static int airoha_pinctrl_set_conf(struc +@@ -2587,44 +2627,34 @@ static int airoha_pinctrl_set_conf(struc } #define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \ @@ -618,7 +618,7 @@ Signed-off-by: Christian Marangi (pin), (val)) static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p) -@@ -2804,12 +2834,13 @@ static int airoha_pinconf_set(struct pin +@@ -2803,12 +2833,13 @@ static int airoha_pinconf_set(struct pin static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev, unsigned int group, unsigned long *config) { @@ -634,7 +634,7 @@ Signed-off-by: Christian Marangi config)) return -ENOTSUPP; -@@ -2826,13 +2857,14 @@ static int airoha_pinconf_group_set(stru +@@ -2825,13 +2856,14 @@ static int airoha_pinconf_group_set(stru unsigned int group, unsigned long *configs, unsigned int num_configs) { @@ -651,7 +651,7 @@ Signed-off-by: Christian Marangi configs, num_configs); if (err) return err; -@@ -2858,23 +2890,16 @@ static const struct pinctrl_ops airoha_p +@@ -2857,23 +2889,16 @@ static const struct pinctrl_ops airoha_p .dt_free_map = pinconf_generic_dt_free_map, }; @@ -678,7 +678,7 @@ Signed-off-by: Christian Marangi pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL); if (!pinctrl) return -ENOMEM; -@@ -2889,14 +2914,23 @@ static int airoha_pinctrl_probe(struct p +@@ -2888,14 +2913,23 @@ static int airoha_pinctrl_probe(struct p pinctrl->chip_scu = map; @@ -704,8 +704,8 @@ Signed-off-by: Christian Marangi + const struct pingroup *grp = &data->grps[i]; err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name, - grp->pins, grp->npins, -@@ -2909,10 +2943,10 @@ static int airoha_pinctrl_probe(struct p + (int *)grp->pins, grp->npins, +@@ -2908,10 +2942,10 @@ static int airoha_pinctrl_probe(struct p } /* build functions */ @@ -716,9 +716,9 @@ Signed-off-by: Christian Marangi - func = &airoha_pinctrl_funcs[i]; + func = &data->funcs[i]; err = pinmux_generic_add_function(pinctrl->ctrl, - func->desc.func.name, - func->desc.func.groups, -@@ -2925,6 +2959,10 @@ static int airoha_pinctrl_probe(struct p + func->desc.name, + func->desc.group_names, +@@ -2924,6 +2958,10 @@ static int airoha_pinctrl_probe(struct p } } @@ -729,7 +729,7 @@ Signed-off-by: Christian Marangi err = pinctrl_enable(pinctrl->ctrl); if (err) return err; -@@ -2933,8 +2971,39 @@ static int airoha_pinctrl_probe(struct p +@@ -2932,8 +2970,39 @@ static int airoha_pinctrl_probe(struct p return airoha_pinctrl_add_gpiochip(pinctrl, pdev); } diff --git a/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch b/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch index df1d96699e..0be484ad6b 100644 --- a/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch +++ b/target/linux/airoha/patches-6.6/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/pinctrl/mediatek/pinctrl-airoha.c +++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -1478,516 +1478,110 @@ static const struct airoha_pinctrl_func_ +@@ -1472,516 +1472,110 @@ static const struct airoha_pinctrl_func_ }, }; diff --git a/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch b/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch index e541cdd610..948d41dfd0 100644 --- a/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch +++ b/target/linux/airoha/patches-6.6/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch @@ -16,7 +16,7 @@ Signed-off-by: Christian Marangi --- a/drivers/pinctrl/mediatek/pinctrl-airoha.c +++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -1078,404 +1078,75 @@ static const struct airoha_pinctrl_func_ +@@ -1072,404 +1072,75 @@ static const struct airoha_pinctrl_func_ }; /* PWM */ diff --git a/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch b/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch index 37d3b29f2d..c4ba9f13b8 100644 --- a/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch +++ b/target/linux/airoha/patches-6.6/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/pinctrl/mediatek/pinctrl-airoha.c +++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -75,6 +75,7 @@ +@@ -69,6 +69,7 @@ #define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20) #define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19) #define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18) @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi #define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17) #define GPIO_PCM_SPI_MODE_MASK BIT(16) #define GPIO_PCM2_MODE_MASK BIT(13) -@@ -132,6 +133,8 @@ +@@ -126,6 +127,8 @@ /* CONF */ #define REG_I2C_SDA_E2 0x001c @@ -32,7 +32,7 @@ Signed-off-by: Christian Marangi #define SPI_MISO_E2_MASK BIT(14) #define SPI_MOSI_E2_MASK BIT(13) #define SPI_CLK_E2_MASK BIT(12) -@@ -139,12 +142,16 @@ +@@ -133,12 +136,16 @@ #define PCIE2_RESET_E2_MASK BIT(10) #define PCIE1_RESET_E2_MASK BIT(9) #define PCIE0_RESET_E2_MASK BIT(8) @@ -49,7 +49,7 @@ Signed-off-by: Christian Marangi #define SPI_MISO_E4_MASK BIT(14) #define SPI_MOSI_E4_MASK BIT(13) #define SPI_CLK_E4_MASK BIT(12) -@@ -152,6 +159,8 @@ +@@ -146,6 +153,8 @@ #define PCIE2_RESET_E4_MASK BIT(10) #define PCIE1_RESET_E4_MASK BIT(9) #define PCIE0_RESET_E4_MASK BIT(8) @@ -58,7 +58,7 @@ Signed-off-by: Christian Marangi #define UART1_RXD_E4_MASK BIT(3) #define UART1_TXD_E4_MASK BIT(2) #define I2C_SCL_E4_MASK BIT(1) -@@ -163,6 +172,8 @@ +@@ -157,6 +166,8 @@ #define REG_GPIO_H_E4 0x0030 #define REG_I2C_SDA_PU 0x0044 @@ -67,7 +67,7 @@ Signed-off-by: Christian Marangi #define SPI_MISO_PU_MASK BIT(14) #define SPI_MOSI_PU_MASK BIT(13) #define SPI_CLK_PU_MASK BIT(12) -@@ -170,12 +181,16 @@ +@@ -164,12 +175,16 @@ #define PCIE2_RESET_PU_MASK BIT(10) #define PCIE1_RESET_PU_MASK BIT(9) #define PCIE0_RESET_PU_MASK BIT(8) @@ -84,7 +84,7 @@ Signed-off-by: Christian Marangi #define SPI_MISO_PD_MASK BIT(14) #define SPI_MOSI_PD_MASK BIT(13) #define SPI_CLK_PD_MASK BIT(12) -@@ -183,6 +198,8 @@ +@@ -177,6 +192,8 @@ #define PCIE2_RESET_PD_MASK BIT(10) #define PCIE1_RESET_PD_MASK BIT(9) #define PCIE0_RESET_PD_MASK BIT(8) @@ -93,7 +93,7 @@ Signed-off-by: Christian Marangi #define UART1_RXD_PD_MASK BIT(3) #define UART1_TXD_PD_MASK BIT(2) #define I2C_SCL_PD_MASK BIT(1) -@@ -630,10 +647,223 @@ static const struct pingroup en7581_pinc +@@ -624,10 +641,223 @@ static const struct pingroup en7581_pinc PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2), }; @@ -317,7 +317,7 @@ Signed-off-by: Christian Marangi static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart", "hsuart_cts_rts", "uart4", "uart5" }; -@@ -646,11 +876,16 @@ static const char *const pcm_spi_groups[ +@@ -640,11 +870,16 @@ static const char *const pcm_spi_groups[ "pcm_spi_cs2_p156", "pcm_spi_cs2_p128", "pcm_spi_cs3", "pcm_spi_cs4" }; @@ -334,7 +334,7 @@ Signed-off-by: Christian Marangi static const char *const pwm_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", -@@ -689,6 +924,22 @@ static const char *const phy3_led1_group +@@ -683,6 +918,22 @@ static const char *const phy3_led1_group "gpio45", "gpio46" }; static const char *const phy4_led1_groups[] = { "gpio43", "gpio44", "gpio45", "gpio46" }; @@ -357,7 +357,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_func_group pon_func_group[] = { { -@@ -766,6 +1017,25 @@ static const struct airoha_pinctrl_func_ +@@ -760,6 +1011,25 @@ static const struct airoha_pinctrl_func_ }, }; @@ -383,7 +383,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_func_group uart_func_group[] = { { .name = "uart2", -@@ -1007,6 +1277,73 @@ static const struct airoha_pinctrl_func_ +@@ -1001,6 +1271,73 @@ static const struct airoha_pinctrl_func_ }, }; @@ -457,7 +457,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_func_group i2s_func_group[] = { { .name = "i2s", -@@ -1077,6 +1414,28 @@ static const struct airoha_pinctrl_func_ +@@ -1071,6 +1408,28 @@ static const struct airoha_pinctrl_func_ }, }; @@ -486,7 +486,7 @@ Signed-off-by: Christian Marangi /* PWM */ #define AIROHA_PINCTRL_PWM(gpio, mux_val) \ { \ -@@ -1255,6 +1614,94 @@ static const struct airoha_pinctrl_func_ +@@ -1249,6 +1608,94 @@ static const struct airoha_pinctrl_func_ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), }; @@ -581,7 +581,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { PINCTRL_FUNC_DESC("pon", pon), PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), -@@ -1281,6 +1728,31 @@ static const struct airoha_pinctrl_func +@@ -1275,6 +1722,31 @@ static const struct airoha_pinctrl_func PINCTRL_FUNC_DESC("phy4_led1", phy4_led1), }; @@ -613,7 +613,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = { PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), -@@ -1342,6 +1814,62 @@ static const struct airoha_pinctrl_conf +@@ -1336,6 +1808,62 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), }; @@ -676,7 +676,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = { PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), -@@ -1403,6 +1931,62 @@ static const struct airoha_pinctrl_conf +@@ -1397,6 +1925,62 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), }; @@ -739,7 +739,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = { PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), -@@ -1464,6 +2048,62 @@ static const struct airoha_pinctrl_conf +@@ -1458,6 +2042,62 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), }; @@ -802,7 +802,7 @@ Signed-off-by: Christian Marangi static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = { PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), -@@ -1525,12 +2165,73 @@ static const struct airoha_pinctrl_conf +@@ -1519,12 +2159,73 @@ static const struct airoha_pinctrl_conf PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), }; @@ -876,7 +876,7 @@ Signed-off-by: Christian Marangi static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev, struct pinctrl_gpio_range *range, int pin) -@@ -2267,8 +2968,40 @@ static const struct airoha_pinctrl_match +@@ -2266,8 +2967,40 @@ static const struct airoha_pinctrl_match }, }; diff --git a/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch b/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch index c9cdb9a326..5016ed7503 100644 --- a/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch +++ b/target/linux/airoha/patches-6.6/123-01-ASoC-mediatek-move-some-header-to-global-include.patch @@ -62,7 +62,7 @@ Signed-off-by: Christian Marangi int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe) --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c -@@ -16,8 +16,8 @@ +@@ -18,8 +18,8 @@ #include "mt2701-afe-common.h" #include "mt2701-afe-clock-ctrl.h" @@ -233,7 +233,7 @@ Signed-off-by: Christian Marangi +#include #include "../common/mtk-dsp-sof-common.h" #include "../common/mtk-soc-card.h" - #include "../common/mtk-soundcard-driver.h" + #include "mt8195-afe-clk.h" --- /dev/null +++ b/include/sound/mediatek/mtk-afe-fe-dai.h @@ -0,0 +1,53 @@ diff --git a/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch b/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch index 00578601c4..93d2baf5c3 100644 --- a/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch +++ b/target/linux/airoha/patches-6.6/123-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch @@ -30,7 +30,7 @@ Signed-off-by: Christian Marangi --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig -@@ -86,6 +86,7 @@ config SND_SOC_ACPI +@@ -78,6 +78,7 @@ config SND_SOC_ACPI # All the supported SoCs source "sound/soc/adi/Kconfig" @@ -40,7 +40,7 @@ Signed-off-by: Christian Marangi source "sound/soc/atmel/Kconfig" --- a/sound/soc/Makefile +++ b/sound/soc/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_SND_SOC) += codecs/ +@@ -36,6 +36,7 @@ obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ obj-$(CONFIG_SND_SOC) += apple/ obj-$(CONFIG_SND_SOC) += adi/ diff --git a/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch b/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch index 3fc0ba7dc7..aa1de9815a 100644 --- a/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch +++ b/target/linux/airoha/patches-6.6/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch @@ -111,9 +111,9 @@ Signed-off-by: Christian Marangi + --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -737,6 +737,13 @@ S: Maintained - F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml - F: drivers/spi/spi-airoha-snfi.c +@@ -647,6 +647,13 @@ S: Supported + F: fs/aio.c + F: include/linux/*aio*.h +AIROHA USB PHY DRIVER +M: Christian Marangi @@ -123,8 +123,8 @@ Signed-off-by: Christian Marangi +F: include/dt-bindings/phy/airoha,an7581-usb-phy.h + AIRSPY MEDIA DRIVER + M: Antti Palosaari L: linux-media@vger.kernel.org - S: Orphan --- /dev/null +++ b/include/dt-bindings/phy/airoha,an7581-usb-phy.h @@ -0,0 +1,11 @@ diff --git a/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch b/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch index 609df08285..96c2d7cded 100644 --- a/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch +++ b/target/linux/airoha/patches-6.6/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -742,6 +742,7 @@ M: Christian Marangi --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -925,6 +925,12 @@ static int mtk_pcie_en7581_power_up(stru +@@ -932,6 +932,12 @@ static int mtk_pcie_en7581_power_up(stru size = lower_32_bits(resource_size(entry->res)); regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); From 42ca1612a2e207d47400d4bbbd4188a1cbc96b22 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Tue, 11 Nov 2025 23:02:22 +0200 Subject: [PATCH 070/128] base-files: introduce a function to get kernel version number A new function "get_linux_version()" to normalize and print the kernel version as an integer. In some migration scripts, it is useful for checking the Linux kernel version. Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/19172 Signed-off-by: Hauke Mehrtens (cherry picked from commit a0fe3cfb62fbf0b5f599c90e488727f493223429) Link: https://github.com/openwrt/openwrt/pull/20739 Signed-off-by: Christian Marangi --- package/base-files/files/lib/functions/system.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh index f43281b5dc..eaed0fba11 100644 --- a/package/base-files/files/lib/functions/system.sh +++ b/package/base-files/files/lib/functions/system.sh @@ -315,3 +315,10 @@ macaddr_canonicalize() { dt_is_enabled() { grep -q okay "/proc/device-tree/$1/status" } + +get_linux_version() { + local ver=$(uname -r) + local minor=${ver%\.*} + + printf "%d%02d%03d" ${ver%%\.*} ${minor#*\.} ${ver##*\.} 2>/dev/null +} From b01c68ddbde3a06d8569e4bab720b2e54eb3e2c9 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Tue, 11 Nov 2025 23:03:43 +0200 Subject: [PATCH 071/128] ipq806x: migrate wifi configuration device paths for 6.12 kernel The device tree PCIe host node names have been changed in the new 6.12 kernel[1]. Hence we have to update the wifi device path to make sure it can work properly. This script is based on: target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.12.y&id=07299ba2e7d98045e6b522f7c5b97f402b15bc82 Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18989 (cherry picked from commit ae70dbc26787497e25faa8d67b5944b7bb9023e4) Backport the migration script that can also work backward, migrating from 6.12 to 6.6. Like going from main/master to stable 24.10. Signed-off-by: Hannu Nyman Link: https://github.com/openwrt/openwrt/pull/20739 Signed-off-by: Christian Marangi --- .../etc/hotplug.d/ieee80211/05-wifi-migrate | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate b/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate new file mode 100644 index 0000000000..fdacfa56b1 --- /dev/null +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate @@ -0,0 +1,47 @@ +#!/bin/sh + +# This must run before 10-wifi-detect + +[ "${ACTION}" = "add" ] || return + +. /lib/functions.sh +. /lib/functions/system.sh + +do_migrate_radio() +{ + local config="$1" + + config_get from "$config" path + + to=${from/pci\//pcie\/} + + # Checks if kernel version is less than 6.12.0, if it is and the path is + # using the new format, then path should be migrated to the old format. + [ "$(get_linux_version)" -lt "612000" ] && to=${from/pcie\//pci\/} + + [ "$from" = "$to" ] && return + + uci set "wireless.${config}.path=${to}" + WIRELESS_CHANGED=true + + logger -t wifi-migrate "Updated path of wireless.${config} from '${from}' to '${to}'" +} + +migrate_radio() +{ + config_load wireless + + config_foreach do_migrate_radio wifi-device +} + +WIRELESS_CHANGED=false + +case "$(board_name)" in +*) + migrate_radio + ;; +esac + +$WIRELESS_CHANGED && uci commit wireless + +exit 0 From d804c3110b2d9290089f6b719092e0dc762c687d Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 10 Nov 2025 19:27:11 +0100 Subject: [PATCH 072/128] airoha: backport patch fixing out of order DMA for ethernet driver Backport upstream patch fixing out of order DMA access for ethernet driver. This is relevant in the context of QoS when packets doesn't follow linear handling by QDMA HW. (cherry picked from commit 3169ffa4c74d7e0a891be29d4ca3a2a4bf218884) [ fix conflict errors ] Signed-off-by: Christian Marangi --- ...he-capability-to-consume-out-of-orde.patch | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch diff --git a/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch b/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch new file mode 100644 index 0000000000..b09ebd57b4 --- /dev/null +++ b/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch @@ -0,0 +1,245 @@ +From 3f47e67dff1f7266e112c50313d63824f6f17102 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 6 Nov 2025 13:53:23 +0100 +Subject: [PATCH] net: airoha: Add the capability to consume out-of-order DMA + tx descriptors + +EN7581 and AN7583 SoCs are capable of DMA mapping non-linear tx skbs on +non-consecutive DMA descriptors. This feature is useful when multiple +flows are queued on the same hw tx queue since it allows to fully utilize +the available tx DMA descriptors and to avoid the starvation of +high-priority flow we have in the current codebase due to head-of-line +blocking introduced by low-priority flows. + +Tested-by: Xuegang Lu +Reviewed-by: Jacob Keller +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106-airoha-tx-linked-list-v2-1-0706d4a322bd@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 85 +++++++++++------------- + drivers/net/ethernet/airoha/airoha_eth.h | 7 +- + 2 files changed, 45 insertions(+), 47 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -892,19 +892,13 @@ static int airoha_qdma_tx_napi_poll(stru + + dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, + DMA_TO_DEVICE); +- memset(e, 0, sizeof(*e)); ++ e->dma_addr = 0; ++ list_add_tail(&e->list, &q->tx_list); ++ + WRITE_ONCE(desc->msg0, 0); + WRITE_ONCE(desc->msg1, 0); + q->queued--; + +- /* completion ring can report out-of-order indexes if hw QoS +- * is enabled and packets with different priority are queued +- * to same DMA ring. Take into account possible out-of-order +- * reports incrementing DMA ring tail pointer +- */ +- while (q->tail != q->head && !q->entry[q->tail].dma_addr) +- q->tail = (q->tail + 1) % q->ndesc; +- + if (skb) { + u16 queue = skb_get_queue_mapping(skb); + struct netdev_queue *txq; +@@ -949,6 +943,7 @@ static int airoha_qdma_init_tx_queue(str + q->ndesc = size; + q->qdma = qdma; + q->free_thr = 1 + MAX_SKB_FRAGS; ++ INIT_LIST_HEAD(&q->tx_list); + + q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), + GFP_KERNEL); +@@ -961,9 +956,9 @@ static int airoha_qdma_init_tx_queue(str + return -ENOMEM; + + for (i = 0; i < q->ndesc; i++) { +- u32 val; ++ u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); + +- val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); ++ list_add_tail(&q->entry[i].list, &q->tx_list); + WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); + } + +@@ -973,9 +968,9 @@ static int airoha_qdma_init_tx_queue(str + + airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, +- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); ++ FIELD_PREP(TX_RING_CPU_IDX_MASK, 0)); + airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, +- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); ++ FIELD_PREP(TX_RING_DMA_IDX_MASK, 0)); + + return 0; + } +@@ -1031,17 +1026,21 @@ static int airoha_qdma_init_tx(struct ai + static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) + { + struct airoha_eth *eth = q->qdma->eth; ++ int i; + + spin_lock_bh(&q->lock); +- while (q->queued) { +- struct airoha_queue_entry *e = &q->entry[q->tail]; ++ for (i = 0; i < q->ndesc; i++) { ++ struct airoha_queue_entry *e = &q->entry[i]; ++ ++ if (!e->dma_addr) ++ continue; + + dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, + DMA_TO_DEVICE); + dev_kfree_skb_any(e->skb); ++ e->dma_addr = 0; + e->skb = NULL; +- +- q->tail = (q->tail + 1) % q->ndesc; ++ list_add_tail(&e->list, &q->tx_list); + q->queued--; + } + spin_unlock_bh(&q->lock); +@@ -1883,20 +1882,6 @@ static u32 airoha_get_dsa_tag(struct sk_ + #endif + } + +-static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags) +-{ +- u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail; +- u32 index = q->head + nr_frags; +- +- /* completion napi can free out-of-order tx descriptors if hw QoS is +- * enabled and packets with different priorities are queued to the same +- * DMA ring. Take into account possible out-of-order reports checking +- * if the tx queue is full using circular buffer head/tail pointers +- * instead of the number of queued packets. +- */ +- return index >= tail; +-} +- + static int airoha_get_fe_port(struct airoha_gdm_port *port) + { + struct airoha_qdma *qdma = port->qdma; +@@ -1919,8 +1904,10 @@ static netdev_tx_t airoha_dev_xmit(struc + struct airoha_gdm_port *port = netdev_priv(dev); + struct airoha_qdma *qdma = port->qdma; + u32 nr_frags, tag, msg0, msg1, len; ++ struct airoha_queue_entry *e; + struct netdev_queue *txq; + struct airoha_queue *q; ++ LIST_HEAD(tx_list); + void *data; + int i, qid; + u16 index; +@@ -1966,7 +1953,7 @@ static netdev_tx_t airoha_dev_xmit(struc + txq = netdev_get_tx_queue(dev, qid); + nr_frags = 1 + skb_shinfo(skb)->nr_frags; + +- if (airoha_dev_tx_queue_busy(q, nr_frags)) { ++ if (q->queued + nr_frags >= q->ndesc) { + /* not enough space in the queue */ + netif_tx_stop_queue(txq); + spin_unlock_bh(&q->lock); +@@ -1975,11 +1962,13 @@ static netdev_tx_t airoha_dev_xmit(struc + + len = skb_headlen(skb); + data = skb->data; +- index = q->head; ++ ++ e = list_first_entry(&q->tx_list, struct airoha_queue_entry, ++ list); ++ index = e - q->entry; + + for (i = 0; i < nr_frags; i++) { + struct airoha_qdma_desc *desc = &q->desc[index]; +- struct airoha_queue_entry *e = &q->entry[index]; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + dma_addr_t addr; + u32 val; +@@ -1989,7 +1978,14 @@ static netdev_tx_t airoha_dev_xmit(struc + if (unlikely(dma_mapping_error(dev->dev.parent, addr))) + goto error_unmap; + +- index = (index + 1) % q->ndesc; ++ list_move_tail(&e->list, &tx_list); ++ e->skb = i ? NULL : skb; ++ e->dma_addr = addr; ++ e->dma_len = len; ++ ++ e = list_first_entry(&q->tx_list, struct airoha_queue_entry, ++ list); ++ index = e - q->entry; + + val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); + if (i < nr_frags - 1) +@@ -2002,15 +1998,9 @@ static netdev_tx_t airoha_dev_xmit(struc + WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); + WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); + +- e->skb = i ? NULL : skb; +- e->dma_addr = addr; +- e->dma_len = len; +- + data = skb_frag_address(frag); + len = skb_frag_size(frag); + } +- +- q->head = index; + q->queued += i; + + skb_tx_timestamp(skb); +@@ -2019,7 +2009,7 @@ static netdev_tx_t airoha_dev_xmit(struc + if (netif_xmit_stopped(txq) || !netdev_xmit_more()) + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), + TX_RING_CPU_IDX_MASK, +- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); ++ FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); + + if (q->ndesc - q->queued < q->free_thr) + netif_tx_stop_queue(txq); +@@ -2029,10 +2019,13 @@ static netdev_tx_t airoha_dev_xmit(struc + return NETDEV_TX_OK; + + error_unmap: +- for (i--; i >= 0; i--) { +- index = (q->head + i) % q->ndesc; +- dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, +- q->entry[index].dma_len, DMA_TO_DEVICE); ++ while (!list_empty(&tx_list)) { ++ e = list_first_entry(&tx_list, struct airoha_queue_entry, ++ list); ++ dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, ++ DMA_TO_DEVICE); ++ e->dma_addr = 0; ++ list_move_tail(&e->list, &q->tx_list); + } + + spin_unlock_bh(&q->lock); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -169,7 +169,10 @@ enum trtcm_param { + struct airoha_queue_entry { + union { + void *buf; +- struct sk_buff *skb; ++ struct { ++ struct list_head list; ++ struct sk_buff *skb; ++ }; + }; + dma_addr_t dma_addr; + u16 dma_len; +@@ -193,6 +196,8 @@ struct airoha_queue { + struct napi_struct napi; + struct page_pool *page_pool; + struct sk_buff *skb; ++ ++ struct list_head tx_list; + }; + + struct airoha_tx_irq_queue { From dddeea5e7ff5db16cf3dc513f8d5c8ca27c65fa6 Mon Sep 17 00:00:00 2001 From: Ernestas Kulik Date: Wed, 12 Nov 2025 10:16:30 +0200 Subject: [PATCH 073/128] =?UTF-8?q?scripts:=20feeds:=20Don=E2=80=99t=20har?= =?UTF-8?q?dcode=20IS=5FTTY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building in environments that set IS_TTY, the feeds script does not honor it and passes a hardcoded value to scan.mk, causing unwanted control characters to appear in stdout. This commit addresses the issue by checking IS_TTY and MAKE_TERMOUT variables and uses their values if defined. Closes #8039 Signed-off-by: Ernestas Kulik Link: https://github.com/openwrt/openwrt/pull/20743 Signed-off-by: Christian Marangi (cherry picked from commit fd7e43d429a370665795fb14c859c046c761e4e9) --- scripts/feeds | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/feeds b/scripts/feeds index 959995c7af..70b52229a3 100755 --- a/scripts/feeds +++ b/scripts/feeds @@ -128,8 +128,14 @@ sub update_index($) -d "./feeds/$name.tmp/info" or mkdir "./feeds/$name.tmp/info" or return 1; system("$mk -s prepare-mk OPENWRT_BUILD= TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); - system("$mk -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); - system("$mk -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"targetinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"target\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" SCAN_MAKEOPTS=\"TARGET_BUILD=1\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); + + my $is_tty = $ENV{IS_TTY}; + $is_tty = defined $is_tty ? $is_tty : $ENV{MAKE_TERMOUT}; + $is_tty = defined $is_tty ? $is_tty : 1; + + system("$mk -s -f include/scan.mk IS_TTY=$is_tty SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); + system("$mk -s -f include/scan.mk IS_TTY=$is_tty SCAN_TARGET=\"targetinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"target\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" SCAN_MAKEOPTS=\"TARGET_BUILD=1\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); + system("ln -sf $name.tmp/.packageinfo ./feeds/$name.index"); system("ln -sf $name.tmp/.targetinfo ./feeds/$name.targetindex"); From 58cde9ec226918812473c77e562b059316b5989a Mon Sep 17 00:00:00 2001 From: George Tsiamasiotis Date: Tue, 23 Sep 2025 23:11:19 +0300 Subject: [PATCH 074/128] scripts/patch-kernel.sh: do not try to check files after patch Since we are not using patch -b, *.orig files are only created when there are conflicts, or never according to posix patch. As such, it doesn't really make sense to always delete *.orig files presuming they are patch backups, even if they are patch backups. Doing so is both deleting potentially useful information for failed patch applications and creating hard to diagnose bugs [1]. In a similar vein, checking for *.rej files does not add any value since we're already checking the patch command's return code. [1]: https://github.com/openwrt/packages/issues/27485 Signed-off-by: George Tsiamasiotis Link: https://github.com/openwrt/openwrt/pull/20141 Signed-off-by: Robert Marko (cherry picked from commit 75ca6bafd614efd1427a979d28d551af775b8e5d) Link: https://github.com/openwrt/openwrt/pull/20742 Signed-off-by: Christian Marangi --- scripts/patch-kernel.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/patch-kernel.sh b/scripts/patch-kernel.sh index 52750dde6e..84bcba8858 100755 --- a/scripts/patch-kernel.sh +++ b/scripts/patch-kernel.sh @@ -43,12 +43,3 @@ for i in ${patchdir}/${patchpattern} ; do exit 1 fi done - -# Check for rejects... -if [ "`find $targetdir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] ; then - echo "Aborting. Reject files found." - exit 1 -fi - -# Remove backup files -find $targetdir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; From 4d1c1d775468c1dc60a8e6e0dd6e1364176c03ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 14 Nov 2025 23:02:27 +0100 Subject: [PATCH 075/128] odhcpd: backport memleak fix from Git HEAD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit be7ca7c0792b config: fix memleak during odhcpd reload https://github.com/openwrt/odhcpd/commit/be7ca7c0792b Signed-off-by: Álvaro Fernández Rojas --- package/network/services/odhcpd/Makefile | 2 +- ...fig-fix-memleak-during-odhcpd-reload.patch | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 package/network/services/odhcpd/patches/0005-config-fix-memleak-during-odhcpd-reload.patch diff --git a/package/network/services/odhcpd/Makefile b/package/network/services/odhcpd/Makefile index 44fb25de6c..707e85be7f 100644 --- a/package/network/services/odhcpd/Makefile +++ b/package/network/services/odhcpd/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=odhcpd -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git diff --git a/package/network/services/odhcpd/patches/0005-config-fix-memleak-during-odhcpd-reload.patch b/package/network/services/odhcpd/patches/0005-config-fix-memleak-during-odhcpd-reload.patch new file mode 100644 index 0000000000..1d61133284 --- /dev/null +++ b/package/network/services/odhcpd/patches/0005-config-fix-memleak-during-odhcpd-reload.patch @@ -0,0 +1,66 @@ +From be7ca7c0792b185263ad86b961ea61129494a7f9 Mon Sep 17 00:00:00 2001 +From: Fei Lv +Date: Fri, 14 Nov 2025 15:31:22 +0800 +Subject: [PATCH] config: fix memleak during odhcpd reload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- The memset in close_interface reset the pios pointer before it + could be freed, causing a memory leak. Relocate the free call + to clean_interface to ensure proper deallocation. + +- Use realloc instead of malloc in config_load_ra_pio() + This function may be called multiple times during odhcpd reload, + and using malloc without freeing the previous allocation was + causing memory leaks. + +Signed-off-by: Fei Lv +Link: https://github.com/openwrt/odhcpd/pull/309 +Signed-off-by: Álvaro Fernández Rojas +--- + src/config.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/src/config.c ++++ b/src/config.c +@@ -314,6 +314,7 @@ static void clean_interface(struct inter + free(iface->dnr[i].svc); + } + free(iface->dnr); ++ free(iface->pios); + memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); + set_interface_defaults(iface); + } +@@ -335,7 +336,6 @@ static void close_interface(struct inter + clean_interface(iface); + free(iface->addr4); + free(iface->addr6); +- free(iface->pios); + free(iface->ifname); + free(iface); + } +@@ -1810,6 +1810,7 @@ static json_object *config_load_ra_pio_j + void config_load_ra_pio(struct interface *iface) + { + json_object *json, *slaac_json; ++ struct ra_pio *new_pios; + size_t pio_cnt; + time_t now; + +@@ -1829,12 +1830,13 @@ void config_load_ra_pio(struct interface + now = odhcpd_time(); + + pio_cnt = json_object_array_length(slaac_json); +- iface->pios = malloc(sizeof(struct ra_pio) * pio_cnt); +- if (!iface->pios) { ++ new_pios = realloc(iface->pios, sizeof(struct ra_pio) * pio_cnt); ++ if (!new_pios) { + json_object_put(json); + return; + } + ++ iface->pios = new_pios; + iface->pio_cnt = 0; + for (size_t i = 0; i < pio_cnt; i++) { + json_object *cur_pio_json, *length_json, *prefix_json; From dbc2b142ceb4c9727b9254b0c9a524537cc39a2d Mon Sep 17 00:00:00 2001 From: Pawel Dembicki Date: Wed, 12 Nov 2025 22:33:24 +0100 Subject: [PATCH 076/128] mac80211: mwl8k: inject DSSS Parameter Set element into beacons if missing Some Marvell AP firmware used with mwl8k misbehaves when beacons do not contain the DSSS Parameter Set (WLAN_EID_DS_PARAMS) with the current channel. When hostapd/mac80211 omits this element (which is valid on some bands), the firmware may report bogus RX channel information and AP mode becomes unusable. Backport the upstream fix that ensures beacons always carry the DSSS Parameter Set for mwl8k: when setting the beacon, detect if the element is missing and inject it after SSID and Supported Rates (per spec ordering). This mirrors behaviour in newer Marvell drivers and restores stable operation. Tested on Linksys EA4500 (88W8366). Fixes: openwrt/openwrt#19088 Link: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git/commit/?id=c4e1ac09ee1c750890e36cb1f841f25518f23589 Signed-off-by: Pawel Dembicki Link: https://github.com/openwrt/openwrt/pull/20757 Signed-off-by: Hauke Mehrtens (cherry picked from commit 38ed1510dbe80a37fd35b9a47e937a32a5a673bd) [refreshed patches] Signed-off-by: Pawel Dembicki Link: https://github.com/openwrt/openwrt/pull/20817 Signed-off-by: Christian Marangi --- ...DS-Params-IE-into-beacons-if-missing.patch | 116 ++++++++++++++++++ ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- ...940-mwl8k_init_devices_synchronously.patch | 4 +- 3 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 package/kernel/mac80211/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch diff --git a/package/kernel/mac80211/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch b/package/kernel/mac80211/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch new file mode 100644 index 0000000000..7e8ad23a49 --- /dev/null +++ b/package/kernel/mac80211/patches/mwl/001-mwl8k-inject-DS-Params-IE-into-beacons-if-missing.patch @@ -0,0 +1,116 @@ +From f4e661a75cdfa7eb88ac0fa832edd4a90775805d Mon Sep 17 00:00:00 2001 +From: Pawel Dembicki +Date: Fri, 7 Nov 2025 23:05:56 +0100 +Subject: [PATCH] mwl8k: inject DS Params IE into beacons if missing + +Some Marvell AP firmware used with mwl8k misbehaves when beacon frames +do not contain a WLAN_EID_DS_PARAMS information element with the current +channel. It was reported on OpenWrt Github issues [0]. + +When hostapd/mac80211 omits DS Params from the beacon (which is valid on +some bands), the firmware stops transmitting sane frames and RX status +starts reporting bogus channel information. This makes AP mode unusable. + +Newer Marvell drivers (mwlwifi [1]) hard-code DS Params IE into AP beacons +for all chips, which suggests this is a firmware requirement rather than +a mwl8k-specific quirk. + +Mirror that behaviour in mwl8k: when setting the beacon, check if +WLAN_EID_DS_PARAMS is present, and if not, extend the beacon and inject +a DS Params IE at the beginning of the IE list, using the current +channel from hw->conf.chandef.chan. + +Tested on Linksys EA4500 (88W8366). + +[0] https://github.com/openwrt/openwrt/issues/19088 +[1] https://github.com/kaloz/mwlwifi/blob/db97edf20fadea2617805006f5230665fadc6a8c/hif/fwcmd.c#L675 + +Tested-by: Antony Kolitsos +Signed-off-by: Pawel Dembicki +--- + drivers/net/wireless/marvell/mwl8k.c | 61 +++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -2966,6 +2966,42 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw + /* + * CMD_SET_BEACON. + */ ++ ++static bool mwl8k_beacon_has_ds_params(const u8 *buf, int len) ++{ ++ const struct ieee80211_mgmt *mgmt = (const void *)buf; ++ int ies_len; ++ ++ if (len <= offsetof(struct ieee80211_mgmt, u.beacon.variable)) ++ return false; ++ ++ ies_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); ++ ++ return cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, ++ ies_len) != NULL; ++} ++ ++static void mwl8k_beacon_copy_inject_ds_params(struct ieee80211_hw *hw, ++ u8 *buf_dst, const u8 *buf_src, ++ int src_len) ++{ ++ const struct ieee80211_mgmt *mgmt = (const void *)buf_src; ++ const u8 *ies; ++ int hdr_len, left; ++ ++ ies = mgmt->u.beacon.variable; ++ hdr_len = ies - buf_src; ++ left = src_len - hdr_len; ++ ++ memcpy(buf_dst, buf_src, hdr_len); ++ ++ /* Inject a DS Params IE at the beginning of the IE list */ ++ buf_dst[hdr_len + 0] = WLAN_EID_DS_PARAMS; ++ buf_dst[hdr_len + 1] = 1; ++ buf_dst[hdr_len + 2] = hw->conf.chandef.chan->hw_value; ++ ++ memcpy(buf_dst + hdr_len + 3, buf_src + hdr_len, left); ++} + struct mwl8k_cmd_set_beacon { + struct mwl8k_cmd_pkt_hdr header; + __le16 beacon_len; +@@ -2975,17 +3011,32 @@ struct mwl8k_cmd_set_beacon { + static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *beacon, int len) + { ++ bool ds_params_present = mwl8k_beacon_has_ds_params(beacon, len); + struct mwl8k_cmd_set_beacon *cmd; +- int rc; ++ int rc, final_len = len; ++ ++ if (!ds_params_present) ++ /* ++ * mwl8k firmware requires a DS Params IE with the current ++ * channel in AP beacons. If mac80211/hostapd does not ++ * include it, inject one here. IE ID + length + channel ++ * number = 3 bytes. ++ */ ++ final_len += 3; + +- cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL); ++ cmd = kzalloc(sizeof(*cmd) + final_len, GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); +- cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); +- cmd->beacon_len = cpu_to_le16(len); +- memcpy(cmd->beacon, beacon, len); ++ cmd->header.length = cpu_to_le16(sizeof(*cmd) + final_len); ++ cmd->beacon_len = cpu_to_le16(final_len); ++ ++ if (ds_params_present) ++ memcpy(cmd->beacon, beacon, len); ++ else ++ mwl8k_beacon_copy_inject_ds_params(hw, cmd->beacon, beacon, ++ len); + + rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + kfree(cmd); diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch index 7baab80d24..9fe2628ee2 100644 --- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5716,6 +5716,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5767,6 +5767,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static const struct pci_device_id mwl8k_pci_id_table[] = { diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch index d021b1e40b..e6a3a7a210 100644 --- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -6302,6 +6302,8 @@ static int mwl8k_probe(struct pci_dev *p +@@ -6353,6 +6353,8 @@ static int mwl8k_probe(struct pci_dev *p priv->running_bsses = 0; @@ -9,7 +9,7 @@ return rc; err_stop_firmware: -@@ -6335,8 +6337,6 @@ static void mwl8k_remove(struct pci_dev +@@ -6386,8 +6388,6 @@ static void mwl8k_remove(struct pci_dev return; priv = hw->priv; From 84927ebac66f08cc0e15b004f2d99307df7ea926 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 3 Oct 2025 23:59:44 +0200 Subject: [PATCH 077/128] mt76: update to Git HEAD (2025-10-03) 9ee788a38251 wifi: mt76: mt7996: fix null pointer deref in mt7996_conf_tx() ec3f05480e5b tools: CMakeLists: update cmake minimum required version to 3.10 Signed-off-by: Christian Marangi (cherry picked from commit 3531322a4ab3966f55f4d83d7f8013a5c3c779f8) --- package/kernel/mt76/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile index 6943acd89d..07275df44c 100644 --- a/package/kernel/mt76/Makefile +++ b/package/kernel/mt76/Makefile @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2025-09-15 -PKG_SOURCE_VERSION:=6467af3bcf1154c2ceb032c903d533f0c718bbc2 -PKG_MIRROR_HASH:=98781ea57cdc97bc63ecb2c1d4004964f2a10663987887445f1c71b76610cd96 +PKG_SOURCE_DATE:=2025-10-03 +PKG_SOURCE_VERSION:=ec3f05480e5b02a39bac93b76253d56b2a19bdb6 +PKG_MIRROR_HASH:=c6469e91204793d0a859b78ab3baa1eb33a97458228a2849451baabb31e6499b PKG_MAINTAINER:=Felix Fietkau PKG_USE_NINJA:=0 From 2b3f8c0d4c13edcf7aae209e1aec7792df0f9a7e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Oct 2025 16:10:08 +0200 Subject: [PATCH 078/128] mt76: update to Git HEAD (2025-10-20) 9050597c4cd6 wifi: mt76: fix license/copyright of util.h 33f29d2345cc wifi: mt76: relicense to BSD-3-Clause-Clear fc25ba82192e add LICENSE file c1349a686cd1 wifi: mt76: mt7921: fix a potential clc buffer length underflow 4e7077f77400 wifi: mt76: mt7996: fix FCS error flag check in RX descriptor 754e3357045d wifi: mt76: mt7996: Remove unnecessary link_id checks in mt7996_tx 2e63c495f59b wifi: mt76: connac: Replace memcpy + hard-coded size with strscpy 95c4df3233ed wifi: mt76: Fix DTS power-limits on little endian systems 6f27d647c0ce wifi: mt76: mt7915: add bf backoff limit table support 1e91eadc9d46 wifi: mt76: wed: use proper wed reference in mt76 wed driver callabacks 2fe5bdbe7e13 wifi: mt76: use GFP_DMA32 for page_pool buffer allocation c63db0fcadb8 wifi: mt76: mt7915: add WDS support when WED is enabled Signed-off-by: Felix Fietkau (cherry picked from commit 13c30c2e58b02427f6071a3674dbaf0e03d9c792) --- package/kernel/mt76/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile index 07275df44c..5f7af13f5c 100644 --- a/package/kernel/mt76/Makefile +++ b/package/kernel/mt76/Makefile @@ -3,14 +3,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mt76 PKG_RELEASE=1 -PKG_LICENSE:=GPLv2 +PKG_LICENSE:=BSD-3-Clause-Clear PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2025-10-03 -PKG_SOURCE_VERSION:=ec3f05480e5b02a39bac93b76253d56b2a19bdb6 -PKG_MIRROR_HASH:=c6469e91204793d0a859b78ab3baa1eb33a97458228a2849451baabb31e6499b +PKG_SOURCE_DATE:=2025-10-20 +PKG_SOURCE_VERSION:=c63db0fcadb88680b35bec202b5142cfd016c10f +PKG_MIRROR_HASH:=38c3c84f5c58b6967283acf524412f6e13628d50add6f09d539f1239fb02b486 PKG_MAINTAINER:=Felix Fietkau PKG_USE_NINJA:=0 From 59b4c9e1142b941ed400c8df3f2a92298c5619c9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 6 Nov 2025 11:36:14 +0000 Subject: [PATCH 079/128] mt76: update to Git HEAD (2025-11-06) 0aece3089a3a wifi: mt76: mt7996: Remove useless check in mt7996_msdu_page_get_from_cache() 05b3d899ad24 wifi: mt76: Move Q_READ/Q_WRITE definitions in dma.h 85e6517b0ac5 wifi: mt76: Add mt76_dev pointer in mt76_queue struct. a3b6c67c97d2 wifi: mt76: Add the capability to set TX token start ID 141a81557070 wifi: mt76: Introduce the NPU generic layer 647d11bb17e0 wifi: mt76: mt7996: Add NPU offload support to MT7996 driver 8ff3b2bfc37f wifi: mt76: mt7996: fix typos in comments 0043147439b4 wifi: mt76: mt7925: refactor regulatory domain handling to regd.[ch] f0e8fe441489 wifi: mt76: mt7925: refactor CLC support check flow 588cc87bf6a2 wifi: mt76: mt7925: refactor regulatory notifier flow dac1d45fe94b wifi: mt76: mt7925: improve EHT capability control in regulatory flow c166c4a0e750 wifi: mt76: mt7925: add auto regdomain switch support d7b059bba166 wifi: mt76: mt7925: disable auto regd changes after user set 84f62a6beb99 wifi: mt76: mmio_*_copy fix byte order and alignment f5ae5b2e8116 Revert "wifi: mt76: mt792x: improve monitor interface handling" 8ae7e6dc1d3a wifi: mt76: adjust BSS conf pointer handling 1b438ebe0d06 wifi: mt76: mt7925: cqm rssi low/high event notify 7519fa4ce62c wifi: mt76: mt7996: fix max nss value when getting rx chainmask ea0580ad065f wifi: mt76: mt7996: no need to wait ACK event for SDO command 74112c2956fb wifi: mt76: mt7996: fix implicit beamforming support for mt7992 361d6bdac45d wifi: mt76: mt7996: support fixed rate for link station d99274cdc30c wifi: mt76: mt7996: fix several fields in mt7996_mcu_bss_basic_tlv() ad90a85b652b wifi: mt76: mt7996: fix teardown command for an MLD peer e9fe8bc03e41 wifi: mt76: mt7996: set link_valid field when initializing wcid 050394665502 wifi: mt76: mt7996: use correct link_id when filling TXD and TXP 5d223855552c wifi: mt76: mt7996: fix MLD group index assignment ab8361dbc421 wifi: mt76: mt7996: fix MLO set key and group key issues 7ce7ab881b3f wifi: mt76: mt7996: fix using wrong phy to start in mt7996_mac_restart() 1e0c23ff754b wifi: mt76: mt7996: fix EMI rings for RRO eb567bc7f9b6 wifi: mt76: mt7925: ensure the 6GHz A-MPDU density cap from the hardware. Signed-off-by: Felix Fietkau (cherry picked from commit e1a584b5d2631c0ba8e82ec850bb45568d137e02) --- package/kernel/mt76/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile index 5f7af13f5c..baced1baf1 100644 --- a/package/kernel/mt76/Makefile +++ b/package/kernel/mt76/Makefile @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2025-10-20 -PKG_SOURCE_VERSION:=c63db0fcadb88680b35bec202b5142cfd016c10f -PKG_MIRROR_HASH:=38c3c84f5c58b6967283acf524412f6e13628d50add6f09d539f1239fb02b486 +PKG_SOURCE_DATE:=2025-11-06 +PKG_SOURCE_VERSION:=eb567bc7f9b692bbf1ddfe31dd740861c58ec85b +PKG_MIRROR_HASH:=7cfe242a5494cdf5d8e8eea86633778a525717528bcce70aedef96eee5594383 PKG_MAINTAINER:=Felix Fietkau PKG_USE_NINJA:=0 From 6c5c8598abf1736506bcc7b6aef006d7891d629d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 16 Nov 2025 15:17:32 +0100 Subject: [PATCH 080/128] mt76: Enable NPU support for Airoha AN7581 SoC Airoha AN7581 SoC supports a Network Processor (NPU) to offload WiFi traffic. Add the required bits to enable the support of it in the MT76 driver. This will be enabled by default if we are compiling for the Airoha AN7581 SoC. Signed-off-by: Lorenzo Bianconi [ improve commit title/description ] Link: https://github.com/openwrt/openwrt/pull/20826 Signed-off-by: Christian Marangi (cherry picked from commit 79d418eed8d86c528714df9fcd64155a8fb5ba49) --- package/kernel/mt76/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile index baced1baf1..3c7494a964 100644 --- a/package/kernel/mt76/Makefile +++ b/package/kernel/mt76/Makefile @@ -494,6 +494,12 @@ ifdef CONFIG_PACKAGE_kmod-mt7921e endif ifdef CONFIG_PACKAGE_kmod-mt7996e PKG_MAKE_FLAGS += CONFIG_MT7996E=m + ifdef CONFIG_TARGET_airoha_an7581 + PKG_MAKE_FLAGS += CONFIG_MT76_NPU=y + PKG_MAKE_FLAGS += CONFIG_MT7996_NPU=y + NOSTDINC_FLAGS += -DCONFIG_MT76_NPU + NOSTDINC_FLAGS += -DCONFIG_MT7996_NPU + endif endif ifdef CONFIG_PACKAGE_kmod-mt7925-common PKG_MAKE_FLAGS += CONFIG_MT7925_COMMON=m From 444299d70c12eb6b8543f990a62fbdd764798771 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 13 Oct 2025 13:03:48 +0200 Subject: [PATCH 081/128] kernel: backport mediatek WED DMA mask fixes Fixes issues on devices with 4 GB RAM. Signed-off-by: Felix Fietkau (cherry picked from commit 3632c0d3ce92802867b4aca9062c1d9b20f7b675) [ fix conflict errors ] Signed-off-by: Christian Marangi --- ...e-proper-wed-reference-in-mt76-wed-d.patch | 79 +++++++++++++++++++ ...dma-mask-limitation-and-GFP_DMA32-fo.patch | 50 ++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 target/linux/generic/backport-6.6/752-32-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch create mode 100644 target/linux/generic/backport-6.6/752-33-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch diff --git a/target/linux/generic/backport-6.6/752-32-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch b/target/linux/generic/backport-6.6/752-32-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch new file mode 100644 index 0000000000..883de549cd --- /dev/null +++ b/target/linux/generic/backport-6.6/752-32-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch @@ -0,0 +1,79 @@ +From: Lorenzo Bianconi +Date: Wed, 8 Oct 2025 12:41:48 +0200 +Subject: [PATCH] wifi: mt76: wed: use proper wed reference in mt76 wed driver + callabacks + +MT7996 driver can use both wed and wed_hif2 devices to offload traffic +from/to the wireless NIC. In the current codebase we assume to always +use the primary wed device in wed callbacks resulting in the following +crash if the hw runs wed_hif2 (e.g. 6GHz link). + +[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a +[ 297.464928] Mem abort info: +[ 297.467722] ESR = 0x0000000096000005 +[ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits +[ 297.476766] SET = 0, FnV = 0 +[ 297.479809] EA = 0, S1PTW = 0 +[ 297.482940] FSC = 0x05: level 1 translation fault +[ 297.487809] Data abort info: +[ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 +[ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000 +[ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000 +[ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP +[ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0 +[ 297.723908] Tainted: [O]=OOT_MODULE +[ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT) +[ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table] +[ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80 +[ 297.757126] sp : ffffffc080fe3ae0 +[ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7 +[ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00 +[ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018 +[ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000 +[ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000 +[ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da +[ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200 +[ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002 +[ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000 +[ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8 +[ 297.831686] Call trace: +[ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.839254] mtk_wed_flow_remove+0x58/0x80 +[ 297.843342] mtk_flow_offload_cmd+0x434/0x574 +[ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40 +[ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table] +[ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table] +[ 297.864463] process_one_work+0x174/0x300 +[ 297.868465] worker_thread+0x278/0x430 +[ 297.872204] kthread+0xd8/0xdc +[ 297.875251] ret_from_fork+0x10/0x20 +[ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421) +[ 297.884901] ---[ end trace 0000000000000000 ]--- + +Fix the issue detecting the proper wed reference to use running wed +callabacks. + +-- Partial backport for data structure change only (rest is in the mt76 package) + +Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support") +Tested-by: Daniel Pawlik +Tested-by: Matteo Croce +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -154,6 +154,7 @@ struct mtk_wed_device { + bool wcid_512; + bool hw_rro; + bool msi; ++ bool hif2; + + u16 token_start; + unsigned int nbuf; diff --git a/target/linux/generic/backport-6.6/752-33-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch b/target/linux/generic/backport-6.6/752-33-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch new file mode 100644 index 0000000000..c1bb1b972b --- /dev/null +++ b/target/linux/generic/backport-6.6/752-33-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch @@ -0,0 +1,50 @@ +From: Rex Lu +Date: Thu, 9 Oct 2025 08:29:34 +0200 +Subject: [PATCH] net: mtk: wed: add dma mask limitation and GFP_DMA32 for + device with more than 4GB DRAM + +Limit tx/rx buffer address to 32-bit address space for board with more +than 4GB DRAM. + +Fixes: 804775dfc2885 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") +Fixes: 6757d345dd7db ("net: ethernet: mtk_wed: introduce hw_rro support for MT7988") +Tested-by: Daniel Pawlik +Tested-by: Matteo Croce +Signed-off-by: Rex Lu +Co-developed-by: Lorenzo Bianconi +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -677,7 +677,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d + void *buf; + int s; + +- page = __dev_alloc_page(GFP_KERNEL); ++ page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32); + if (!page) + return -ENOMEM; + +@@ -800,7 +800,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_we + struct page *page; + int s; + +- page = __dev_alloc_page(GFP_KERNEL); ++ page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32); + if (!page) + return -ENOMEM; + +@@ -2438,6 +2438,10 @@ mtk_wed_attach(struct mtk_wed_device *de + dev->version = hw->version; + dev->hw->pcie_base = mtk_wed_get_pcie_base(dev); + ++ ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32)); ++ if (ret) ++ goto out; ++ + if (hw->eth->dma_dev == hw->eth->dev && + of_dma_is_coherent(hw->eth->dev->of_node)) + mtk_eth_set_dma_device(hw->eth, hw->dev); From 443fc115767f4f1c95fb8536c7e615c5371cc1da Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 22 Nov 2025 10:01:55 +0100 Subject: [PATCH 082/128] package: drop creating spurious tmp directory in feed directory In implementing APK support it seems a a leftover was never removed that creates an unused tmp directory in the package feed directory. Drop it as it's not used anywhere. What is actually needed is the creation of the $$(PDIR_$(1)) directory for the feed package directory in the bin/packages directory. This was a side effect of using INSTALL_DIR on $$(PDIR_$(1))/tmp that indirectly creates the $$(PDIR_$(1)) parent directory. Fixes: d788ab376f85 ("build: add APK package build capabilities") Signed-off-by: Christian Marangi (cherry picked from commit f9802d70c633e5c502466e7b276613362967c8cb) --- include/package-pack.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/package-pack.mk b/include/package-pack.mk index 9d06c8b647..aa734f5af0 100644 --- a/include/package-pack.mk +++ b/include/package-pack.mk @@ -248,7 +248,7 @@ endif ) endif - $(INSTALL_DIR) $$(PDIR_$(1))/tmp + $(INSTALL_DIR) $$(PDIR_$(1)) ifeq ($(CONFIG_USE_APK),) mkdir -p $$(IDIR_$(1))/CONTROL From 648fa1b6d38bc6a7a242a4786081b739a4bfe91d Mon Sep 17 00:00:00 2001 From: Goetz Goerisch Date: Tue, 25 Nov 2025 07:53:40 +0100 Subject: [PATCH 083/128] kernel: bump 6.6 to 6.6.117 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.117 Manually updated: bcm27xx/patches-6.6/950-0814-media-i2c-adv7180-Add-support-for-V4L2_CID_LINK_FREQ.patch Updated with Raspberry Pi patch. All patches auto-refreshed. Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20927 (cherry picked from commit 0337cdfb3370b6cd439b1bcaa7427523f2288cb1) Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/20952 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 +- ...rl-airoha-Add-support-for-EN7581-SoC.patch | 2 +- ...he-capability-to-consume-out-of-orde.patch | 26 +++++------ ...-airoha-deassert-XSI-line-on-hw-init.patch | 2 +- ...nitial-fixup-for-GDM3-4-port-support.patch | 2 +- ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 4 +- ...iroha-add-phylink-support-for-GDM2-4.patch | 16 +++---- ...oup-Disable-cgroup-memory-by-default.patch | 4 +- ...180-Default-to-the-first-valid-input.patch | 4 +- ...v7180-Add-YPrPb-support-for-ADV7282M.patch | 2 +- ...ce-quirks-for-Freeway-Airmouse-T3-an.patch | 4 +- ...7-Support-for-the-Sony-IMX477-sensor.patch | 2 +- ...9-Support-for-the-Sony-IMX519-sensor.patch | 2 +- ...vicetree-Add-documentation-for-imx37.patch | 2 +- ...CS_HIGH-if-GPIO-descriptors-are-used.patch | 4 +- ...-Nasty-hack-to-allow-input-selection.patch | 8 ++-- ...a-i2c-Add-IMX708-CMOS-sensor-binding.patch | 2 +- ...a-i2c-Replace-IMX708-sensor-binding-.patch | 2 +- ...ci_sync-Add-fallback-bd-address-prop.patch | 4 +- ...a-imx258-Rename-to-include-vendor-pr.patch | 2 +- ...nt-to-request-a-particular-dev-fbN-n.patch | 2 +- ...ndings-i2c-Add-Rohm-BU64754-bindings.patch | 2 +- ...2c-Add-driver-for-OmniVision-OV64A40.patch | 2 +- ...0-Use-MEDIA_BUS_FMT_UYVY8_1X16-for-C.patch | 4 +- ...0-Add-support-for-V4L2_CID_LINK_FREQ.patch | 46 ++++++++++--------- ...ible-to-apply-PWM-changes-in-atomic-.patch | 2 +- ...-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch | 2 +- ...s-Add-bindings-for-Raspberry-Pi-PiSP.patch | 2 +- ...-bindings-Add-RPI-RP2040-GPIO-Bridge.patch | 2 +- ...river-for-the-RPI-RP2040-GPIO-bridge.patch | 2 +- ...th-hci_sync-Fix-crash-on-NULL-parent.patch | 2 +- ...edia-dt-bindings-i2c-Add-Sony-IMX500.patch | 2 +- ...2c-Add-driver-for-Sony-IMX500-sensor.patch | 2 +- ...n-Maintain-TLB-coherency-in-LRU-code.patch | 2 +- ...l-command-line-to-disable-memory-cgr.patch | 4 +- ...-kernel-command-line-to-disable-memo.patch | 2 +- ...klog-NAPI-to-clean-up-the-defer_list.patch | 2 +- ...nt-API-support-for-32-bit-arch-with-.patch | 4 +- ...frag_count-handling-in-page_pool_is_.patch | 6 +-- ...ort-for-scanning-PHY-in-PHY-packages.patch | 4 +- ...c-move-TX-timer-arm-after-DMA-enable.patch | 12 ++--- ...-v6.9-r8169-add-support-for-RTL8126A.patch | 2 +- ...r8169-add-support-for-RTL8126A-rev.b.patch | 2 +- ...adjust-version-numbering-for-RTL8126.patch | 2 +- ...rge-chip-versions-70-and-71-RTL8126A.patch | 2 +- ...v6.16-r8169-add-support-for-RTL8127A.patch | 2 +- ...-nvmem-layouts-add-U-Boot-env-layout.patch | 2 +- ...y-to-free-deferred-skbs-while-waitin.patch | 4 +- .../721-net-add-packet-mangeling.patch | 2 +- .../780-usb-net-MeigLink_modem_support.patch | 4 +- .../generic/hack-6.6/902-debloat_proc.patch | 4 +- ...add-uImage.FIT-subimage-block-driver.patch | 2 +- ...680-net-add-TCP-fraglist-GRO-support.patch | 4 +- ...les-ignore-EOPNOTSUPP-on-flowtable-d.patch | 2 +- ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 4 +- .../810-pci_disable_common_quirks.patch | 6 +-- ...msm-use-sdhci_set_clock-instead-of-s.patch | 2 +- ...m-comment-unused-sdhci_msm_set_clock.patch | 2 +- ...introduce-the-Qualcomm-IPQESS-driver.patch | 2 +- ...dsa-add-out-of-band-tagging-protocol.patch | 4 +- ...-negotiation-of-in-band-capabilities.patch | 6 +-- .../810-uvc-add-iPassion-iP2970-support.patch | 2 +- ...NTAINERS-Update-all-StarFive-entries.patch | 18 ++++---- ...ove-performance-usb-using-lowmem-for.patch | 2 +- ...ma_alloc_noncoherent-to-alloc-low-me.patch | 2 +- .../1009-net-stmmac-use-GFP_DMA32.patch | 2 +- ...arfive-Add-JH7100-audio-reset-driver.patch | 2 +- 67 files changed, 148 insertions(+), 146 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index 6bedc40098..3a848b96e5 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .116 -LINUX_KERNEL_HASH-6.6.116 = a9a59742c29be284c205dc87cbe9b065f9688488132c8f5a6057a5539230a51d +LINUX_VERSION-6.6 = .117 +LINUX_KERNEL_HASH-6.6.117 = 643b31079222fdbda70cfdd0b68c514f05a3926104be4762a4685f62818b43d1 diff --git a/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch index 502f89f26d..a7d38881ed 100644 --- a/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch +++ b/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch @@ -29,7 +29,7 @@ Signed-off-by: Linus Walleij --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -16871,6 +16871,13 @@ F: drivers/pinctrl/ +@@ -16872,6 +16872,13 @@ F: drivers/pinctrl/ F: include/dt-bindings/pinctrl/ F: include/linux/pinctrl/ diff --git a/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch b/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch index b09ebd57b4..29bca55364 100644 --- a/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch +++ b/target/linux/airoha/patches-6.6/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch @@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -892,19 +892,13 @@ static int airoha_qdma_tx_napi_poll(stru +@@ -893,19 +893,13 @@ static int airoha_qdma_tx_napi_poll(stru dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, DMA_TO_DEVICE); @@ -46,7 +46,7 @@ Signed-off-by: Jakub Kicinski if (skb) { u16 queue = skb_get_queue_mapping(skb); struct netdev_queue *txq; -@@ -949,6 +943,7 @@ static int airoha_qdma_init_tx_queue(str +@@ -950,6 +944,7 @@ static int airoha_qdma_init_tx_queue(str q->ndesc = size; q->qdma = qdma; q->free_thr = 1 + MAX_SKB_FRAGS; @@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), GFP_KERNEL); -@@ -961,9 +956,9 @@ static int airoha_qdma_init_tx_queue(str +@@ -962,9 +957,9 @@ static int airoha_qdma_init_tx_queue(str return -ENOMEM; for (i = 0; i < q->ndesc; i++) { @@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); } -@@ -973,9 +968,9 @@ static int airoha_qdma_init_tx_queue(str +@@ -974,9 +969,9 @@ static int airoha_qdma_init_tx_queue(str airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, @@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski return 0; } -@@ -1031,17 +1026,21 @@ static int airoha_qdma_init_tx(struct ai +@@ -1032,17 +1027,21 @@ static int airoha_qdma_init_tx(struct ai static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) { struct airoha_eth *eth = q->qdma->eth; @@ -104,7 +104,7 @@ Signed-off-by: Jakub Kicinski q->queued--; } spin_unlock_bh(&q->lock); -@@ -1883,20 +1882,6 @@ static u32 airoha_get_dsa_tag(struct sk_ +@@ -1884,20 +1883,6 @@ static u32 airoha_get_dsa_tag(struct sk_ #endif } @@ -125,7 +125,7 @@ Signed-off-by: Jakub Kicinski static int airoha_get_fe_port(struct airoha_gdm_port *port) { struct airoha_qdma *qdma = port->qdma; -@@ -1919,8 +1904,10 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1920,8 +1905,10 @@ static netdev_tx_t airoha_dev_xmit(struc struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; u32 nr_frags, tag, msg0, msg1, len; @@ -136,7 +136,7 @@ Signed-off-by: Jakub Kicinski void *data; int i, qid; u16 index; -@@ -1966,7 +1953,7 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1967,7 +1954,7 @@ static netdev_tx_t airoha_dev_xmit(struc txq = netdev_get_tx_queue(dev, qid); nr_frags = 1 + skb_shinfo(skb)->nr_frags; @@ -145,7 +145,7 @@ Signed-off-by: Jakub Kicinski /* not enough space in the queue */ netif_tx_stop_queue(txq); spin_unlock_bh(&q->lock); -@@ -1975,11 +1962,13 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1976,11 +1963,13 @@ static netdev_tx_t airoha_dev_xmit(struc len = skb_headlen(skb); data = skb->data; @@ -161,7 +161,7 @@ Signed-off-by: Jakub Kicinski skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; dma_addr_t addr; u32 val; -@@ -1989,7 +1978,14 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -1990,7 +1979,14 @@ static netdev_tx_t airoha_dev_xmit(struc if (unlikely(dma_mapping_error(dev->dev.parent, addr))) goto error_unmap; @@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); if (i < nr_frags - 1) -@@ -2002,15 +1998,9 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -2003,15 +1999,9 @@ static netdev_tx_t airoha_dev_xmit(struc WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); @@ -193,7 +193,7 @@ Signed-off-by: Jakub Kicinski q->queued += i; skb_tx_timestamp(skb); -@@ -2019,7 +2009,7 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -2020,7 +2010,7 @@ static netdev_tx_t airoha_dev_xmit(struc if (netif_xmit_stopped(txq) || !netdev_xmit_more()) airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, @@ -202,7 +202,7 @@ Signed-off-by: Jakub Kicinski if (q->ndesc - q->queued < q->free_thr) netif_tx_stop_queue(txq); -@@ -2029,10 +2019,13 @@ static netdev_tx_t airoha_dev_xmit(struc +@@ -2030,10 +2020,13 @@ static netdev_tx_t airoha_dev_xmit(struc return NETDEV_TX_OK; error_unmap: diff --git a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch index e1e6baed40..d7e312dfcf 100644 --- a/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ b/target/linux/airoha/patches-6.6/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1384,6 +1384,10 @@ static int airoha_hw_init(struct platfor +@@ -1383,6 +1383,10 @@ static int airoha_hw_init(struct platfor if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index 5750bc3dbb..7b395bfcb7 100644 --- a/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.6/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi airoha_fe_crsn_qsel_init(eth); -@@ -1626,7 +1628,8 @@ static int airoha_dev_open(struct net_de +@@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de if (err) return err; diff --git a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index 5da8a24a7e..e6b7730db0 100644 --- a/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.6/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3096,7 +3096,6 @@ static void airoha_remove(struct platfor +@@ -3089,7 +3089,6 @@ static void airoha_remove(struct platfor } static const char * const en7581_xsi_rsts_names[] = { @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi "hsi0-mac", "hsi1-mac", "hsi-mac", -@@ -3128,7 +3127,6 @@ static int airoha_en7581_get_src_port_id +@@ -3121,7 +3120,6 @@ static int airoha_en7581_get_src_port_id } static const char * const an7583_xsi_rsts_names[] = { diff --git a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index ac17676436..6e7b7dfa13 100644 --- a/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.6/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { struct airoha_eth *eth = port->qdma->eth; -@@ -1623,6 +1629,17 @@ static int airoha_dev_open(struct net_de +@@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); if (err) -@@ -1676,6 +1693,11 @@ static int airoha_dev_stop(struct net_de +@@ -1675,6 +1692,11 @@ static int airoha_dev_stop(struct net_de } } @@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi return 0; } -@@ -2824,6 +2846,20 @@ static const struct ethtool_ops airoha_e +@@ -2817,6 +2839,20 @@ static const struct ethtool_ops airoha_e .get_link = ethtool_op_get_link, }; @@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { int i; -@@ -2868,6 +2904,99 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2861,6 +2897,99 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { -@@ -2946,6 +3075,12 @@ static int airoha_alloc_gdm_port(struct +@@ -2939,6 +3068,12 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3061,6 +3196,10 @@ error_hw_cleanup: +@@ -3054,6 +3189,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3088,6 +3227,10 @@ static void airoha_remove(struct platfor +@@ -3081,6 +3220,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -531,6 +531,10 @@ struct airoha_gdm_port { +@@ -536,6 +536,10 @@ struct airoha_gdm_port { struct net_device *dev; int id; diff --git a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch index eb29af01c1..b3cce67f3b 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch @@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell for_each_subsys(ss, ssid) { if (ss->early_init) { struct cgroup_subsys_state *css = -@@ -6769,6 +6778,10 @@ static int __init cgroup_disable(char *s +@@ -6785,6 +6794,10 @@ static int __init cgroup_disable(char *s strcmp(token, ss->legacy_name)) continue; @@ -51,7 +51,7 @@ Signed-off-by: Phil Elwell static_branch_disable(cgroup_subsys_enabled_key[i]); pr_info("Disabling %s control group subsystem\n", ss->name); -@@ -6787,6 +6800,31 @@ static int __init cgroup_disable(char *s +@@ -6803,6 +6816,31 @@ static int __init cgroup_disable(char *s } __setup("cgroup_disable=", cgroup_disable); diff --git a/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch b/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch index 181b69b807..7669317e60 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch @@ -16,7 +16,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c -@@ -1350,6 +1350,7 @@ static const struct adv7180_chip_info ad +@@ -1340,6 +1340,7 @@ static const struct adv7180_chip_info ad static int init_device(struct adv7180_state *state) { int ret; @@ -24,7 +24,7 @@ Signed-off-by: Dave Stevenson mutex_lock(&state->mutex); -@@ -1397,6 +1398,18 @@ static int init_device(struct adv7180_st +@@ -1387,6 +1388,18 @@ static int init_device(struct adv7180_st goto out_unlock; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch b/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch index caa83f409f..faaf79f2ae 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch @@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c -@@ -1339,6 +1339,7 @@ static const struct adv7180_chip_info ad +@@ -1329,6 +1329,7 @@ static const struct adv7180_chip_info ad BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) | BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) | BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) | diff --git a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch index 96c04d52c7..c460bf78ff 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch @@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 -@@ -1449,6 +1452,9 @@ +@@ -1453,6 +1456,9 @@ #define USB_VENDOR_ID_XIAOMI 0x2717 #define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014 @@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL }, -@@ -213,6 +214,7 @@ static const struct hid_device_id hid_qu +@@ -215,6 +216,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET }, diff --git a/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch index 264b3ca376..08ba072318 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch @@ -343,7 +343,7 @@ Signed-off-by: Naushir Patuck +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20058,6 +20058,14 @@ T: git git://linuxtv.org/media_tree.git +@@ -20059,6 +20059,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml F: drivers/media/i2c/imx415.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch index 2ba00932c2..240c63509c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch @@ -177,7 +177,7 @@ Signed-off-by: Phil Elwell +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20066,6 +20066,14 @@ T: git git://linuxtv.org/media_tree.git +@@ -20067,6 +20067,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx477.yaml F: drivers/media/i2c/imx477.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch b/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch index 019ca418ae..3af5c0e95c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch @@ -132,7 +132,7 @@ Signed-off-by: David Plowman +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20063,6 +20063,7 @@ M: Raspberry Pi Kernel Maintenance --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c -@@ -3747,6 +3747,7 @@ static int spi_set_cs_timing(struct spi_ +@@ -3757,6 +3757,7 @@ static int spi_set_cs_timing(struct spi_ */ int spi_setup(struct spi_device *spi) { @@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell unsigned bad_bits, ugly_bits; int status = 0; -@@ -3767,6 +3768,14 @@ int spi_setup(struct spi_device *spi) +@@ -3777,6 +3778,14 @@ int spi_setup(struct spi_device *spi) (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) return -EINVAL; diff --git a/target/linux/bcm27xx/patches-6.6/950-0395-media-adv7180-Nasty-hack-to-allow-input-selection.patch b/target/linux/bcm27xx/patches-6.6/950-0395-media-adv7180-Nasty-hack-to-allow-input-selection.patch index 22168e3c4e..7dc86ae220 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0395-media-adv7180-Nasty-hack-to-allow-input-selection.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0395-media-adv7180-Nasty-hack-to-allow-input-selection.patch @@ -31,7 +31,7 @@ Signed-off-by: Dave Stevenson struct adv7180_state; #define ADV7180_FLAG_RESET_POWERED BIT(0) -@@ -407,10 +411,24 @@ out: +@@ -402,10 +406,24 @@ out: return ret; } @@ -57,7 +57,7 @@ Signed-off-by: Dave Stevenson if (ret) return ret; -@@ -436,7 +454,11 @@ static int adv7180_program_std(struct ad +@@ -431,7 +449,11 @@ static int adv7180_program_std(struct ad static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) { struct adv7180_state *state = to_state(sd); @@ -70,7 +70,7 @@ Signed-off-by: Dave Stevenson if (ret) return ret; -@@ -458,6 +480,8 @@ static int adv7180_g_std(struct v4l2_sub +@@ -453,6 +475,8 @@ static int adv7180_g_std(struct v4l2_sub { struct adv7180_state *state = to_state(sd); @@ -79,7 +79,7 @@ Signed-off-by: Dave Stevenson *norm = state->curr_norm; return 0; -@@ -891,6 +915,8 @@ static int adv7180_s_stream(struct v4l2_ +@@ -881,6 +905,8 @@ static int adv7180_s_stream(struct v4l2_ return 0; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0407-dtbindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch b/target/linux/bcm27xx/patches-6.6/950-0407-dtbindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch index 5962bb3fbb..986922d799 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0407-dtbindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0407-dtbindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch @@ -138,7 +138,7 @@ Signed-off-by: Dave Stevenson +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20107,6 +20107,14 @@ T: git git://linuxtv.org/media_tree.git +@@ -20108,6 +20108,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx519.yaml F: drivers/media/i2c/imx519.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0434-dt-bindings-media-i2c-Replace-IMX708-sensor-binding-.patch b/target/linux/bcm27xx/patches-6.6/950-0434-dt-bindings-media-i2c-Replace-IMX708-sensor-binding-.patch index 5c8457c869..f3d68c4546 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0434-dt-bindings-media-i2c-Replace-IMX708-sensor-binding-.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0434-dt-bindings-media-i2c-Replace-IMX708-sensor-binding-.patch @@ -271,7 +271,7 @@ Signed-off-by: Naushir Patuck +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20112,7 +20112,7 @@ M: Raspberry Pi Kernel Maintenance --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4936,6 +4936,7 @@ static const struct { +@@ -4941,6 +4941,7 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { @@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell int ret = 0; bool invalid_bdaddr; size_t i; -@@ -4964,7 +4965,8 @@ static int hci_dev_setup_sync(struct hci +@@ -4969,7 +4970,8 @@ static int hci_dev_setup_sync(struct hci test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); if (!ret) { if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) && diff --git a/target/linux/bcm27xx/patches-6.6/950-0460-dt-bindings-media-imx258-Rename-to-include-vendor-pr.patch b/target/linux/bcm27xx/patches-6.6/950-0460-dt-bindings-media-imx258-Rename-to-include-vendor-pr.patch index 9a10fe7315..50ae214755 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0460-dt-bindings-media-imx258-Rename-to-include-vendor-pr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0460-dt-bindings-media-imx258-Rename-to-include-vendor-pr.patch @@ -291,7 +291,7 @@ Signed-off-by: Dave Stevenson + }; --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20013,7 +20013,7 @@ M: Sakari Ailus #ifdef CONFIG_GUMSTIX_AM200EPD { -@@ -1046,6 +1049,12 @@ static void do_unregister_framebuffer(st +@@ -1047,6 +1050,12 @@ static void do_unregister_framebuffer(st put_fb_info(fb_info); } diff --git a/target/linux/bcm27xx/patches-6.6/950-0767-media-dt-bindings-i2c-Add-Rohm-BU64754-bindings.patch b/target/linux/bcm27xx/patches-6.6/950-0767-media-dt-bindings-i2c-Add-Rohm-BU64754-bindings.patch index 2d32590927..607954b209 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0767-media-dt-bindings-i2c-Add-Rohm-BU64754-bindings.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0767-media-dt-bindings-i2c-Add-Rohm-BU64754-bindings.patch @@ -67,7 +67,7 @@ Signed-off-by: Jacopo Mondi +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -18620,6 +18620,13 @@ S: Supported +@@ -18621,6 +18621,13 @@ S: Supported F: drivers/iio/light/rohm-bu27008.c F: drivers/iio/light/rohm-bu27034.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0768-media-i2c-Add-driver-for-OmniVision-OV64A40.patch b/target/linux/bcm27xx/patches-6.6/950-0768-media-i2c-Add-driver-for-OmniVision-OV64A40.patch index 477ac8319f..6075a9d5e7 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0768-media-i2c-Add-driver-for-OmniVision-OV64A40.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0768-media-i2c-Add-driver-for-OmniVision-OV64A40.patch @@ -16,7 +16,7 @@ Signed-off-by: Jacopo Mondi --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -15872,6 +15872,14 @@ S: Maintained +@@ -15873,6 +15873,14 @@ S: Maintained T: git git://linuxtv.org/media_tree.git F: drivers/media/i2c/ov5695.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0813-media-i2c-adv7180-Use-MEDIA_BUS_FMT_UYVY8_1X16-for-C.patch b/target/linux/bcm27xx/patches-6.6/950-0813-media-i2c-adv7180-Use-MEDIA_BUS_FMT_UYVY8_1X16-for-C.patch index efb0fad7fe..10c014b3bf 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0813-media-i2c-adv7180-Use-MEDIA_BUS_FMT_UYVY8_1X16-for-C.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0813-media-i2c-adv7180-Use-MEDIA_BUS_FMT_UYVY8_1X16-for-C.patch @@ -17,7 +17,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c -@@ -728,10 +728,15 @@ static int adv7180_enum_mbus_code(struct +@@ -723,10 +723,15 @@ static int adv7180_enum_mbus_code(struct struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { @@ -34,7 +34,7 @@ Signed-off-by: Dave Stevenson return 0; } -@@ -741,7 +746,10 @@ static int adv7180_mbus_fmt(struct v4l2_ +@@ -736,7 +741,10 @@ static int adv7180_mbus_fmt(struct v4l2_ { struct adv7180_state *state = to_state(sd); diff --git a/target/linux/bcm27xx/patches-6.6/950-0814-media-i2c-adv7180-Add-support-for-V4L2_CID_LINK_FREQ.patch b/target/linux/bcm27xx/patches-6.6/950-0814-media-i2c-adv7180-Add-support-for-V4L2_CID_LINK_FREQ.patch index 20de51aabb..72f19418f0 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0814-media-i2c-adv7180-Add-support-for-V4L2_CID_LINK_FREQ.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0814-media-i2c-adv7180-Add-support-for-V4L2_CID_LINK_FREQ.patch @@ -1,18 +1,13 @@ -From 3e7d0d9be5353186136c661e551ad442bba50e45 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 21 Dec 2023 18:03:34 +0000 -Subject: [PATCH 0814/1085] media: i2c: adv7180: Add support for - V4L2_CID_LINK_FREQ +From 954129f16c200e41a00ebebe2e22efc01b243538 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Fri, 14 Nov 2025 14:08:18 +0000 +Subject: [PATCH] Revert "Revert "media: i2c: adv7180: Add support for + V4L2_CID_LINK_FREQ"" -For CSI2 receivers that need to know the link frequency, -add it as a control to the driver. -Interlaced modes are 216Mbp/s or 108MHz, whilst going through -the I2P to deinterlace gives 432Mb/s or 216MHz. - -Signed-off-by: Dave Stevenson +This reverts commit 00ecb85c58501f8f7ae75fcb069bbbad5542e853. --- - drivers/media/i2c/adv7180.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) + drivers/media/i2c/adv7180.c | 39 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 37 insertions(+), 2 deletions(-) --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -41,7 +36,7 @@ Signed-off-by: Dave Stevenson }; #define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \ struct adv7180_state, \ -@@ -621,6 +632,9 @@ static int adv7180_s_ctrl(struct v4l2_ct +@@ -616,6 +627,9 @@ static int adv7180_s_ctrl(struct v4l2_ct if (ret) return ret; @@ -51,7 +46,7 @@ Signed-off-by: Dave Stevenson val = ctrl->val; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: -@@ -662,6 +676,7 @@ static int adv7180_s_ctrl(struct v4l2_ct +@@ -657,6 +671,7 @@ static int adv7180_s_ctrl(struct v4l2_ct ret = -EINVAL; } @@ -59,7 +54,7 @@ Signed-off-by: Dave Stevenson mutex_unlock(&state->mutex); return ret; } -@@ -682,7 +697,7 @@ static const struct v4l2_ctrl_config adv +@@ -677,7 +692,7 @@ static const struct v4l2_ctrl_config adv static int adv7180_init_controls(struct adv7180_state *state) { @@ -68,7 +63,7 @@ Signed-off-by: Dave Stevenson v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops, V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN, -@@ -708,6 +723,17 @@ static int adv7180_init_controls(struct +@@ -703,6 +718,17 @@ static int adv7180_init_controls(struct test_pattern_menu); } @@ -86,14 +81,21 @@ Signed-off-by: Dave Stevenson state->sd.ctrl_handler = &state->ctrl_hdl; if (state->ctrl_hdl.error) { int err = state->ctrl_hdl.error; -@@ -840,6 +866,10 @@ static int adv7180_set_pad_format(struct - adv7180_set_power(state, false); - adv7180_set_field_mode(state); - adv7180_set_power(state, true); +@@ -830,7 +856,16 @@ static int adv7180_set_pad_format(struct + ret = adv7180_mbus_fmt(sd, &format->format); + + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { +- state->field = format->format.field; ++ if (state->field != format->format.field) { ++ state->field = format->format.field; ++ adv7180_set_power(state, false); ++ adv7180_set_field_mode(state); ++ adv7180_set_power(state, true); + if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) + __v4l2_ctrl_s_ctrl(state->link_freq, + (state->field == V4L2_FIELD_NONE) ? + I2P_IDX : INTERLACED_IDX); - } ++ } } else { framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0); + *framefmt = format->format; diff --git a/target/linux/bcm27xx/patches-6.6/950-1128-pwm-Make-it-possible-to-apply-PWM-changes-in-atomic-.patch b/target/linux/bcm27xx/patches-6.6/950-1128-pwm-Make-it-possible-to-apply-PWM-changes-in-atomic-.patch index 2441e8223e..3377683128 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1128-pwm-Make-it-possible-to-apply-PWM-changes-in-atomic-.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1128-pwm-Make-it-possible-to-apply-PWM-changes-in-atomic-.patch @@ -48,7 +48,7 @@ Signed-off-by: Thierry Reding drivers cannot. If you rely on getting the inactive state, use .duty_cycle=0, --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -17438,7 +17438,7 @@ F: drivers/video/backlight/pwm_bl.c +@@ -17439,7 +17439,7 @@ F: drivers/video/backlight/pwm_bl.c F: include/dt-bindings/pwm/ F: include/linux/pwm.h F: include/linux/pwm_backlight.h diff --git a/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch index a95742b475..a2e36d50d6 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch @@ -23,7 +23,7 @@ Signed-off-by: Jacopo Mondi --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -18033,6 +18033,13 @@ L: linux-wireless@vger.kernel.org +@@ -18034,6 +18034,13 @@ L: linux-wireless@vger.kernel.org S: Orphan F: drivers/net/wireless/legacy/ray* diff --git a/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch index e6f15fa471..12f91d9784 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch @@ -87,7 +87,7 @@ Reviewed-by: Naushir Patuck + }; --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -18038,6 +18038,7 @@ M: Jacopo Mondi L: linux-media@vger.kernel.org S: Maintained diff --git a/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch index abdf8157a5..785b36e3cf 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch @@ -94,7 +94,7 @@ Signed-off-by: Richard Oliver + --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -18028,6 +18028,11 @@ F: drivers/ras/ +@@ -18029,6 +18029,11 @@ F: drivers/ras/ F: include/linux/ras.h F: include/ras/ras_event.h diff --git a/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch index 3d977db80d..2ae7494e8e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch @@ -25,7 +25,7 @@ Signed-off-by: Richard Oliver --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -18032,6 +18032,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER +@@ -18033,6 +18033,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER M: Raspberry Pi Kernel Maintenance S: Maintained F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml diff --git a/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch index a14c5389c0..5b254943b4 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4936,7 +4936,8 @@ static const struct { +@@ -4941,7 +4941,8 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { diff --git a/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch b/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch index cfd4b46d4f..d4979f73e0 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch @@ -150,7 +150,7 @@ Signed-off-by: Richard Oliver + --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20128,6 +20128,13 @@ F: Documentation/devicetree/bindings/med +@@ -20129,6 +20129,13 @@ F: Documentation/devicetree/bindings/med F: Documentation/devicetree/bindings/media/i2c/imx477.yaml F: drivers/media/i2c/imx477.c diff --git a/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch index c6b9196a52..12e5e2b9e4 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch @@ -21,7 +21,7 @@ Signed-off-by: Richard Oliver --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20134,6 +20134,7 @@ L: linux-media@vger.kernel.org +@@ -20135,6 +20135,7 @@ L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml diff --git a/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch b/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch index 3c60865aa7..bd5aff311b 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/mm/vmscan.c +++ b/mm/vmscan.c -@@ -4723,7 +4723,7 @@ void lru_gen_look_around(struct page_vma +@@ -4724,7 +4724,7 @@ void lru_gen_look_around(struct page_vma if (!folio) continue; diff --git a/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch b/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch index 7946586d40..af8543bb10 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch @@ -171,7 +171,7 @@ Signed-off-by: Maíra Canal for_each_subsys(ss, ssid) { if (ss->early_init) { struct cgroup_subsys_state *css = -@@ -6778,10 +6769,6 @@ static int __init cgroup_disable(char *s +@@ -6794,10 +6785,6 @@ static int __init cgroup_disable(char *s strcmp(token, ss->legacy_name)) continue; @@ -182,7 +182,7 @@ Signed-off-by: Maíra Canal static_branch_disable(cgroup_subsys_enabled_key[i]); pr_info("Disabling %s control group subsystem\n", ss->name); -@@ -6815,7 +6802,7 @@ static int __init cgroup_enable(char *st +@@ -6831,7 +6818,7 @@ static int __init cgroup_enable(char *st strcmp(token, ss->legacy_name)) continue; diff --git a/target/linux/bcm27xx/patches-6.6/950-1445-fixup-cgroup-Use-kernel-command-line-to-disable-memo.patch b/target/linux/bcm27xx/patches-6.6/950-1445-fixup-cgroup-Use-kernel-command-line-to-disable-memo.patch index 5241744b2c..9a0f438e7a 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1445-fixup-cgroup-Use-kernel-command-line-to-disable-memo.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1445-fixup-cgroup-Use-kernel-command-line-to-disable-memo.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c -@@ -6802,11 +6802,19 @@ static int __init cgroup_enable(char *st +@@ -6818,11 +6818,19 @@ static int __init cgroup_enable(char *st strcmp(token, ss->legacy_name)) continue; diff --git a/target/linux/generic/backport-6.6/602-v6.10-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch b/target/linux/generic/backport-6.6/602-v6.10-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch index d6ef75db69..90d1032cd0 100644 --- a/target/linux/generic/backport-6.6/602-v6.10-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch +++ b/target/linux/generic/backport-6.6/602-v6.10-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch @@ -108,7 +108,7 @@ Signed-off-by: Paolo Abeni #endif --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -6863,8 +6863,8 @@ nodefer: __kfree_skb(skb); +@@ -6867,8 +6867,8 @@ nodefer: __kfree_skb(skb); /* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU * if we are unlucky enough (this seems very unlikely). */ diff --git a/target/linux/generic/backport-6.6/620-01-v6.7-page_pool-fragment-API-support-for-32-bit-arch-with-.patch b/target/linux/generic/backport-6.6/620-01-v6.7-page_pool-fragment-API-support-for-32-bit-arch-with-.patch index 0f57e2ec66..5e30465179 100644 --- a/target/linux/generic/backport-6.6/620-01-v6.7-page_pool-fragment-API-support-for-32-bit-arch-with-.patch +++ b/target/linux/generic/backport-6.6/620-01-v6.7-page_pool-fragment-API-support-for-32-bit-arch-with-.patch @@ -104,7 +104,7 @@ Signed-off-by: Jakub Kicinski static inline bool page_pool_put(struct page_pool *pool) --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -211,10 +211,6 @@ static int page_pool_init(struct page_po +@@ -207,10 +207,6 @@ static int page_pool_init(struct page_po */ } @@ -115,7 +115,7 @@ Signed-off-by: Jakub Kicinski #ifdef CONFIG_PAGE_POOL_STATS pool->recycle_stats = alloc_percpu(struct page_pool_recycle_stats); if (!pool->recycle_stats) -@@ -363,12 +359,20 @@ static bool page_pool_dma_map(struct pag +@@ -359,12 +355,20 @@ static bool page_pool_dma_map(struct pag if (dma_mapping_error(pool->p.dev, dma)) return false; diff --git a/target/linux/generic/backport-6.6/620-02-v6.7-page_pool-unify-frag_count-handling-in-page_pool_is_.patch b/target/linux/generic/backport-6.6/620-02-v6.7-page_pool-unify-frag_count-handling-in-page_pool_is_.patch index 1ad0eb449d..c238a8847a 100644 --- a/target/linux/generic/backport-6.6/620-02-v6.7-page_pool-unify-frag_count-handling-in-page_pool_is_.patch +++ b/target/linux/generic/backport-6.6/620-02-v6.7-page_pool-unify-frag_count-handling-in-page_pool_is_.patch @@ -147,7 +147,7 @@ Signed-off-by: Jakub Kicinski page_pool_put_defragged_page(pool, page, dma_sync_size, allow_direct); --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -380,6 +380,14 @@ static void page_pool_set_pp_info(struct +@@ -376,6 +376,14 @@ static void page_pool_set_pp_info(struct { page->pp = pool; page->pp_magic |= PP_SIGNATURE; @@ -162,7 +162,7 @@ Signed-off-by: Jakub Kicinski if (pool->p.init_callback) pool->p.init_callback(page, pool->p.init_arg); } -@@ -676,7 +684,7 @@ void page_pool_put_page_bulk(struct page +@@ -678,7 +686,7 @@ void page_pool_put_page_bulk(struct page struct page *page = virt_to_head_page(data[i]); /* It is not the last user for the page frag case */ @@ -171,7 +171,7 @@ Signed-off-by: Jakub Kicinski continue; page = __page_pool_put_page(pool, page, -1, false); -@@ -752,8 +760,7 @@ struct page *page_pool_alloc_frag(struct +@@ -754,8 +762,7 @@ struct page *page_pool_alloc_frag(struct unsigned int max_size = PAGE_SIZE << pool->p.order; struct page *page = pool->frag_page; diff --git a/target/linux/generic/backport-6.6/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch b/target/linux/generic/backport-6.6/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch index 9a2b082001..af2cba11df 100644 --- a/target/linux/generic/backport-6.6/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch +++ b/target/linux/generic/backport-6.6/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch @@ -143,7 +143,7 @@ Signed-off-by: David S. Miller } --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c -@@ -456,19 +456,34 @@ EXPORT_SYMBOL(of_mdio_find_bus); +@@ -459,19 +459,34 @@ EXPORT_SYMBOL(of_mdio_find_bus); * found, set the of_node pointer for the mdio device. This allows * auto-probed phy devices to be supplied with information passed in * via DT. @@ -185,7 +185,7 @@ Signed-off-by: David S. Miller addr = of_mdio_parse_addr(dev, child); if (addr < 0) continue; -@@ -478,9 +493,22 @@ static void of_mdiobus_link_mdiodev(stru +@@ -481,9 +496,22 @@ static void of_mdiobus_link_mdiodev(stru /* The refcount on "child" is passed to the mdio * device. Do _not_ use of_node_put(child) here. */ diff --git a/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch b/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch index 00829a15df..fd0d9047c0 100644 --- a/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch +++ b/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch @@ -42,7 +42,7 @@ Signed-off-by: Paolo Abeni u64_stats_update_begin(&txq_stats->napi_syncp); u64_stats_add(&txq_stats->napi.tx_packets, tx_packets); -@@ -5611,6 +5615,7 @@ static int stmmac_napi_poll_tx(struct na +@@ -5609,6 +5613,7 @@ static int stmmac_napi_poll_tx(struct na container_of(napi, struct stmmac_channel, tx_napi); struct stmmac_priv *priv = ch->priv_data; struct stmmac_txq_stats *txq_stats; @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni u32 chan = ch->index; int work_done; -@@ -5619,7 +5624,7 @@ static int stmmac_napi_poll_tx(struct na +@@ -5617,7 +5622,7 @@ static int stmmac_napi_poll_tx(struct na u64_stats_inc(&txq_stats->napi.poll); u64_stats_update_end(&txq_stats->napi_syncp); @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni work_done = min(work_done, budget); if (work_done < budget && napi_complete_done(napi, work_done)) { -@@ -5630,6 +5635,10 @@ static int stmmac_napi_poll_tx(struct na +@@ -5628,6 +5633,10 @@ static int stmmac_napi_poll_tx(struct na spin_unlock_irqrestore(&ch->lock, flags); } @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni return work_done; } -@@ -5638,6 +5647,7 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5636,6 +5645,7 @@ static int stmmac_napi_poll_rxtx(struct struct stmmac_channel *ch = container_of(napi, struct stmmac_channel, rxtx_napi); struct stmmac_priv *priv = ch->priv_data; @@ -78,7 +78,7 @@ Signed-off-by: Paolo Abeni int rx_done, tx_done, rxtx_done; struct stmmac_rxq_stats *rxq_stats; struct stmmac_txq_stats *txq_stats; -@@ -5653,7 +5663,7 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5651,7 +5661,7 @@ static int stmmac_napi_poll_rxtx(struct u64_stats_inc(&txq_stats->napi.poll); u64_stats_update_end(&txq_stats->napi_syncp); @@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni tx_done = min(tx_done, budget); rx_done = stmmac_rx_zc(priv, budget, chan); -@@ -5678,6 +5688,10 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5676,6 +5686,10 @@ static int stmmac_napi_poll_rxtx(struct spin_unlock_irqrestore(&ch->lock, flags); } diff --git a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch index 27f9637f1b..4c4b89b951 100644 --- a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch +++ b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch @@ -221,7 +221,7 @@ Signed-off-by: David S. Miller if (tp->mac_version == RTL_GIGA_MAC_VER_63) r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000); @@ -3611,6 +3645,10 @@ static void rtl_hw_start_8125_common(str - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000); r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); + if (tp->mac_version == RTL_GIGA_MAC_VER_65) diff --git a/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch index bbe6928885..a921806bb6 100644 --- a/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch +++ b/target/linux/generic/backport-6.6/780-22-v6.12-r8169-add-support-for-RTL8126A-rev.b.patch @@ -181,7 +181,7 @@ Signed-off-by: Jakub Kicinski else if (tp->mac_version == RTL_GIGA_MAC_VER_63) r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); @@ -3739,7 +3748,8 @@ static void rtl_hw_start_8125_common(str - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000); r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); - if (tp->mac_version == RTL_GIGA_MAC_VER_65) diff --git a/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch b/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch index 6f1f9c177a..b1678bb9ac 100644 --- a/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch +++ b/target/linux/generic/backport-6.6/780-47-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch @@ -183,7 +183,7 @@ Signed-off-by: Jakub Kicinski else if (tp->mac_version == RTL_GIGA_MAC_VER_63) r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); @@ -3720,8 +3720,8 @@ static void rtl_hw_start_8125_common(str - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000); r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); - if (tp->mac_version == RTL_GIGA_MAC_VER_65 || diff --git a/target/linux/generic/backport-6.6/780-62-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch b/target/linux/generic/backport-6.6/780-62-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch index 08f7d4f90a..1feff1526a 100644 --- a/target/linux/generic/backport-6.6/780-62-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch +++ b/target/linux/generic/backport-6.6/780-62-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch @@ -69,7 +69,7 @@ Signed-off-by: Jakub Kicinski else if (tp->mac_version == RTL_GIGA_MAC_VER_63) r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); @@ -3718,8 +3714,7 @@ static void rtl_hw_start_8125_common(str - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000); r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); - if (tp->mac_version == RTL_GIGA_MAC_VER_70 || diff --git a/target/linux/generic/backport-6.6/780-65-v6.16-r8169-add-support-for-RTL8127A.patch b/target/linux/generic/backport-6.6/780-65-v6.16-r8169-add-support-for-RTL8127A.patch index 93f7bbc0cf..4872132eb6 100644 --- a/target/linux/generic/backport-6.6/780-65-v6.16-r8169-add-support-for-RTL8127A.patch +++ b/target/linux/generic/backport-6.6/780-65-v6.16-r8169-add-support-for-RTL8127A.patch @@ -97,7 +97,7 @@ Signed-off-by: Jakub Kicinski else if (tp->mac_version == RTL_GIGA_MAC_VER_63) r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); @@ -3712,7 +3724,8 @@ static void rtl_hw_start_8125_common(str - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000); r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); - if (tp->mac_version == RTL_GIGA_MAC_VER_70) diff --git a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch index 3f105cfd2b..f869fc2037 100644 --- a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch +++ b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch @@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -21989,6 +21989,7 @@ U-BOOT ENVIRONMENT VARIABLES +@@ -21990,6 +21990,7 @@ U-BOOT ENVIRONMENT VARIABLES M: Rafał Miłecki S: Maintained F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml diff --git a/target/linux/generic/hack-6.6/610-net-page_pool-try-to-free-deferred-skbs-while-waitin.patch b/target/linux/generic/hack-6.6/610-net-page_pool-try-to-free-deferred-skbs-while-waitin.patch index cfe35bc51a..304b272c42 100644 --- a/target/linux/generic/hack-6.6/610-net-page_pool-try-to-free-deferred-skbs-while-waitin.patch +++ b/target/linux/generic/hack-6.6/610-net-page_pool-try-to-free-deferred-skbs-while-waitin.patch @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -873,7 +873,8 @@ static void page_pool_release_retry(stru +@@ -875,7 +875,8 @@ static void page_pool_release_retry(stru { struct delayed_work *dwq = to_delayed_work(wq); struct page_pool *pool = container_of(dwq, typeof(*pool), release_dw); @@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau inflight = page_pool_release(pool); /* In rare cases, a driver bug may cause inflight to go negative. -@@ -885,6 +886,21 @@ static void page_pool_release_retry(stru +@@ -887,6 +888,21 @@ static void page_pool_release_retry(stru if (inflight <= 0) return; diff --git a/target/linux/generic/hack-6.6/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-6.6/721-net-add-packet-mangeling.patch index 1b210ee3cc..7d9b00e861 100644 --- a/target/linux/generic/hack-6.6/721-net-add-packet-mangeling.patch +++ b/target/linux/generic/hack-6.6/721-net-add-packet-mangeling.patch @@ -127,7 +127,7 @@ Signed-off-by: Felix Fietkau #include #include -@@ -844,6 +845,22 @@ skb_fail: +@@ -848,6 +849,22 @@ skb_fail: } EXPORT_SYMBOL(__napi_alloc_skb); diff --git a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch index 9d389dd3fc..610c95c181 100644 --- a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch @@ -10,7 +10,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c -@@ -1084,6 +1084,11 @@ static const struct usb_device_id produc +@@ -1090,6 +1090,11 @@ static const struct usb_device_id produc USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), .driver_info = (unsigned long)&qmi_wwan_info, }, @@ -22,7 +22,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ -@@ -1091,6 +1096,7 @@ static const struct usb_device_id produc +@@ -1097,6 +1102,7 @@ static const struct usb_device_id produc {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ diff --git a/target/linux/generic/hack-6.6/902-debloat_proc.patch b/target/linux/generic/hack-6.6/902-debloat_proc.patch index ed6b751e1c..b4a0eaad3f 100644 --- a/target/linux/generic/hack-6.6/902-debloat_proc.patch +++ b/target/linux/generic/hack-6.6/902-debloat_proc.patch @@ -246,7 +246,7 @@ Signed-off-by: Felix Fietkau &vmalloc_op, --- a/mm/vmstat.c +++ b/mm/vmstat.c -@@ -2136,10 +2136,12 @@ void __init init_mm_internals(void) +@@ -2137,10 +2137,12 @@ void __init init_mm_internals(void) start_shepherd_timer(); #endif #ifdef CONFIG_PROC_FS @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -4165,6 +4165,8 @@ static __net_initdata struct pernet_oper +@@ -4168,6 +4168,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { diff --git a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch index 056b49db3e..1ad2210352 100644 --- a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch +++ b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch @@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -22016,6 +22016,12 @@ F: Documentation/filesystems/ubifs-authe +@@ -22017,6 +22017,12 @@ F: Documentation/filesystems/ubifs-authe F: Documentation/filesystems/ubifs.rst F: fs/ubifs/ diff --git a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch index bb2beff43a..3e9a233ced 100644 --- a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch +++ b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch @@ -21,7 +21,7 @@ Signe-off-by: Felix Fietkau --- a/include/net/gro.h +++ b/include/net/gro.h -@@ -439,6 +439,7 @@ static inline __wsum ip6_gro_compute_pse +@@ -442,6 +442,7 @@ static inline __wsum ip6_gro_compute_pse } int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb); @@ -45,7 +45,7 @@ Signe-off-by: Felix Fietkau INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff)); --- a/net/core/gro.c +++ b/net/core/gro.c -@@ -228,6 +228,33 @@ done: +@@ -225,6 +225,33 @@ done: return 0; } diff --git a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch index e0c3e206da..c5cc8c5acd 100644 --- a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c -@@ -8448,7 +8448,7 @@ static int nft_register_flowtable_net_ho +@@ -8463,7 +8463,7 @@ static int nft_register_flowtable_net_ho err = flowtable->data.type->setup(&flowtable->data, hook->ops.dev, FLOW_BLOCK_BIND); diff --git a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 31e29c447e..433e7616c2 100644 --- a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -24,7 +24,7 @@ Signed-off-by: Felix Fietkau --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c -@@ -201,6 +201,7 @@ void br_flood(struct net_bridge *br, str +@@ -202,6 +202,7 @@ void br_flood(struct net_bridge *br, str enum br_pkt_type pkt_type, bool local_rcv, bool local_orig, u16 vid) { @@ -32,7 +32,7 @@ Signed-off-by: Felix Fietkau struct net_bridge_port *prev = NULL; struct net_bridge_port *p; -@@ -218,6 +219,10 @@ void br_flood(struct net_bridge *br, str +@@ -219,6 +220,10 @@ void br_flood(struct net_bridge *br, str case BR_PKT_MULTICAST: if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) continue; diff --git a/target/linux/generic/pending-6.6/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-6.6/810-pci_disable_common_quirks.patch index e4c8caff22..2d138d123a 100644 --- a/target/linux/generic/pending-6.6/810-pci_disable_common_quirks.patch +++ b/target/linux/generic/pending-6.6/810-pci_disable_common_quirks.patch @@ -33,7 +33,7 @@ Signed-off-by: Gabor Juhos /* * The Mellanox Tavor device gives false positive parity errors. Disable * parity error reporting. -@@ -3501,6 +3502,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I +@@ -3502,6 +3503,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); @@ -42,7 +42,7 @@ Signed-off-by: Gabor Juhos /* * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. * To work around this, query the size it should be configured to by the -@@ -3526,6 +3529,8 @@ static void quirk_intel_ntb(struct pci_d +@@ -3527,6 +3530,8 @@ static void quirk_intel_ntb(struct pci_d DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); @@ -51,7 +51,7 @@ Signed-off-by: Gabor Juhos /* * Some BIOS implementations leave the Intel GPU interrupts enabled, even * though no one is handling them (e.g., if the i915 driver is never -@@ -3564,6 +3569,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN +@@ -3565,6 +3570,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); diff --git a/target/linux/ipq40xx/patches-6.6/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch b/target/linux/ipq40xx/patches-6.6/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch index 737da1e2fe..dc3faee799 100644 --- a/target/linux/ipq40xx/patches-6.6/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch +++ b/target/linux/ipq40xx/patches-6.6/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch @@ -13,7 +13,7 @@ Signed-off-by: Robert Marko --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c -@@ -2383,7 +2383,7 @@ MODULE_DEVICE_TABLE(of, sdhci_msm_dt_mat +@@ -2398,7 +2398,7 @@ MODULE_DEVICE_TABLE(of, sdhci_msm_dt_mat static const struct sdhci_ops sdhci_msm_ops = { .reset = sdhci_and_cqhci_reset, diff --git a/target/linux/ipq40xx/patches-6.6/401-mmc-sdhci-msm-comment-unused-sdhci_msm_set_clock.patch b/target/linux/ipq40xx/patches-6.6/401-mmc-sdhci-msm-comment-unused-sdhci_msm_set_clock.patch index 6e0f35b6fc..8a81756d67 100644 --- a/target/linux/ipq40xx/patches-6.6/401-mmc-sdhci-msm-comment-unused-sdhci_msm_set_clock.patch +++ b/target/linux/ipq40xx/patches-6.6/401-mmc-sdhci-msm-comment-unused-sdhci_msm_set_clock.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c -@@ -1818,49 +1818,49 @@ static unsigned int sdhci_msm_get_min_cl +@@ -1833,49 +1833,49 @@ static unsigned int sdhci_msm_get_min_cl return SDHCI_MSM_MIN_CLOCK; } diff --git a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch index b8557bacc7..39e1bceefc 100644 --- a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch +++ b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch @@ -32,7 +32,7 @@ Signed-off-by: Maxime Chevallier --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -17717,6 +17717,13 @@ L: netdev@vger.kernel.org +@@ -17718,6 +17718,13 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/qualcomm/emac/ diff --git a/target/linux/ipq40xx/patches-6.6/701-net-dsa-add-out-of-band-tagging-protocol.patch b/target/linux/ipq40xx/patches-6.6/701-net-dsa-add-out-of-band-tagging-protocol.patch index 292f6e6f10..2db87575a9 100644 --- a/target/linux/ipq40xx/patches-6.6/701-net-dsa-add-out-of-band-tagging-protocol.patch +++ b/target/linux/ipq40xx/patches-6.6/701-net-dsa-add-out-of-band-tagging-protocol.patch @@ -64,7 +64,7 @@ Signed-off-by: Maxime Chevallier --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -17723,6 +17723,7 @@ L: netdev@vger.kernel.org +@@ -17724,6 +17724,7 @@ L: netdev@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/net/qcom,ipq4019-ess-edma.yaml F: drivers/net/ethernet/qualcomm/ipqess/ @@ -136,7 +136,7 @@ Signed-off-by: Maxime Chevallier #include #include #include -@@ -4823,6 +4827,9 @@ static const u8 skb_ext_type_len[] = { +@@ -4827,6 +4831,9 @@ static const u8 skb_ext_type_len[] = { #if IS_ENABLED(CONFIG_MCTP_FLOWS) [SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow), #endif diff --git a/target/linux/mediatek/patches-6.6/739-net-add-negotiation-of-in-band-capabilities.patch b/target/linux/mediatek/patches-6.6/739-net-add-negotiation-of-in-band-capabilities.patch index b0c7897945..629b124125 100644 --- a/target/linux/mediatek/patches-6.6/739-net-add-negotiation-of-in-band-capabilities.patch +++ b/target/linux/mediatek/patches-6.6/739-net-add-negotiation-of-in-band-capabilities.patch @@ -956,7 +956,7 @@ publishing the in-band capabilities from the BCM84881 PHY driver. static int m88e1111_config_aneg(struct phy_device *phydev) { int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR); -@@ -3292,6 +3334,8 @@ static struct phy_driver marvell_drivers +@@ -3329,6 +3371,8 @@ static struct phy_driver marvell_drivers .name = "Marvell 88E1112", /* PHY_GBIT_FEATURES */ .probe = marvell_probe, @@ -965,7 +965,7 @@ publishing the in-band capabilities from the BCM84881 PHY driver. .config_init = m88e1112_config_init, .config_aneg = marvell_config_aneg, .config_intr = marvell_config_intr, -@@ -3312,6 +3356,8 @@ static struct phy_driver marvell_drivers +@@ -3349,6 +3393,8 @@ static struct phy_driver marvell_drivers .name = "Marvell 88E1111", /* PHY_GBIT_FEATURES */ .probe = marvell_probe, @@ -974,7 +974,7 @@ publishing the in-band capabilities from the BCM84881 PHY driver. .config_init = m88e1111gbe_config_init, .config_aneg = m88e1111_config_aneg, .read_status = marvell_read_status, -@@ -3333,6 +3379,8 @@ static struct phy_driver marvell_drivers +@@ -3370,6 +3416,8 @@ static struct phy_driver marvell_drivers .name = "Marvell 88E1111 (Finisar)", /* PHY_GBIT_FEATURES */ .probe = marvell_probe, diff --git a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch index 9122652337..1a68ba4430 100644 --- a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch +++ b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch @@ -13,7 +13,7 @@ Signed-off-by: John Crispin --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -3329,6 +3329,18 @@ static const struct usb_device_id uvc_id +@@ -3342,6 +3342,18 @@ static const struct usb_device_id uvc_id .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, diff --git a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch index 57e8c08c81..5f2c94914f 100644 --- a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch +++ b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch @@ -27,7 +27,7 @@ Signed-off-by: Hal Feng DRM DRIVERS FOR STI M: Alain Volmat L: dri-devel@lists.freedesktop.org -@@ -16017,6 +16025,13 @@ F: Documentation/i2c/busses/i2c-ocores.r +@@ -16018,6 +16026,13 @@ F: Documentation/i2c/busses/i2c-ocores.r F: drivers/i2c/busses/i2c-ocores.c F: include/linux/platform_data/i2c-ocores.h @@ -41,7 +41,7 @@ Signed-off-by: Hal Feng OPENRISC ARCHITECTURE M: Jonas Bonn M: Stefan Kristiansson -@@ -16428,6 +16443,14 @@ S: Maintained +@@ -16429,6 +16444,14 @@ S: Maintained F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c @@ -56,7 +56,7 @@ Signed-off-by: Hal Feng PCI DRIVER FOR RENESAS R-CAR M: Marek Vasut M: Yoshihiro Shimoda -@@ -16659,7 +16682,7 @@ M: Daire McNamara PCIE DRIVER FOR QUALCOMM MSM M: Manivannan Sadhasivam -@@ -16683,6 +16706,13 @@ S: Maintained +@@ -16684,6 +16707,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie* F: drivers/pci/controller/dwc/pcie-uniphier* @@ -79,7 +79,7 @@ Signed-off-by: Hal Feng PCIE DRIVER FOR ST SPEAR13XX M: Pratyush Anand L: linux-pci@vger.kernel.org -@@ -18455,7 +18485,7 @@ F: drivers/char/hw_random/mpfs-rng.c +@@ -18456,7 +18486,7 @@ F: drivers/char/hw_random/mpfs-rng.c F: drivers/clk/microchip/clk-mpfs*.c F: drivers/i2c/busses/i2c-microchip-corei2c.c F: drivers/mailbox/mailbox-mpfs.c @@ -88,7 +88,7 @@ Signed-off-by: Hal Feng F: drivers/pwm/pwm-microchip-core.c F: drivers/reset/reset-mpfs.c F: drivers/rtc/rtc-mpfs.c -@@ -20436,6 +20466,15 @@ M: Ion Badulescu +@@ -20437,6 +20467,15 @@ M: Ion Badulescu S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* @@ -104,7 +104,7 @@ Signed-off-by: Hal Feng STARFIVE CRYPTO DRIVER M: Jia Jie Ho M: William Qiu -@@ -20474,6 +20513,13 @@ S: Supported +@@ -20475,6 +20514,13 @@ S: Supported F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml F: drivers/clk/starfive/clk-starfive-jh7110-pll.c @@ -118,7 +118,7 @@ Signed-off-by: Hal Feng STARFIVE JH7110 SYSCON M: William Qiu M: Xingyu Wu -@@ -20521,9 +20567,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c +@@ -20522,9 +20568,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c STARFIVE JH71XX PMU CONTROLLER DRIVER M: Walker Chen @@ -130,7 +130,7 @@ Signed-off-by: Hal Feng F: include/dt-bindings/power/starfive,jh7110-pmu.h STARFIVE SOC DRIVERS -@@ -20531,7 +20578,13 @@ M: Conor Dooley +@@ -20532,7 +20579,13 @@ M: Conor Dooley S: Maintained T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ F: Documentation/devicetree/bindings/soc/starfive/ diff --git a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch index 95d83d46bb..2cc8c7aba1 100644 --- a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch +++ b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch @@ -143,7 +143,7 @@ Signed-off-by: minda.chen * something other than the default (~1ms minimum between interrupts). --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c -@@ -253,6 +253,14 @@ int xhci_plat_probe(struct platform_devi +@@ -254,6 +254,14 @@ int xhci_plat_probe(struct platform_devi if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk")) xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; diff --git a/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch index 2a72bcb9cf..714d09441c 100644 --- a/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch +++ b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch @@ -88,7 +88,7 @@ Signed-off-by: Minda Chen /* --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c -@@ -255,10 +255,11 @@ int xhci_plat_probe(struct platform_devi +@@ -256,10 +256,11 @@ int xhci_plat_probe(struct platform_devi if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) { xhci->quirks |= XHCI_LOCAL_BUFFER; diff --git a/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch index 4d3997b24e..9b5ad54f97 100644 --- a/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch +++ b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch @@ -19,7 +19,7 @@ Signed-off-by: Matteo Croce if (priv->dma_cap.host_dma_width <= 32) gfp |= GFP_DMA32; -@@ -4693,7 +4693,7 @@ static inline void stmmac_rx_refill(stru +@@ -4690,7 +4690,7 @@ static inline void stmmac_rx_refill(stru struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; int dirty = stmmac_rx_dirty(priv, queue); unsigned int entry = rx_q->dirty_rx; diff --git a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch index 79e7d4ddb4..8b24eb33e5 100644 --- a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch +++ b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch @@ -20,7 +20,7 @@ Signed-off-by: Emil Renner Berthing --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20555,7 +20555,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS +@@ -20556,7 +20556,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS M: Emil Renner Berthing M: Hal Feng S: Maintained From 6ff763e78ceff83ffef7db08f7cc364bbc05ca50 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 27 Nov 2025 21:13:04 +0100 Subject: [PATCH 084/128] kernel: mtd: spinand: esmt: add support for F50L1G41LC Backport upstream patch to add support for the ESMT F50L1G41LC flash chip. It is used in multiple Cudy products manufactured starting November 2025. (cherry picked from commit 9424b2b78626702012dc73616bfd21029712b5f7) Link: https://github.com/openwrt/openwrt/pull/20963 Signed-off-by: Hauke Mehrtens --- .../901-snand-mtk-bmt-support.patch | 6 +- ...nand-esmt-add-support-for-F50L1G41LC.patch | 84 +++++++++++++++++++ ...flip_threshold-to-75-of-ECC-strength.patch | 2 +- ...nd-Add-support-for-Etron-EM73D044VCx.patch | 8 +- .../330-snand-mtk-bmt-support.patch | 6 +- ...Add-support-for-the-Fidelix-FM35X1GA.patch | 4 +- ...and-Add-calibration-support-for-spin.patch | 4 +- ...nor-Add-calibration-support-for-spi-.patch | 2 +- ...960-asus-hack-u-boot-ignore-mtdparts.patch | 4 +- 9 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 target/linux/generic/backport-6.6/422-v6.19-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch diff --git a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch index 90619d971e..e62a810a57 100644 --- a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch +++ b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch @@ -8,7 +8,7 @@ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) { -@@ -1352,6 +1353,7 @@ static int spinand_probe(struct spi_mem +@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem if (ret) return ret; @@ -16,7 +16,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_spinand_cleanup; -@@ -1359,6 +1361,7 @@ static int spinand_probe(struct spi_mem +@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem return 0; err_spinand_cleanup: @@ -24,7 +24,7 @@ spinand_cleanup(spinand); return ret; -@@ -1377,6 +1380,7 @@ static int spinand_remove(struct spi_mem +@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem if (ret) return ret; diff --git a/target/linux/generic/backport-6.6/422-v6.19-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch b/target/linux/generic/backport-6.6/422-v6.19-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch new file mode 100644 index 0000000000..f260d2ba8e --- /dev/null +++ b/target/linux/generic/backport-6.6/422-v6.19-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch @@ -0,0 +1,84 @@ +From b98994cb9bc24f5c7575c86650f96c384576fdfa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 17 Nov 2025 02:54:19 +0000 +Subject: [PATCH] mtd: spinand: esmt: add support for F50L1G41LC + +This adds support for ESMT F50L1G41LC, which appears to be an updated +version of the already supported F50L1G41LB. +Add esmt_8c SPI_NAND manufacturer to account for the newly used vendor +ID with support for the ESMT F50L1G41LC chip. + +Link: https://github.com/openwrt/openwrt/pull/15214#issuecomment-3514824435 +Signed-off-by: Daniel Golle +Signed-off-by: Miquel Raynal +--- + drivers/mtd/nand/spi/core.c | 1 + + drivers/mtd/nand/spi/esmt.c | 24 ++++++++++++++++++++++++ + include/linux/mtd/spinand.h | 1 + + 3 files changed, 26 insertions(+) + +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -942,6 +942,7 @@ static const struct nand_ops spinand_ops + static const struct spinand_manufacturer *spinand_manufacturers[] = { + &alliancememory_spinand_manufacturer, + &ato_spinand_manufacturer, ++ &esmt_8c_spinand_manufacturer, + &esmt_c8_spinand_manufacturer, + &fmsh_spinand_manufacturer, + &foresee_spinand_manufacturer, +--- a/drivers/mtd/nand/spi/esmt.c ++++ b/drivers/mtd/nand/spi/esmt.c +@@ -11,6 +11,7 @@ + + /* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ + #define SPINAND_MFR_ESMT_C8 0xc8 ++#define SPINAND_MFR_ESMT_8C 0x8c + + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -102,6 +103,19 @@ static const struct mtd_ooblayout_ops f5 + .free = f50l1g41lb_ooblayout_free, + }; + ++ ++static const struct spinand_info esmt_8c_spinand_table[] = { ++ SPINAND_INFO("F50L1G41LC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x2C), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(1, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), ++}; ++ + static const struct spinand_info esmt_c8_spinand_table[] = { + SPINAND_INFO("F50L1G41LB", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01, 0x7f, +@@ -138,6 +152,14 @@ static const struct spinand_info esmt_c8 + static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = { + }; + ++const struct spinand_manufacturer esmt_8c_spinand_manufacturer = { ++ .id = SPINAND_MFR_ESMT_8C, ++ .name = "ESMT", ++ .chips = esmt_8c_spinand_table, ++ .nchips = ARRAY_SIZE(esmt_8c_spinand_table), ++ .ops = &esmt_spinand_manuf_ops, ++}; ++ + const struct spinand_manufacturer esmt_c8_spinand_manufacturer = { + .id = SPINAND_MFR_ESMT_C8, + .name = "ESMT", +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -262,6 +262,7 @@ struct spinand_manufacturer { + /* SPI NAND manufacturers */ + extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; + extern const struct spinand_manufacturer ato_spinand_manufacturer; ++extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer; + extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; + extern const struct spinand_manufacturer fmsh_spinand_manufacturer; + extern const struct spinand_manufacturer foresee_spinand_manufacturer; diff --git a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch index 7f60c21a3a..814b50e19c 100644 --- a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch +++ b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch @@ -53,7 +53,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -1291,6 +1291,7 @@ static int spinand_init(struct spinand_d +@@ -1292,6 +1292,7 @@ static int spinand_init(struct spinand_d /* Propagate ECC information to mtd_info */ mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength; mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size; diff --git a/target/linux/generic/pending-6.6/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-6.6/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch index 65efad224d..7d7899ee59 100644 --- a/target/linux/generic/pending-6.6/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch +++ b/target/linux/generic/pending-6.6/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch @@ -49,9 +49,9 @@ Submitted-by: Daniel Danzberger obj-$(CONFIG_MTD_SPI_NAND) += spinand.o --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -943,6 +943,7 @@ static const struct spinand_manufacturer - &alliancememory_spinand_manufacturer, +@@ -944,6 +944,7 @@ static const struct spinand_manufacturer &ato_spinand_manufacturer, + &esmt_8c_spinand_manufacturer, &esmt_c8_spinand_manufacturer, + &etron_spinand_manufacturer, &fmsh_spinand_manufacturer, @@ -160,9 +160,9 @@ Submitted-by: Daniel Danzberger +}; --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h -@@ -263,6 +263,7 @@ struct spinand_manufacturer { - extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; +@@ -264,6 +264,7 @@ extern const struct spinand_manufacturer extern const struct spinand_manufacturer ato_spinand_manufacturer; + extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer; extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; +extern const struct spinand_manufacturer etron_spinand_manufacturer; extern const struct spinand_manufacturer fmsh_spinand_manufacturer; diff --git a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch index 90619d971e..e62a810a57 100644 --- a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch +++ b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch @@ -8,7 +8,7 @@ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) { -@@ -1352,6 +1353,7 @@ static int spinand_probe(struct spi_mem +@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem if (ret) return ret; @@ -16,7 +16,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_spinand_cleanup; -@@ -1359,6 +1361,7 @@ static int spinand_probe(struct spi_mem +@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem return 0; err_spinand_cleanup: @@ -24,7 +24,7 @@ spinand_cleanup(spinand); return ret; -@@ -1377,6 +1380,7 @@ static int spinand_remove(struct spi_mem +@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem if (ret) return ret; diff --git a/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch b/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch index 9ff6e811ec..5a60d49541 100644 --- a/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch +++ b/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch @@ -24,7 +24,7 @@ Signed-off-by: Davide Fioravanti obj-$(CONFIG_MTD_SPI_NAND) += spinand.o --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -946,6 +946,7 @@ static const struct spinand_manufacturer +@@ -947,6 +947,7 @@ static const struct spinand_manufacturer &esmt_c8_spinand_manufacturer, &etron_spinand_manufacturer, &fmsh_spinand_manufacturer, @@ -113,7 +113,7 @@ Signed-off-by: Davide Fioravanti +}; --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h -@@ -265,6 +265,7 @@ extern const struct spinand_manufacturer +@@ -266,6 +266,7 @@ extern const struct spinand_manufacturer extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; extern const struct spinand_manufacturer etron_spinand_manufacturer; extern const struct spinand_manufacturer fmsh_spinand_manufacturer; diff --git a/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch index 8da008f09f..7d54700718 100644 --- a/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch +++ b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch @@ -11,7 +11,7 @@ Signed-off-by: SkyLake.Huang --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -984,6 +984,56 @@ static int spinand_manufacturer_match(st +@@ -985,6 +985,56 @@ static int spinand_manufacturer_match(st return -ENOTSUPP; } @@ -68,7 +68,7 @@ Signed-off-by: SkyLake.Huang static int spinand_id_detect(struct spinand_device *spinand) { u8 *id = spinand->id.data; -@@ -1234,6 +1284,10 @@ static int spinand_init(struct spinand_d +@@ -1235,6 +1285,10 @@ static int spinand_init(struct spinand_d if (!spinand->scratchbuf) return -ENOMEM; diff --git a/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch b/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch index f4802f5d15..e11283051e 100644 --- a/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch +++ b/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch @@ -12,7 +12,7 @@ Signed-off-by: SkyLake.Huang --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -1025,7 +1025,10 @@ int spinand_cal_read(void *priv, u32 *ad +@@ -1026,7 +1026,10 @@ int spinand_cal_read(void *priv, u32 *ad if (ret) return ret; diff --git a/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch b/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch index 3167dc9c59..8337e12887 100644 --- a/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch +++ b/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch @@ -29,7 +29,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -1446,6 +1446,7 @@ static int spinand_remove(struct spi_mem +@@ -1447,6 +1447,7 @@ static int spinand_remove(struct spi_mem static const struct spi_device_id spinand_ids[] = { { .name = "spi-nand" }, @@ -37,7 +37,7 @@ Signed-off-by: Daniel Golle { /* sentinel */ }, }; MODULE_DEVICE_TABLE(spi, spinand_ids); -@@ -1453,6 +1454,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids); +@@ -1454,6 +1455,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids); #ifdef CONFIG_OF static const struct of_device_id spinand_of_ids[] = { { .compatible = "spi-nand" }, From 804a2e6c513187cb809dfc890f2660fac1b3fd99 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 27 Nov 2025 22:27:55 +0100 Subject: [PATCH 085/128] uboot-mediatek: mtd: spinand: esmt: add support for F50L1G41LC Add support for esmt F50L1G41LC flash chip. It is used in some recent Cudy devices. (cherry picked from commit c84025dea29602d149d22a86502d784f292441fe) Link: https://github.com/openwrt/openwrt/pull/20963 Signed-off-by: Hauke Mehrtens --- ...nand-esmt-add-support-for-F50L1G41LC.patch | 68 +++++++++++++++++++ ...ialized-the-watchdog-subsystem-later.patch | 6 +- 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 package/boot/uboot-mediatek/patches/102-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch diff --git a/package/boot/uboot-mediatek/patches/102-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch b/package/boot/uboot-mediatek/patches/102-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch new file mode 100644 index 0000000000..3a6990e7bd --- /dev/null +++ b/package/boot/uboot-mediatek/patches/102-mtd-spinand-esmt-add-support-for-F50L1G41LC.patch @@ -0,0 +1,68 @@ +Subject: [PATCH] mtd: spinand: esmt: add support for F50L1G41LC + +This adds support for ESMT F50L1G41LC, which appears to be an updated +version of the already supported F50L1G41LB. +Add esmt_8c SPI_NAND manufacturer to account for the newly used vendor +ID with support for the ESMT F50L1G41LC chip. + +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -834,6 +834,7 @@ static const struct spinand_manufacturer + &toshiba_spinand_manufacturer, + &winbond_spinand_manufacturer, + &esmt_c8_spinand_manufacturer, ++ &esmt_8c_spinand_manufacturer, + &xtx_spinand_manufacturer, + }; + +--- a/drivers/mtd/nand/spi/esmt.c ++++ b/drivers/mtd/nand/spi/esmt.c +@@ -13,6 +13,7 @@ + + /* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ + #define SPINAND_MFR_ESMT_C8 0xc8 ++#define SPINAND_MFR_ESMT_8C 0x8c + + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -104,6 +105,18 @@ static const struct mtd_ooblayout_ops f5 + .rfree = f50l1g41lb_ooblayout_free, + }; + ++static const struct spinand_info esmt_8c_spinand_table[] = { ++ SPINAND_INFO("F50L1G41LC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x2C), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(1, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), ++}; ++ + static const struct spinand_info esmt_c8_spinand_table[] = { + SPINAND_INFO("F50L1G41LB", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01), +@@ -135,3 +148,11 @@ const struct spinand_manufacturer esmt_c + .nchips = ARRAY_SIZE(esmt_c8_spinand_table), + .ops = &esmt_spinand_manuf_ops, + }; ++ ++const struct spinand_manufacturer esmt_8c_spinand_manufacturer = { ++ .id = SPINAND_MFR_ESMT_8C, ++ .name = "ESMT", ++ .chips = esmt_8c_spinand_table, ++ .nchips = ARRAY_SIZE(esmt_8c_spinand_table), ++ .ops = &esmt_spinand_manuf_ops, ++}; +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -252,6 +252,7 @@ extern const struct spinand_manufacturer + extern const struct spinand_manufacturer toshiba_spinand_manufacturer; + extern const struct spinand_manufacturer winbond_spinand_manufacturer; + extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; ++extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer; + extern const struct spinand_manufacturer xtx_spinand_manufacturer; + + /** diff --git a/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch b/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch index 7919b36560..c220c65f57 100644 --- a/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch +++ b/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch @@ -13,7 +13,7 @@ Signed-off-by: Enrico Mioso --- a/common/board_r.c +++ b/common/board_r.c -@@ -663,19 +663,13 @@ static init_fnc_t init_sequence_r[] = { +@@ -651,19 +651,13 @@ static init_fnc_t init_sequence_r[] = { serial_initialize, initr_announce, dm_announce, @@ -33,7 +33,7 @@ Signed-off-by: Enrico Mioso #if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT) /* * Do early PCI configuration _before_ the flash gets initialised, -@@ -690,7 +684,6 @@ static init_fnc_t init_sequence_r[] = { +@@ -678,7 +672,6 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_MTD_NOR_FLASH initr_flash, #endif @@ -41,7 +41,7 @@ Signed-off-by: Enrico Mioso #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) /* initialize higher level parts of CPU like time base and timers */ cpu_init_r, -@@ -719,6 +712,10 @@ static init_fnc_t init_sequence_r[] = { +@@ -707,6 +700,10 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_PVBLOCK initr_pvblock, #endif From e35f37791f0906edab0f6adc3125750402cba096 Mon Sep 17 00:00:00 2001 From: Liangbin Lian Date: Wed, 24 Sep 2025 19:49:26 +0800 Subject: [PATCH 086/128] uboot-rockchip: add support for LinkEase EasePi R1 generic-rk3568 is enough Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20147 (cherry picked from commit ef093299dbb8d9e9b8120be9d5314dbf4af1528d) Link: https://github.com/openwrt/openwrt/pull/20744 Signed-off-by: Hauke Mehrtens --- package/boot/uboot-rockchip/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 4f688396c3..6b87fb193a 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -226,6 +226,13 @@ define U-Boot/fastrhino-r66s-rk3568 lunzn_fastrhino-r66s endef +define U-Boot/generic-rk3568 + $(U-Boot/rk3568/Default) + NAME:=Generic RK3566/RK3568 board + BUILD_DEVICES:= \ + linkease_easepi-r1 +endef + define U-Boot/nanopi-r5c-rk3568 $(U-Boot/rk3568/Default) NAME:=NanoPi R5C @@ -341,6 +348,7 @@ UBOOT_TARGETS := \ rock-3c-rk3566 \ bpi-r2-pro-rk3568 \ fastrhino-r66s-rk3568 \ + generic-rk3568 \ nanopi-r5c-rk3568 \ nanopi-r5s-rk3568 \ radxa-e25-rk3568 \ From c795a91579532e00de9abd2be4b97e62780610c5 Mon Sep 17 00:00:00 2001 From: Liangbin Lian Date: Wed, 24 Sep 2025 20:08:13 +0800 Subject: [PATCH 087/128] rockchip: Add support for RK3568 LinkEase EasePi R1 Specification: - Rockchip RK3568 - 2GB/4GB LPDDR4 RAM - 16GB on-board eMMC - 1x M.2 key for 2280 NVMe (PCIe 3.0) - 1x USB 3.0 Type-A - 1x USB 2.0 Type-C (for USB flashing) - 2x 1000 Base-T (native, RTL8211F) - 2x 2500 Base-T (PCIe, RTL8125B) - 1x HDMI 2.0 Output - 12v DC Jack - 1x Power key connected to PMIC - 2x LEDs (one static power supplied, one GPIO controlled) Debug Serial Port: 3.3V TTL, 3-pin 2.54mm pitch connector, 1500000 bauds, 'J7' on board with G/R/T (GND/RX/TX) pins marked Installation - eMMC: -Boot official firmware (OpenWRT based) -Upload sysupgrade.img.gz to /tmp/firmware.bin (with scp or web page) -Flash to eMMC: sysupgrade -n -p -F /tmp/firmware.bin Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20147 (cherry picked from commit 8ca4caacd039bba6d53d3c578fbcf21b6a2fbff2) [refresh patches upon 24.10 branch] Link: https://github.com/openwrt/openwrt/pull/20744 Signed-off-by: Hauke Mehrtens --- .../armv8/base-files/etc/board.d/02_network | 4 + .../etc/hotplug.d/net/40-net-smp-affinity | 1 + target/linux/rockchip/image/armv8.mk | 9 + ...-dts-rockchip-add-LinkEase-EasePi-R1.patch | 669 ++++++++++++++++++ ...-rockchip-Add-support-for-NanoPi-R6S.patch | 2 +- ...-rockchip-Add-support-for-NanoPi-R6C.patch | 2 +- ...-dts-rockchip-Add-ArmSom-Sige7-board.patch | 2 +- ...ED-properties-for-LinkEase-EasePi-R1.patch | 14 + 8 files changed, 700 insertions(+), 3 deletions(-) create mode 100644 target/linux/rockchip/patches-6.6/025-v6.19-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch create mode 100644 target/linux/rockchip/patches-6.6/135-arm64-dts-rockchip-Update-LED-properties-for-LinkEase-EasePi-R1.patch diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network index 56e0cc2408..02c66b873e 100644 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network @@ -33,6 +33,9 @@ rockchip_setup_interfaces() friendlyarm,nanopi-r6s) ucidef_set_interfaces_lan_wan 'eth0 eth2' 'eth1' ;; + linkease,easepi-r1) + ucidef_set_interfaces_lan_wan 'eth1 eth2 eth3' 'eth0' + ;; sinovoip,rk3568-bpi-r2pro) ucidef_set_interfaces_lan_wan 'lan0 lan1 lan2 lan3' 'eth0' ;; @@ -54,6 +57,7 @@ rockchip_setup_macs() friendlyarm,nanopc-t6|\ friendlyarm,nanopi-r2c|\ friendlyarm,nanopi-r2s|\ + linkease,easepi-r1|\ lunzn,fastrhino-r66s) wan_mac=$(macaddr_generate_from_mmc_cid mmcblk0) lan_mac=$(macaddr_add "$wan_mac" 1) diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity index d9ca53b7e1..9277dad3e7 100644 --- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity +++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity @@ -32,6 +32,7 @@ case "$(board_name)" in armsom,sige7|\ friendlyarm,nanopi-r3s|\ friendlyarm,nanopi-r5c|\ +linkease,easepi-r1|\ lunzn,fastrhino-r66s|\ radxa,e25|\ sinovoip,rk3568-bpi-r2pro) diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index af224bb608..07272d244c 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -124,6 +124,15 @@ define Device/friendlyarm_nanopi-r6s endef TARGET_DEVICES += friendlyarm_nanopi-r6s +define Device/linkease_easepi-r1 + DEVICE_VENDOR := LinkEase + DEVICE_MODEL := EasePi R1 + SOC := rk3568 + UBOOT_DEVICE_NAME := generic-rk3568 + DEVICE_PACKAGES := blkdiscard block-mount kmod-button-hotplug kmod-nvme kmod-r8169 +endef +TARGET_DEVICES += linkease_easepi-r1 + define Device/lunzn_fastrhino-r66s DEVICE_VENDOR := Lunzn DEVICE_MODEL := FastRhino R66S diff --git a/target/linux/rockchip/patches-6.6/025-v6.19-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch b/target/linux/rockchip/patches-6.6/025-v6.19-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch new file mode 100644 index 0000000000..afd7a82125 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/025-v6.19-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch @@ -0,0 +1,669 @@ +From deaefeaf3df433d50935b9a85076041040f06d74 Mon Sep 17 00:00:00 2001 +From: Liangbin Lian +Date: Tue, 14 Oct 2025 13:12:26 +0800 +Subject: [PATCH] arm64: dts: rockchip: add LinkEase EasePi R1 + +LinkEase EasePi R1 [1] is a high-performance mini router. + +Specification: +- Rockchip RK3568 +- 2GB/4GB LPDDR4 RAM +- 16GB on-board eMMC +- 1x M.2 key for 2280 NVMe (PCIe 3.0) +- 1x USB 3.0 Type-A +- 1x USB 2.0 Type-C (for USB flashing) +- 2x 1000 Base-T (native, RTL8211F) +- 2x 2500 Base-T (PCIe, RTL8125B) +- 1x HDMI 2.0 Output +- 12v DC Jack +- 1x Power key connected to PMIC +- 2x LEDs (one static power supplied, one GPIO controlled) + +[1] https://doc.linkease.com/zh/guide/easepi-r1/hardware.html + +Reviewed-by: Andrew Lunn +Signed-off-by: Liangbin Lian +Link: https://patch.msgid.link/20251014051226.64255-4-jjm2473@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3568-easepi-r1.dts | 623 ++++++++++++++++++ + 2 files changed, 624 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts + +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -91,6 +91,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-so + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-box-demo.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-easepi-r1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r68s.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts +@@ -0,0 +1,623 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "LinkEase EasePi R1"; ++ compatible = "linkease,easepi-r1", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ mmc0 = &sdhci; ++ }; ++ ++ chosen: chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 0>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ ++ button-recovery { ++ label = "Recovery"; ++ linux,code = ; ++ press-threshold-microvolt = <1750>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&status_led_pin>; ++ ++ status_led: led-status { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ dc_12v: regulator-dc-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_12v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc3v3_sys: regulator-vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ regulator-vdd0v95-25glan { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vdd0v95_25glan_en>; ++ regulator-name = "vdd0v95_25glan"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <950000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_nvme: regulator-vcc3v3-nvme { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc3v3_nvme_en>; ++ regulator-name = "vcc3v3_nvme"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++}; ++ ++&combphy1 { ++ status = "okay"; ++}; ++ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ phy-handle = <&rgmii_phy1>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ system-power-controller; ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ wakeup-source; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-always-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <950000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0_8ch { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x1>; ++ pinctrl-0 = <ð_phy0_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&mdio1 { ++ rgmii_phy1: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x1>; ++ pinctrl-0 = <ð_phy1_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++/* ETH3 */ ++&pcie2x1 { ++ reset-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ data-lanes = <1 2>; ++ status = "okay"; ++}; ++ ++/* ETH2 */ ++&pcie3x1 { ++ num-lanes = <1>; ++ reset-gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++/* M.2 Key for 2280 NVMe */ ++&pcie3x2 { ++ num-lanes = <1>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_nvme>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ gmac0 { ++ eth_phy0_reset_pin: eth-phy0-reset-pin { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gmac1 { ++ eth_phy1_reset_pin: eth-phy1-reset-pin { ++ rockchip,pins = <2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gpio-leds { ++ status_led_pin: status-led-pin { ++ rockchip,pins = <2 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ nvme { ++ vcc3v3_nvme_en: vcc3v3-nvme-en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie-nic { ++ vdd0v95_25glan_en: vdd0v95-25glan-en { ++ rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic-int { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++/* OTG Only USB2.0, Only device mode */ ++&usb_host0_xhci { ++ dr_mode = "peripheral"; ++ extcon = <&usb2phy0>; ++ maximum-speed = "high-speed"; ++ phys = <&usb2phy0_otg>; ++ phy-names = "usb2-phy"; ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_host { ++ phy-supply = <&vcc5v0_sys>; ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; diff --git a/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch index f31f38ac9d..811a75fd75 100644 --- a/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch +++ b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch @@ -17,7 +17,7 @@ Signed-off-by: Heiko Stuebner --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -109,4 +109,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-na +@@ -110,4 +110,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-na dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb diff --git a/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch b/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch index b63c01338f..4b3f686bf1 100644 --- a/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch +++ b/target/linux/rockchip/patches-6.6/054-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6C.patch @@ -17,7 +17,7 @@ Signed-off-by: Heiko Stuebner --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -110,4 +110,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ro +@@ -111,4 +111,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ro dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb diff --git a/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch b/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch index c60b979109..cecbfe457c 100644 --- a/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch +++ b/target/linux/rockchip/patches-6.6/056-01-v6.10-arm64-dts-rockchip-Add-ArmSom-Sige7-board.patch @@ -44,7 +44,7 @@ Signed-off-by: Heiko Stuebner --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -102,6 +102,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-ra +@@ -103,6 +103,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-ra dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb diff --git a/target/linux/rockchip/patches-6.6/135-arm64-dts-rockchip-Update-LED-properties-for-LinkEase-EasePi-R1.patch b/target/linux/rockchip/patches-6.6/135-arm64-dts-rockchip-Update-LED-properties-for-LinkEase-EasePi-R1.patch new file mode 100644 index 0000000000..90046967e3 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/135-arm64-dts-rockchip-Update-LED-properties-for-LinkEase-EasePi-R1.patch @@ -0,0 +1,14 @@ +--- a/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts +@@ -17,6 +17,11 @@ + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; ++ ++ led-boot = &status_led; ++ led-failsafe = &status_led; ++ led-running = &status_led; ++ led-upgrade = &status_led; + }; + + chosen: chosen { From fbaf5271d21fdd9551c886c3121a7d04554ac84c Mon Sep 17 00:00:00 2001 From: Liangbin Lian Date: Fri, 14 Nov 2025 14:06:10 +0800 Subject: [PATCH 088/128] rockchip: make NIC name predictable for LinkEase EasePi R1 The probe order for PCIe buses and devices is non-deterministic, making the names eth2 and eth3 unpredictable (they may be swapped). This patch fixes the names by referencing the device path using `ucidef_set_network_device_path`. This patch ensures that the OpenWrt interface name matches the case label. Fixes: 8ca4caacd039 ("rockchip: Add support for RK3568 LinkEase EasePi R1") Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20779 (cherry picked from commit d7530c1e5405cf93ecd0a38ef758cba5760dfd97) Link: https://github.com/openwrt/openwrt/pull/20744 Signed-off-by: Hauke Mehrtens --- target/linux/rockchip/armv8/base-files/etc/board.d/02_network | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network index 02c66b873e..606e77410b 100644 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network @@ -34,6 +34,8 @@ rockchip_setup_interfaces() ucidef_set_interfaces_lan_wan 'eth0 eth2' 'eth1' ;; linkease,easepi-r1) + ucidef_set_network_device_path eth2 'platform/3c0400000.pcie/pci0001:10/0001:10:00.0/0001:11:00.0' + ucidef_set_network_device_path eth3 'platform/3c0000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0' ucidef_set_interfaces_lan_wan 'eth1 eth2 eth3' 'eth0' ;; sinovoip,rk3568-bpi-r2pro) From 9c25d39d3efe8defff7eb9d116f66b48070b3bb9 Mon Sep 17 00:00:00 2001 From: Liangbin Lian Date: Thu, 13 Nov 2025 15:17:57 +0800 Subject: [PATCH 089/128] uboot-rockchip: add dedicated uboot for LinkEase EasePi R1 The generic-rk3568 does not reset the gmac phy, causing the kernel to fail to initialize gmac during cold boot with the error message "mdio_bus stmmac-1: MDIO device at address 1 is missing." Adding a dedicated uboot for EasePi R1 to resolve this issue. The EasePi R1's DTS hasn't been merged into the Linux release yet, so it cannot be submitted to the upstream u-boot. Fixes: ef093299db ("uboot-rockchip: add support for LinkEase EasePi R1") Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20772 (cherry picked from commit 5dff7b45d30f7aea5c7d10f276ce4c72ec6bd6ed) With changes: 1. Reorder patch file names (`105-*` to `106-*`). 2. configs/easepi-r1-rk3568_defconfig needs CONFIG_SPL_PAD_TO on u-boot 2024.10. Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20744 Signed-off-by: Hauke Mehrtens --- package/boot/uboot-rockchip/Makefile | 16 +- ...-dts-rockchip-add-LinkEase-EasePi-R1.patch | 662 ++++++++++++++++++ ...oard-rockchip-add-LinkEase-EasePi-R1.patch | 124 ++++ 3 files changed, 794 insertions(+), 8 deletions(-) create mode 100644 package/boot/uboot-rockchip/patches/106-1-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch create mode 100644 package/boot/uboot-rockchip/patches/106-2-board-rockchip-add-LinkEase-EasePi-R1.patch diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 6b87fb193a..74cacde33e 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -219,6 +219,13 @@ define U-Boot/bpi-r2-pro-rk3568 sinovoip_bpi-r2-pro endef +define U-Boot/easepi-r1-rk3568 + $(U-Boot/rk3568/Default) + NAME:=LinkEase EasePi R1 + BUILD_DEVICES:= \ + linkease_easepi-r1 +endef + define U-Boot/fastrhino-r66s-rk3568 $(U-Boot/rk3568/Default) NAME:=FastRhino R66S @@ -226,13 +233,6 @@ define U-Boot/fastrhino-r66s-rk3568 lunzn_fastrhino-r66s endef -define U-Boot/generic-rk3568 - $(U-Boot/rk3568/Default) - NAME:=Generic RK3566/RK3568 board - BUILD_DEVICES:= \ - linkease_easepi-r1 -endef - define U-Boot/nanopi-r5c-rk3568 $(U-Boot/rk3568/Default) NAME:=NanoPi R5C @@ -347,8 +347,8 @@ UBOOT_TARGETS := \ radxa-zero-3-rk3566 \ rock-3c-rk3566 \ bpi-r2-pro-rk3568 \ + easepi-r1-rk3568 \ fastrhino-r66s-rk3568 \ - generic-rk3568 \ nanopi-r5c-rk3568 \ nanopi-r5s-rk3568 \ radxa-e25-rk3568 \ diff --git a/package/boot/uboot-rockchip/patches/106-1-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch b/package/boot/uboot-rockchip/patches/106-1-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch new file mode 100644 index 0000000000..ad8b1d2eff --- /dev/null +++ b/package/boot/uboot-rockchip/patches/106-1-arm64-dts-rockchip-add-LinkEase-EasePi-R1.patch @@ -0,0 +1,662 @@ +From 63d60b21fd4933080ff22bdc21652f7c2a14bc52 Mon Sep 17 00:00:00 2001 +From: Liangbin Lian +Date: Tue, 14 Oct 2025 13:12:26 +0800 +Subject: [PATCH 1/2] arm64: dts: rockchip: add LinkEase EasePi R1 + +LinkEase EasePi R1 [1] is a high-performance mini router. + +Specification: +- Rockchip RK3568 +- 2GB/4GB LPDDR4 RAM +- 16GB on-board eMMC +- 1x M.2 key for 2280 NVMe (PCIe 3.0) +- 1x USB 3.0 Type-A +- 1x USB 2.0 Type-C (for USB flashing) +- 2x 1000 Base-T (native, RTL8211F) +- 2x 2500 Base-T (PCIe, RTL8125B) +- 1x HDMI 2.0 Output +- 12v DC Jack +- 1x Power key connected to PMIC +- 2x LEDs (one static power supplied, one GPIO controlled) + +[1] https://doc.linkease.com/zh/guide/easepi-r1/hardware.html + +Reviewed-by: Andrew Lunn +Signed-off-by: Liangbin Lian +Link: https://patch.msgid.link/20251014051226.64255-4-jjm2473@gmail.com +Signed-off-by: Heiko Stuebner + +[ upstream commit: deaefeaf3df433d50935b9a85076041040f06d74 ] + +Signed-off-by: Liangbin Lian +--- + .../src/arm64/rockchip/rk3568-easepi-r1.dts | 623 ++++++++++++++++++ + 1 file changed, 623 insertions(+) + create mode 100644 dts/upstream/src/arm64/rockchip/rk3568-easepi-r1.dts + +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3568-easepi-r1.dts +@@ -0,0 +1,623 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "LinkEase EasePi R1"; ++ compatible = "linkease,easepi-r1", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ mmc0 = &sdhci; ++ }; ++ ++ chosen: chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 0>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ ++ button-recovery { ++ label = "Recovery"; ++ linux,code = ; ++ press-threshold-microvolt = <1750>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&status_led_pin>; ++ ++ status_led: led-status { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ dc_12v: regulator-dc-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_12v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc3v3_sys: regulator-vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ regulator-vdd0v95-25glan { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vdd0v95_25glan_en>; ++ regulator-name = "vdd0v95_25glan"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <950000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_nvme: regulator-vcc3v3-nvme { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc3v3_nvme_en>; ++ regulator-name = "vcc3v3_nvme"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++}; ++ ++&combphy1 { ++ status = "okay"; ++}; ++ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ phy-handle = <&rgmii_phy1>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ system-power-controller; ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ wakeup-source; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-always-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <950000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0_8ch { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x1>; ++ pinctrl-0 = <ð_phy0_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&mdio1 { ++ rgmii_phy1: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x1>; ++ pinctrl-0 = <ð_phy1_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++/* ETH3 */ ++&pcie2x1 { ++ reset-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ data-lanes = <1 2>; ++ status = "okay"; ++}; ++ ++/* ETH2 */ ++&pcie3x1 { ++ num-lanes = <1>; ++ reset-gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++/* M.2 Key for 2280 NVMe */ ++&pcie3x2 { ++ num-lanes = <1>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_nvme>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ gmac0 { ++ eth_phy0_reset_pin: eth-phy0-reset-pin { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gmac1 { ++ eth_phy1_reset_pin: eth-phy1-reset-pin { ++ rockchip,pins = <2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gpio-leds { ++ status_led_pin: status-led-pin { ++ rockchip,pins = <2 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ nvme { ++ vcc3v3_nvme_en: vcc3v3-nvme-en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie-nic { ++ vdd0v95_25glan_en: vdd0v95-25glan-en { ++ rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic-int { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++/* OTG Only USB2.0, Only device mode */ ++&usb_host0_xhci { ++ dr_mode = "peripheral"; ++ extcon = <&usb2phy0>; ++ maximum-speed = "high-speed"; ++ phys = <&usb2phy0_otg>; ++ phy-names = "usb2-phy"; ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_host { ++ phy-supply = <&vcc5v0_sys>; ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; diff --git a/package/boot/uboot-rockchip/patches/106-2-board-rockchip-add-LinkEase-EasePi-R1.patch b/package/boot/uboot-rockchip/patches/106-2-board-rockchip-add-LinkEase-EasePi-R1.patch new file mode 100644 index 0000000000..76e4cd0329 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/106-2-board-rockchip-add-LinkEase-EasePi-R1.patch @@ -0,0 +1,124 @@ +From bb1996b423b81b94b1468fffe5eb9949434b941e Mon Sep 17 00:00:00 2001 +From: Liangbin Lian +Date: Thu, 13 Nov 2025 14:51:21 +0800 +Subject: [PATCH 2/2] board: rockchip: add LinkEase EasePi R1 + +LinkEase EasePi R1 [1] is a high-performance mini router. + +Specification: +- Rockchip RK3568 +- 2GB/4GB LPDDR4 RAM +- 16GB on-board eMMC +- 1x M.2 key for 2280 NVMe (PCIe 3.0) +- 1x USB 3.0 Type-A +- 1x USB 2.0 Type-C (for USB flashing) +- 2x 1000 Base-T (native, RTL8211F) +- 2x 2500 Base-T (PCIe, RTL8125B) +- 1x HDMI 2.0 Output +- 12v DC Jack +- 1x Power key connected to PMIC +- 2x LEDs (one static power supplied, one GPIO controlled) + +[1] https://doc.linkease.com/zh/guide/easepi-r1/hardware.html + +Signed-off-by: Liangbin Lian +--- + arch/arm/dts/rk3568-easepi-r1-u-boot.dtsi | 3 + + configs/easepi-r1-rk3568_defconfig | 84 +++++++++++++++++++++++ + 2 files changed, 87 insertions(+) + create mode 100644 arch/arm/dts/rk3568-easepi-r1-u-boot.dtsi + create mode 100644 configs/easepi-r1-rk3568_defconfig + +--- /dev/null ++++ b/arch/arm/dts/rk3568-easepi-r1-u-boot.dtsi +@@ -0,0 +1,3 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++#include "rk356x-u-boot.dtsi" +--- /dev/null ++++ b/configs/easepi-r1-rk3568_defconfig +@@ -0,0 +1,84 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3568-easepi-r1" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_SPL_SERIAL=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-easepi-r1.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_ATF=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_ROCKUSB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_SPL_DM_SEQ_ALIAS=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_SPL_CLK=y ++# CONFIG_USB_FUNCTION_FASTBOOT is not set ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_PHY_REALTEK=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_DWC_ETH_QOS_ROCKCHIP=y ++CONFIG_RTL8169=y ++CONFIG_NVME_PCI=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_SPL_USB_DWC3_GENERIC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_USB_FUNCTION_ROCKUSB=y ++CONFIG_ERRNO_STR=y From 414f196a9644113d4e1ce153cb5129794f15b7c7 Mon Sep 17 00:00:00 2001 From: Liangbin Lian Date: Thu, 13 Nov 2025 15:26:03 +0800 Subject: [PATCH 090/128] rockchip: LinkEase EasePi R1 use dedicated uboot Fixes the "mdio_bus stmmac-1: MDIO device at address 1 is missing" error that occurs during cold boot when initializing GMAC. Fixes: 8ca4caacd039 ("rockchip: Add support for RK3568 LinkEase EasePi R1") Signed-off-by: Liangbin Lian Link: https://github.com/openwrt/openwrt/pull/20772 (cherry picked from commit e6a5ca0da7377645be7b9ba70b18de3b9bab5342) Link: https://github.com/openwrt/openwrt/pull/20744 Signed-off-by: Hauke Mehrtens --- target/linux/rockchip/image/armv8.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index 07272d244c..c28835d5cd 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -128,7 +128,6 @@ define Device/linkease_easepi-r1 DEVICE_VENDOR := LinkEase DEVICE_MODEL := EasePi R1 SOC := rk3568 - UBOOT_DEVICE_NAME := generic-rk3568 DEVICE_PACKAGES := blkdiscard block-mount kmod-button-hotplug kmod-nvme kmod-r8169 endef TARGET_DEVICES += linkease_easepi-r1 From 51108508f10eb25f99395ec9334f996813bc5a22 Mon Sep 17 00:00:00 2001 From: Michal Halva Date: Sat, 2 Aug 2025 20:46:14 +0200 Subject: [PATCH 091/128] mediatek: filogic: add support for Cudy WR3000P v1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hardware -------- MediaTek MT7981 WiSoC 512MB DDR4 RAM 128MB SPI-NAND MediaTek MT7981 2x2 DBDC 802.11ax 2T2R (2.4 / 5) 4 LAN MediaTek MT7531 PHY 1 WAN RTL8221B-VB-CG 2.5Gbps PHY UART: 115200 8N1 3.3V USB2 Port PoE on WAN Port MAC: LAN MAC: label mac WAN MAC: label mac + 1 2.4G MAC: label mac 5G MAC: label mac + 1 with LA bit set Gotchas: WAN LED does not light up (might require further DTS tweaks) PoE on WAN port was not tested This commit is heavily based on WR3000H one, I've just ported DTS differences from the official image to get USB support and proper LED mapping. Installation ------------ [Untested as I've received and used a transitional image from Cudy] 1. Connect to the serial port as described in the "Hardware" section. 2. Power on the device + press reset pin. Keep pressing reset pin to enter the U-Boot shell. 3. Download the OpenWrt initramfs image. Place it on an TFTP server connected to the Cudy LAN ports. Make sure the server is reachable at 192.168.1.88. Rename the image to "cudy3000p.bin" 4. Download and boot the OpenWrt initramfs image. $ tftpboot 0x46000000 cudy3000s.bin; bootm 0x46000000 5. Transfer the OpenWrt sysupgrade image to the device using scp. Install with sysupgrade. Signed-off-by: Michal Halva Link: https://github.com/openwrt/openwrt/pull/19636 (cherry picked from commit 04e9d154f209c0390d962c10e75ed3c49bd5a9e9) Signed-off-by: Thibaut VARÈNE Link: https://github.com/openwrt/openwrt/pull/20830 Signed-off-by: Hauke Mehrtens --- .../mediatek/dts/mt7981b-cudy-wr3000p-v1.dts | 153 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 3 +- .../etc/hotplug.d/ieee80211/11_fix_wifi_mac | 1 + .../base-files/lib/upgrade/platform.sh | 3 +- target/linux/mediatek/image/filogic.mk | 17 ++ 5 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 target/linux/mediatek/dts/mt7981b-cudy-wr3000p-v1.dts diff --git a/target/linux/mediatek/dts/mt7981b-cudy-wr3000p-v1.dts b/target/linux/mediatek/dts/mt7981b-cudy-wr3000p-v1.dts new file mode 100644 index 0000000000..0bee64d7b8 --- /dev/null +++ b/target/linux/mediatek/dts/mt7981b-cudy-wr3000p-v1.dts @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; + +#include "mt7981b-cudy-wr3000-nand.dtsi" + +/ { + model = "Cudy WR3000P v1"; + compatible = "cudy,wr3000p-v1", "mediatek,mt7981"; + + aliases { + label-mac-device = &gmac0; + led-boot = &led_status; + led-failsafe = &led_status; + led-running = &led_status; + led-upgrade = &led_status; + serial0 = &uart0; + }; + + leds { + compatible = "gpio-leds"; + + led_status: led-status { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&pio 11 GPIO_ACTIVE_LOW>; + }; + + led-internet { + function = LED_FUNCTION_WAN_ONLINE; + color = ; + gpios = <&pio 6 GPIO_ACTIVE_LOW>; + }; + + led-wlan2g { + function = LED_FUNCTION_WLAN_2GHZ; + color = ; + gpios = <&pio 7 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + led-wlan5g { + function = LED_FUNCTION_WLAN_5GHZ; + color = ; + gpios = <&pio 9 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + + led-wan { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&pio 5 GPIO_ACTIVE_LOW>; + }; + + led-usb { + function = LED_FUNCTION_USB; + color = ; + gpios = <&pio 4 GPIO_ACTIVE_LOW>; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + usb_vbus: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpios = <&pio 10 GPIO_ACTIVE_LOW>; + regulator-boot-on; + }; +}; + +ð { + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-handle = <&phy6>; + phy-mode = "2500base-x"; + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_bdinfo_de00 1>; + label = "wan"; + }; +}; + +&mdio_bus { + phy6: ethernet-phy@6 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <6>; + reset-assert-us = <100000>; + reset-deassert-us = <100000>; + reset-gpios = <&pio 3 GPIO_ACTIVE_LOW>; + }; +}; + +&switch { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; +}; + +&xhci { + vusb33-supply = <®_3p3v>; + vbus-supply = <&usb_vbus>; + mediatek,u3p-dis-msk = <0x01>; + phys = <&u2port0 PHY_TYPE_USB2>; + status = "okay"; +}; + +&usb_phy { + status = "okay"; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index 217f495f95..950dcf7143 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -42,7 +42,8 @@ wavlink,wl-wn573hx3) cudy,wr3000-v1) ucidef_set_led_netdev "wan" "wan" "blue:wan" "wan" ;; -cudy,wr3000h-v1) +cudy,wr3000h-v1|\ +cudy,wr3000p-v1) ucidef_set_led_netdev "lan1" "lan1" "white:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan2" "lan2" "white:lan-2" "lan2" "link tx rx" ucidef_set_led_netdev "lan3" "lan3" "white:lan-3" "lan3" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac index 58672d9d72..fe98657a1a 100644 --- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac +++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac @@ -84,6 +84,7 @@ case "$board" in cudy,wr3000e-v1|\ cudy,wr3000s-v1|\ cudy,wr3000h-v1|\ + cudy,wr3000p-v1|\ cudy,wr3000-v1) addr=$(mtd_get_mac_binary bdinfo 0xde00) # Originally, phy0 is phy1 mac with LA bit set. However, this would conflict diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index bd66551198..3cc8b91b74 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -127,7 +127,8 @@ platform_do_upgrade() { CI_KERNPART="linux" nand_do_upgrade "$1" ;; - cudy,wr3000h-v1) + cudy,wr3000h-v1|\ + cudy,wr3000p-v1) CI_UBIPART="ubi" nand_do_upgrade "$1" ;; diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 2cf44bee14..17289675a6 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -856,6 +856,23 @@ define Device/cudy_wr3000h-v1 endef TARGET_DEVICES += cudy_wr3000h-v1 +define Device/cudy_wr3000p-v1 + DEVICE_VENDOR := Cudy + DEVICE_MODEL := WR3000P + DEVICE_VARIANT := v1 + DEVICE_DTS := mt7981b-cudy-wr3000p-v1 + DEVICE_DTS_DIR := ../dts + SUPPORTED_DEVICES += R57 + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 65536k + KERNEL_IN_UBI := 1 + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata + DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware +endef +TARGET_DEVICES += cudy_wr3000p-v1 + define Device/dlink_aquila-pro-ai-m30-a1 DEVICE_VENDOR := D-Link DEVICE_MODEL := AQUILA PRO AI M30 From ea96f50747de0a788822e1b8ad8621975cf17dbc Mon Sep 17 00:00:00 2001 From: Donghyun Ko Date: Fri, 1 Aug 2025 15:01:07 +0900 Subject: [PATCH 092/128] mediatek: add support for ipTIME AX7800M-6E Specification ------------- - SoC : MediaTek MT7986AV quad-core ARM Cortex-A53 2GHz - RAM : DDR4 512Mbytes, Nanya Technology NT5AD256M16E4 - Flash : 128Mbytes NAND Flash, ESMT F50L1G41LB - WLAN : MediaTek MT7976DAN, MediaTek MT7916AN, MediaTek MT7976AN - 2.4GHz : b/g/n/ax, Multi User MIMO - 5GHz : a/n/ac/ax, Multi User MIMO - 6GHz : ax, Multi User MIMO - Ethernet : 10/100/1000 Mbps x4, LAN (MediaTek MT7531AE) 10/100/1000/2500 Mbps x1, WAN (MaxLinear GPY211C0VC) - UART : 1x4 pin header on PCB - [J1] 3.3V, TX, RX, GND (115200, 8N1) - Buttons : WPS, Reset - Switches : Rfkill Slide Switch - USB : 1x USB 3.0 (MediaTek MT7986AV peripheral) - FAN : 1x Fan (off - slow - fast) - LEDs : 1x Power (Blue) 1x CPU (Blue) 1x Wi-Fi 6GHz (Blue) 1x Wi-Fi 5GHz (Blue) 1x Wi-Fi 2.4GHz (Blue) 4x LAN activity (Blue) 1x WAN activity (Blue) 1x USB 3.0 (Blue) - Power : 12VDC, 3.5A (Center positive polarity) MAC address ----------- +-----------+-------------------+------------------------+ | Interface | MAC | Algorithm | +-----------+-------------------+------------------------+ | WLAN 2.4G | 58:86:94:xx:xx:xx | label1 | | WLAN 5G | 5A:86:94:xx:xx:xx | label2 with LA Bit set | | WLAN 6G | 5A:86:94:xx:xx:xx | label1 with LA Bit set | | WAN | 58:86:94:xx:xx:xx | label1 + 1 | | LAN | 58:86:94:xx:xx:xx | label1 + 3 | +-----------+-------------------+------------------------+ The WLAN 2.4G MAC address (label1) was found in 'Factory' partition, 0xA0004 The WLAN 5G MAC address (label2) was found in 'Factory' partition, 0x4 Installation ------------ 1. Download the OEM recovery software (ipTIME Firmware Wizard (11ac)) from the manufacturer's website 2. Download the *squashfs-factory.bin file from the OpenWrt website 3. Press a reset button, and power up the router (keep pressing the reset button) 4. Wait more than 10 seconds until the CPU LED stop blinking 5. Connect the router (LAN port) to the PC 6. Run the OEM recovery software and follow the instructions 7. Select the *squashfs-factory.bin file during the router recovery process 8. Wait for the router to boot from *squashfs-factory.bin Note: The router will automatically reboot if no file is uploaded within 55 seconds. Fan Control ------------ The fan speed is controlled by writing a value from 0 to 2 to the `fan1_target` file. ``` cd /sys/devices/platform/gpio-fan/hwmon/hwmon2 echo '0' > fan1_target // off echo '1' > fan1_target // slow echo '2' > fan1_target // fast ``` Limitation: Enabling Wi-Fi 6E ---------- Wi-Fi 6E (6GHz) does not work out of the box on LuCI. After installation, you need to configure a few settings in the `radio1` and `default_radio1` sections of the `/etc/config/wireless`. Once you have made these changes, you can enable and use Wi-Fi 6E. In the `radio1` section, you need to add three common options: - band: must be set to `6g` - country: a valid country code for the 6GHz band - channel: a preferrend scanning channel (PSC) for 6GHz In the `default_radio1` section, you need to add the SSID and key: - ssid: The public name of your Wi-Fi network - key: The Wi-Fi password - encryption: must be set to either `sae` for WPA3 or `owe` for OWE (open network) Example: ``` config wifi-device 'radio1' ... option band '6g' option country 'KR' option channel '37' ... config wifi-iface 'default_radio1' ... option ssid 'my_wifi_6e_name' option key 'my_strong_password1234' option encryption 'sae' ... ``` Note: A list of all the 6GHz PSC channels: ``` 5, 21, 37, 53, 69, 85, 101, 117, 133, 149, 165, 181, 197, 213, and 229 ``` Limitation: Maximum Transmit Power (Wi-Fi 6E) ---------- The maximum transmit power is currently broken. In the drop-down menu, you can only choose between "driver default" and "255 dBm (2147493647 mW)". There is currently no workaround for the issue. Please leave the maximum transmit power set to "driver default". Signed-off-by: Donghyun Ko Link: https://github.com/openwrt/openwrt/pull/19763 (cherry picked from commit 2503e5bc3798556c10e7027b0013fdeda07ced1f) Signed-off-by: Donghyun Ko Link: https://github.com/openwrt/openwrt/pull/20773 Signed-off-by: Hauke Mehrtens --- .../dts/mt7986a-iptime-ax7800m-6e.dts | 428 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 3 + .../filogic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/ieee80211/11_fix_wifi_mac | 6 + target/linux/mediatek/image/filogic.mk | 19 + 5 files changed, 457 insertions(+) create mode 100644 target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts diff --git a/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts b/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts new file mode 100644 index 0000000000..72b96caca3 --- /dev/null +++ b/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts @@ -0,0 +1,428 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT + +/dts-v1/; +#include +#include +#include +#include + +#include "mt7986a.dtsi" + +/ { + model = "ipTIME AX7800M-6E"; + compatible = "iptime,ax7800m-6e", "mediatek,mt7986a"; + + aliases { + serial0 = &uart0; + label-mac-device = &gmac1; + led-boot = &led_cpu; + led-failsafe = &led_cpu; + led-running = &led_cpu; + led-upgrade = &led_cpu; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@40000000 { + reg = <0 0x40000000 0 0x20000000>; + device_type = "memory"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-0 { + label = "wps"; + gpios = <&pio 10 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + button-1 { + label = "reset"; + gpios = <&pio 9 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + switch-0 { + label = "rfkill"; + gpios = <&pio 15 GPIO_ACTIVE_HIGH>; + linux,code = ; + linux,input-type = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&pio 22 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + led-1 { + color = ; + function = LED_FUNCTION_USB; + gpios = <&pio 11 GPIO_ACTIVE_LOW>; + }; + + led_cpu: led-2 { + color = ; + function = LED_FUNCTION_CPU; + gpios = <&pio 21 GPIO_ACTIVE_LOW>; + }; + + led-3 { + color = ; + function = LED_FUNCTION_WLAN_2GHZ; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + led-4 { + color = ; + function = LED_FUNCTION_WLAN_6GHZ; + gpios = <&pio 12 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + + led-5 { + color = ; + function = LED_FUNCTION_WLAN_5GHZ; + gpios = <&pio 2 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy2tpt"; + }; + }; + + gpio-fan { + compatible = "gpio-fan"; + gpios = <&pio 19 GPIO_ACTIVE_HIGH + &pio 18 GPIO_ACTIVE_HIGH>; + /* We don't know the exact rpm, just use dummy values here. */ + gpio-fan,speed-map = <0 0>, <1 1>, <2 2>; + #cooling-cells = <2>; + }; +}; + +&pio { + spi_flash_pins: spi-flash-pins-33-to-38 { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + pcie_pins: pcie-pins { + mux { + function = "pcie"; + groups = "pcie_pereset"; + }; + }; + + wf_2g_5g_pins: wf_2g_5g-pins { + mux { + function = "wifi"; + groups = "wf_2g", "wf_5g"; + }; + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = <4>; + }; + }; + + wf_dbdc_pins: wf-dbdc-pins { + mux { + function = "wifi"; + groups = "wf_dbdc"; + }; + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = <4>; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-buswidth = <4>; + spi-rx-buswidth = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "BL2"; + reg = <0x0 0x100000>; + read-only; + }; + + partition@100000 { + label = "u-boot-env"; + reg = <0x100000 0x80000>; + }; + + partition@180000 { + label = "Factory"; + reg = <0x180000 0x200000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + macaddr_factory_4: macaddr@4 { + compatible = "mac-base"; + reg = <0x4 0x6>; + #nvmem-cell-cells = <1>; + }; + + eeprom_factory_a0000: eeprom@a0000 { + reg = <0xa0000 0x1000>; + }; + + macaddr_factory_a0004: macaddr@a0004 { + compatible = "mac-base"; + reg = <0xa0004 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + + partition@380000 { + label = "FIP"; + reg = <0x380000 0x200000>; + read-only; + }; + + partition@580000 { + label = "ubi"; + reg = <0x580000 0x6e00000>; + }; + }; + }; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_factory_a0004 (3)>; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "2500base-x"; + phy-handle = <&phy6>; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_factory_a0004 (1)>; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; + reset-delay-us = <50000>; + reset-post-delay-us = <20000>; + }; +}; + +&mdio { + phy6: phy@6 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <6>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_WAN; + }; + }; + }; + + switch@1f { + compatible = "mediatek,mt7531"; + reg = <0x1f>; + reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; + reset-assert-us = <10000>; + reset-deassert-us = <10000>; + + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&pio>; + interrupts = <66 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; +}; + +&wifi { + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + pinctrl-names = "default", "dbdc"; + pinctrl-0 = <&wf_2g_5g_pins>; + pinctrl-1 = <&wf_dbdc_pins>; + status = "okay"; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pins>; + status = "okay"; + + pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <0x03>; + #size-cells = <0x02>; + + wifi@0,0 { + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_a0000>; + nvmem-cell-names = "eeprom"; + + band@0 { + reg = <0>; + nvmem-cells = <&macaddr_factory_a0004 (0)>; + nvmem-cell-names = "mac-address"; + }; + + band@1 { + reg = <1>; + nvmem-cells = <&macaddr_factory_a0004 (0)>; + nvmem-cell-names = "mac-address"; + }; + + band@2 { + reg = <2>; + nvmem-cells = <&macaddr_factory_4 (0)>; + nvmem-cell-names = "mac-address"; + }; + }; + }; +}; + +&pcie_phy { + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&crypto { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&ssusb { + status = "okay"; +}; + +&usb_phy { + status = "okay"; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index 950dcf7143..ede0ea936f 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -71,6 +71,9 @@ iptime,ax3000q) iptime,ax3000sm) ucidef_set_led_netdev "wan" "wan" "amber:wan" "eth1" "link tx rx" ;; +iptime,ax7800m-6e) + ucidef_set_led_netdev "wan" "wan" "mdio-bus:06:blue:wan" "eth1" "link tx rx" + ;; mercusys,mr80x-v3) ucidef_set_led_netdev "lan1" "lan-1" "green:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan2" "lan-2" "green:lan-2" "lan2" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index e876ef75ed..ccb1dbc6d2 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -48,6 +48,7 @@ mediatek_setup_interfaces() ;; asus,tuf-ax4200|\ iptime,ax3000sm|\ + iptime,ax7800m-6e|\ jdcloud,re-cp-03|\ mediatek,mt7981-rfb|\ netcore,n60|\ diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac index fe98657a1a..b0b301559b 100644 --- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac +++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac @@ -118,6 +118,12 @@ case "$board" in [ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_unsetbit $(macaddr_unsetbit $(macaddr_unsetbit $(macaddr_setbit $addr 26) 25) 27) 28) > \ /sys${DEVPATH}/macaddress ;; + iptime,ax7800m-6e) + addr1=$(mtd_get_mac_binary "Factory" 0xa0004) + addr2=$(mtd_get_mac_binary "Factory" 0x4) + [ "$PHYNBR" = "1" ] && macaddr_setbit_la $addr1 > /sys${DEVPATH}/macaddress + [ "$PHYNBR" = "2" ] && macaddr_setbit_la $addr2 > /sys${DEVPATH}/macaddress + ;; jcg,q30-pro|\ netcore,n60) # Originally, phy1 is phy0 mac with LA bit set. However, this would conflict diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 17289675a6..a512bb2efa 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1131,6 +1131,25 @@ define Device/iptime_ax3000sm endef TARGET_DEVICES += iptime_ax3000sm +define Device/iptime_ax7800m-6e + DEVICE_VENDOR := ipTIME + DEVICE_MODEL := AX7800M-6E + DEVICE_DTS := mt7986a-iptime-ax7800m-6e + DEVICE_DTS_DIR := ../dts + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 32768k + KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin := sysupgrade-tar | append-metadata | check-size | iptime-crc32 ax7800m + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata + DEVICE_PACKAGES := kmod-usb3 kmod-mt7915e kmod-mt7916-firmware kmod-mt7986-firmware mt7986-wo-firmware kmod-hwmon-gpiofan + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += iptime_ax7800m-6e + define Device/jcg_q30-pro DEVICE_VENDOR := JCG DEVICE_MODEL := Q30 PRO From 9f8c60c2c8589dd6b7ec51c9b1931e69da0ed8bb Mon Sep 17 00:00:00 2001 From: Donghyun Ko Date: Sun, 23 Nov 2025 19:01:21 +0900 Subject: [PATCH 093/128] mediatek: use dt-bindings drive strength macros for ipTIME AX7800M-6E Replace hardcoded numbers with the dt-bindings drive strength macros defined in "dt-bindings/pinctrl/mt65xx.h". Signed-off-by: Donghyun Ko Link: https://github.com/openwrt/openwrt/pull/20894 (cherry picked from commit 2c667f2df4dac12386c7081f68cf02d7f95a9faa) Signed-off-by: Donghyun Ko Link: https://github.com/openwrt/openwrt/pull/20773 Signed-off-by: Hauke Mehrtens --- target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts b/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts index 72b96caca3..59ac770cfc 100644 --- a/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts +++ b/target/linux/mediatek/dts/mt7986a-iptime-ax7800m-6e.dts @@ -149,7 +149,7 @@ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", "WF1_TOP_CLK", "WF1_TOP_DATA"; - drive-strength = <4>; + drive-strength = ; }; }; @@ -166,7 +166,7 @@ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", "WF1_TOP_CLK", "WF1_TOP_DATA"; - drive-strength = <4>; + drive-strength = ; }; }; }; From c6e59d06afca02ccb2541631cacc769ae4d6569f Mon Sep 17 00:00:00 2001 From: Luis Mita Date: Wed, 1 Oct 2025 18:42:58 -0400 Subject: [PATCH 094/128] ramips: mt7621: add support for Cudy AP1300 Outdoor v1 Hardware: - SoC: MediaTek MT7621DAT - Flash: 16 MiB XM25QH128C - RAM: 128 MiB - WLAN: 2.4 GHz (MT7603E, 11n), 5 GHz (MediaTek MT7613BEN, 11ac) - Ethernet: 1x10/100/1000 Mbps LAN - Buttons: 1 Reset button, 1 WPS button - LEDs: 5x Green - Serial Console: unpopulated header 115200 8n1 (silkscreen on PCB) - Power: POE 802.3af (37-57V DC) MAC addresses: +---------+-------------------+-----------+ | | MAC | Algorithm | +---------+-------------------+-----------+ | LAN | 80:af:ca:xx:xx:x0 | label | | WLAN 2g | 80:af:ca:xx:xx:x0 | label | | WLAN 5g | 82:af:ca:xx:xx:x1 | +1 | +---------+-------------------+-----------+ Installation: The factory firmware is locked: you can only work with Cudy signed firmware. Download a intermediate firmware signed by Cudy here: https://www.cudy.com/blogs/faq/openwrt-software-download After that, login to the router (192.168.10.254, password "admin") and install the intermediate firmware. If you can reach LuCI or SSH now on the intermediate firmware, just use the sysupgrade image with the 'Keep settings' option turned off. Special thanks to Daniel de Kock for starting the porting work at #16265. Signed-off-by: Luis Mita Co-Authored-By: Daniel de Kock Co-Authored-By: Hauke Mehrtens Link: https://github.com/openwrt/openwrt/pull/20268 (cherry picked from commit 8fb644e9e8416df0d7051d8e35b57b06a030c05e) Link: https://github.com/openwrt/openwrt/pull/20710 Signed-off-by: Hauke Mehrtens --- .../dts/mt7621_cudy_ap1300-outdoor-v1.dts | 213 ++++++++++++++++++ target/linux/ramips/image/mt7621.mk | 14 ++ .../mt7621/base-files/etc/board.d/01_leds | 3 + .../mt7621/base-files/etc/board.d/02_network | 1 + 4 files changed, 231 insertions(+) create mode 100644 target/linux/ramips/dts/mt7621_cudy_ap1300-outdoor-v1.dts diff --git a/target/linux/ramips/dts/mt7621_cudy_ap1300-outdoor-v1.dts b/target/linux/ramips/dts/mt7621_cudy_ap1300-outdoor-v1.dts new file mode 100644 index 0000000000..f6dbd17a87 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_cudy_ap1300-outdoor-v1.dts @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + compatible = "cudy,ap1300-outdoor-v1", "mediatek,mt7621-soc"; + model = "Cudy AP1300 Outdoor v1"; + + aliases { + led-boot = &led_sys; + led-failsafe = &led_sys; + led-running = &led_sys; + led-upgrade = &led_sys; + label-mac-device = &gmac0; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + wps { + label = "wps"; + gpios = <&gpio 10 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + led_sys:status { + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_STATUS; + }; + + internet { + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WAN_ONLINE; + }; + + lan { + gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_LAN; + }; + + wifi2g { + gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WLAN_2GHZ; + linux,default-trigger = "phy0tpt"; + }; + + wifi5g { + gpios = <&gpio 45 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WLAN_5GHZ; + linux,default-trigger = "phy1tpt"; + }; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&gpio 7 GPIO_ACTIVE_LOW>; + hw_algo = "toggle"; + /* hw_margin_ms seems to be around 30s for this device*/ + hw_margin_ms = <10000>; + always-running; + }; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x400>; + }; + + eeprom_factory_8000: eeprom@8000 { + reg = <0x8000 0x4da8>; + }; + }; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0xf80000>; + }; + + partition@fd0000 { + label = "debug"; + reg = <0xfd0000 0x10000>; + read-only; + }; + + partition@fe0000 { + label = "backup"; + reg = <0xfe0000 0x10000>; + read-only; + }; + + partition@ff0000 { + label = "bdinfo"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_bdinfo_de00: macaddr@de00 { + compatible = "mac-base"; + reg = <0xde00 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +}; + +&pcie { + status = "okay"; +}; + + +&pcie0 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_0>, <&macaddr_bdinfo_de00 1>; + nvmem-cell-names = "eeprom", "mac-address"; + ieee80211-freq-limit = <2400000 2500000>; + }; +}; + +&pcie1 { + wifi@1,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_8000>, <&macaddr_bdinfo_de00 2>; + nvmem-cell-names = "eeprom", "mac-address"; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_bdinfo_de00 1>; + nvmem-cell-names = "mac-address"; +}; + +&switch0 { + ports { + port@4 { + status = "okay"; + label = "lan"; + }; + }; +}; + +&state_default { + gpio { + groups = "wdt", "i2c", "jtag"; + function = "gpio"; + }; +}; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 03761edc94..fcef42bfb9 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -702,6 +702,20 @@ define Device/confiabits_mt7621-v1 endef TARGET_DEVICES += confiabits_mt7621-v1 +define Device/cudy_ap1300-outdoor-v1 + $(Device/dsa-migration) + $(Device/uimage-lzma-loader) + DEVICE_VENDOR := Cudy + DEVICE_MODEL := AP1300 Outdoor + DEVICE_VARIANT := v1 + IMAGE_SIZE := 15872k + UIMAGE_NAME := R39 + DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap \ + -uboot-envtools + SUPPORTED_DEVICES += R39 +endef +TARGET_DEVICES += cudy_ap1300-outdoor-v1 + define Device/cudy_m1300-v2 $(Device/dsa-migration) IMAGE_SIZE := 15872k diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds index 5d92006d66..94f36c1f6e 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds @@ -58,6 +58,9 @@ wifire,s1500-nbn) belkin,rt1800) ucidef_set_led_netdev "wan" "wan" "white:wan" "wan" ;; +cudy,ap1300-outdoor-v1) + ucidef_set_led_netdev "lan" "lan" "green:lan" "lan" + ;; confiabits,mt7621-v1|\ genexis,pulse-ex400|\ netis,n6) diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network index 337d3ad904..9d2f119c7e 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network @@ -40,6 +40,7 @@ ramips_setup_interfaces() arcadyan,we410443|\ asus,rp-ac56|\ asus,rp-ac87|\ + cudy,ap1300-outdoor-v1|\ dlink,dap-1620-b1|\ dlink,dap-x1860-a1|\ dlink,dra-1360-a1|\ From 913e26b20fb532b47f6da5a16278cfd20deb2f41 Mon Sep 17 00:00:00 2001 From: "Qing W." Date: Sun, 23 Nov 2025 01:33:52 -0500 Subject: [PATCH 095/128] mediatek: add support for WAVLINK WL-WN536AX6 Rev a Product name: Wavlink WL-WN536AX6 Rev a "Mighty LX2" Product link: https://www.wavlink.com/en_us/product/WL-WN536AX6.html Specifications: SOC: MT7986AV RAM: 512MB DDR4 Flash: 128MB SPI NAND Ports: 4 LAN (1G) & 1 WAN (2.5G) WIFI: MT7976PN + MT7975N LEDs: 8 (STATUS, WIFI, WAN, LAN1, LAN2, LAN3, LAN4, PWR) USB: 1 (3.0) MAC table, same as stock firmware: LAN: 80:3F:5D:xx:xx:x1 partition "hw" at 0x44e (ASCII) WAN: 80:3F:5D:xx:xx:x2 partition "hw" at 0x460 (ASCII) 2G: 80:3F:5D:xx:xx:x3 5G: 80:3F:5D:xx:xx:x4 * Installation with OEM WebUI: Note: Make sure PC is connected on LAN1 port. The OEM firmware has an unknown root password and settings are kept after upgrading firmware. Therefore, a customized Openwrt firmware is needed to remove the root password on login, by adding `passwd -d root` to /etc/init.d/bootcount. The WebUI does a filename check so the customized firmware is named accordingly. 1. Download modified firmware file `WAVLINK_WN536AX6-A_M36AX6_V250320-WO-437baca-modified.bin` from https://github.com/ses1er/firmware-misc/tree/main/wavlink/wl-wn536ax6a 2. Log into WebUI on default IP: http://192.168.20.1 3. Browse to More (top menu) -> System -> Firmware Upgrade. 4. Under `Local Upgrade` section, check the device to be upgraded and upload downloaded modified firmware. Click `UPLOAD FILE`, then `APPLY` 5. Wait about 2 minutes (ignore progress bar), and browse to http://192.168.20.1. You should see LUCI login page. Username is root and no password. 6. Browse to `System -> Backup/Flash Firmware`, click on `Flash Image`, click `Browse` and locate `openwrt-mediatek-filogic-wavlink_wl-wn536ax6-a-squashfs-sysupgrade.bin` file. 7. Uncheck `Keep settings and retain the current configuration` and click `Continue`. 8. Router will now be set to IP 192.168.1.1 which is the Openwrt default. * Installation with UART: Note: Having UART connected while cold booting the device will result in a kernel panic when initializing wifi. I've found this workaround: 1. Power off the device and ensure UART is not connected to PC. 2. Power up the device, when lights come on, plug in UART. 3. Warm boots and soft restarts will not cause kernel panic for the duration of device being powered on. Repeat steps for subsequent cold boots. 1. Configure TFTP server with IP 192.168.1.66. Copy `openwrt-mediatek-filogic-wavlink_wl-wn536ax6a-initramfs.itb` to TFTP root. 2. Interrupt boot by pressing 0. 3. Run the following in Uboot console: `setenv serverip 192.168.1.66; setenv ipaddr 192.168.1.1; tftpboot 0x46000000 openwrt-mediatek-filogic-wavlink_wl-wn536ax6-a-initramfs.itb; bootm` 4. Transfer `openwrt-mediatek-filogic-wavlink_wl-wn536ax6-a-squashfs-sysupgrade.bin` to device: (`scp -O openwrt-mediatek-filogic-wavlink_wl-wn536ax6-a-squashfs-sysupgrade.bin root@192.168.1.1:/tmp/`) 5. Run the following on device: `sysupgrade -n /tmp/openwrt-mediatek-filogic-wavlink_wl-wn536ax6-a-squashfs-sysupgrade.bin` Signed-off-by: Qing W. Tested-by: Martin Blumenstingl Link: https://github.com/openwrt/openwrt/pull/20760 (cherry picked from commit 1748ce8295377fe121b5ea9d307bd757c307b475) Link: https://github.com/openwrt/openwrt/pull/20775 Signed-off-by: Hauke Mehrtens --- .../dts/mt7986a-wavlink-wl-wn536ax6-a.dts | 385 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 4 + .../filogic/base-files/etc/board.d/02_network | 1 + target/linux/mediatek/image/filogic.mk | 18 + 4 files changed, 408 insertions(+) create mode 100644 target/linux/mediatek/dts/mt7986a-wavlink-wl-wn536ax6-a.dts diff --git a/target/linux/mediatek/dts/mt7986a-wavlink-wl-wn536ax6-a.dts b/target/linux/mediatek/dts/mt7986a-wavlink-wl-wn536ax6-a.dts new file mode 100644 index 0000000000..eb70f8ff21 --- /dev/null +++ b/target/linux/mediatek/dts/mt7986a-wavlink-wl-wn536ax6-a.dts @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; +#include +#include +#include +#include + +#include "mt7986a.dtsi" + +/ { + compatible = "wavlink,wl-wn536ax6-a", "mediatek,mt7986a"; + model = "WAVLINK WL-WN536AX6 Rev a"; + + aliases { + serial0 = &uart0; + label-mac-device = &wifi; + led-boot = &led_status_blue; + led-failsafe = &led_status_blue; + led-running = &led_status_blue; + led-upgrade = &led_status_blue; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 9 GPIO_ACTIVE_LOW>; + }; + + pair { + label = "pair"; + linux,code = ; + gpios = <&pio 10 GPIO_ACTIVE_LOW>; + }; + + turbo { + label = "turbo"; + linux,code = ; + gpios = <&pio 12 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_WAN; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&pio 14 GPIO_ACTIVE_HIGH>; + }; + + led_status_blue: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 31 GPIO_ACTIVE_LOW>; + }; + + led-3 { + color = ; + function = LED_FUNCTION_WLAN; + gpios = <&pio 32 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + }; + + memory@40000000 { + reg = <0 0x40000000 0 0x20000000>; + device_type = "memory"; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + /* LAN */ + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_hw_44e 0>; + + fixed-link { + full-duplex; + pause; + speed = <2500>; + }; + }; + + /* WAN */ + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "2500base-x"; + phy-handle = <&phy6>; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_hw_44e 1>; + }; + + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + /* MaxLinear GPY211C 2.5G PHY */ + phy6: phy@6 { + /* + * Force the ID here as the PHY only reports it's + * (C45) ID correctly after a reset (before resetting + * it reports 0xfffffff, which causes only the genphy + * driver to match). + */ + compatible = "ethernet-phy-id67c9.de10"; + reg = <6>; + reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; + reset-assert-us = <600>; + reset-deassert-us = <20000>; + phy-mode = "2500base-x"; + }; + + switch@1f { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + }; +}; + +&pio { + spi_flash_pins: spi-flash-pins-33-to-38 { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + bias-pull-down = ; + drive-strength = ; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + bias-pull-down = ; + drive-strength = ; + }; + }; + + wf_2g_5g_pins: wf_2g_5g-pins { + mux { + function = "wifi"; + groups = "wf_2g", "wf_5g"; + }; + + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = ; + }; + }; + + wf_dbdc_pins: wf_dbdc-pins { + mux { + function = "wifi"; + groups = "wf_dbdc"; + }; + + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = ; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + + /* Macronix SPI NAND (128M) */ + flash@0 { + compatible = "spi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + spi-cal-enable; + spi-cal-mode = "read-data"; + spi-cal-datalen = <7>; + spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4e 0x41 0x4e 0x44>; + spi-cal-addrlen = <5>; + spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "BL2"; + reg = <0x0 0x100000>; + read-only; + }; + + partition@100000 { + label = "u-boot-env"; + reg = <0x100000 0x80000>; + }; + + partition@180000 { + label = "Factory"; + reg = <0x180000 0x200000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + }; + }; + + partition@380000 { + label = "FIP"; + reg = <0x380000 0x200000>; + read-only; + }; + + partition@580000 { + label = "ubi"; + reg = <0x580000 0x4000000>; + }; + + partition@7580000 { + label = "HW"; + reg = <0x4580000 0x80000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_hw_44e: macaddr@44e { + compatible = "mac-base"; + reg = <0x44e 0x11>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +}; + +&ssusb { + status = "okay"; + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; +}; + +&uart0 { + status = "okay"; +}; + +&usb_phy { + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&wifi { + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + pinctrl-names = "default", "dbdc"; + pinctrl-0 = <&wf_2g_5g_pins>; + pinctrl-1 = <&wf_dbdc_pins>; + status = "okay"; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index ede0ea936f..c8c1aab525 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -154,6 +154,10 @@ tplink,re6000xd) ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-1" "lan2" "link tx rx" ucidef_set_led_netdev "eth1" "lan-3" "blue:lan-2" "eth1" "link tx rx" ;; +wavlink,wl-wn536ax6-a) + ucidef_set_led_netdev "wifi" "wifi" "blue:wlan" "phy1-ap0" "link" + ucidef_set_led_netdev "wan" "wan" "blue:wan" "eth1" "link tx rx" + ;; wavlink,wl-wn586x3) ucidef_set_led_netdev "lan-1" "lan-1" "blue:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-2" "lan2" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index ccb1dbc6d2..f9bf2b1faf 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -54,6 +54,7 @@ mediatek_setup_interfaces() netcore,n60|\ ruijie,rg-x60-pro|\ unielec,u7981-01*|\ + wavlink,wl-wn536ax6-a|\ zbtlink,zbt-z8102ax|\ zbtlink,zbt-z8102ax-v2|\ zyxel,ex5601-t0-stock|\ diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index a512bb2efa..78e77ea28d 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1853,6 +1853,24 @@ define Device/unielec_u7981-01-nand endef TARGET_DEVICES += unielec_u7981-01-nand +define Device/wavlink_wl-wn536ax6-a + DEVICE_VENDOR := WAVLINK + DEVICE_MODEL := WL-WN536AX6 + DEVICE_VARIANT := Rev a + DEVICE_DTS := mt7986a-wavlink-wl-wn536ax6-a + DEVICE_DTS_DIR := ../dts + DEVICE_DTS_LOADADDR := 0x47000000 + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 65536k + KERNEL_INITRAMFS_SUFFIX := .itb + KERNEL_IN_UBI := 1 + DEVICE_PACKAGES := kmod-usb3 kmod-mt7915e kmod-mt7986-firmware mt7986-wo-firmware + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += wavlink_wl-wn536ax6-a + define Device/wavlink_wl-wn586x3 DEVICE_VENDOR := WAVLINK DEVICE_MODEL := WL-WN586X3 From e781816fe1ffd19a00a9d66d77898924798579c7 Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Tue, 25 Nov 2025 14:10:50 +0200 Subject: [PATCH 096/128] formal: fix workflow permissions Fix formality check permissions that are needed to post optional summaries back to the PR. Link: https://github.com/openwrt/actions-shared-workflows/pull/64 Signed-off-by: George Sapkin Link: https://github.com/openwrt/openwrt/pull/20930 (cherry picked from commit 9f6c16e722e6f1553e8242e907e3a23accc3912d) Link: https://github.com/openwrt/openwrt/pull/20986 Signed-off-by: Robert Marko --- .github/workflows/formal.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml index 081129d6f0..d57b17a562 100644 --- a/.github/workflows/formal.yml +++ b/.github/workflows/formal.yml @@ -5,8 +5,14 @@ on: permissions: contents: read + pull-requests: write jobs: build: name: Test Formalities uses: openwrt/actions-shared-workflows/.github/workflows/formal.yml@main + # with: + # # Post formality check summaries to the PR. + # # Repo's permissions need to be updated for actions to modify PRs: + # # https://docs.github.com/en/rest/issues/comments?apiVersion=2022-11-28#create-an-issue-comment + # post_comment: true From 13226471ef02e622cb42ab36d0fb1322c3b93449 Mon Sep 17 00:00:00 2001 From: Andy Chiang Date: Tue, 9 Sep 2025 07:37:09 +0700 Subject: [PATCH 097/128] ppp: add reqprefix norelease ac_mac Use ppp and enable autoipv6, odhcp6c supports reqprefix and norelease to minimize the chance of IPv6 PD changes.[1] PPPoE supports connecting to a specific AC/BRAS by using the pppoe-mac parameter.[2] 1. https://github.com/openwrt/openwrt/blob/master/package/network/ipv6/odhcp6c/files/dhcpv6.sh#L67 https://github.com/openwrt/openwrt/blob/master/package/network/ipv6/odhcp6c/files/dhcpv6.sh#L77 2. https://github.com/ppp-project/ppp/blob/master/pppd/plugins/pppoe/plugin.c#L93 Signed-off-by: Andy Chiang Link: https://github.com/openwrt/openwrt/pull/19978 Signed-off-by: Robert Marko (cherry picked from commit 7079e456ade5aad41e265c55cee49e4692807ecf) Link: https://github.com/openwrt/openwrt/pull/20824 Signed-off-by: Christian Marangi --- .../network/services/ppp/files/lib/netifd/ppp6-up | 2 ++ package/network/services/ppp/files/ppp.sh | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package/network/services/ppp/files/lib/netifd/ppp6-up b/package/network/services/ppp/files/lib/netifd/ppp6-up index 51339ad3ec..913e50015f 100755 --- a/package/network/services/ppp/files/lib/netifd/ppp6-up +++ b/package/network/services/ppp/files/lib/netifd/ppp6-up @@ -26,9 +26,11 @@ if [ -n "$AUTOIPV6" ]; then [ -n "$ZONE" ] && json_add_string zone "$ZONE" [ -n "$EXTENDPREFIX" ] && json_add_string extendprefix 1 [ -n "$IP6TABLE" ] && json_add_string ip6table $IP6TABLE + [ -n "$REQPREFIX" ] && json_add_string reqprefix $REQPREFIX [ -n "$PEERDNS" ] && json_add_boolean peerdns $PEERDNS [ "$NOSOURCEFILTER" = "1" ] && json_add_boolean sourcefilter "0" [ "$DELEGATE" = "0" ] && json_add_boolean delegate "0" + [ -n "$NORELEASE" ] && json_add_boolean norelease "1" json_close_object ubus call network add_dynamic "$(json_dump)" fi diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh index d7c0cdb1ae..79fc61fcaa 100755 --- a/package/network/services/ppp/files/ppp.sh +++ b/package/network/services/ppp/files/ppp.sh @@ -79,18 +79,20 @@ ppp_generic_init_config() { proto_config_add_int mtu proto_config_add_string pppname proto_config_add_string unnumbered + proto_config_add_string reqprefix proto_config_add_boolean persist proto_config_add_int maxfail proto_config_add_int holdoff proto_config_add_boolean sourcefilter proto_config_add_boolean delegate + proto_config_add_boolean norelease } ppp_generic_setup() { local config="$1"; shift local localip - json_get_vars ip6table demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered persist maxfail holdoff peerdns sourcefilter delegate + json_get_vars ip6table demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered reqprefix persist maxfail holdoff peerdns sourcefilter delegate norelease [ ! -e /proc/sys/net/ipv6 ] && ipv6=0 || json_get_var ipv6 ipv6 @@ -101,6 +103,11 @@ ppp_generic_setup() { autoipv6=1 fi + if [ "$autoipv6" != 1 ]; then + reqprefix="" + norelease="" + fi + if [ "${demand:-0}" -gt 0 ]; then demand="precompiled-active-filter /etc/ppp/filter demand idle $demand" else @@ -137,6 +144,7 @@ ppp_generic_setup() { [ -n "$disconnect" ] || json_get_var disconnect disconnect [ "$sourcefilter" = "0" ] || sourcefilter="" [ "$delegate" != "0" ] && delegate="" + [ "$norelease" = "1" ] || norelease="" proto_run_command "$config" /usr/sbin/pppd \ nodetach ipparam "$config" \ @@ -145,6 +153,8 @@ ppp_generic_setup() { ${lcp_failure:+lcp-echo-interval $lcp_interval lcp-echo-failure $lcp_failure $lcp_adaptive} \ ${ipv6:++ipv6} \ ${autoipv6:+set AUTOIPV6=1} \ + ${reqprefix:+set REQPREFIX=$reqprefix} \ + ${norelease:+set NORELEASE=1} \ ${ip6table:+set IP6TABLE=$ip6table} \ ${peerdns:+set PEERDNS=$peerdns} \ ${sourcefilter:+set NOSOURCEFILTER=1} \ @@ -215,6 +225,7 @@ proto_pppoe_init_config() { ppp_generic_init_config proto_config_add_string "ac" proto_config_add_string "service" + proto_config_add_string "ac_mac" proto_config_add_string "host_uniq" proto_config_add_int "padi_attempts" proto_config_add_int "padi_timeout" @@ -233,6 +244,7 @@ proto_pppoe_setup() { json_get_var ac ac json_get_var service service + json_get_var ac_mac ac_mac json_get_var host_uniq host_uniq json_get_var padi_attempts padi_attempts json_get_var padi_timeout padi_timeout @@ -241,6 +253,7 @@ proto_pppoe_setup() { plugin pppoe.so \ ${ac:+rp_pppoe_ac "$ac"} \ ${service:+rp_pppoe_service "$service"} \ + ${ac_mac:+pppoe-mac "$ac_mac"} \ ${host_uniq:+host-uniq "$host_uniq"} \ ${padi_attempts:+pppoe-padi-attempts $padi_attempts} \ ${padi_timeout:+pppoe-padi-timeout $padi_timeout} \ From b1528735da529677519b13961aee783a718f313c Mon Sep 17 00:00:00 2001 From: Goetz Goerisch Date: Tue, 2 Dec 2025 17:10:46 +0100 Subject: [PATCH 098/128] kernel: bump 6.6 to 6.6.118 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.118 All patches auto-refreshed. Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/21022 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 ++-- .../linux/bcm53xx/patches-6.6/905-BCM53573-minor-hacks.patch | 4 ++-- .../301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch | 2 +- ...kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch | 4 ++-- .../linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index 3a848b96e5..e5c3c5c302 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .117 -LINUX_KERNEL_HASH-6.6.117 = 643b31079222fdbda70cfdd0b68c514f05a3926104be4762a4685f62818b43d1 +LINUX_VERSION-6.6 = .118 +LINUX_KERNEL_HASH-6.6.118 = 4bdddce35474afc8d26f74ebfbcd0e1045ecd15f69e60f53529dba143374b17d diff --git a/target/linux/bcm53xx/patches-6.6/905-BCM53573-minor-hacks.patch b/target/linux/bcm53xx/patches-6.6/905-BCM53573-minor-hacks.patch index 44573cb46a..afb0a1b8a3 100644 --- a/target/linux/bcm53xx/patches-6.6/905-BCM53573-minor-hacks.patch +++ b/target/linux/bcm53xx/patches-6.6/905-BCM53573-minor-hacks.patch @@ -21,7 +21,7 @@ Signed-off-by: Rafał Miłecki clocks { --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c -@@ -331,14 +331,6 @@ static int bcma_register_devices(struct +@@ -337,14 +337,6 @@ static int bcma_register_devices(struct } #endif @@ -36,7 +36,7 @@ Signed-off-by: Rafał Miłecki #ifdef CONFIG_BCMA_NFLASH if (bus->drv_cc.nflash.present) { err = platform_device_register(&bcma_nflash_dev); -@@ -418,6 +410,14 @@ int bcma_bus_register(struct bcma_bus *b +@@ -424,6 +416,14 @@ int bcma_bus_register(struct bcma_bus *b bcma_register_core(bus, core); } diff --git a/target/linux/generic/backport-6.6/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch b/target/linux/generic/backport-6.6/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch index adc924c09a..d76c562940 100644 --- a/target/linux/generic/backport-6.6/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch +++ b/target/linux/generic/backport-6.6/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch @@ -128,7 +128,7 @@ Signed-off-by: Kees Cook #ifdef __BIG_ENDIAN --- a/include/linux/kernel.h +++ b/include/linux/kernel.h -@@ -38,14 +38,6 @@ +@@ -39,14 +39,6 @@ #define STACK_MAGIC 0xdeadbeef diff --git a/target/linux/generic/backport-6.6/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch b/target/linux/generic/backport-6.6/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch index b9c40e6206..48c58c1ca2 100644 --- a/target/linux/generic/backport-6.6/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch +++ b/target/linux/generic/backport-6.6/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch @@ -23,7 +23,7 @@ Signed-off-by: Kees Cook --- a/include/linux/kernel.h +++ b/include/linux/kernel.h -@@ -32,6 +32,8 @@ +@@ -33,6 +33,8 @@ #include #include #include @@ -32,7 +32,7 @@ Signed-off-by: Kees Cook #include #include -@@ -57,34 +59,6 @@ +@@ -52,34 +54,6 @@ } \ ) diff --git a/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch index a011cf8ffa..73e25f45cd 100644 --- a/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch +++ b/target/linux/generic/hack-6.6/810-bcma-ssb-fallback-sprom.patch @@ -54,7 +54,7 @@ Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SP --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c -@@ -671,6 +671,14 @@ static int __init bcma_modinit(void) +@@ -677,6 +677,14 @@ static int __init bcma_modinit(void) { int err; From 15601a545e1147f25ab53ecb971f4bcb08a4327d Mon Sep 17 00:00:00 2001 From: Mikhail Zhilkin Date: Sat, 22 Nov 2025 19:05:52 +0300 Subject: [PATCH 099/128] kernel: fix QE bit for Fudan Micro FM25S01A SPI-NAND According to datasheet (http://eng.fmsh.com/nvm/FM25S01A_ds_eng.pdf) there is no QE (Quad Enable) bit for FM25S01A flash, so remove it. Signed-off-by: Mikhail Zhilkin Link: https://github.com/openwrt/openwrt/pull/20872 (cherry picked from commit 40fc91be6e9e0aa0038c0624ad39e3e70d264e53) [Update patch path and number] Signed-off-by: Mikhail Zhilkin Link: https://github.com/openwrt/openwrt/pull/20974 Signed-off-by: Hauke Mehrtens --- ...msh-remove-QE-bit-for-FM25S01A-flash.patch | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 target/linux/generic/backport-6.6/420-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch diff --git a/target/linux/generic/backport-6.6/420-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch b/target/linux/generic/backport-6.6/420-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch new file mode 100644 index 0000000000..7f9ec6aca4 --- /dev/null +++ b/target/linux/generic/backport-6.6/420-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch @@ -0,0 +1,28 @@ +From a1d3bc606bf5c3b3ea811cc2019df6285d75b00f Mon Sep 17 00:00:00 2001 +From: Mikhail Kshevetskiy +Date: Mon, 3 Nov 2025 04:01:48 +0300 +Subject: [PATCH] mtd: spinand: fmsh: remove QE bit for FM25S01A flash + +According to datasheet (http://eng.fmsh.com/nvm/FM25S01A_ds_eng.pdf) +there is no QE (Quad Enable) bit for FM25S01A flash, so remove it. + +Fixes: 5f284dc15ca86 ("mtd: spinand: add support for FudanMicro FM25S01A") +Signed-off-by: Mikhail Kshevetskiy +Tested-by: Tianling Shen +Signed-off-by: Miquel Raynal +Link: Link: https://lore.kernel.org/linux-mtd/176216634975.908445.2776312239779833518.b4-ty@bootlin.com +--- + drivers/mtd/nand/spi/fmsh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/nand/spi/fmsh.c ++++ b/drivers/mtd/nand/spi/fmsh.c +@@ -58,7 +58,7 @@ static const struct spinand_info fmsh_sp + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- SPINAND_HAS_QE_BIT, ++ 0, + SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), + }; + From 96a67d2f2eef8d1f0760bf826ab187fb6e75671b Mon Sep 17 00:00:00 2001 From: Mikhail Zhilkin Date: Sat, 22 Nov 2025 19:18:36 +0300 Subject: [PATCH 100/128] kernel: add support for Fudan Micro FM25S01BI3 SPI-NAND Add support for Fudan Micro FM25S01BI3 SPI NAND. Link: https://www.fmsh.com/nvm/FM25S01BI3_ds_eng.pdf Signed-off-by: Mikhail Zhilkin Link: https://github.com/openwrt/openwrt/pull/20872 (cherry picked from commit 05cddcd12a9d401631f59953f78919c7e58d7b98) [Update patch path] Signed-off-by: Mikhail Zhilkin Link: https://github.com/openwrt/openwrt/pull/20974 Signed-off-by: Hauke Mehrtens --- ...dd-support-for-FudanMicro-FM25S01BI3.patch | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 target/linux/generic/pending-6.6/403-mtd-spinand-add-support-for-FudanMicro-FM25S01BI3.patch diff --git a/target/linux/generic/pending-6.6/403-mtd-spinand-add-support-for-FudanMicro-FM25S01BI3.patch b/target/linux/generic/pending-6.6/403-mtd-spinand-add-support-for-FudanMicro-FM25S01BI3.patch new file mode 100644 index 0000000000..f35344233f --- /dev/null +++ b/target/linux/generic/pending-6.6/403-mtd-spinand-add-support-for-FudanMicro-FM25S01BI3.patch @@ -0,0 +1,117 @@ +To: Miquel Raynal , + Richard Weinberger , Vignesh Raghavendra , + Tudor Ambarus , Mark Brown +Cc: linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org +From: Mikhail Zhilkin +Subject: [PATCH] mtd: spinand: add support for FudanMicro FM25S01BI3 + +Add support for FudanMicro FM25S01BI3 SPI NAND. + +Link: https://www.fmsh.com/nvm/FM25S01BI3_ds_eng.pdf + +Signed-off-by: Mikhail Zhilkin +Link: https://lore.kernel.org/linux-mtd/130e0f3f-93e4-47cf-82f0-93ba58a3a670@gmail.com +--- + drivers/mtd/nand/spi/fmsh.c | 72 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +--- a/drivers/mtd/nand/spi/fmsh.c ++++ b/drivers/mtd/nand/spi/fmsh.c +@@ -9,6 +9,13 @@ + #include + #include + ++#define FM25S01BI3_STATUS_ECC_MASK (7 << 4) ++ #define FM25S01BI3_STATUS_ECC_NO_BITFLIPS (0 << 4) ++ #define FM25S01BI3_STATUS_ECC_1_3_BITFLIPS (1 << 4) ++ #define FM25S01BI3_STATUS_ECC_UNCOR_ERROR (2 << 4) ++ #define FM25S01BI3_STATUS_ECC_4_6_BITFLIPS (3 << 4) ++ #define FM25S01BI3_STATUS_ECC_7_8_BITFLIPS (5 << 4) ++ + #define SPINAND_MFR_FMSH 0xA1 + + static SPINAND_OP_VARIANTS(read_cache_variants, +@@ -45,11 +52,66 @@ static int fm25s01a_ooblayout_free(struc + return 0; + } + ++static int fm25s01bi3_ecc_get_status(struct spinand_device *spinand, ++ u8 status) ++{ ++ switch (status & FM25S01BI3_STATUS_ECC_MASK) { ++ case FM25S01BI3_STATUS_ECC_NO_BITFLIPS: ++ return 0; ++ ++ case FM25S01BI3_STATUS_ECC_UNCOR_ERROR: ++ return -EBADMSG; ++ ++ case FM25S01BI3_STATUS_ECC_1_3_BITFLIPS: ++ return 3; ++ ++ case FM25S01BI3_STATUS_ECC_4_6_BITFLIPS: ++ return 6; ++ ++ case FM25S01BI3_STATUS_ECC_7_8_BITFLIPS: ++ return 8; ++ ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ ++static int fm25s01bi3_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ if (section) ++ return -ERANGE; ++ ++ region->offset = 64; ++ region->length = 64; ++ ++ return 0; ++} ++ ++static int fm25s01bi3_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ if (section > 3) ++ return -ERANGE; ++ ++ region->offset = (16 * section) + 4; ++ region->length = 12; ++ ++ return 0; ++} ++ + static const struct mtd_ooblayout_ops fm25s01a_ooblayout = { + .ecc = fm25s01a_ooblayout_ecc, + .free = fm25s01a_ooblayout_free, + }; + ++static const struct mtd_ooblayout_ops fm25s01bi3_ooblayout = { ++ .ecc = fm25s01bi3_ooblayout_ecc, ++ .free = fm25s01bi3_ooblayout_free, ++}; ++ + static const struct spinand_info fmsh_spinand_table[] = { + SPINAND_INFO("FM25S01A", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), +@@ -60,6 +122,16 @@ static const struct spinand_info fmsh_sp + &update_cache_variants), + 0, + SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), ++ SPINAND_INFO("FM25S01BI3", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xd4), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&fm25s01bi3_ooblayout, ++ fm25s01bi3_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { From 9c23ecf31cf5edd413916edb5c133de1e2b6d04b Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 4 Dec 2025 19:08:08 +0100 Subject: [PATCH 101/128] sdk: filter out main on GIT_BRANCH parsing Branch named main was never filter out on parsing the GIT_BRANCH define. Add main to the name of branch that should be filtered. Signed-off-by: Christian Marangi (cherry picked from commit 0338dd44d5755fdd9bd38ce18e823cc024979240) --- target/sdk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/sdk/Makefile b/target/sdk/Makefile index a2eb35c1d4..da1fb949ef 100644 --- a/target/sdk/Makefile +++ b/target/sdk/Makefile @@ -41,7 +41,7 @@ SDK_DIRS = \ GIT_URL:=$(shell git config --get remote.origin.url 2>/dev/null) GIT_URL:=$(if $(CONFIG_BUILDBOT),$(filter git://% http://% https://%,$(GIT_URL)),$(GIT_URL)) GIT_COMMIT:=$(shell git rev-parse HEAD 2>/dev/null) -GIT_BRANCH:=$(filter-out master HEAD,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) +GIT_BRANCH:=$(filter-out master main HEAD,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) GIT_TAGNAME:=$(shell git show-ref --tags --dereference 2>/dev/null | sed -ne '/^$(GIT_COMMIT) / { s|^.*/||; s|\^.*||; p }') BASE_FEED:=$(if $(GIT_URL),src-git-full base $(GIT_URL)$(if $(GIT_BRANCH),;$(GIT_BRANCH),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME)))) From d0c2c30e5072cc917599a2d8b328a5c6560326c7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 4 Dec 2025 19:11:17 +0100 Subject: [PATCH 102/128] sdk: invert logic for GIT_BRANCH and GIT_TAGNAME There is currently a logic error with generating the base feed string. In the scenario where the commit of a Tag match the latest commit of a stable branch, the stable branch have priority over the tag name. This results in generating SDK that actually target the branch instead of the specific tag. To fix this invert the logic and give priority to the tag name. Fixes: #18583 (cherry picked from commit 289172b00e7193df8a2afa1eee54b43148470698) [ fix conflict error ] Signed-off-by: Christian Marangi --- target/sdk/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/sdk/Makefile b/target/sdk/Makefile index da1fb949ef..48b8833ffe 100644 --- a/target/sdk/Makefile +++ b/target/sdk/Makefile @@ -44,10 +44,10 @@ GIT_COMMIT:=$(shell git rev-parse HEAD 2>/dev/null) GIT_BRANCH:=$(filter-out master main HEAD,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) GIT_TAGNAME:=$(shell git show-ref --tags --dereference 2>/dev/null | sed -ne '/^$(GIT_COMMIT) / { s|^.*/||; s|\^.*||; p }') -BASE_FEED:=$(if $(GIT_URL),src-git-full base $(GIT_URL)$(if $(GIT_BRANCH),;$(GIT_BRANCH),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME)))) +BASE_FEED:=$(if $(GIT_URL),src-git-full base $(GIT_URL)$(if $(GIT_TAGNAME),;$(GIT_TAGNAME),$(if $(GIT_BRANCH),;$(GIT_BRANCH)))) BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),$(shell cd $(TOPDIR); LC_ALL=C git svn info 2>/dev/null | sed -ne 's/^URL: /src-gitsvn base /p')) BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),$(shell cd $(TOPDIR); LC_ALL=C svn info 2>/dev/null | sed -ne 's/^URL: /src-svn base /p')) -BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),src-git-full base $(PROJECT_GIT)/openwrt/openwrt.git$(if $(GIT_BRANCH),;$(GIT_BRANCH),$(if $(GIT_TAGNAME),;$(GIT_TAGNAME)))) +BASE_FEED:=$(if $(BASE_FEED),$(BASE_FEED),src-git-full base $(PROJECT_GIT)/openwrt/openwrt.git$(if $(GIT_TAGNAME),;$(GIT_TAGNAME),$(if $(GIT_BRANCH),;$(GIT_BRANCH)))) KDIR_BASE = $(patsubst $(TOPDIR)/%,%,$(LINUX_DIR)) KDIR_ARCHES = $(LINUX_KARCH) From 0ed59099ee105925926df4d811b131b97706d530 Mon Sep 17 00:00:00 2001 From: Shine <4c.fce2@proton.me> Date: Tue, 11 Nov 2025 19:49:16 +0100 Subject: [PATCH 103/128] mpc85xx: p1010: Fix Sophos RED 15w NAND partitions This partially reverts 78d259e7d28d212425164fc64bf0b9d8669d6020. That commit broke mounting the root fs on Sophos RED 15w due to partition size mismatch, and changed the partition sequence, causing the OpenWrt partition numbers to change from mtd3:kernel/mtd4:ubi to mtd4:kernel/mtd5:ubi. Fixes: 78d259e7d28d ("mpc85xx: fix some dtc warnings") (cherry-picked from commit 09e7b24ceb5d9310334c4f88327dc6d58052e7fd) Signed-off-by: Shine <4c.fce2@proton.me> Link: https://github.com/openwrt/openwrt/pull/21062 Signed-off-by: Hauke Mehrtens --- .../arch/powerpc/boot/dts/red-15w-rev1.dts | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/red-15w-rev1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/red-15w-rev1.dts index 19bb8023ed..ac7209bd51 100644 --- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/red-15w-rev1.dts +++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/red-15w-rev1.dts @@ -165,23 +165,19 @@ read-only; }; + partition@300000 { + reg = <0x300000 0x800000>; + label = "kernel"; + }; + + partition@b00000 { + reg = <0xb00000 0x7500000>; + label = "ubi"; + }; + oem-partition@300000 { reg = <0x300000 0x1900000>; label = "sophos-os1"; - - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - reg = <0x0 0x800000>; - label = "kernel"; - }; - - partition@800000 { - reg = <0x800000 0x7500000>; - label = "ubi"; - }; }; oem-partition@1c00000 { From 9fa8e7e9a3a98282fac09880b014e980e476796d Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Thu, 13 Nov 2025 21:41:30 +0800 Subject: [PATCH 104/128] mediatek: fix ubi size for zbtlink zbt z8102ax v2 According to the factory uboot and firmware[1], the ubi size is set to 512 MiB (0x20000000) and it exceeds the size of the flash, after that the uboot and kernel resizes it to 114.5 MiB (0x7280000) instead of 114.125 MiB (0x7220000). The mismatch of the ubi size causes kernel fails to read ubi volumes and throws panic. Trim whitespaces while at it. 1. https://github.com/immortalwrt/immortalwrt/issues/2123#issuecomment-3523744128 Fixes: c908fc7d9591 ("mediatek: add support for Zbtlink ZBT-Z8102AX v2") Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20769 Signed-off-by: Hauke Mehrtens (cherry picked from commit d2fa070f7014e8b1144a23e343b31390e7f565ff) [rebased upon 24.10 branch] Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/21085 Signed-off-by: Robert Marko --- .../mediatek/dts/mt7981b-zbtlink-zbt-z8102ax-v2.dts | 12 ++++++------ .../filogic/base-files/etc/board.d/05_compat-version | 3 ++- target/linux/mediatek/image/filogic.mk | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/target/linux/mediatek/dts/mt7981b-zbtlink-zbt-z8102ax-v2.dts b/target/linux/mediatek/dts/mt7981b-zbtlink-zbt-z8102ax-v2.dts index 08fc4b977a..f96be22355 100644 --- a/target/linux/mediatek/dts/mt7981b-zbtlink-zbt-z8102ax-v2.dts +++ b/target/linux/mediatek/dts/mt7981b-zbtlink-zbt-z8102ax-v2.dts @@ -38,7 +38,7 @@ linux,code = ; gpios = <&pio 0 GPIO_ACTIVE_LOW>; }; - + }; leds { @@ -55,20 +55,20 @@ color = ; function = LED_FUNCTION_STATUS; }; - + led_status_blue: blue { gpios = <&pio 11 GPIO_ACTIVE_LOW>; color = ; function = LED_FUNCTION_STATUS; }; - + led_status_5g1: 5g1 { gpios = <&pio 8 GPIO_ACTIVE_LOW>; color = ; function = LED_FUNCTION_USB; function-enumerator = <0>; }; - + led_status_5g2: 5g2 { gpios = <&pio 13 GPIO_ACTIVE_LOW>; color = ; @@ -135,7 +135,7 @@ pause; }; }; - + gmac1: mac@1 { compatible = "mediatek,eth-mac"; reg = <1>; @@ -207,7 +207,7 @@ nand_rootfs: partition@580000 { label = "ubi"; - reg = <0x0580000 0x7220000>; + reg = <0x0580000 0x7280000>; }; }; }; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/05_compat-version b/target/linux/mediatek/filogic/base-files/etc/board.d/05_compat-version index 9b704b983c..74591b7b0f 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/05_compat-version +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/05_compat-version @@ -8,7 +8,8 @@ case "$(board_name)" in bananapi,bpi-r3) ucidef_set_compat_version "1.2" ;; - routerich,ax3000) + routerich,ax3000|\ + zbtlink,zbt-z8102ax-v2) ucidef_set_compat_version "1.1" ;; esac diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 78e77ea28d..da2a01b51c 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -2096,6 +2096,8 @@ define Device/zbtlink_zbt-z8102ax-v2 IMAGES += factory.bin IMAGE/factory.bin := append-ubi | check-size $$(IMAGE_SIZE) IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata + DEVICE_COMPAT_VERSION := 1.1 + DEVICE_COMPAT_MESSAGE := Partition layout has been changed to fit the bootloader endef TARGET_DEVICES += zbtlink_zbt-z8102ax-v2 From c0b10f74428c92a4505c3390837cde5ef68672bd Mon Sep 17 00:00:00 2001 From: Andreas Gnau Date: Wed, 10 Dec 2025 18:21:45 +0100 Subject: [PATCH 105/128] build: depend on tools/zstd for download Downloading packages from git requires zstd to compress their tarballs. Make sure that zstd from host tools is compiled when running make download. Otherwise, either the download would fail because zstd is not present or a random version from the host would be used leading to hash mismatches. Signed-off-by: Andreas Gnau Link: https://github.com/openwrt/openwrt/pull/21125 Signed-off-by: Christian Marangi (cherry picked from commit f3e4620f592be9413a5c71fbc4b664c50a158faa) --- include/toplevel.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/toplevel.mk b/include/toplevel.mk index 092dff786c..5923d089fc 100644 --- a/include/toplevel.mk +++ b/include/toplevel.mk @@ -201,7 +201,7 @@ else DOWNLOAD_DIRS = package/download endif -download: .config FORCE $(if $(wildcard $(STAGING_DIR_HOST)/bin/flock),,tools/flock/compile) +download: .config FORCE $(if $(wildcard $(STAGING_DIR_HOST)/bin/flock),,tools/flock/compile) $(if $(wildcard $(STAGING_DIR_HOST)/bin/zstd),,tools/zstd/compile) @+$(foreach dir,$(DOWNLOAD_DIRS),$(SUBMAKE) $(dir);) clean dirclean: .config From 581050ce4e1f28a8e371cbd090f48945e02d4448 Mon Sep 17 00:00:00 2001 From: Goetz Goerisch Date: Sun, 7 Dec 2025 08:48:11 +0100 Subject: [PATCH 106/128] kernel: bump 6.6 to 6.6.119 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.119 Removed upstreamed patch: bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch [1] All other patches auto-refreshed. Upstream patch: [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.6.119&id=fd6a1261d05d7f4d6630229e1f280dd7256b9ce8 Signed-off-by: Goetz Goerisch Link: https://github.com/openwrt/openwrt/pull/21076 Signed-off-by: Hauke Mehrtens --- include/kernel-6.6 | 4 +- .../901-snand-mtk-bmt-support.patch | 6 +-- ...all-the-downstream-rpi-sound-card-dr.patch | 2 +- ...-add-FS-LS-bus-instance-parkmode-dis.patch | 4 +- ...-Always-request-for-user-confirmatio.patch | 45 ------------------- ...d-support-for-setting-NAK-enhancemen.patch | 4 +- ...wc3-Set-DMA-and-coherent-masks-early.patch | 16 +++---- ...-nvmem-layouts-add-U-Boot-env-layout.patch | 2 +- ...flip_threshold-to-75-of-ECC-strength.patch | 2 +- ...add-uImage.FIT-subimage-block-driver.patch | 2 +- .../701-staging-add-fsl_ppfe-driver.patch | 4 +- .../330-snand-mtk-bmt-support.patch | 6 +-- ...ers-spi-mem-Add-spi-calibration-hook.patch | 4 +- ...and-Add-calibration-support-for-spin.patch | 2 +- ...960-asus-hack-u-boot-ignore-mtdparts.patch | 4 +- ...or-support-mtd-name-from-device-tree.patch | 4 +- ...c3-add-optional-PHY-interface-clocks.patch | 6 +-- ...NTAINERS-Update-all-StarFive-entries.patch | 8 ++-- ...arfive-Add-JH7100-audio-reset-driver.patch | 2 +- 19 files changed, 41 insertions(+), 86 deletions(-) delete mode 100644 target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch diff --git a/include/kernel-6.6 b/include/kernel-6.6 index e5c3c5c302..7f4bc6fbfa 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .118 -LINUX_KERNEL_HASH-6.6.118 = 4bdddce35474afc8d26f74ebfbcd0e1045ecd15f69e60f53529dba143374b17d +LINUX_VERSION-6.6 = .119 +LINUX_KERNEL_HASH-6.6.119 = 3da09b980bb404cc28793479bb2d6c636522679215ffa65a04c893575253e5e8 diff --git a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch index e62a810a57..ad11affefe 100644 --- a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch +++ b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch @@ -8,7 +8,7 @@ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) { -@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem +@@ -1355,6 +1356,7 @@ static int spinand_probe(struct spi_mem if (ret) return ret; @@ -16,7 +16,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_spinand_cleanup; -@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem +@@ -1362,6 +1364,7 @@ static int spinand_probe(struct spi_mem return 0; err_spinand_cleanup: @@ -24,7 +24,7 @@ spinand_cleanup(spinand); return ret; -@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem +@@ -1380,6 +1383,7 @@ static int spinand_remove(struct spi_mem if (ret) return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch index 09ad4d0ac7..8521837175 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch @@ -17583,7 +17583,7 @@ Signed-off-by: Phil Elwell * For devices with more than one control interface, we assume the --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c -@@ -2278,6 +2278,8 @@ static const struct usb_audio_quirk_flag +@@ -2279,6 +2279,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ QUIRK_FLAG_ALIGN_TRANSFER), diff --git a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch index 77aebef467..fe0a610ab8 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch @@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -1367,6 +1367,9 @@ static int dwc3_core_init(struct dwc3 *d +@@ -1368,6 +1368,9 @@ static int dwc3_core_init(struct dwc3 *d if (dwc->parkmode_disable_hs_quirk) reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS; @@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell if (DWC3_VER_IS_WITHIN(DWC3, 290A, ANY) && (dwc->maximum_speed == USB_SPEED_HIGH || dwc->maximum_speed == USB_SPEED_FULL)) -@@ -1634,6 +1637,8 @@ static void dwc3_get_properties(struct d +@@ -1635,6 +1638,8 @@ static void dwc3_get_properties(struct d "snps,parkmode-disable-ss-quirk"); dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev, "snps,parkmode-disable-hs-quirk"); diff --git a/target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch b/target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch deleted file mode 100644 index e549f27d7b..0000000000 --- a/target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d6a12dd8f4e9362f7dd355969dd046adc44b1f47 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 1 Mar 2021 09:12:44 +0000 -Subject: [PATCH 1255/1350] Revert "Bluetooth: Always request for user - confirmation for Just Works (LE SC)" - -This reverts commit ffee202a78c2980688bc5d2f7d56480e69a5e0c9. - -The commit "Bluetooth: Always request for user confirmation for Just -Works" prevents BLE devices pairing in (at least) the Raspberry Pi OS -GUI. After reverting it, pairing works again. Although this companion -commit ("... (LE SC)") has not been demonstrated to be problematic, -it follows the same logic and therefore could affect some use cases. - -If another solution to the problem is found then this reversion will -be removed. - -See: https://github.com/raspberrypi/linux/issues/4139 - -Signed-off-by: Phil Elwell ---- - net/bluetooth/smp.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- a/net/bluetooth/smp.c -+++ b/net/bluetooth/smp.c -@@ -2208,7 +2208,7 @@ mackey_and_ltk: - if (err) - return SMP_UNSPECIFIED; - -- if (smp->method == REQ_OOB) { -+ if (smp->method == JUST_WORKS || smp->method == REQ_OOB) { - if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { - sc_dhkey_check(smp); - SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); -@@ -2223,9 +2223,6 @@ mackey_and_ltk: - confirm_hint = 0; - - confirm: -- if (smp->method == JUST_WORKS) -- confirm_hint = 1; -- - err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, - hcon->dst_type, passkey, confirm_hint); - if (err) diff --git a/target/linux/bcm27xx/patches-6.6/950-1359-usb-dwc3-core-add-support-for-setting-NAK-enhancemen.patch b/target/linux/bcm27xx/patches-6.6/950-1359-usb-dwc3-core-add-support-for-setting-NAK-enhancemen.patch index db0cce8d59..38ee7d3aef 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1359-usb-dwc3-core-add-support-for-setting-NAK-enhancemen.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1359-usb-dwc3-core-add-support-for-setting-NAK-enhancemen.patch @@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -1361,6 +1361,12 @@ static int dwc3_core_init(struct dwc3 *d +@@ -1362,6 +1362,12 @@ static int dwc3_core_init(struct dwc3 *d if (dwc->dis_tx_ipgap_linecheck_quirk) reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; @@ -35,7 +35,7 @@ Signed-off-by: Jonathan Bell if (dwc->parkmode_disable_ss_quirk) reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS; -@@ -1633,6 +1639,10 @@ static void dwc3_get_properties(struct d +@@ -1634,6 +1640,10 @@ static void dwc3_get_properties(struct d "snps,resume-hs-terminations"); dwc->ulpi_ext_vbus_drv = device_property_read_bool(dev, "snps,ulpi-ext-vbus-drv"); diff --git a/target/linux/bcm27xx/patches-6.6/950-1539-Reapply-usb-dwc3-Set-DMA-and-coherent-masks-early.patch b/target/linux/bcm27xx/patches-6.6/950-1539-Reapply-usb-dwc3-Set-DMA-and-coherent-masks-early.patch index 327819f289..95cbe44e38 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1539-Reapply-usb-dwc3-Set-DMA-and-coherent-masks-early.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1539-Reapply-usb-dwc3-Set-DMA-and-coherent-masks-early.patch @@ -171,7 +171,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. }, --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -1223,6 +1223,24 @@ static void dwc3_config_threshold(struct +@@ -1224,6 +1224,24 @@ static void dwc3_config_threshold(struct } } @@ -196,7 +196,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure -@@ -1288,6 +1306,8 @@ static int dwc3_core_init(struct dwc3 *d +@@ -1289,6 +1307,8 @@ static int dwc3_core_init(struct dwc3 *d dwc3_set_incr_burst_type(dwc); @@ -205,7 +205,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. ret = dwc3_phy_power_on(dwc); if (ret) goto err_exit_phy; -@@ -1386,6 +1406,24 @@ static int dwc3_core_init(struct dwc3 *d +@@ -1387,6 +1407,24 @@ static int dwc3_core_init(struct dwc3 *d dwc3_config_threshold(dwc); @@ -230,7 +230,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. return 0; err_power_off_phy: -@@ -1529,6 +1567,7 @@ static void dwc3_get_properties(struct d +@@ -1530,6 +1568,7 @@ static void dwc3_get_properties(struct d u8 tx_thr_num_pkt_prd = 0; u8 tx_max_burst_prd = 0; u8 tx_fifo_resize_max_num; @@ -238,7 +238,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. /* default to highest possible threshold */ lpm_nyet_threshold = 0xf; -@@ -1549,6 +1588,9 @@ static void dwc3_get_properties(struct d +@@ -1550,6 +1589,9 @@ static void dwc3_get_properties(struct d */ tx_fifo_resize_max_num = 6; @@ -248,7 +248,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); dwc->dr_mode = usb_get_dr_mode(dev); -@@ -1669,6 +1711,9 @@ static void dwc3_get_properties(struct d +@@ -1670,6 +1712,9 @@ static void dwc3_get_properties(struct d dwc->dis_split_quirk = device_property_read_bool(dev, "snps,dis-split-quirk"); @@ -258,7 +258,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; -@@ -1686,6 +1731,8 @@ static void dwc3_get_properties(struct d +@@ -1687,6 +1732,8 @@ static void dwc3_get_properties(struct d dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd; dwc->tx_max_burst_prd = tx_max_burst_prd; @@ -267,7 +267,7 @@ This reverts commit 09dfdf6129532e19b2cfd4992d1d09e7119ccd48. dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; } -@@ -1978,6 +2025,12 @@ static int dwc3_probe(struct platform_de +@@ -1979,6 +2026,12 @@ static int dwc3_probe(struct platform_de if (IS_ERR(dwc->usb_psy)) return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); diff --git a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch index f869fc2037..e087b51c20 100644 --- a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch +++ b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch @@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -21990,6 +21990,7 @@ U-BOOT ENVIRONMENT VARIABLES +@@ -21984,6 +21984,7 @@ U-BOOT ENVIRONMENT VARIABLES M: Rafał Miłecki S: Maintained F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml diff --git a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch index 814b50e19c..6b935eb602 100644 --- a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch +++ b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch @@ -53,7 +53,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -1292,6 +1292,7 @@ static int spinand_init(struct spinand_d +@@ -1294,6 +1294,7 @@ static int spinand_init(struct spinand_d /* Propagate ECC information to mtd_info */ mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength; mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size; diff --git a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch index 1ad2210352..1d91f8372a 100644 --- a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch +++ b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch @@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -22017,6 +22017,12 @@ F: Documentation/filesystems/ubifs-authe +@@ -22011,6 +22011,12 @@ F: Documentation/filesystems/ubifs-authe F: Documentation/filesystems/ubifs.rst F: fs/ubifs/ diff --git a/target/linux/layerscape/patches-6.6/701-staging-add-fsl_ppfe-driver.patch b/target/linux/layerscape/patches-6.6/701-staging-add-fsl_ppfe-driver.patch index 59bbb964c5..f912d4ed3b 100644 --- a/target/linux/layerscape/patches-6.6/701-staging-add-fsl_ppfe-driver.patch +++ b/target/linux/layerscape/patches-6.6/701-staging-add-fsl_ppfe-driver.patch @@ -908,7 +908,7 @@ Signed-off-by: Dong Aisheng L: linux-spi@vger.kernel.org --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig -@@ -78,4 +78,6 @@ source "drivers/staging/qlge/Kconfig" +@@ -76,4 +76,6 @@ source "drivers/staging/qlge/Kconfig" source "drivers/staging/vme_user/Kconfig" @@ -917,7 +917,7 @@ Signed-off-by: Dong Aisheng endif # STAGING --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile -@@ -28,3 +28,4 @@ obj-$(CONFIG_PI433) += pi433/ +@@ -27,3 +27,4 @@ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_QLGE) += qlge/ diff --git a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch index e62a810a57..ad11affefe 100644 --- a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch +++ b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch @@ -8,7 +8,7 @@ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) { -@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem +@@ -1355,6 +1356,7 @@ static int spinand_probe(struct spi_mem if (ret) return ret; @@ -16,7 +16,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_spinand_cleanup; -@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem +@@ -1362,6 +1364,7 @@ static int spinand_probe(struct spi_mem return 0; err_spinand_cleanup: @@ -24,7 +24,7 @@ spinand_cleanup(spinand); return ret; -@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem +@@ -1380,6 +1383,7 @@ static int spinand_remove(struct spi_mem if (ret) return ret; diff --git a/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch b/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch index d9fe480b17..c0b51d84ad 100644 --- a/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch +++ b/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch @@ -11,7 +11,7 @@ Signed-off-by: SkyLake.Huang --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c -@@ -419,6 +419,14 @@ int spi_mem_exec_op(struct spi_mem *mem, +@@ -439,6 +439,14 @@ int spi_mem_exec_op(struct spi_mem *mem, } EXPORT_SYMBOL_GPL(spi_mem_exec_op); @@ -28,7 +28,7 @@ Signed-off-by: SkyLake.Huang * upper layer if necessary --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h -@@ -370,6 +370,10 @@ bool spi_mem_supports_op(struct spi_mem +@@ -388,6 +388,10 @@ bool spi_mem_supports_op(struct spi_mem int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op); diff --git a/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch index 7d54700718..45d1199f8d 100644 --- a/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch +++ b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch @@ -68,7 +68,7 @@ Signed-off-by: SkyLake.Huang static int spinand_id_detect(struct spinand_device *spinand) { u8 *id = spinand->id.data; -@@ -1235,6 +1285,10 @@ static int spinand_init(struct spinand_d +@@ -1237,6 +1287,10 @@ static int spinand_init(struct spinand_d if (!spinand->scratchbuf) return -ENOMEM; diff --git a/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch b/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch index 8337e12887..14d98e9025 100644 --- a/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch +++ b/target/linux/mediatek/patches-6.6/960-asus-hack-u-boot-ignore-mtdparts.patch @@ -29,7 +29,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c -@@ -1447,6 +1447,7 @@ static int spinand_remove(struct spi_mem +@@ -1449,6 +1449,7 @@ static int spinand_remove(struct spi_mem static const struct spi_device_id spinand_ids[] = { { .name = "spi-nand" }, @@ -37,7 +37,7 @@ Signed-off-by: Daniel Golle { /* sentinel */ }, }; MODULE_DEVICE_TABLE(spi, spinand_ids); -@@ -1454,6 +1455,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids); +@@ -1456,6 +1457,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids); #ifdef CONFIG_OF static const struct of_device_id spinand_of_ids[] = { { .compatible = "spi-nand" }, diff --git a/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch b/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch index 0000c22a89..3e2a7abff5 100644 --- a/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch +++ b/target/linux/pistachio/patches-6.6/401-mtd-nor-support-mtd-name-from-device-tree.patch @@ -10,7 +10,7 @@ Signed-off-by: Abhimanyu Vishwakarma --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c -@@ -846,7 +846,9 @@ static int spi_mem_probe(struct spi_devi +@@ -883,7 +883,9 @@ static int spi_mem_probe(struct spi_devi { struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver); struct spi_controller *ctlr = spi->controller; @@ -20,7 +20,7 @@ Signed-off-by: Abhimanyu Vishwakarma mem = devm_kzalloc(&spi->dev, sizeof(*mem), GFP_KERNEL); if (!mem) -@@ -854,10 +856,15 @@ static int spi_mem_probe(struct spi_devi +@@ -891,10 +893,15 @@ static int spi_mem_probe(struct spi_devi mem->spi = spi; diff --git a/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch index 4d358ea219..02c47b4826 100644 --- a/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch +++ b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch @@ -18,7 +18,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -860,8 +860,20 @@ static int dwc3_clk_enable(struct dwc3 * +@@ -861,8 +861,20 @@ static int dwc3_clk_enable(struct dwc3 * if (ret) goto disable_ref_clk; @@ -39,7 +39,7 @@ Signed-off-by: Greg Kroah-Hartman disable_ref_clk: clk_disable_unprepare(dwc->ref_clk); disable_bus_clk: -@@ -871,6 +883,8 @@ disable_bus_clk: +@@ -872,6 +884,8 @@ disable_bus_clk: static void dwc3_clk_disable(struct dwc3 *dwc) { @@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman clk_disable_unprepare(dwc->susp_clk); clk_disable_unprepare(dwc->ref_clk); clk_disable_unprepare(dwc->bus_clk); -@@ -1886,6 +1900,20 @@ static int dwc3_get_clocks(struct dwc3 * +@@ -1887,6 +1901,20 @@ static int dwc3_get_clocks(struct dwc3 * } } diff --git a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch index 5f2c94914f..1f023052fc 100644 --- a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch +++ b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch @@ -88,7 +88,7 @@ Signed-off-by: Hal Feng F: drivers/pwm/pwm-microchip-core.c F: drivers/reset/reset-mpfs.c F: drivers/rtc/rtc-mpfs.c -@@ -20437,6 +20467,15 @@ M: Ion Badulescu +@@ -20431,6 +20461,15 @@ M: Ion Badulescu S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* @@ -104,7 +104,7 @@ Signed-off-by: Hal Feng STARFIVE CRYPTO DRIVER M: Jia Jie Ho M: William Qiu -@@ -20475,6 +20514,13 @@ S: Supported +@@ -20469,6 +20508,13 @@ S: Supported F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml F: drivers/clk/starfive/clk-starfive-jh7110-pll.c @@ -118,7 +118,7 @@ Signed-off-by: Hal Feng STARFIVE JH7110 SYSCON M: William Qiu M: Xingyu Wu -@@ -20522,9 +20568,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c +@@ -20516,9 +20562,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c STARFIVE JH71XX PMU CONTROLLER DRIVER M: Walker Chen @@ -130,7 +130,7 @@ Signed-off-by: Hal Feng F: include/dt-bindings/power/starfive,jh7110-pmu.h STARFIVE SOC DRIVERS -@@ -20532,7 +20579,13 @@ M: Conor Dooley +@@ -20526,7 +20573,13 @@ M: Conor Dooley S: Maintained T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ F: Documentation/devicetree/bindings/soc/starfive/ diff --git a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch index 8b24eb33e5..578b6bf84a 100644 --- a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch +++ b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch @@ -20,7 +20,7 @@ Signed-off-by: Emil Renner Berthing --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20556,7 +20556,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS +@@ -20550,7 +20550,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS M: Emil Renner Berthing M: Hal Feng S: Maintained From 6a92e68c51651da16bc8eb8d7eb5da19f2fe8091 Mon Sep 17 00:00:00 2001 From: Marcin Leksmark Date: Thu, 11 Sep 2025 16:40:20 +0200 Subject: [PATCH 107/128] ramips: add support for D-Link DIR-2660 A2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for D-Link DIR-2660 A2. Based on the commit: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=b5dd746cbb1aaf91f4b68e9f3eda97413550d904, Both devices look identical, except for the A1/A2 designation. You can safely install the A1 firmware for the A2 – I've been testing it for several months as a DUMB AP – without any problems. Specifications: * SoC: MediaTek MT7621AT * RAM: 256 MB (DDR3) * Flash: 128 MB (NAND) * WiFi: MediaTek MT7615N (x2) * Switch: 1 WAN, 4 LAN (Gigabit) * Ports: 1 USB 2.0, 1 USB 3.0 * Buttons: Reset, WPS * LEDs: Power (white/orange), Internet (white/orange), WiFi 2.4G (white), WiFi 5G (white), USB 3.0 (white), USB 2.0 (white) Notes: * WiFi 2.4G and WiFi 5G LEDs are wired directly to the wireless chips Installation: * D-Link Recovery GUI: power down the router, press and hold the reset button, then re-plug it. Keep the reset button pressed until the power LED starts flashing orange, manually assign a static IP address under the 192.168.0.xxx subnet (e.g. 192.168.0.2) and go to http://192.168.0.1 * Some modern browsers may have problems flashing via the Recovery GUI, if that occurs consider uploading the firmware through cURL: curl -v -i -F "firmware=@file.bin" 192.168.0.1 Signed-off-by: Marcin Leksmark Link: https://github.com/openwrt/openwrt/pull/20020 (cherry picked from commit 485f9b0d31fb406f3f4f0f4327cd6320443e550e) Link: https://github.com/openwrt/openwrt/pull/21113 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/image/mt7621.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index fcef42bfb9..28745e9e82 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -960,6 +960,9 @@ define Device/dlink_dir-2660-a1 $(Device/dlink_dir_nand_128m) DEVICE_MODEL := DIR-2660 DEVICE_VARIANT := A1 + DEVICE_ALT0_VENDOR := D-Link + DEVICE_ALT0_MODEL := DIR-2660 + DEVICE_ALT0_VARIANT := A2 endef TARGET_DEVICES += dlink_dir-2660-a1 From 849811889350319f7aade56b083a58fc7b1d1bfc Mon Sep 17 00:00:00 2001 From: Oliver Sedlbauer Date: Mon, 8 Dec 2025 10:29:33 +0100 Subject: [PATCH 108/128] mac80211: ath12k: backport correctly handle mcast packets Backport upstream commit that fixes handling of multicast packets. Without this patch, ARP resolution fails, and connectivity from a station to an AP does not work reliably until traffic is initiated by the AP. Signed-off-by: Oliver Sedlbauer Link: https://github.com/openwrt/openwrt/pull/21088 Signed-off-by: Hauke Mehrtens --- ...ectly-handle-mcast-packets-for-clien.patch | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch diff --git a/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch b/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch new file mode 100644 index 0000000000..2e5e080524 --- /dev/null +++ b/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch @@ -0,0 +1,66 @@ +From a1eb56723b3203d366d2293a368b8bc8ef8894cd Mon Sep 17 00:00:00 2001 +From: Sarika Sharma +Date: Fri, 11 Apr 2025 11:45:23 +0530 +Subject: [PATCH] wifi: ath12k: correctly handle mcast packets for clients + +commit 4541b0c8c3c1b85564971d497224e57cf8076a02 upstream. + +Currently, RX is_mcbc bit is set for packets sent from client as +destination address (DA) is multicast/broadcast address, but packets +are actually unicast as receiver address (RA) is not multicast address. +Hence, packets are not handled properly due to this is_mcbc bit. + +Therefore, reset the is_mcbc bit if interface type is AP. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Sarika Sharma +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250411061523.859387-3-quic_sarishar@quicinc.com +Signed-off-by: Jeff Johnson +[ Adjust context ] +Signed-off-by: Oliver Sedlbauer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath12k/dp_rx.c | 5 +++++ + drivers/net/wireless/ath/ath12k/peer.c | 3 +++ + drivers/net/wireless/ath/ath12k/peer.h | 2 ++ + 3 files changed, 10 insertions(+) + +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -2214,6 +2214,11 @@ static void ath12k_dp_rx_h_mpdu(struct a + spin_lock_bh(&ar->ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu); + if (peer) { ++ /* resetting mcbc bit because mcbc packets are unicast ++ * packets only for AP as STA sends unicast packets. ++ */ ++ rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; ++ + if (rxcb->is_mcbc) + enctype = peer->sec_type_grp; + else +--- a/drivers/net/wireless/ath/ath12k/peer.c ++++ b/drivers/net/wireless/ath/ath12k/peer.c +@@ -331,6 +331,9 @@ int ath12k_peer_create(struct ath12k *ar + arvif->ast_idx = peer->hw_peer_id; + } + ++ if (arvif->vif->type == NL80211_IFTYPE_AP) ++ peer->ucast_ra_only = true; ++ + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + +--- a/drivers/net/wireless/ath/ath12k/peer.h ++++ b/drivers/net/wireless/ath/ath12k/peer.h +@@ -47,6 +47,8 @@ struct ath12k_peer { + + /* protected by ab->data_lock */ + bool dp_setup_done; ++ ++ bool ucast_ra_only; + }; + + void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); From 237b1c29e15206554c27049bbb109311311534a9 Mon Sep 17 00:00:00 2001 From: Brian Lee Date: Thu, 4 Dec 2025 18:09:49 +0900 Subject: [PATCH 109/128] mediatek: filogic: add support for ASUS TUF-AX4200Q MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ASUS TUF-AX4200Q(TUF 小旋风Pro WiFi6 AX4200) is a home router that adds an additional 2.5G Ethernet port to ASUS TUF-AX4200. Hardware - - - - - - - - - SOC : MediaTek MT7986 - RAM : 512MB DDR3 - FLASH : 256MB SPI-NAND (Winbond W25N02KV) - WIFI : Mediatek MT7986 DBDC 802.11ax 2.4/5 GHz - ETH : MediaTek MT7531 Switch MaxLinear GPY211C 2.5 N-Base-T PHY (WAN) MaxLinear GPY211C 2.5 N-Base-T PHY (LAN) - UART : 3V3 115200 8N1 (Pinout silkscreened / Do not ocnnect VCC) Installation - - - - - - - - Vendor-UI Method: 1. Download or make the OpenWrt initramfs.trx image 2. Connect the PC via LAN to one of the yellow router ports and wait until your PC to get a DHCP lease. 3. Browse to http://192.168.50.1/ 4. If your router is brand new, finish the setup process and log into the Web-UI. 5. Navigate to Administration -> Firmware Upgrade and upload the downloaded OpenWrt image. 6. Wait for OpenWrt to boot. Transfer the sysupgrade image to the device using SCP and install using sysupgrade. $ sysupgrade -n TFTP Method: 1. Download the OpenWrt initramfs image. Copy the image to a TFTP server reachable at 192.168.1.70/24. Rename the image to tufax4200q.bin. 2. Connect the PC with TFTP server to the TUF-AX4200Q. Set a static ip on the ethernet interface of your PC. (IP address: 192.168.1.70, subnet mask: 255.255.255.0) Connect to the serial console, interrupt the autoboot process by pressing '4' when prompted. 3. Download & Boot the OpenWrt initramfs image. $ setenv ipaddr 192.168.1.1 $ setenv serverip 192.168.1.70 $ tftpboot 0x46000000 tufax4200q.bin $ bootm 0x46000000 4. Wait for OpenWrt to boot. Transfer the sysupgrade image to the device using SCP and install using sysupgrade. $ sysupgrade -n (based on support for ASUS RT-AX52 by achterin and trx image generation by remittor) Link: https://github.com/openwrt/openwrt/pull/20900 (cherry picked from commit e7086d7a2fc00410df079b4897a47a823a36068d) Signed-off-by: Brian Lee Link: https://github.com/openwrt/openwrt/pull/21036 Signed-off-by: Hauke Mehrtens --- .../mediatek/dts/mt7986a-asus-tuf-ax4200q.dts | 435 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 4 + .../filogic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/ieee80211/11_fix_wifi_mac | 1 + .../base-files/lib/preinit/10_fix_eth_mac.sh | 1 + .../base-files/lib/upgrade/platform.sh | 2 + target/linux/mediatek/image/filogic.mk | 22 + 7 files changed, 466 insertions(+) create mode 100644 target/linux/mediatek/dts/mt7986a-asus-tuf-ax4200q.dts diff --git a/target/linux/mediatek/dts/mt7986a-asus-tuf-ax4200q.dts b/target/linux/mediatek/dts/mt7986a-asus-tuf-ax4200q.dts new file mode 100644 index 0000000000..3161d53076 --- /dev/null +++ b/target/linux/mediatek/dts/mt7986a-asus-tuf-ax4200q.dts @@ -0,0 +1,435 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; +#include +#include +#include +#include + +#include "mt7986a.dtsi" + +/ { + model = "ASUS TUF-AX4200Q"; + compatible = "asus,tuf-ax4200q", "mediatek,mt7986a"; + + aliases { + serial0 = &uart0; + label-mac-device = &gmac0; + led-boot = &led_system; + led-failsafe = &led_system; + led-running = &led_system; + led-upgrade = &led_system; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-override = ""; + }; + + memory@40000000 { + reg = <0 0x40000000 0 0x20000000>; + device_type = "memory"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&pio 9 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + mesh { + label = "wps"; + gpios = <&pio 10 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + wlan { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy1tpt"; + }; + + led_system: system { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&pio 11 GPIO_ACTIVE_HIGH>; + }; + + wan-red { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&pio 12 GPIO_ACTIVE_LOW>; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + /* LAN */ + compatible = "mediatek,eth-mac"; + reg = <0>; + nvmem-cells = <&macaddr_factory_4>; + nvmem-cell-names = "mac-address"; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mac@1 { + /* WAN */ + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "2500base-x"; + phy-handle = <&phy6>; + }; + + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; + reset-delay-us = <50000>; + reset-post-delay-us = <20000>; + + phy5: phy@5 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <5>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + active-high; + color = ; + function = LED_FUNCTION_LAN; + }; + }; + }; + + phy6: phy@6 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <6>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_WAN; + }; + }; + }; + + switch@1f { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + label = "lan1"; + phy-handle = <&swphy1>; + }; + + port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&swphy2>; + }; + + port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&swphy3>; + }; + + port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&swphy4>; + }; + + port@5 { + reg = <5>; + label = "lan5"; + phy-mode = "2500base-x"; + phy-handle = <&phy5>; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + swphy1: phy@1 { + reg = <1>; + + mediatek,led-config = < + 0x21 0x8009 /* BASIC_CTRL */ + 0x22 0x0c00 /* ON_DURATION */ + 0x23 0x1400 /* BLINK_DURATION */ + 0x24 0x8000 /* LED0_ON_CTRL */ + 0x25 0x0000 /* LED0_BLINK_CTRL */ + 0x26 0xc007 /* LED1_ON_CTRL */ + 0x27 0x003f /* LED1_BLINK_CTRL */ + >; + }; + + swphy2: phy@2 { + reg = <2>; + + mediatek,led-config = < + 0x21 0x8009 /* BASIC_CTRL */ + 0x22 0x0c00 /* ON_DURATION */ + 0x23 0x1400 /* BLINK_DURATION */ + 0x24 0x8000 /* LED0_ON_CTRL */ + 0x25 0x0000 /* LED0_BLINK_CTRL */ + 0x26 0xc007 /* LED1_ON_CTRL */ + 0x27 0x003f /* LED1_BLINK_CTRL */ + >; + }; + + swphy3: phy@3 { + reg = <3>; + + mediatek,led-config = < + 0x21 0x8009 /* BASIC_CTRL */ + 0x22 0x0c00 /* ON_DURATION */ + 0x23 0x1400 /* BLINK_DURATION */ + 0x24 0x8000 /* LED0_ON_CTRL */ + 0x25 0x0000 /* LED0_BLINK_CTRL */ + 0x26 0xc007 /* LED1_ON_CTRL */ + 0x27 0x003f /* LED1_BLINK_CTRL */ + >; + }; + + swphy4: phy@4 { + reg = <4>; + + mediatek,led-config = < + 0x21 0x8009 /* BASIC_CTRL */ + 0x22 0x0c00 /* ON_DURATION */ + 0x23 0x1400 /* BLINK_DURATION */ + 0x24 0x8000 /* LED0_ON_CTRL */ + 0x25 0x0000 /* LED0_BLINK_CTRL */ + 0x26 0xc007 /* LED1_ON_CTRL */ + 0x27 0x003f /* LED1_BLINK_CTRL */ + >; + }; + }; + }; + }; +}; + +&pio { + spi_flash_pins: spi-flash-pins-33-to-38 { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-disable; /* bias-disable */ + }; + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-disable; /* bias-disable */ + }; + }; + + wf_2g_5g_pins: wf_2g_5g-pins { + mux { + function = "wifi"; + groups = "wf_2g", "wf_5g"; + }; + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = ; + }; + }; + + wf_dbdc_pins: wf-dbdc-pins { + mux { + function = "wifi"; + groups = "wf_dbdc"; + }; + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = ; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + + spi_nand_flash: flash@0 { + compatible = "u-boot-dont-touch-spi-nand"; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + /* + * ASUS bootloader tries to replace the partitions defined in + * Device Tree and by that also deletes all additional properties + * needed for UBI and NVMEM-on-UBI. + * Prevent this from happening by tricking the loader to delete and + * replace a bait node instead (works with older bootloaders). + */ + partitions: dummy { + compatible = "u-boot-dummy-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x0>; + label = "remove_me"; + }; + }; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x400000>; + label = "bootloader"; + read-only; + }; + + partition@400000 { + compatible = "linux,ubi"; + reg = <0x400000 0xfc00000>; + label = "UBI_DEV"; + + volumes { + ubi-volume-factory { + volname = "Factory"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + macaddr_factory_4: macaddr@4 { + reg = <0x4 0x6>; + }; + }; + }; + }; + }; + }; + }; +}; + +&watchdog { + status = "okay"; +}; + +&wifi { + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + pinctrl-0 = <&wf_2g_5g_pins>; + pinctrl-1 = <&wf_dbdc_pins>; + pinctrl-names = "default", "dbdc"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; + status = "okay"; +}; + +&usb_phy { + status = "okay"; +}; + diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index c8c1aab525..0f5270483d 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -14,6 +14,10 @@ abt,asr3000) asus,rt-ax52) ucidef_set_led_netdev "wan" "wan" "blue:wan" "wan" "link tx rx" ;; +asus,tuf-ax4200q) + ucidef_set_led_netdev "lan5" "LAN5" "mdio-bus:05:white:lan" "lan5" "link tx rx" + ucidef_set_led_netdev "wan" "WAN" "mdio-bus:06:white:wan" "eth1" "link tx rx" + ;; confiabits,mt7981) ucidef_set_led_netdev "lan1" "lan1" "blue:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan2" "lan2" "blue:lan-2" "lan2" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index f9bf2b1faf..f2c38d595a 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -61,6 +61,7 @@ mediatek_setup_interfaces() zyxel,ex5601-t0-ubootmod) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" eth1 ;; + asus,tuf-ax4200q|\ asus,tuf-ax6000|\ glinet,gl-mt6000|\ tplink,tl-xdr4288|\ diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac index b0b301559b..aa70cfc0c3 100644 --- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac +++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac @@ -39,6 +39,7 @@ case "$board" in ;; asus,rt-ax52|\ asus,tuf-ax4200|\ + asus,tuf-ax4200q|\ asus,tuf-ax6000) CI_UBIPART="UBI_DEV" addr=$(mtd_get_mac_binary_ubi "Factory" 0x4) diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh index 936ed44ff9..8a8424e97c 100644 --- a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh +++ b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh @@ -21,6 +21,7 @@ preinit_set_mac_address() { ip link set dev internet address "$wan_mac" ;; asus,tuf-ax4200|\ + asus,tuf-ax4200q|\ asus,tuf-ax6000) CI_UBIPART="UBI_DEV" addr=$(mtd_get_mac_binary_ubi "Factory" 0x4) diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index 3cc8b91b74..8ba706f85b 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -122,6 +122,7 @@ platform_do_upgrade() { asus,rt-ax52|\ asus,rt-ax59u|\ asus,tuf-ax4200|\ + asus,tuf-ax4200q|\ asus,tuf-ax6000) CI_UBIPART="UBI_DEV" CI_KERNPART="linux" @@ -256,6 +257,7 @@ platform_pre_upgrade() { asus,rt-ax52|\ asus,rt-ax59u|\ asus,tuf-ax4200|\ + asus,tuf-ax4200q|\ asus,tuf-ax6000) asus_initial_setup ;; diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index da2a01b51c..8eb0932a98 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -304,6 +304,28 @@ define Device/asus_tuf-ax4200 endef TARGET_DEVICES += asus_tuf-ax4200 +define Device/asus_tuf-ax4200q + DEVICE_VENDOR := ASUS + DEVICE_MODEL := TUF-AX4200Q + DEVICE_DTS := mt7986a-asus-tuf-ax4200q + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-usb3 kmod-mt7915e kmod-mt7986-firmware mt7986-wo-firmware + IMAGES := sysupgrade.bin + KERNEL := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +ifeq ($(IB),) +ifeq ($(CONFIG_TARGET_INITRAMFS_FORCE),y) + ARTIFACTS := initramfs.trx + ARTIFACT/initramfs.trx := append-image-stage initramfs-kernel.bin | \ + uImage none | asus-trx -v 3 -n TUF-AX4200 +endif +endif +endef +TARGET_DEVICES += asus_tuf-ax4200q + define Device/arcadyan_mozart DEVICE_VENDOR := Arcadyan DEVICE_MODEL := Mozart From ce660d934f06044be7cce1bd877cad63e806daa2 Mon Sep 17 00:00:00 2001 From: Mikhail Zadorozhnyi Date: Sat, 11 Oct 2025 12:00:06 +0300 Subject: [PATCH 110/128] mvebu: gl-mv1000: fix sdhci1 controller GL-MV1000 external SD controller was broken by a recent kernel update between OpenWRT releases 24.10.2 and 24.10.3 due to a mistake in Device Tree: "regulator-gpio" was defined without required "gpios" property. Since "no-1-8-v" property is also defined for this controller a switchable vqmmc-supply regulator performs no function - a fixed 3.3V IO voltage will always be used. This regulator definition was probably added by mistake from a Device Tree from another device. Remove incomplete vcc_sd_reg1 regulator definition to fix this issue. Issue discussion for reference: openwrt/openwrt#20309 Upstream commit: 6f2325b23d2cfa28099c26c299ae774625f1872b Signed-off-by: Mikhail Zadorozhnyi Link: https://github.com/openwrt/openwrt/pull/20378 Signed-off-by: Hauke Mehrtens --- .../boot/dts/marvell/armada-3720-gl-mv1000.dts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts index e098ede75f..2ad9660e48 100644 --- a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts +++ b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts @@ -26,19 +26,6 @@ reg = <0x00000000 0x00000000 0x00000000 0x20000000>; }; - vcc_sd_reg1: regulator { - compatible = "regulator-gpio"; - regulator-name = "vcc_sd1"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - - gpios-states = <0>; - states = <1800000 0x1 - 3300000 0x0>; - enable-active-high; - }; - keys { compatible = "gpio-keys"; @@ -149,7 +136,6 @@ cd-gpios = <&gpionb 17 GPIO_ACTIVE_LOW>; marvell,pad-type = "sd"; no-1-8-v; - vqmmc-supply = <&vcc_sd_reg1>; status = "okay"; }; From 61408bb99a1673ae8579a0386be53d79e542fc1b Mon Sep 17 00:00:00 2001 From: Coia Prant Date: Wed, 1 Oct 2025 18:04:26 +0800 Subject: [PATCH 111/128] ramips: add support for Hongdian H8850 v20 This is an industrial 4G router equipped with OpenWrt SNAPSHOT OEM customized version WARNING: The original firmware device tree is modified from evb boards, and the device tree name is evb board. This submitted device tree is a modified version, which deletes the non-this-device parts and adds GPIO watchdog. Specification: - SoC: MediaTek MT7628DAN - Flash: 16 MB - RAM: 64 MB - Power: DC 5V-36V 1.5A - Ethernet: 1x WAN/LAN, 3x LAN (10/100 Mbps) - Wireless radio: 802.11n 2.4g-only - LED: System/Power (PWR): Always Off Modem (NET): GPIO/3 active-low LAN: Always On RF (Modem Signal): GPIO/2 active-low WIFI: GPIO/44 active-low - Button: WPS / RESET: GPIO/11 active-low - UART: 1x UART on PCB - 115200 8N1 - GPIO Watchdog: GPIO/0 mode=toggle timeout=1s - Modem: 1x Built-in modem on board (Power: GPIO/4 active-high) - SIM Slots: 1x SIM Slots Issue: - Factory partition not store mac address on original firmware Flash instruction: Using TTL: 1. Connect the board to the computer via TTL. 2. Enter original firmware failsafe mode. 3. Use wget download firmware to board /tmp 4. Use command "mtd -r write openwrt-ramips-mt76x8-hongdian_h8850-v20-squashfs-sysupgrade.bin firmware" to flash Original Firmware Dump / More details: https://blog.gov.cooking/archives/research-hongdian-h8850-v20-and-flash.html Signed-off-by: Coia Prant Tested-by: Coia Prant Link: https://github.com/openwrt/openwrt/pull/20259 (cherry picked from commit 23a070dfb1fd3ed7659fad4934a6a38d8693326f) Link: https://github.com/openwrt/openwrt/pull/21007 Signed-off-by: Hauke Mehrtens --- .../dts/mt7628an_hongdian_h8850-v20.dts | 157 ++++++++++++++++++ target/linux/ramips/image/mt76x8.mk | 9 + .../mt76x8/base-files/etc/board.d/02_network | 12 +- .../base-files/etc/board.d/03_gpio_switches | 3 + 4 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 target/linux/ramips/dts/mt7628an_hongdian_h8850-v20.dts diff --git a/target/linux/ramips/dts/mt7628an_hongdian_h8850-v20.dts b/target/linux/ramips/dts/mt7628an_hongdian_h8850-v20.dts new file mode 100644 index 0000000000..8983203e2c --- /dev/null +++ b/target/linux/ramips/dts/mt7628an_hongdian_h8850-v20.dts @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7628an.dtsi" + +#include +#include +#include + +/ { + compatible = "hongdian,h8850-v20", "mediatek,mt7628an-soc"; + model = "Hongdian H8850 v20"; + + aliases { + led-boot = &led_net; + led-failsafe = &led_net; + led-running = &led_net; + led-upgrade = &led_net; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + leds { + compatible = "gpio-leds"; + + led-rf { + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + color = ; + function = "rf"; + }; + + led_net: led-net { + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_MOBILE; + }; + + led-wifi { + gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + color = ; + function = LED_FUNCTION_WLAN; + linux,default-trigger = "phy0tpt"; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + + gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; + hw_algo = "toggle"; + hw_margin_ms = <600>; + always-running; + }; + + gpio-export { + compatible = "gpio-export"; + + gpio_modem_power { + gpio-export,name = "modem_power"; + gpio-export,output = <1>; + gpios = <&gpio 4 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&watchdog { + status = "disabled"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x400>; + }; + + macaddr_factory_4: macaddr@4 { + reg = <0x4 0x6>; + }; + }; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "i2s", "i2c", "spi cs1", "gpio", "perst", "refclk", "wdt", "p4led_an", "wled_an"; + function = "gpio"; + }; +}; + +ðernet { + nvmem-cells = <&macaddr_factory_4>; + nvmem-cell-names = "mac-address"; +}; + +&esw { + mediatek,portmap = <0x3e>; + mediatek,portdisable = <0x30>; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; +}; diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk index 94cccab743..f1873a794e 100644 --- a/target/linux/ramips/image/mt76x8.mk +++ b/target/linux/ramips/image/mt76x8.mk @@ -347,6 +347,15 @@ define Device/hongdian_h7920-v40 endef TARGET_DEVICES += hongdian_h7920-v40 +define Device/hongdian_h8850-v20 + IMAGE_SIZE := 16064k + DEVICE_VENDOR := Hongdian + DEVICE_MODEL := H8850 + DEVICE_VARIANT := v20 + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi +endef +TARGET_DEVICES += hongdian_h8850-v20 + define Device/iptime_a3 IMAGE_SIZE := 7936k UIMAGE_NAME := a3 diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network index 92168d1fcf..b47c499e95 100644 --- a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network @@ -117,6 +117,12 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "0:lan" "1:lan" "4:wan" "6@eth0" ;; + hongdian,h8850-v20|\ + keenetic,kn-1613|\ + motorola,mwr03) + ucidef_add_switch "switch0" \ + "1:lan" "2:lan" "3:lan" "0:wan" "6@eth0" + ;; iptime,a3|\ totolink,a3) ucidef_add_switch "switch0" \ @@ -132,11 +138,6 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "0:lan" "1:lan" "2:lan" "6@eth0" ;; - keenetic,kn-1613|\ - motorola,mwr03) - ucidef_add_switch "switch0" \ - "1:lan" "2:lan" "3:lan" "0:wan" "6@eth0" - ;; kroks,kndrt31r19) ucidef_add_switch "switch0" \ "0:lan" "6@eth0" @@ -260,6 +261,7 @@ ramips_setup_macs() ;; duzun,dm06|\ hongdian,h7920-v40|\ + hongdian,h8850-v20|\ netgear,r6020|\ netgear,r6080|\ netgear,r6120|\ diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt76x8/base-files/etc/board.d/03_gpio_switches index c70e59c480..199a8466a0 100644 --- a/target/linux/ramips/mt76x8/base-files/etc/board.d/03_gpio_switches +++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/03_gpio_switches @@ -13,6 +13,9 @@ hongdian,h7920-v40) ucidef_add_gpio_switch "modem_enable" "Modem power" "modem_power" "1" ucidef_add_gpio_switch "switch_serial_mode" "Switch RS232 to RS485" "serial_rs485_mode" "0" ;; +hongdian,h8850-v20) + ucidef_add_gpio_switch "modem_enable" "Modem power" "modem_power" "1" + ;; esac board_config_flush From a9858a9632b06bc0a998e55c8338af56fa797d42 Mon Sep 17 00:00:00 2001 From: Marcin Leksmark Date: Sat, 6 Dec 2025 14:43:22 +0100 Subject: [PATCH 112/128] ramips: add support for Cudy C200P MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for Cudy C200P. Because v24.10 stable has no regulator definition, so we cannot make simple cherry-pick. We need another DTS file. Specifications: SoC: MediaTek MT7621AT RAM: 256 MB (DDR3) Flash: 16 MB (NOR) POE Chip: IP804AR Interfaces: Switch: 1 WAN, 4 LAN (Gigabit) Gigabit RJ45 PoE Ports on 2~5 Max Power on a Single PoE Ports 30W PoE Ports : The PoE ports comply with IEEE 802.3at/af standards. Ports: 1 USB-A 3.0 Ports LED: System PoE Max Status Link/ACT/PoE Status of Each PoE Port Physical Buttons: Reset Button Power Input: DC Jack Power Methods: DC: 54V 1.11A 802.3at/af PoE Passive PoE: 24/48V Max Power Consumption (W): Total: 60W PoE: 55W PoE (when USB Device is plugged in): 50W No PoE: 5W Installation: To install OpenWRT, you need the intermediate firmware from Cudy. (U-boot is locked). After installing the intermediate firmware, you can install OpenWRT via sysupgrade. Recovery: TFTP available. 1. Place the recovery.bin in the serving directory of your TFTP server. 2. Set your IP to 192.168.1.88/24. 3. Press the “Reset” button of Cudy router and hold it. Before the Cudy router is powered on and before TFTP start to download the firmware, don't release the “Reset” button. 4. Power on the Cudy router. 5. You can release the reset button only when TFTP starts downloading firmware. 6. When the SYSTEM LED turns solid green, the upgrade is complete. Serial: 1. Serial connection parameters: 115200 / 8N1 2. Serial connection voltage: 3.3V PoE is not supported at the time of PR. The IP804R chip is not yet supported by OpenWRT. Signed-off-by: Marcin Leksmark Link: https://github.com/openwrt/openwrt/pull/21064 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/dts/mt7621_cudy_c200p.dts | 199 ++++++++++++++++++ target/linux/ramips/image/mt7621.mk | 10 + .../mt7621/base-files/etc/board.d/02_network | 7 +- 3 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 target/linux/ramips/dts/mt7621_cudy_c200p.dts diff --git a/target/linux/ramips/dts/mt7621_cudy_c200p.dts b/target/linux/ramips/dts/mt7621_cudy_c200p.dts new file mode 100644 index 0000000000..df1b923f93 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_cudy_c200p.dts @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + compatible = "cudy,c200p", "mediatek,mt7621-soc"; + model = "Cudy C200P"; + + aliases { + led-boot = &led_sys; + led-failsafe = &led_sys; + led-running = &led_sys; + led-upgrade = &led_sys; + label-mac-device = &gmac0; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&gpio 10 GPIO_ACTIVE_HIGH>; + hw_algo = "toggle"; + hw_margin_ms = <1000>; + always-running; + }; + + reg_vbus: regulator { + compatible = "regulator-fixed"; + regulator-name = "power_usb"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpios = <&gpio 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + output-reg-vbus { + compatible = "regulator-output"; + vout-supply = <®_vbus>; + }; + + gpio-export { + compatible = "gpio-export"; + #size-cells = <0>; + + pse { + gpio-export,name = "pse"; + gpio-export,output = <1>; + gpios = <&gpio 14 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_sys: status { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led_poe { + color = ; + function = LED_FUNCTION_INDICATOR; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&xhci { + vbus-supply = <®_vbus>; +}; + +&i2c { + status = "okay"; +}; + +&gmac0 { + nvmem-cells = <&macaddr_bdinfo_de00 0>; + nvmem-cell-names = "mac-address"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0xfa0000>; + }; + + partition@ff0000 { + label = "bdinfo"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_bdinfo_de00: macaddr@de00 { + compatible = "mac-base"; + reg = <0xde00 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "jtag", "uart2", "uart3", "wdt"; + function = "gpio"; + }; +}; + +&gmac1 { + status = "okay"; + label = "wan"; + phy-handle = <ðphy4>; + + nvmem-cells = <&macaddr_bdinfo_de00 1>; + nvmem-cell-names = "mac-address"; +}; + +ðphy4 { + /delete-property/ interrupts; +}; + +&switch0 { + ports { + port@0 { + status = "okay"; + label = "lan5"; + }; + + port@1 { + status = "okay"; + label = "lan4"; + }; + + port@2 { + status = "okay"; + label = "lan3"; + }; + + port@3 { + status = "okay"; + label = "lan2"; + }; + + }; +}; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 28745e9e82..83b8767622 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -716,6 +716,16 @@ define Device/cudy_ap1300-outdoor-v1 endef TARGET_DEVICES += cudy_ap1300-outdoor-v1 +define Device/cudy_c200p + $(Device/dsa-migration) + DEVICE_VENDOR := Cudy + DEVICE_MODEL := C200P + IMAGE_SIZE := 15872k + UIMAGE_NAME := R74 + DEVICE_PACKAGES := -uboot-envtools -wpad-basic-mbedtls kmod-usb3 +endef +TARGET_DEVICES += cudy_c200p + define Device/cudy_m1300-v2 $(Device/dsa-migration) IMAGE_SIZE := 15872k diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network index 9d2f119c7e..15c98242ad 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network @@ -115,6 +115,10 @@ ramips_setup_interfaces() uci add_list firewall.@zone[1].network='eth_data' uci add_list firewall.@zone[1].network='eth_om' ;; + cudy,c200p|\ + mikrotik,routerboard-750gr3) + ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan" + ;; dlink,covr-x1860-a1) ucidef_set_interfaces_lan_wan "ethernet" "internet" ;; @@ -133,9 +137,6 @@ ramips_setup_interfaces() gnubee,gb-pc2) ucidef_set_interface_lan "ethblack ethblue ethyellow" ;; - mikrotik,routerboard-750gr3) - ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan" - ;; mikrotik,routerboard-760igs) ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan sfp" ;; From 4a3409f628e2aebabac02c81750b25373c22d992 Mon Sep 17 00:00:00 2001 From: David DeGraw Date: Fri, 18 Apr 2025 11:55:34 -0600 Subject: [PATCH 113/128] ramips: add support for Cudy R700 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the same hardware as the Cudy WR2100 that's had support for some time now, just without the WLAN hardware. This PR is mostly copied from the commit that added support for the WR2100, here: 3501db9 Specifications: SoC: MT7621 CPU: 880 MHz Flash: 16 MiB RAM: 128 MiB Ethernet: 5x Gbit ports Installation: There are two known options: The Luci-based UI. Press and hold the reset button during power up. The router will request 'recovery.bin' from a TFTP server at 192.168.1.88. Both options require a signed firmware binary. A signed firmware can be found in GitHub PR #18532. R4 & R5 need to be shorted (0-100Ω) for the UART to work. Link: https://github.com/openwrt/openwrt/pull/18532 Signed-off-by: David DeGraw (cherry picked from commit 75403dd1d05bea1b65349ebb9f8b7deb40b9c802) Link: https://github.com/openwrt/openwrt/pull/21068 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/dts/mt7621_cudy_r700.dts | 203 ++++++++++++++++++ target/linux/ramips/image/mt7621.mk | 10 + .../mt7621/base-files/etc/board.d/01_leds | 1 + 3 files changed, 214 insertions(+) create mode 100644 target/linux/ramips/dts/mt7621_cudy_r700.dts diff --git a/target/linux/ramips/dts/mt7621_cudy_r700.dts b/target/linux/ramips/dts/mt7621_cudy_r700.dts new file mode 100644 index 0000000000..6d1c1ec004 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_cudy_r700.dts @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + compatible = "cudy,r700", "mediatek,mt7621-soc"; + model = "Cudy R700"; + + aliases { + led-boot = &led_internet_blue; + led-failsafe = &led_internet_blue; + led-running = &led_internet_blue; + led-upgrade = &led_internet_blue; + label-mac-device = &gmac0; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_internet_blue: internet_blue { + label = "blue:internet"; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + }; + + internet_red { + label = "red:internet"; + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + }; + + wan { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "green:lan1"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "green:lan2"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + }; + + lan3 { + label = "green:lan3"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + + lan4 { + label = "green:lan4"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_bdinfo_de00 0>; + nvmem-cell-names = "mac-address"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x400>; + }; + + eeprom_factory_8000: eeprom@8000 { + reg = <0x8000 0x4da8>; + }; + }; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0xf80000>; + }; + + partition@fd0000 { + label = "debug"; + reg = <0xfd0000 0x10000>; + read-only; + }; + + partition@fe0000 { + label = "backup"; + reg = <0xfe0000 0x10000>; + read-only; + }; + + partition@ff0000 { + label = "bdinfo"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_bdinfo_de00: macaddr@de00 { + compatible = "mac-base"; + reg = <0xde00 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "i2c", "jtag", "uart3", "wdt"; + function = "gpio"; + }; +}; + +&gmac1 { + status = "okay"; + label = "wan"; + phy-handle = <ðphy4>; + + nvmem-cells = <&macaddr_bdinfo_de00 1>; + nvmem-cell-names = "mac-address"; +}; + +&switch0 { + ports { + port@0 { + status = "okay"; + label = "lan1"; + }; + + port@1 { + status = "okay"; + label = "lan2"; + }; + + port@2 { + status = "okay"; + label = "lan3"; + }; + + port@3 { + status = "okay"; + label = "lan4"; + }; + }; +}; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 83b8767622..31bdb40b26 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -795,6 +795,16 @@ define Device/cudy_wr2100 endef TARGET_DEVICES += cudy_wr2100 +define Device/cudy_r700 + $(Device/dsa-migration) + DEVICE_VENDOR := Cudy + DEVICE_MODEL := R700 + IMAGE_SIZE := 15872k + UIMAGE_NAME := R29 + DEVICE_PACKAGES := -uboot-envtools +endef +TARGET_DEVICES += cudy_r700 + define Device/cudy_x6-v1 $(Device/dsa-migration) IMAGE_SIZE := 32256k diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds index 94f36c1f6e..4c4e7a2f42 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds @@ -66,6 +66,7 @@ genexis,pulse-ex400|\ netis,n6) ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" "link tx rx" ;; +cudy,r700|\ cudy,wr2100) ucidef_set_led_netdev "lan1" "lan1" "green:lan1" "lan1" ucidef_set_led_netdev "lan2" "lan2" "green:lan2" "lan2" From 22391baf99634fc9f24d47a5ca475a654f444cd3 Mon Sep 17 00:00:00 2001 From: Marcin Leksmark Date: Wed, 12 Nov 2025 21:39:56 +0100 Subject: [PATCH 114/128] ramips: fix support for Cudy r700 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes support for Cudy r700. Original PR: https://github.com/openwrt/openwrt/pull/18532 Fixed: - WAN port functionality; - RESET button; - Status LED; - LAN port names consistent with the chassis; - Merged partitions "debug", "backup" & "firmware" to one partition "firmware" ("debug" & "backup" contained unimportant data); - Removed redundant DTS elements. Installation: To install OpenWRT, you need the intermediate firmware from Cudy. (U-boot is locked). After installing the intermediate firmware, you can install OpenWRT via sysupgrade. Recovery: TFTP available. 1. Place the recovery.bin in the serving directory of your TFTP server. 2. Set your IP to 192.168.1.88/24. 3. Press the “Reset” button of Cudy router and hold it. Before the Cudy router is powered on and before TFTP start to download the firmware, don't release the “Reset” button. 4. Power on the Cudy router. 5. You can release the reset button only when TFTP starts downloading firmware. 6. When the SYSTEM LED turns solid green, the upgrade is complete. Fixes: 75403dd1d05b ("ramips: add support for Cudy R700") Link: https://github.com/openwrt/openwrt/pull/20756 (cherry picked from commit 35a86267e90312f24fd11553cd5a5db0736b79ca) Signed-off-by: Marcin Leksmark Link: https://github.com/openwrt/openwrt/pull/21068 Signed-off-by: Hauke Mehrtens --- target/linux/ramips/dts/mt7621_cudy_r700.dts | 81 ++++--------------- target/linux/ramips/image/mt7621.mk | 2 +- .../mt7621/base-files/etc/board.d/01_leds | 1 - .../mt7621/base-files/etc/board.d/02_network | 1 + 4 files changed, 16 insertions(+), 69 deletions(-) diff --git a/target/linux/ramips/dts/mt7621_cudy_r700.dts b/target/linux/ramips/dts/mt7621_cudy_r700.dts index 6d1c1ec004..ce23e1a701 100644 --- a/target/linux/ramips/dts/mt7621_cudy_r700.dts +++ b/target/linux/ramips/dts/mt7621_cudy_r700.dts @@ -11,10 +11,9 @@ model = "Cudy R700"; aliases { - led-boot = &led_internet_blue; - led-failsafe = &led_internet_blue; - led-running = &led_internet_blue; - led-upgrade = &led_internet_blue; + led-boot = &led_status_green; + led-failsafe = &led_status_green; + led-running = &led_status_green; label-mac-device = &gmac0; }; @@ -27,7 +26,7 @@ reset { label = "reset"; - gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; linux,code = ; }; }; @@ -35,41 +34,11 @@ leds { compatible = "gpio-leds"; - led_internet_blue: internet_blue { - label = "blue:internet"; - gpios = <&gpio 4 GPIO_ACTIVE_LOW>; - }; - - internet_red { - label = "red:internet"; - gpios = <&gpio 3 GPIO_ACTIVE_LOW>; - }; - - wan { - function = LED_FUNCTION_WAN; + led_status_green: led-status-green { color = ; + function = LED_FUNCTION_STATUS; gpios = <&gpio 13 GPIO_ACTIVE_LOW>; }; - - lan1 { - label = "green:lan1"; - gpios = <&gpio 14 GPIO_ACTIVE_LOW>; - }; - - lan2 { - label = "green:lan2"; - gpios = <&gpio 18 GPIO_ACTIVE_LOW>; - }; - - lan3 { - label = "green:lan3"; - gpios = <&gpio 16 GPIO_ACTIVE_LOW>; - }; - - lan4 { - label = "green:lan4"; - gpios = <&gpio 15 GPIO_ACTIVE_LOW>; - }; }; }; @@ -107,38 +76,12 @@ label = "factory"; reg = <0x40000 0x10000>; read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - eeprom_factory_0: eeprom@0 { - reg = <0x0 0x400>; - }; - - eeprom_factory_8000: eeprom@8000 { - reg = <0x8000 0x4da8>; - }; - }; }; partition@50000 { compatible = "denx,uimage"; label = "firmware"; - reg = <0x50000 0xf80000>; - }; - - partition@fd0000 { - label = "debug"; - reg = <0xfd0000 0x10000>; - read-only; - }; - - partition@fe0000 { - label = "backup"; - reg = <0xfe0000 0x10000>; - read-only; + reg = <0x50000 0xfa0000>; }; partition@ff0000 { @@ -178,16 +121,20 @@ nvmem-cell-names = "mac-address"; }; +ðphy4 { + /delete-property/ interrupts; +}; + &switch0 { ports { port@0 { status = "okay"; - label = "lan1"; + label = "lan5"; }; port@1 { status = "okay"; - label = "lan2"; + label = "lan4"; }; port@2 { @@ -197,7 +144,7 @@ port@3 { status = "okay"; - label = "lan4"; + label = "lan2"; }; }; }; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 31bdb40b26..4184977b27 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -801,7 +801,7 @@ define Device/cudy_r700 DEVICE_MODEL := R700 IMAGE_SIZE := 15872k UIMAGE_NAME := R29 - DEVICE_PACKAGES := -uboot-envtools + DEVICE_PACKAGES := -uboot-envtools -wpad-basic-mbedtls endef TARGET_DEVICES += cudy_r700 diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds index 4c4e7a2f42..94f36c1f6e 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds @@ -66,7 +66,6 @@ genexis,pulse-ex400|\ netis,n6) ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" "link tx rx" ;; -cudy,r700|\ cudy,wr2100) ucidef_set_led_netdev "lan1" "lan1" "green:lan1" "lan1" ucidef_set_led_netdev "lan2" "lan2" "green:lan2" "lan2" diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network index 15c98242ad..557755064a 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network @@ -116,6 +116,7 @@ ramips_setup_interfaces() uci add_list firewall.@zone[1].network='eth_om' ;; cudy,c200p|\ + cudy,r700|\ mikrotik,routerboard-750gr3) ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan" ;; From 9123a0c358d0b5275fcd99c3001f47020d27425b Mon Sep 17 00:00:00 2001 From: Shine <4c.fce2@proton.me> Date: Thu, 11 Dec 2025 00:21:48 +0100 Subject: [PATCH 115/128] mpc85xx: p1010: Use zImage loader for Watchguard Firebox T10 Since kernel 6.1, the Watchguard Firebox T10 can't boot anymore due to increased kernel size. This commit introduces the zImage loader from 7d768a9 to boot the kernel. This is required, since the U-Boot version used in this device appears to have a hard limit of 16MB for the kernel size it can handle. The current kernel size is around 17MB, though, due to kernel page alignment required for memory protection. (cherry-picked from commit be7aa5bda40ee05b1dd0b4f4a1bf88e653ef875a) Signed-off-by: Shine <4c.fce2@proton.me> Link: https://github.com/openwrt/openwrt/pull/21130 Signed-off-by: Hauke Mehrtens --- target/linux/mpc85xx/image/p1010.mk | 5 +++++ target/linux/mpc85xx/p1010/target.mk | 2 +- ...atch.patch => 108-powerpc-85xx-firebox-t10-support.patch} | 3 ++- .../patches-6.6/111-powerpc-85xx-hpe-msm-support.patch | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) rename target/linux/mpc85xx/patches-6.6/{108-powerpc-85xx-firebox-t10-support.patch.patch => 108-powerpc-85xx-firebox-t10-support.patch} (93%) diff --git a/target/linux/mpc85xx/image/p1010.mk b/target/linux/mpc85xx/image/p1010.mk index 1f898c483f..c873c29f9d 100644 --- a/target/linux/mpc85xx/image/p1010.mk +++ b/target/linux/mpc85xx/image/p1010.mk @@ -78,7 +78,12 @@ define Device/watchguard_firebox-t10 DEVICE_VENDOR := Watchguard DEVICE_MODEL := Firebox T10 DEVICE_PACKAGES := kmod-rtc-s35390a kmod-eeprom-at24 + # This boot loader doesn't reliably boot an uncompressed image, + # therefore resort to gzipping the already compressed zImage KERNEL = kernel-bin | gzip | fit gzip $(KDIR)/image-$$(DEVICE_DTS).dtb + KERNEL_NAME := zImage.la3000000 + KERNEL_ENTRY := 0x3000000 + KERNEL_LOADADDR := 0x3000000 IMAGES := sysupgrade.bin IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata endef diff --git a/target/linux/mpc85xx/p1010/target.mk b/target/linux/mpc85xx/p1010/target.mk index 6b54390863..b6236196f3 100644 --- a/target/linux/mpc85xx/p1010/target.mk +++ b/target/linux/mpc85xx/p1010/target.mk @@ -1,5 +1,5 @@ BOARDNAME:=P1010 -KERNEL_IMAGES:=simpleImage.br200-wp simpleImage.tl-wdr4900-v1 simpleImage.ws-ap3715i +KERNEL_IMAGES:=simpleImage.br200-wp simpleImage.tl-wdr4900-v1 simpleImage.ws-ap3715i zImage.la3000000 define Target/Description Build firmware images for P1010 based boards. diff --git a/target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch.patch b/target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch similarity index 93% rename from target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch.patch rename to target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch index 2c722e4d9b..910154bf0d 100644 --- a/target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch.patch +++ b/target/linux/mpc85xx/patches-6.6/108-powerpc-85xx-firebox-t10-support.patch @@ -1,6 +1,6 @@ --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig -@@ -83,6 +83,16 @@ config WS_AP3825I +@@ -83,6 +83,17 @@ config WS_AP3825I This board is a Concurrent Dual-Band wireless access point with a Freescale P1020 SoC. @@ -9,6 +9,7 @@ + select DEFAULT_UIMAGE + select ARCH_REQUIRE_GPIOLIB + select GPIO_MPC8XXX ++ select PPC_ZIMAGE_LA3000000 + help + This option enables support for the Watchguard Firebox T10 board. + This board is a VPN Gateway-Router with a diff --git a/target/linux/mpc85xx/patches-6.6/111-powerpc-85xx-hpe-msm-support.patch b/target/linux/mpc85xx/patches-6.6/111-powerpc-85xx-hpe-msm-support.patch index 1d1fb4f54f..f87b2af1d2 100644 --- a/target/linux/mpc85xx/patches-6.6/111-powerpc-85xx-hpe-msm-support.patch +++ b/target/linux/mpc85xx/patches-6.6/111-powerpc-85xx-hpe-msm-support.patch @@ -1,6 +1,6 @@ --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig -@@ -114,6 +114,18 @@ config FIREBOX_T10 +@@ -115,6 +115,18 @@ config FIREBOX_T10 This board is a VPN Gateway-Router with a Freescale P1010 SoC. From f415748ba8e979757595d8619feddc3ec8aca788 Mon Sep 17 00:00:00 2001 From: Florian Maurer Date: Fri, 3 Oct 2025 09:30:59 +0200 Subject: [PATCH 116/128] ath11k: fix transmit queue flushing through flush_sta implementation warning print "ath11k c000000.wifi: failed to flush transmit queue 0" is observed during busy times. The mac80211 fallback implementation of `flush_sta` does not handle the per STA queues well. This is fixed by providing a ath11k specific implementation of flush_sta telling the firmware to flush a given station. The draining of the transmit queues should therefore stop correctly, even if new packets arrive in the mean time. An upstream ath11k RFC is available at: https://patchwork.kernel.org/project/linux-wireless/patch/GV1P250MB14333A5BF24623C4753A10E1E8E0A@GV1P250MB1433.EURP250.PROD.OUTLOOK.COM/ The patch was tested on a Xiaomi AX3600. Signed-off-by: Florian Maurer Tested-by: Florian Maurer Co-authored-by: Benjamin Berg Tested-by: Flole Link: https://github.com/openwrt/openwrt/pull/20293 Signed-off-by: Christian Marangi (cherry picked from commit 8faa9dedb40dd0d7f7ebe59fddb2d33ed7a75190) Signed-off-by: Felix Baumann Link: https://github.com/openwrt/openwrt/pull/20667 Signed-off-by: Hauke Mehrtens --- ...k_mac_op_flush_sta-to-properly-flush.patch | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch diff --git a/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch b/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch new file mode 100644 index 0000000000..0612150f3c --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch @@ -0,0 +1,65 @@ +From b5ade0e0e1c1622a85fbfd2c93b41caff479f305 Mon Sep 17 00:00:00 2001 +From: Florian Maurer +Date: Fri, 3 Oct 2025 12:56:13 +0200 +Subject: [PATCH] ath11k: add ath11k_mac_op_flush_sta to properly flush pending + packets + +When a STA is marked as no longer authorized, if the driver doesn't +implement flush_sta(), mac80211 calls ieee80211_flush_queues() to +flush hardware queues to avoid sending unencrypted frames. + +This has became a problem for ath11k because ieee80211_flush_queues() +will stop all traffic and call ath11k_flush, which waits until the +whole HW queue is empty. In a busy environment this will trigger a +timeout warning and stalls other STAs. + +Fix this by implementing flush_sta method using WMI command to flush +frames of a specific STA. +Flushed frames will be marked as discard in tx complete indication. + +warning print "ath11k c000000.wifi: failed to flush transmit queue 0" +was observed on various openwrt devices, and is fixed through this patch. + +Tested-by: Florian Maurer +Tested-by: Flole +Co-developed-by: Benjamin Berg +Signed-off-by: Benjamin Berg +Signed-off-by: Florian Maurer +--- + drivers/net/wireless/ath/ath11k/mac.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -8278,6 +8278,23 @@ static void ath11k_mac_op_flush(struct i + ath11k_mac_flush_tx_complete(ar); + } + ++static void ath11k_mac_op_flush_sta(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct ath11k_vif *arvif = (void *)vif->drv_priv; ++ struct ath11k *ar = hw->priv; ++ struct peer_flush_params params = { ++ .peer_tid_bitmap = 0xFF, ++ .vdev_id = arvif->vdev_id, ++ }; ++ int ret; ++ ++ ret = ath11k_wmi_send_peer_flush_tids_cmd(ar, sta->addr, ¶ms); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to flush sta %pM: %d\n", sta->addr, ret); ++} ++ + static bool + ath11k_mac_has_single_legacy_rate(struct ath11k *ar, + enum nl80211_band band, +@@ -9910,6 +9927,7 @@ static const struct ieee80211_ops ath11k + .set_bitrate_mask = ath11k_mac_op_set_bitrate_mask, + .get_survey = ath11k_mac_op_get_survey, + .flush = ath11k_mac_op_flush, ++ .flush_sta = ath11k_mac_op_flush_sta, + .sta_statistics = ath11k_mac_op_sta_statistics, + CFG80211_TESTMODE_CMD(ath11k_tm_cmd) + From 454fd695894fba1fb81d5b6fa92feab8707d7419 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 11 Dec 2025 23:25:19 +0100 Subject: [PATCH 117/128] mac80211: update to version 6.12.61 This contains the following commits: ``` git log --oneline v6.12.52...v6.12.61 -- drivers/net/wireless/ net/mac80211/ net/wireless/ a1eb56723b32 wifi: ath12k: correctly handle mcast packets for clients c0a9c2c1b7b9 wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work d4caee32a9f8 wifi: cfg80211: add an hrtimer based delayed work item 6455948c8aab wifi: mac80211: reject address change while connecting 80dc5a2ce5b7 wifi: ath11k: Clear affinity hint before calling ath11k_pcic_free_irq() in error path acd24d509227 wifi: mac80211: skip rate verification for not captured PSDUs 53cf801b8555 wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp() e8fa86b0bd96 wifi: mac80211_hwsim: Limit destroy_on_close radio removal to netgroup 77d4afd6c78b Revert "wifi: ath10k: avoid unnecessary wait for service ready message" 07d862c7de3d wifi: ath12k: Increase DP_REO_CMD_RING_SIZE to 256 522734fc807c wifi: mac80211: Track NAN interface start/stop 8db790c2491e wifi: ath10k: Fix connection after GTK rekeying 72f1984246e6 wifi: rtw89: renew a completion for each H2C command waiting C2H event 336da4414300 wifi: rtw89: obtain RX path from ppdu status IE00 da91687f01f4 wifi: mt76: mt7996: fix memory leak on mt7996_mcu_sta_key_tlv error a534dd44b70e wifi: mt76: mt76_eeprom_override to int aa5ed215cfe8 wifi: mt76: mt7996: Temporarily disable EPCS efe2ef24feab wifi: mt76: mt7921: Add 160MHz beamformee capability for mt7922 device 5de410dfb4d9 wifi: mac80211: Fix HE capabilities element check f157d1cb2cdc wifi: iwlwifi: fw: Add ASUS to PPAG and TAS list c9df78e84e85 wifi: mac80211: Fix 6 GHz Band capabilities element advertisement in lower bands 958234997dd5 wifi: rtw89: fix BSSID comparison for non-transmitted BSSID ca18975c4de2 wifi: rtw89: wow: remove notify during WoWLAN net-detect bc1ca06998c1 wifi: rtw88: sdio: use indirect IO for device registers before power-on 8ebef59d0294 wifi: rtw89: print just once for unknown C2H events 5596a90c8952 wifi: mac80211: fix key tailroom accounting leak 23b8682f05ec wifi: mac80211: don't mark keys for inactive links as uploaded e3373f10c6a6 wifi: ath11k: avoid bit operation on key flags 50f50dd024b4 wifi: ath11k: add support for MU EDCA 2a6cd5951ba8 wifi: ath12k: free skb during idr cleanup callback 775e37df2acc wifi: ath11k: Add missing platform IDs for quirk table c4840991ee4c wifi: ath10k: Fix memory leak on unsupported WMI command a6eed58249e7 wifi: brcmfmac: fix crash while sending Action Frames in standalone AP Mode 57100b87c778 wifi: ath12k: fix read pointer after free in ath12k_mac_assign_vif_to_vdev() 4a63523d3541 wifi: cfg80211: Add missing lock in cfg80211_check_and_end_cac() e9fd43b799d2 wifi: rtw89: avoid possible TX wait initialization race b419093e5e42 wifi: mt76: mt7921u: Add VID/PID for Netgear A7500 feb1774aaf85 wifi: mt76: mt7925u: Add VID/PID for Netgear A9000 bd3ac455a88d wifi: ath11k: HAL SRNG: don't deinitialize and re-initialize again 8055133a9f64 wifi: rtw89: avoid circular locking dependency in ser_state_run() 1c873416758f wifi: mac80211: fix Rx packet handling when pubsta information is not available 6e7d9fa61d7d wifi: ath10k: avoid unnecessary wait for service ready message 8d4f6ab4c53e wifi: ath12k: fix wrong logging ID used for CE fc00890c55e3 wifi: mt76: mt7915: fix mt7981 pre-calibration e18c4e6ba36c wifi: mt76: mt7996: Convert mt7996_wed_rro_addr to LE f481404a9826 wifi: mt76: mt7996: Fix RX packets configuration for primary WED device 57519239c76c wifi: mt76: fix potential memory leak in mt76_wmac_probe() 27c8e2e4b56f wifi: iwlwifi: Remove redundant header files 605402433eb8 wifi: mwifiex: send world regulatory domain to driver ``` The removed patch was added upstream. Link: https://github.com/openwrt/openwrt/pull/21134 Signed-off-by: Hauke Mehrtens --- package/kernel/mac80211/Makefile | 4 +- .../930-ath10k_add_tpt_led_trigger.patch | 4 +- ...75-ath10k-use-tpt-trigger-by-default.patch | 2 +- ...-power-reduction-for-US-regulatory-d.patch | 8 +-- ...k-always-use-mac80211-loss-detection.patch | 2 +- .../991-ath10k-support-flush_sta-method.patch | 6 +- ...k_mac_op_flush_sta-to-properly-flush.patch | 4 +- ...upport-setting-FW-memory-mode-via-DT.patch | 4 +- ...-and-handle-country-code-for-WCN7850.patch | 18 ++--- ...ectly-handle-mcast-packets-for-clien.patch | 66 ------------------- ...fer-a-ccode-from-OTP-over-nvram-file.patch | 2 +- ...eroperating-DPP-and-other-encryption.patch | 2 +- ...mfmac-disable-dump_survey-on-bcm2835.patch | 6 +- .../patches/build/140-trace_backport.patch | 2 +- ...x-init_vqs-build-error-on-kernel-6.6.patch | 4 +- ...-the-RX-descriptor-with-a-single-fun.patch | 2 +- ...e-data-rate-fallback-for-older-chips.patch | 2 +- .../110-mac80211_keep_keys_on_stop_ap.patch | 2 +- .../mac80211/patches/subsys/210-ap_scan.patch | 2 +- ...dd-AQL-support-for-broadcast-packets.patch | 2 +- ...11-add-option-for-vif-allowed-radios.patch | 6 +- ...s-net_device-to-.set_monitor_channel.patch | 4 +- ...d-flag-to-opt-out-of-virtual-monitor.patch | 20 +++--- ...d-support-for-the-monitor-SKIP_TX-fl.patch | 4 +- ...x-vif-addr-when-switching-from-monit.patch | 4 +- ...pport-EHT-1024-aggregation-size-in-T.patch | 2 +- ...d-link-iteration-macro-for-link-data.patch | 2 +- ...211-extend-beacon-monitoring-for-MLO.patch | 4 +- ...extend-connection-monitoring-for-MLO.patch | 6 +- 29 files changed, 65 insertions(+), 131 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 80ffb9f598..93f664dbb4 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=6.12.52 +PKG_VERSION:=6.12.61 PKG_RELEASE:=1 PKG_LICENSE:=GPL-2.0-only PKG_LICENSE_FILES:=COPYING PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ -PKG_HASH:=ed6ef4c67e08b294ed1101c7cc5ae584a5f338c99ef95362fa3921eb6d207f5d +PKG_HASH:=9db2f836dba7f38ad68f8798720ad4360bce6a3557bde02b88b3a4f068c77118 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)backports-$(PKG_VERSION) diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch index c71123a8fe..ad43dcef90 100644 --- a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -9924,6 +9924,21 @@ static int ath10k_mac_init_rd(struct ath +@@ -9932,6 +9932,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -22,7 +22,7 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -10286,6 +10301,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -10294,6 +10309,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch index be2ccfd0bf..d5f8a56c00 100644 --- a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch +++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch @@ -40,7 +40,7 @@ Signed-off-by: Mathias Kresin if (ret) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10302,7 +10302,7 @@ int ath10k_mac_register(struct ath10k *a +@@ -10310,7 +10310,7 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; #ifdef CPTCFG_MAC80211_LEDS diff --git a/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch index f1770cfbe0..2aba614090 100644 --- a/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +++ b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch @@ -28,7 +28,7 @@ Forwarded: no --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -1022,6 +1022,40 @@ static inline int ath10k_vdev_setup_sync +@@ -1030,6 +1030,40 @@ static inline int ath10k_vdev_setup_sync return ar->last_wmi_vdev_start_status; } @@ -69,7 +69,7 @@ Forwarded: no static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) { struct cfg80211_chan_def *chandef = NULL; -@@ -1054,7 +1088,8 @@ static int ath10k_monitor_vdev_start(str +@@ -1062,7 +1096,8 @@ static int ath10k_monitor_vdev_start(str arg.channel.min_power = 0; arg.channel.max_power = channel->max_power * 2; arg.channel.max_reg_power = channel->max_reg_power * 2; @@ -79,7 +79,7 @@ Forwarded: no reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); -@@ -1500,7 +1535,8 @@ static int ath10k_vdev_start_restart(str +@@ -1508,7 +1543,8 @@ static int ath10k_vdev_start_restart(str arg.channel.min_power = 0; arg.channel.max_power = chandef->chan->max_power * 2; arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; @@ -89,7 +89,7 @@ Forwarded: no if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; -@@ -3431,7 +3467,8 @@ static int ath10k_update_channel_list(st +@@ -3439,7 +3475,8 @@ static int ath10k_update_channel_list(st ch->min_power = 0; ch->max_power = channel->max_power * 2; ch->max_reg_power = channel->max_reg_power * 2; diff --git a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch index f7387595a9..619555cbad 100644 --- a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch +++ b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10094,7 +10094,6 @@ int ath10k_mac_register(struct ath10k *a +@@ -10102,7 +10102,6 @@ int ath10k_mac_register(struct ath10k *a ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); ieee80211_hw_set(ar->hw, QUEUE_CONTROL); ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); diff --git a/package/kernel/mac80211/patches/ath10k/991-ath10k-support-flush_sta-method.patch b/package/kernel/mac80211/patches/ath10k/991-ath10k-support-flush_sta-method.patch index c426d4b6a8..1111568af2 100644 --- a/package/kernel/mac80211/patches/ath10k/991-ath10k-support-flush_sta-method.patch +++ b/package/kernel/mac80211/patches/ath10k/991-ath10k-support-flush_sta-method.patch @@ -29,7 +29,7 @@ Tested-by: Florian Maurer --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -8135,6 +8135,20 @@ static void ath10k_flush(struct ieee8021 +@@ -8143,6 +8143,20 @@ static void ath10k_flush(struct ieee8021 mutex_unlock(&ar->conf_mutex); } @@ -50,7 +50,7 @@ Tested-by: Florian Maurer /* TODO: Implement this function properly * For now it is needed to reply to Probe Requests in IBSS mode. * Probably we need this information from FW. -@@ -9486,6 +9500,7 @@ static const struct ieee80211_ops ath10k +@@ -9494,6 +9508,7 @@ static const struct ieee80211_ops ath10k .set_rts_threshold = ath10k_set_rts_threshold, .set_frag_threshold = ath10k_mac_op_set_frag_threshold, .flush = ath10k_flush, @@ -58,7 +58,7 @@ Tested-by: Florian Maurer .tx_last_beacon = ath10k_tx_last_beacon, .set_antenna = ath10k_set_antenna, .get_antenna = ath10k_get_antenna, -@@ -10307,6 +10322,9 @@ int ath10k_mac_register(struct ath10k *a +@@ -10315,6 +10330,9 @@ int ath10k_mac_register(struct ath10k *a if (!ar->hw_params.hw_ops->set_coverage_class) ar->ops->set_coverage_class = NULL; diff --git a/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch b/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch index 0612150f3c..056c2f09e5 100644 --- a/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch +++ b/package/kernel/mac80211/patches/ath11k/453-ath11k-add-ath11k_mac_op_flush_sta-to-properly-flush.patch @@ -31,7 +31,7 @@ Signed-off-by: Florian Maurer --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8278,6 +8278,23 @@ static void ath11k_mac_op_flush(struct i +@@ -8327,6 +8327,23 @@ static void ath11k_mac_op_flush(struct i ath11k_mac_flush_tx_complete(ar); } @@ -55,7 +55,7 @@ Signed-off-by: Florian Maurer static bool ath11k_mac_has_single_legacy_rate(struct ath11k *ar, enum nl80211_band band, -@@ -9910,6 +9927,7 @@ static const struct ieee80211_ops ath11k +@@ -9959,6 +9976,7 @@ static const struct ieee80211_ops ath11k .set_bitrate_mask = ath11k_mac_op_set_bitrate_mask, .get_survey = ath11k_mac_op_get_survey, .flush = ath11k_mac_op_flush, diff --git a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch index 2bc1ca3c7d..c7ce4b7235 100644 --- a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch +++ b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch @@ -31,7 +31,7 @@ Signed-off-by: Robert Marko { .hw_rev = ATH11K_HW_IPQ8074, .name = "ipq8074 hw2.0", -@@ -2201,7 +2201,8 @@ static void ath11k_core_reset(struct wor +@@ -2239,7 +2239,8 @@ static void ath11k_core_reset(struct wor static int ath11k_init_hw_params(struct ath11k_base *ab) { const struct ath11k_hw_params *hw_params = NULL; @@ -41,7 +41,7 @@ Signed-off-by: Robert Marko for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { hw_params = &ath11k_hw_params[i]; -@@ -2217,7 +2218,31 @@ static int ath11k_init_hw_params(struct +@@ -2255,7 +2256,31 @@ static int ath11k_init_hw_params(struct ab->hw_params = *hw_params; diff --git a/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch b/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch index b265fcdeab..5005b796da 100644 --- a/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch +++ b/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch @@ -532,7 +532,7 @@ Acked-by: Jeff Johnson return ret; } -@@ -5998,7 +6013,7 @@ static int ath12k_mac_start(struct ath12 +@@ -6000,7 +6015,7 @@ static int ath12k_mac_start(struct ath12 /* TODO: Do we need to enable ANI? */ @@ -541,7 +541,7 @@ Acked-by: Jeff Johnson ar->num_started_vdevs = 0; ar->num_created_vdevs = 0; -@@ -6178,6 +6193,9 @@ static void ath12k_mac_stop(struct ath12 +@@ -6180,6 +6195,9 @@ static void ath12k_mac_stop(struct ath12 cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ar->ab->rfkill_work); @@ -551,7 +551,7 @@ Acked-by: Jeff Johnson spin_lock_bh(&ar->data_lock); list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { -@@ -6424,6 +6442,117 @@ static void ath12k_mac_op_update_vif_off +@@ -6426,6 +6444,117 @@ static void ath12k_mac_op_update_vif_off ath12k_mac_update_vif_offload(arvif); } @@ -669,7 +669,7 @@ Acked-by: Jeff Johnson static int ath12k_mac_vdev_create(struct ath12k *ar, struct ieee80211_vif *vif) { struct ath12k_hw *ah = ar->ah; -@@ -6538,6 +6667,7 @@ static int ath12k_mac_vdev_create(struct +@@ -6540,6 +6669,7 @@ static int ath12k_mac_vdev_create(struct arvif->vdev_id, ret); goto err_peer_del; } @@ -677,7 +677,7 @@ Acked-by: Jeff Johnson break; case WMI_VDEV_TYPE_STA: param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY; -@@ -6576,6 +6706,13 @@ static int ath12k_mac_vdev_create(struct +@@ -6578,6 +6708,13 @@ static int ath12k_mac_vdev_create(struct arvif->vdev_id, ret); goto err_peer_del; } @@ -691,7 +691,7 @@ Acked-by: Jeff Johnson break; default: break; -@@ -6916,6 +7053,11 @@ static void ath12k_mac_op_remove_interfa +@@ -6918,6 +7055,11 @@ static void ath12k_mac_op_remove_interfa ath12k_dbg(ab, ATH12K_DBG_MAC, "mac remove interface (vdev %d)\n", arvif->vdev_id); @@ -703,7 +703,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ret = ath12k_peer_delete(ar, arvif->vdev_id, vif->addr); if (ret) -@@ -7756,6 +7898,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc +@@ -7758,6 +7900,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc ar->num_started_vdevs == 1 && ar->monitor_vdev_created) ath12k_mac_monitor_stop(ar); @@ -718,7 +718,7 @@ Acked-by: Jeff Johnson mutex_unlock(&ar->conf_mutex); } -@@ -8294,6 +8444,14 @@ ath12k_mac_op_reconfig_complete(struct i +@@ -8296,6 +8446,14 @@ ath12k_mac_op_reconfig_complete(struct i ath12k_warn(ar->ab, "pdev %d successfully recovered\n", ar->pdev->pdev_id); @@ -733,7 +733,7 @@ Acked-by: Jeff Johnson if (ab->is_reset) { recovery_count = atomic_inc_return(&ab->recovery_count); -@@ -9344,6 +9502,9 @@ static void ath12k_mac_setup(struct ath1 +@@ -9346,6 +9504,9 @@ static void ath12k_mac_setup(struct ath1 INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); diff --git a/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch b/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch deleted file mode 100644 index 2e5e080524..0000000000 --- a/package/kernel/mac80211/patches/ath12k/002-wifi-ath12k-correctly-handle-mcast-packets-for-clien.patch +++ /dev/null @@ -1,66 +0,0 @@ -From a1eb56723b3203d366d2293a368b8bc8ef8894cd Mon Sep 17 00:00:00 2001 -From: Sarika Sharma -Date: Fri, 11 Apr 2025 11:45:23 +0530 -Subject: [PATCH] wifi: ath12k: correctly handle mcast packets for clients - -commit 4541b0c8c3c1b85564971d497224e57cf8076a02 upstream. - -Currently, RX is_mcbc bit is set for packets sent from client as -destination address (DA) is multicast/broadcast address, but packets -are actually unicast as receiver address (RA) is not multicast address. -Hence, packets are not handled properly due to this is_mcbc bit. - -Therefore, reset the is_mcbc bit if interface type is AP. - -Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 - -Signed-off-by: Sarika Sharma -Reviewed-by: Vasanthakumar Thiagarajan -Link: https://patch.msgid.link/20250411061523.859387-3-quic_sarishar@quicinc.com -Signed-off-by: Jeff Johnson -[ Adjust context ] -Signed-off-by: Oliver Sedlbauer -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/wireless/ath/ath12k/dp_rx.c | 5 +++++ - drivers/net/wireless/ath/ath12k/peer.c | 3 +++ - drivers/net/wireless/ath/ath12k/peer.h | 2 ++ - 3 files changed, 10 insertions(+) - ---- a/drivers/net/wireless/ath/ath12k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c -@@ -2214,6 +2214,11 @@ static void ath12k_dp_rx_h_mpdu(struct a - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu); - if (peer) { -+ /* resetting mcbc bit because mcbc packets are unicast -+ * packets only for AP as STA sends unicast packets. -+ */ -+ rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; -+ - if (rxcb->is_mcbc) - enctype = peer->sec_type_grp; - else ---- a/drivers/net/wireless/ath/ath12k/peer.c -+++ b/drivers/net/wireless/ath/ath12k/peer.c -@@ -331,6 +331,9 @@ int ath12k_peer_create(struct ath12k *ar - arvif->ast_idx = peer->hw_peer_id; - } - -+ if (arvif->vif->type == NL80211_IFTYPE_AP) -+ peer->ucast_ra_only = true; -+ - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; - peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; - ---- a/drivers/net/wireless/ath/ath12k/peer.h -+++ b/drivers/net/wireless/ath/ath12k/peer.h -@@ -47,6 +47,8 @@ struct ath12k_peer { - - /* protected by ab->data_lock */ - bool dp_setup_done; -+ -+ bool ucast_ra_only; - }; - - void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); diff --git a/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch b/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch index 9a7f9eb266..f3606dce41 100644 --- a/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch +++ b/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch @@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell #include #include #include -@@ -8212,31 +8213,45 @@ static void brcmf_cfg80211_reg_notifier( +@@ -8211,31 +8212,45 @@ static void brcmf_cfg80211_reg_notifier( struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); struct brcmf_pub *drvr = cfg->pub; struct brcmf_fil_country_le ccreq; diff --git a/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch b/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch index 080ce2bb86..ccf3ae71fd 100644 --- a/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch +++ b/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch @@ -119,7 +119,7 @@ Signed-off-by: Chi-hsien Lin err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe_abort", &int_val, sizeof(s32)); if (err) -@@ -1826,6 +1830,7 @@ bool brcmf_p2p_send_action_frame(struct +@@ -1817,6 +1821,7 @@ bool brcmf_p2p_send_action_frame(struct /* validate channel and p2p ies */ if (config_af_params.search_channel && IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) && diff --git a/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch b/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch index 0dd0d11c18..97af080710 100644 --- a/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch +++ b/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch @@ -9,7 +9,7 @@ Signed-off-by: Álvaro Fernández Rojas --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -7991,6 +7991,7 @@ static s32 brcmf_translate_country_code( +@@ -7990,6 +7990,7 @@ static s32 brcmf_translate_country_code( return 0; } @@ -17,7 +17,7 @@ Signed-off-by: Álvaro Fernández Rojas static int brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey) { -@@ -8213,6 +8214,7 @@ exit: +@@ -8212,6 +8213,7 @@ exit: brcmf_set_mpc(ifp, 1); return err; } @@ -25,7 +25,7 @@ Signed-off-by: Álvaro Fernández Rojas static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *req) -@@ -8379,8 +8381,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802 +@@ -8378,8 +8380,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; #endif diff --git a/package/kernel/mac80211/patches/build/140-trace_backport.patch b/package/kernel/mac80211/patches/build/140-trace_backport.patch index 8b77b7e83d..50cbc2255e 100644 --- a/package/kernel/mac80211/patches/build/140-trace_backport.patch +++ b/package/kernel/mac80211/patches/build/140-trace_backport.patch @@ -530,7 +530,7 @@ --- a/net/wireless/trace.h +++ b/net/wireless/trace.h -@@ -446,7 +446,7 @@ TRACE_EVENT(rdev_add_virtual_intf, +@@ -467,7 +467,7 @@ TRACE_EVENT(rdev_add_virtual_intf, ), TP_fast_assign( WIPHY_ASSIGN; diff --git a/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch b/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch index 229deee9e8..42acb1d627 100644 --- a/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch +++ b/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c -@@ -6636,6 +6636,7 @@ static void hwsim_virtio_rx_done(struct +@@ -6637,6 +6637,7 @@ static void hwsim_virtio_rx_done(struct static int init_vqs(struct virtio_device *vdev) { @@ -8,7 +8,7 @@ struct virtqueue_info vqs_info[HWSIM_NUM_VQS] = { [HWSIM_VQ_TX] = { "tx", hwsim_virtio_tx_done }, [HWSIM_VQ_RX] = { "rx", hwsim_virtio_rx_done }, -@@ -6643,6 +6644,19 @@ static int init_vqs(struct virtio_device +@@ -6644,6 +6645,19 @@ static int init_vqs(struct virtio_device return virtio_find_vqs(vdev, HWSIM_NUM_VQS, hwsim_vqs, vqs_info, NULL); diff --git a/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch index 4c6966a3c6..2f7bdce51a 100644 --- a/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch +++ b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch @@ -535,7 +535,7 @@ Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com struct rtw_rx_pkt_stat *pkt_stat); --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -979,8 +979,7 @@ static void rtw_sdio_rxfifo_recv(struct +@@ -983,8 +983,7 @@ static void rtw_sdio_rxfifo_recv(struct while (true) { rx_desc = skb->data; diff --git a/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch index 9c3bf29321..3e28fe9595 100644 --- a/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch +++ b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch @@ -121,7 +121,7 @@ Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com .ht_supported = true, --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -862,7 +862,7 @@ static void rtw_sdio_tx_skb_prepare(stru +@@ -866,7 +866,7 @@ static void rtw_sdio_tx_skb_prepare(stru pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch index 68534f4e7b..c0f0fbc796 100644 --- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch @@ -9,7 +9,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1649,12 +1649,6 @@ static int ieee80211_stop_ap(struct wiph +@@ -1663,12 +1663,6 @@ static int ieee80211_stop_ap(struct wiph __sta_info_flush(sdata, true, link_id); diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index ca4ac8adb6..0e886899c9 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -8,7 +8,7 @@ Subject: [PATCH] mac80211: allow scans in access point mode (for site survey) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2863,6 +2863,8 @@ static int ieee80211_scan(struct wiphy * +@@ -2877,6 +2877,8 @@ static int ieee80211_scan(struct wiphy * */ fallthrough; case NL80211_IFTYPE_AP: diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch index 6ec52af9a4..b976e8d7a2 100644 --- a/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch +++ b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch @@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1360,10 +1360,12 @@ struct ieee80211_local { +@@ -1362,10 +1362,12 @@ struct ieee80211_local { spinlock_t handle_wake_tx_queue_lock; u16 airtime_flags; diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch b/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch index 4ecbc514fc..faf40ddb2e 100644 --- a/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch +++ b/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch @@ -23,7 +23,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -6274,6 +6274,7 @@ enum ieee80211_ap_reg_power { +@@ -6352,6 +6352,7 @@ enum ieee80211_ap_reg_power { * entered. * @links.cac_time_ms: CAC time in ms * @valid_links: bitmap describing what elements of @links are valid @@ -31,7 +31,7 @@ Signed-off-by: Felix Fietkau */ struct wireless_dev { struct wiphy *wiphy; -@@ -6386,6 +6387,8 @@ struct wireless_dev { +@@ -6464,6 +6465,8 @@ struct wireless_dev { unsigned int cac_time_ms; } links[IEEE80211_MLD_MAX_NUM_LINKS]; u16 valid_links; @@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau }; static inline const u8 *wdev_address(struct wireless_dev *wdev) -@@ -6572,6 +6575,17 @@ bool cfg80211_radio_chandef_valid(const +@@ -6650,6 +6653,17 @@ bool cfg80211_radio_chandef_valid(const const struct cfg80211_chan_def *chandef); /** diff --git a/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch b/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch index f1fc9190fc..a2a269ee35 100644 --- a/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch +++ b/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch @@ -59,7 +59,7 @@ Signed-off-by: Felix Fietkau int (*scan)(struct wiphy *wiphy, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -879,6 +879,7 @@ static int ieee80211_get_station(struct +@@ -893,6 +893,7 @@ static int ieee80211_get_station(struct } static int ieee80211_set_monitor_channel(struct wiphy *wiphy, @@ -126,7 +126,7 @@ Signed-off-by: Felix Fietkau } --- a/net/wireless/trace.h +++ b/net/wireless/trace.h -@@ -1318,19 +1318,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_chann +@@ -1339,19 +1339,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_chann ); TRACE_EVENT(rdev_set_monitor_channel, diff --git a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch index bb2d5da1a4..5f27b3d103 100644 --- a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch +++ b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch @@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau ieee80211_set_mu_mimo_follow(monitor_sdata, params); if (params->flags) { -@@ -889,22 +894,25 @@ static int ieee80211_set_monitor_channel +@@ -903,22 +908,25 @@ static int ieee80211_set_monitor_channel lockdep_assert_wiphy(local->hw.wiphy); @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (ret) return ret; done: -@@ -3050,7 +3058,8 @@ static int ieee80211_set_tx_power(struct +@@ -3064,7 +3072,8 @@ static int ieee80211_set_tx_power(struct if (wdev) { sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) return -EOPNOTSUPP; -@@ -3098,7 +3107,8 @@ static int ieee80211_set_tx_power(struct +@@ -3112,7 +3121,8 @@ static int ieee80211_set_tx_power(struct } list_for_each_entry(sdata, &local->interfaces, list) { @@ -115,7 +115,7 @@ Signed-off-by: Felix Fietkau has_monitor = true; continue; } -@@ -3108,7 +3118,8 @@ static int ieee80211_set_tx_power(struct +@@ -3122,7 +3132,8 @@ static int ieee80211_set_tx_power(struct sdata->vif.bss_conf.txpower_type = txp_type; } list_for_each_entry(sdata, &local->interfaces, list) { @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau continue; ieee80211_recalc_txpower(sdata, update_txp_type); } -@@ -4303,7 +4314,8 @@ static int ieee80211_cfg_get_channel(str +@@ -4317,7 +4328,8 @@ static int ieee80211_cfg_get_channel(str if (chanctx_conf) { *chandef = link->conf->chanreq.oper; ret = 0; @@ -201,7 +201,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -279,8 +279,13 @@ static int _ieee80211_change_mac(struct +@@ -296,8 +296,13 @@ static int _ieee80211_change_mac(struct ret = eth_mac_addr(sdata->dev, sa); if (ret == 0) { @@ -217,7 +217,7 @@ Signed-off-by: Felix Fietkau } /* Regardless of eth_mac_addr() return we still want to add the -@@ -705,9 +710,11 @@ static void ieee80211_do_stop(struct iee +@@ -722,9 +727,11 @@ static void ieee80211_do_stop(struct iee ieee80211_recalc_idle(local); ieee80211_recalc_offload(local); @@ -230,7 +230,7 @@ Signed-off-by: Felix Fietkau fallthrough; default: if (!going_down) -@@ -1140,7 +1147,8 @@ int ieee80211_add_virtual_monitor(struct +@@ -1157,7 +1164,8 @@ int ieee80211_add_virtual_monitor(struct ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); @@ -240,7 +240,7 @@ Signed-off-by: Felix Fietkau return 0; sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); -@@ -1202,6 +1210,9 @@ void ieee80211_del_virtual_monitor(struc +@@ -1219,6 +1227,9 @@ void ieee80211_del_virtual_monitor(struc { struct ieee80211_sub_if_data *sdata; @@ -250,7 +250,7 @@ Signed-off-by: Felix Fietkau ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); -@@ -1345,7 +1356,8 @@ int ieee80211_do_open(struct wireless_de +@@ -1362,7 +1373,8 @@ int ieee80211_do_open(struct wireless_de break; } diff --git a/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch b/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch index 3cd8baefe1..f25ed44c80 100644 --- a/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch +++ b/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1382,7 +1382,7 @@ struct ieee80211_local { +@@ -1384,7 +1384,7 @@ struct ieee80211_local { spinlock_t queue_stop_reason_lock; int open_count; @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau fif_probe_req; --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -1103,6 +1103,8 @@ void ieee80211_adjust_monitor_flags(stru +@@ -1120,6 +1120,8 @@ void ieee80211_adjust_monitor_flags(stru ADJUST(CONTROL, control); ADJUST(CONTROL, pspoll); ADJUST(OTHER_BSS, other_bss); diff --git a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch index 4e6d2ee5e9..a803736c4c 100644 --- a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch +++ b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch @@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau u8 cab_queue; --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -279,13 +279,8 @@ static int _ieee80211_change_mac(struct +@@ -296,13 +296,8 @@ static int _ieee80211_change_mac(struct ret = eth_mac_addr(sdata->dev, sa); if (ret == 0) { @@ -52,7 +52,7 @@ Signed-off-by: Felix Fietkau } /* Regardless of eth_mac_addr() return we still want to add the -@@ -1336,6 +1331,8 @@ int ieee80211_do_open(struct wireless_de +@@ -1353,6 +1348,8 @@ int ieee80211_do_open(struct wireless_de } } diff --git a/package/kernel/mac80211/patches/subsys/342-wifi-mac80211-Support-EHT-1024-aggregation-size-in-T.patch b/package/kernel/mac80211/patches/subsys/342-wifi-mac80211-Support-EHT-1024-aggregation-size-in-T.patch index e4159d2b3d..ec5255c20c 100644 --- a/package/kernel/mac80211/patches/subsys/342-wifi-mac80211-Support-EHT-1024-aggregation-size-in-T.patch +++ b/package/kernel/mac80211/patches/subsys/342-wifi-mac80211-Support-EHT-1024-aggregation-size-in-T.patch @@ -284,7 +284,7 @@ Signed-off-by: Johannes Berg sta->ampdu_mlme.tid_rx_manage_offl)) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -2131,14 +2131,19 @@ int ieee80211_send_smps_action(struct ie +@@ -2133,14 +2133,19 @@ int ieee80211_send_smps_action(struct ie const u8 *bssid, int link_id); bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old, enum ieee80211_smps_mode smps_mode_new); diff --git a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch index fd6e5dc169..e2cd61962b 100644 --- a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch +++ b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch @@ -25,7 +25,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1220,6 +1220,19 @@ struct ieee80211_sub_if_data *vif_to_sda +@@ -1222,6 +1222,19 @@ struct ieee80211_sub_if_data *vif_to_sda ((__link) = sdata_dereference((__sdata)->link[__link_id], \ (__sdata)))) diff --git a/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch b/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch index 7722bcf64c..c45dcec3e3 100644 --- a/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch +++ b/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch @@ -23,7 +23,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -2167,6 +2167,21 @@ static void ieee80211_csa_switch_work(st +@@ -2168,6 +2168,21 @@ static void ieee80211_csa_switch_work(st } } @@ -45,7 +45,7 @@ Signed-off-by: Johannes Berg ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata); } -@@ -7892,6 +7907,29 @@ void ieee80211_sta_work(struct ieee80211 +@@ -7893,6 +7908,29 @@ void ieee80211_sta_work(struct ieee80211 } } diff --git a/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch b/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch index 9f16bea626..10ba0cb06d 100644 --- a/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch +++ b/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch @@ -25,7 +25,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -3841,9 +3841,6 @@ static void ieee80211_mgd_probe_ap_send( +@@ -3842,9 +3842,6 @@ static void ieee80211_mgd_probe_ap_send( lockdep_assert_wiphy(sdata->local->hw.wiphy); @@ -35,7 +35,7 @@ Signed-off-by: Johannes Berg /* * Try sending broadcast probe requests for the last three * probe requests after the first ones failed since some -@@ -3889,9 +3886,6 @@ static void ieee80211_mgd_probe_ap(struc +@@ -3890,9 +3887,6 @@ static void ieee80211_mgd_probe_ap(struc lockdep_assert_wiphy(sdata->local->hw.wiphy); @@ -45,7 +45,7 @@ Signed-off-by: Johannes Berg if (!ieee80211_sdata_running(sdata)) return; -@@ -7950,36 +7944,73 @@ static void ieee80211_sta_bcn_mon_timer( +@@ -7951,36 +7945,73 @@ static void ieee80211_sta_bcn_mon_timer( &sdata->u.mgd.beacon_connection_loss_work); } From 8db7b6ff53042848cb9212069b3ebec33076c38a Mon Sep 17 00:00:00 2001 From: Ari Kurniawan Date: Mon, 15 Sep 2025 20:13:29 +0700 Subject: [PATCH 118/128] mediatek: filogic: add support for Totolink X6000R Specification : - SOC : Mediatek MT7981B (1.3GHz) - RAM : 256MB - Flash : 16MB SPI NOR - Ports : 4 LAN (1G) & 1 WAN (1G) - WIFI : MediaTek dual-band WiFi 6 - 2.4 GHz : b/g/n/ax, MIMO 2x2 - 5 GHz : a/n/ac/ax, MIMO 2x2 - Buttons : Reset & WPS/Mesh - LEDS : WAN (Green), Status (Red & Blue) - Power : 12V1A Install via OEM web ui: Upload the sysupgrade image to firmware upgrade page on OEM web ui Install via recovery / revert to stock firmware: 1. Unplug from power 2. Download the Sysupgrade (for openwrt installation) or OEM Factory image (for revert to stock firmware) 3. Set your computer ethernet IP to 192.168.1.X, subnet 255.255.255.0 (X=your chosen ip number ranging from 2-254) 4. Press and hold reset button while turn on / plug power adapter to the router. Wait untill ALL LAN green LED turn on, then release the reset button. 5. Plug the LAN cable from your computer into LAN 1 port then open web browser, and type in the address column : 192.168.1.1 6. Upload the sysupgrade / oem factory image 7. Wait until the router finished flashing (the router will reboot) 8. Set ethernet ip to dhcp 9. Open 192.168.1.1 (for openwrt install) / 192.168.0.1 (for OEM firmware) Signed-off-by: Ari Kurniawan Link: https://github.com/openwrt/openwrt/pull/20035 (cherry picked from commit 7cd10add2de3c8227cf7383c7ca5cf3b12eeb822) Signed-off-by: Ari Kurniawan Link: https://github.com/openwrt/openwrt/pull/20674 Signed-off-by: Hauke Mehrtens --- .../mediatek/dts/mt7981b-totolink-x6000r.dts | 254 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 3 + target/linux/mediatek/image/filogic.mk | 11 + 3 files changed, 268 insertions(+) create mode 100644 target/linux/mediatek/dts/mt7981b-totolink-x6000r.dts diff --git a/target/linux/mediatek/dts/mt7981b-totolink-x6000r.dts b/target/linux/mediatek/dts/mt7981b-totolink-x6000r.dts new file mode 100644 index 0000000000..80d4cdea73 --- /dev/null +++ b/target/linux/mediatek/dts/mt7981b-totolink-x6000r.dts @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; + +#include + +#include "mt7981.dtsi" + +/ { + model = "TOTOLINK X6000R"; + compatible = "totolink,x6000r", "mediatek,mt7981"; + + aliases { + label-mac-device = &gmac0; + led-boot = &led_status; + led-failsafe = &led_status_red; + led-running = &led_status; + led-upgrade = &led_status; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@40000000 { + reg = <0 0x40000000 0 0x10000000>; + device_type = "memory"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_WAN; + color = ; + gpios = <&pio 8 GPIO_ACTIVE_LOW>; + }; + + led_status_red: led-1 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 13 GPIO_ACTIVE_LOW>; + }; + + led_status: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 15 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins &gbe_led0_pins &gbe_led1_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + nvmem-cells = <&macaddr_factory_14>; + nvmem-cell-names = "mac-address"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "gmii"; + phy-handle = <&int_gbe_phy>; + label = "wan"; + + nvmem-cells = <&macaddr_factory_1a>; + nvmem-cell-names = "mac-address"; + }; +}; + +&mdio_bus { + switch: switch@1f { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&pio>; + interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; +}; + +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&spi2_flash_pins>; + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "jedec,spi-nor"; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "BL2"; + reg = <0x00000 0x40000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "Factory"; + reg = <0x50000 0xb0000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + macaddr_factory_14: macaddr@14 { + reg = <0x14 0x6>; + }; + + macaddr_factory_1a: macaddr@1a { + reg = <0x1a 0x6>; + }; + }; + }; + + partition@100000 { + label = "FIP"; + reg = <0x100000 0x80000>; + read-only; + }; + + partition@180000 { + compatible = "denx,fit"; + label = "firmware"; + reg = <0x180000 0xe00000>; + }; + }; + }; +}; + +&pio { + spi2_flash_pins: spi2-pins { + mux { + function = "spi"; + groups = "spi2", "spi2_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; +}; + +&wifi { + status = "okay"; + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index 0f5270483d..7f8fb4b7c4 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -153,6 +153,9 @@ smartrg,sdg-8733a) ucidef_set_led_netdev "wan-orange" "WAN" "mdio-bus:08:orange:wan" "wan" "link_100 link_1000" ucidef_set_led_netdev "wan-white" "WAN" "mdio-bus:08:white:wan" "wan" "link_10000" ;; +totolink,x6000r) + ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" "link tx rx" + ;; tplink,re6000xd) ucidef_set_led_netdev "lan-1" "lan-1" "blue:lan-0" "lan1" "link tx rx" ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-1" "lan2" "link tx rx" diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 8eb0932a98..e33f8a3aec 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1761,6 +1761,17 @@ define Device/ruijie_rg-x60-pro endef TARGET_DEVICES += ruijie_rg-x60-pro +define Device/totolink_x6000r + DEVICE_VENDOR := TOTOLINK + DEVICE_MODEL := X6000R + DEVICE_DTS := mt7981b-totolink-x6000r + DEVICE_DTS_DIR := ../dts + IMAGES := sysupgrade.bin + IMAGE_SIZE := 14336k + DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware +endef +TARGET_DEVICES += totolink_x6000r + define Device/tplink_archer-ax80-v1 DEVICE_VENDOR := TP-Link DEVICE_MODEL := Archer AX80V1 From 30b7a5f27aa34aa3392a5f6e1e54b02d30934cde Mon Sep 17 00:00:00 2001 From: Ayra Hikari Date: Thu, 30 Oct 2025 19:08:50 +0700 Subject: [PATCH 119/128] mediatek/filogic: fix Totolink X6000R sysupgrade failed Fix Totolink X6000R image failing to upgrade via sysupgrade due to an incorrect upgrade case. The fallback upgrade path used the NAND upgrade routine, which caused the "layout volume not found" error on NOR flash devices. By adding a specific case for this board, sysupgrade now uses `default_do_upgrade`, which is compatible with the NOR flash layout. Fixes: 7cd10ad Signed-off-by: Ayra Hikari (cherry picked from commit 7cd10add2de3c8227cf7383c7ca5cf3b12eeb822) Link: https://github.com/openwrt/openwrt/pull/20674 Signed-off-by: Hauke Mehrtens --- .../linux/mediatek/filogic/base-files/lib/upgrade/platform.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index 8ba706f85b..8af61b0289 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -136,7 +136,8 @@ platform_do_upgrade() { cudy,re3000-v1|\ cudy,wr3000-v1|\ yuncore,ax835|\ - wavlink,wl-wn573hx3) + wavlink,wl-wn573hx3|\ + totolink,x6000r) default_do_upgrade "$1" ;; dlink,aquila-pro-ai-m30-a1|\ From 3c97c4a44cbeb767281f3260c1f6da4772432807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Sat, 6 Dec 2025 18:34:37 +0000 Subject: [PATCH 120/128] dropbear: enable configurable port forwarding options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently its only possible to disable port forwarding only for specific keys, via the OpenSSH-style restriction in `authorized_keys` file. In some use cases it might be feasible to disable such features globally on service level, so lets add new LocalPortForward and RemotePortForward config knobs. Signed-off-by: Petr Štetiar Link: https://github.com/openwrt/openwrt/pull/21071 (cherry picked from commit 83f6177dbf44fa92ecf6d2e1cda9f92cfc5fe849) [ fix conflict error ] Signed-off-by: Christian Marangi --- package/network/services/dropbear/files/dropbear.config | 2 ++ package/network/services/dropbear/files/dropbear.init | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/package/network/services/dropbear/files/dropbear.config b/package/network/services/dropbear/files/dropbear.config index 7eb5975449..7957cd6a49 100644 --- a/package/network/services/dropbear/files/dropbear.config +++ b/package/network/services/dropbear/files/dropbear.config @@ -5,3 +5,5 @@ config dropbear main option RootPasswordAuth 'on' option Port '22' # option BannerFile '/etc/banner' +# option LocalPortForward 'off' +# option RemotePortForward 'off' diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 395237f9bc..6e45a55a64 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -179,6 +179,8 @@ validate_section_dropbear() 'IdleTimeout:uinteger:0' \ 'MaxAuthTries:uinteger:3' \ 'RecvWindowSize:uinteger:262144' \ + 'LocalPortForward:bool:1' \ + 'RemotePortForward:bool:1' \ 'mdns:bool:1' } @@ -319,6 +321,8 @@ dropbear_instance() fi [ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s [ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a + [ "${LocalPortForward}" -eq 0 ] && procd_append_param command -j + [ "${RemotePortForward}" -eq 0 ] && procd_append_param command -k [ -n "${ForceCommand}" ] && procd_append_param command -c "${ForceCommand}" [ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g [ "${RootLogin}" -eq 0 ] && procd_append_param command -w From b8d232d9dca82078b89f3a18da434cfbae641f2b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 15 Dec 2025 02:02:35 +0100 Subject: [PATCH 121/128] kernel: Fix boot of realtek rtl838x Revert two patches from upstream Linux: https://github.com/gregkh/linux/commit/135713cd0751bf296e515f5fdec234320f73bbd8 https://github.com/gregkh/linux/commit/231ac951fabae2aaed8b2c00b4a097107be49c8c This fixes a boot hang on realtek rtl838x switches. This is the last printed message: Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear) Thread on mips mailing list: https://lore.kernel.org/linux-mips/b35fe4b3-8f42-49f4-a6bf-9f0e56d4050c@hauke-m.de/T/#u Link: https://github.com/openwrt/openwrt/pull/21166 Signed-off-by: Hauke Mehrtens --- ...malloc-tlb_vpn-array-to-avoid-stack-.patch | 60 +++++++ ...revent-a-TLB-shutdown-on-initial-uni.patch | 146 ++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 target/linux/generic/pending-6.6/360-Revert-MIPS-mm-kmalloc-tlb_vpn-array-to-avoid-stack-.patch create mode 100644 target/linux/generic/pending-6.6/361-Revert-MIPS-mm-Prevent-a-TLB-shutdown-on-initial-uni.patch diff --git a/target/linux/generic/pending-6.6/360-Revert-MIPS-mm-kmalloc-tlb_vpn-array-to-avoid-stack-.patch b/target/linux/generic/pending-6.6/360-Revert-MIPS-mm-kmalloc-tlb_vpn-array-to-avoid-stack-.patch new file mode 100644 index 0000000000..1b53919a0c --- /dev/null +++ b/target/linux/generic/pending-6.6/360-Revert-MIPS-mm-kmalloc-tlb_vpn-array-to-avoid-stack-.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Mon, 15 Dec 2025 01:45:07 +0100 +Subject: Revert "MIPS: mm: kmalloc tlb_vpn array to avoid stack overflow" + +This reverts commit 231ac951fabae2aaed8b2c00b4a097107be49c8c. +--- + arch/mips/mm/tlb-r4k.c | 18 ++---------------- + 1 file changed, 2 insertions(+), 16 deletions(-) + +--- a/arch/mips/mm/tlb-r4k.c ++++ b/arch/mips/mm/tlb-r4k.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -521,26 +520,17 @@ static int r4k_vpn_cmp(const void *a, co + * Initialise all TLB entries with unique values that do not clash with + * what we have been handed over and what we'll be using ourselves. + */ +-static void __ref r4k_tlb_uniquify(void) ++static void r4k_tlb_uniquify(void) + { ++ unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; + int tlbsize = current_cpu_data.tlbsize; +- bool use_slab = slab_is_available(); + int start = num_wired_entries(); +- phys_addr_t tlb_vpn_size; +- unsigned long *tlb_vpns; + unsigned long vpn_mask; + int cnt, ent, idx, i; + + vpn_mask = GENMASK(cpu_vmbits - 1, 13); + vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; + +- tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); +- tlb_vpns = (use_slab ? +- kmalloc(tlb_vpn_size, GFP_KERNEL) : +- memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns))); +- if (WARN_ON(!tlb_vpns)) +- return; /* Pray local_flush_tlb_all() is good enough. */ +- + htw_stop(); + + for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { +@@ -593,10 +583,6 @@ static void __ref r4k_tlb_uniquify(void) + tlbw_use_hazard(); + htw_start(); + flush_micro_tlb(); +- if (use_slab) +- kfree(tlb_vpns); +- else +- memblock_free(tlb_vpns, tlb_vpn_size); + } + + /* diff --git a/target/linux/generic/pending-6.6/361-Revert-MIPS-mm-Prevent-a-TLB-shutdown-on-initial-uni.patch b/target/linux/generic/pending-6.6/361-Revert-MIPS-mm-Prevent-a-TLB-shutdown-on-initial-uni.patch new file mode 100644 index 0000000000..17d0b50ad8 --- /dev/null +++ b/target/linux/generic/pending-6.6/361-Revert-MIPS-mm-Prevent-a-TLB-shutdown-on-initial-uni.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Mon, 15 Dec 2025 01:45:20 +0100 +Subject: Revert "MIPS: mm: Prevent a TLB shutdown on initial uniquification" + +This reverts commit 135713cd0751bf296e515f5fdec234320f73bbd8. +--- + arch/mips/mm/tlb-r4k.c | 100 +++++++++++++++-------------------------- + 1 file changed, 37 insertions(+), 63 deletions(-) + +--- a/arch/mips/mm/tlb-r4k.c ++++ b/arch/mips/mm/tlb-r4k.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + + #include + #include +@@ -507,79 +506,55 @@ static int __init set_ntlb(char *str) + + __setup("ntlb=", set_ntlb); + +- +-/* Comparison function for EntryHi VPN fields. */ +-static int r4k_vpn_cmp(const void *a, const void *b) +-{ +- long v = *(unsigned long *)a - *(unsigned long *)b; +- int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; +- return s ? (v != 0) | v >> s : v; +-} +- +-/* +- * Initialise all TLB entries with unique values that do not clash with +- * what we have been handed over and what we'll be using ourselves. +- */ ++/* Initialise all TLB entries with unique values */ + static void r4k_tlb_uniquify(void) + { +- unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; +- int tlbsize = current_cpu_data.tlbsize; +- int start = num_wired_entries(); +- unsigned long vpn_mask; +- int cnt, ent, idx, i; +- +- vpn_mask = GENMASK(cpu_vmbits - 1, 13); +- vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; ++ int entry = num_wired_entries(); + + htw_stop(); ++ write_c0_entrylo0(0); ++ write_c0_entrylo1(0); + +- for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { +- unsigned long vpn; ++ while (entry < current_cpu_data.tlbsize) { ++ unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); ++ unsigned long asid = 0; ++ int idx; + +- write_c0_index(i); +- mtc0_tlbr_hazard(); +- tlb_read(); +- tlb_read_hazard(); +- vpn = read_c0_entryhi(); +- vpn &= vpn_mask & PAGE_MASK; +- tlb_vpns[cnt] = vpn; ++ /* Skip wired MMID to make ginvt_mmid work */ ++ if (cpu_has_mmid) ++ asid = MMID_KERNEL_WIRED + 1; + +- /* Prevent any large pages from overlapping regular ones. */ +- write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK); ++ /* Check for match before using UNIQUE_ENTRYHI */ ++ do { ++ if (cpu_has_mmid) { ++ write_c0_memorymapid(asid); ++ write_c0_entryhi(UNIQUE_ENTRYHI(entry)); ++ } else { ++ write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid); ++ } ++ mtc0_tlbw_hazard(); ++ tlb_probe(); ++ tlb_probe_hazard(); ++ idx = read_c0_index(); ++ /* No match or match is on current entry */ ++ if (idx < 0 || idx == entry) ++ break; ++ /* ++ * If we hit a match, we need to try again with ++ * a different ASID. ++ */ ++ asid++; ++ } while (asid < asid_mask); ++ ++ if (idx >= 0 && idx != entry) ++ panic("Unable to uniquify TLB entry %d", idx); ++ ++ write_c0_index(entry); + mtc0_tlbw_hazard(); + tlb_write_indexed(); +- tlbw_use_hazard(); ++ entry++; + } + +- sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL); +- +- write_c0_pagemask(PM_DEFAULT_MASK); +- write_c0_entrylo0(0); +- write_c0_entrylo1(0); +- +- idx = 0; +- ent = tlbsize; +- for (i = start; i < tlbsize; i++) +- while (1) { +- unsigned long entryhi, vpn; +- +- entryhi = UNIQUE_ENTRYHI(ent); +- vpn = entryhi & vpn_mask & PAGE_MASK; +- +- if (idx >= cnt || vpn < tlb_vpns[idx]) { +- write_c0_entryhi(entryhi); +- write_c0_index(i); +- mtc0_tlbw_hazard(); +- tlb_write_indexed(); +- ent++; +- break; +- } else if (vpn == tlb_vpns[idx]) { +- ent++; +- } else { +- idx++; +- } +- } +- + tlbw_use_hazard(); + htw_start(); + flush_micro_tlb(); +@@ -625,7 +600,6 @@ static void r4k_tlb_configure(void) + + /* From this point on the ARC firmware is dead. */ + r4k_tlb_uniquify(); +- local_flush_tlb_all(); + + /* Did I tell you that ARC SUCKS? */ + } From 7aa929881e444ebc0ec0ae6cf027144db26392d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= Date: Fri, 24 Oct 2025 11:27:59 +0200 Subject: [PATCH 122/128] mediatek/filogic: fix Cudy WR3000H ethernet port order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ports are physically labelled in reverse order on the device. This patch aligns logical names with physical ones. LED order on front of device is correct after this patch. Fixes: 9d66b8b312fb6a4087244ee3ee10e1ba1623df81 Signed-off-by: Thibaut VARÈNE Link: https://github.com/openwrt/openwrt/pull/20528 (cherry picked from commit 887cab883bc4b3e104b70e74af775522d060e1d4) Signed-off-by: Thibaut VARÈNE Link: https://github.com/openwrt/openwrt/pull/21173 Signed-off-by: Hauke Mehrtens --- target/linux/mediatek/dts/mt7981b-cudy-wr3000h-v1.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/mediatek/dts/mt7981b-cudy-wr3000h-v1.dts b/target/linux/mediatek/dts/mt7981b-cudy-wr3000h-v1.dts index e34d2a9ad2..69e1098b43 100644 --- a/target/linux/mediatek/dts/mt7981b-cudy-wr3000h-v1.dts +++ b/target/linux/mediatek/dts/mt7981b-cudy-wr3000h-v1.dts @@ -118,22 +118,22 @@ port@0 { reg = <0>; - label = "lan1"; + label = "lan4"; }; port@1 { reg = <1>; - label = "lan2"; + label = "lan3"; }; port@2 { reg = <2>; - label = "lan3"; + label = "lan2"; }; port@3 { reg = <3>; - label = "lan4"; + label = "lan1"; }; port@6 { From 58a0211f8201ab622b7b11d31629d6d755bd6526 Mon Sep 17 00:00:00 2001 From: Martin Nadvornik Date: Mon, 15 Dec 2025 16:54:52 +0100 Subject: [PATCH 123/128] mediatek: fix IPv4 address missing on interface in failsafe mode for cudy ap3000-v1 cudy ap3000-v1 did not work correctly in failsafe mode because the address 192.168.1.1 was missing on the eth0 inteface. it was reachable via it's IPv6 link-local address however. this commit fixes the issue. Fixes: https://github.com/openwrt/openwrt/issues/20750 Signed-off-by: Martin Nadvornik Link: https://github.com/openwrt/openwrt/pull/21172 Signed-off-by: Hauke Mehrtens (cherry picked from commit e5cd6461c905184db8f49692f931b20fec4b819e) --- .../linux/mediatek/base-files/lib/preinit/05_set_preinit_iface | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface index 5d8151741d..acfeaf2d4a 100644 --- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface +++ b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface @@ -10,6 +10,7 @@ set_preinit_iface() { ip link set eth1 up ifname=eth1 ;; + cudy,ap3000-v1|\ cudy,ap3000outdoor-v1|\ cudy,re3000-v1|\ ubnt,unifi-6-lr|\ From 0f52a05723988633882d6c52122009ce11f8956b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 17 Dec 2025 00:41:30 +0100 Subject: [PATCH 124/128] dropbear: backport security fixes This fixes the following security problems: CVE-2025-14282: Avoid privilege escalation via unix stream forwarding in Dropbear server. CVE-2019-6111: This allowed a malicious server to overwrite arbitrary local files. This backports two upstream merged PRs: https://github.com/mkj/dropbear/pull/391 https://github.com/mkj/dropbear/pull/394 and this upstream commit: https://github.com/mkj/dropbear/commit/48a17cff6aa104b8e806ddb2191f83f1024060f1 Link: https://github.com/openwrt/openwrt/pull/21192 Signed-off-by: Hauke Mehrtens --- package/network/services/dropbear/Makefile | 2 +- ...privileges-after-user-authentication.patch | 262 ++++++++++++++++++ ...-Remove-return-code-from-login_login.patch | 91 ++++++ ...saved-group-when-dropping-privileges.patch | 260 +++++++++++++++++ ...-Limit-rekey-to-current-hostkey-type.patch | 64 +++++ ...-Restore-seteuid-for-authorized_keys.patch | 41 +++ .../patches/006-scp-CVE-2019-6111-fix.patch | 153 ++++++++++ .../dropbear/patches/110-change_user.patch | 11 +- 8 files changed, 880 insertions(+), 4 deletions(-) create mode 100644 package/network/services/dropbear/patches/001-Drop-privileges-after-user-authentication.patch create mode 100644 package/network/services/dropbear/patches/002-Remove-return-code-from-login_login.patch create mode 100644 package/network/services/dropbear/patches/003-Retain-utmp-saved-group-when-dropping-privileges.patch create mode 100644 package/network/services/dropbear/patches/004-Limit-rekey-to-current-hostkey-type.patch create mode 100644 package/network/services/dropbear/patches/005-Restore-seteuid-for-authorized_keys.patch create mode 100644 package/network/services/dropbear/patches/006-scp-CVE-2019-6111-fix.patch diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index e13b6c2145..dd54c5bc25 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dropbear PKG_VERSION:=2024.86 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ diff --git a/package/network/services/dropbear/patches/001-Drop-privileges-after-user-authentication.patch b/package/network/services/dropbear/patches/001-Drop-privileges-after-user-authentication.patch new file mode 100644 index 0000000000..66830ee81d --- /dev/null +++ b/package/network/services/dropbear/patches/001-Drop-privileges-after-user-authentication.patch @@ -0,0 +1,262 @@ +From 61cfbc66aefcb047534210713f3aac097100e5f5 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 9 Dec 2025 15:08:06 +0900 +Subject: Drop privileges after user authentication + +Instead of switching user privileges after forking to a shell, switch +to the user immediately upon successful authentication. + +This will require further commits to fix utmp and hostkey handling. + +The DROPBEAR_SVR_DROP_PRIVS configuration option controls this +behaviour. This should generally be enabled, but can be set to 0 for +incompatible platforms. In future it may become non-optional, those +platforms should be investigated. + +Most uses of DROPBEAR_SVR_MULTIUSER have been replaced by +!DROPBEAR_SVR_DROP_PRIVS. + +(cherry picked from commit e0251be2354e1a5c6eccfc2cf4b64243625dafcc) +--- + .github/workflows/build.yml | 2 ++ + src/auth.h | 1 + + src/default_options.h | 6 +++++ + src/svr-agentfwd.c | 14 ++++++++---- + src/svr-auth.c | 45 +++++++++++++++++++++++++++++++++++++ + src/svr-authpubkey.c | 6 +++-- + src/svr-chansession.c | 26 ++------------------- + src/sysoptions.h | 3 +++ + 8 files changed, 73 insertions(+), 30 deletions(-) + +--- a/.github/workflows/build.yml ++++ b/.github/workflows/build.yml +@@ -217,6 +217,8 @@ jobs: + echo "#define DROPBEAR_SVR_PASSWORD_AUTH 0" >> localoptions.h + # 1 second timeout is too short + sed -i "s/DEFAULT_IDLE_TIMEOUT 1/DEFAULT_IDLE_TIMEOUT 99/" localoptions.h ++ # DROPBEAR_SVR_DROP_PRIVS is on by default, turn it off ++ echo "#define DROPBEAR_SVR_DROP_PRIVS 0" >> localoptions.h + + - name: make + run: | +--- a/src/auth.h ++++ b/src/auth.h +@@ -40,6 +40,7 @@ void send_msg_userauth_banner(const buff + void svr_auth_password(int valid_user); + void svr_auth_pubkey(int valid_user); + void svr_auth_pam(int valid_user); ++void svr_switch_user(void); + + #if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT + int svr_pubkey_allows_agentfwd(void); +--- a/src/default_options.h ++++ b/src/default_options.h +@@ -297,6 +297,12 @@ group1 in Dropbear server too */ + /* -T server option overrides */ + #define MAX_AUTH_TRIES 10 + ++/* Change server process to user privileges after authentication. */ ++#ifndef DROPBEAR_SVR_DROP_PRIVS ++/* Default is enabled. Should only be disabled if platforms are incompatible */ ++#define DROPBEAR_SVR_DROP_PRIVS DROPBEAR_SVR_MULTIUSER ++#endif ++ + /* Delay introduced before closing an unauthenticated session (seconds). + Disabled by default, can be set to say 30 seconds to reduce the speed + of password brute forcing. Note that there is a risk of denial of +--- a/src/svr-agentfwd.c ++++ b/src/svr-agentfwd.c +@@ -151,7 +151,7 @@ void svr_agentcleanup(struct ChanSess * + + if (chansess->agentfile != NULL && chansess->agentdir != NULL) { + +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + /* Remove the dir as the user. That way they can't cause problems except + * for themselves */ + uid = getuid(); +@@ -160,6 +160,9 @@ void svr_agentcleanup(struct ChanSess * + (seteuid(ses.authstate.pw_uid)) < 0) { + dropbear_exit("Failed to set euid"); + } ++#else ++ (void)uid; ++ (void)gid; + #endif + + /* 2 for "/" and "\0" */ +@@ -172,7 +175,7 @@ void svr_agentcleanup(struct ChanSess * + + rmdir(chansess->agentdir); + +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + if ((seteuid(uid)) < 0 || + (setegid(gid)) < 0) { + dropbear_exit("Failed to revert euid"); +@@ -219,7 +222,7 @@ static int bindagent(int fd, struct Chan + gid_t gid; + int ret = DROPBEAR_FAILURE; + +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + /* drop to user privs to make the dir/file */ + uid = getuid(); + gid = getgid(); +@@ -227,6 +230,9 @@ static int bindagent(int fd, struct Chan + (seteuid(ses.authstate.pw_uid)) < 0) { + dropbear_exit("Failed to set euid"); + } ++#else ++ (void)uid; ++ (void)gid; + #endif + + memset((void*)&addr, 0x0, sizeof(addr)); +@@ -267,7 +273,7 @@ bindsocket: + + + out: +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + if ((seteuid(uid)) < 0 || + (setegid(gid)) < 0) { + dropbear_exit("Failed to revert euid"); +--- a/src/svr-auth.c ++++ b/src/svr-auth.c +@@ -456,12 +456,22 @@ void send_msg_userauth_success() { + /* authdone must be set after encrypt_packet() for + * delayed-zlib mode */ + ses.authstate.authdone = 1; ++ ++#if DROPBEAR_DROP_PRIVS ++ svr_switch_user(); ++#endif + ses.connect_time = 0; + + ++#if DROPBEAR_DROP_PRIVS ++ /* If running as the user, we can rely on the OS ++ * to limit allowed ports */ ++ ses.allowprivport = 1; ++#else + if (ses.authstate.pw_uid == 0) { + ses.allowprivport = 1; + } ++#endif + + /* Remove from the list of pre-auth sockets. Should be m_close(), since if + * we fail, we might end up leaking connection slots, and disallow new +@@ -471,3 +481,38 @@ void send_msg_userauth_success() { + TRACE(("leave send_msg_userauth_success")) + + } ++ ++/* Switch to the ses.authstate user. ++ * Fails if not running as root and the user differs. ++ * ++ * This may be called either after authentication, or ++ * after shell/command fork if DROPBEAR_SVR_DROP_PRIVS is unset. ++ */ ++void svr_switch_user(void) { ++ assert(ses.authstate.authdone); ++ ++ /* We can only change uid/gid as root ... */ ++ if (getuid() == 0) { ++ ++ if ((setgid(ses.authstate.pw_gid) < 0) || ++ (initgroups(ses.authstate.pw_name, ++ ses.authstate.pw_gid) < 0)) { ++ dropbear_exit("Error changing user group"); ++ } ++ if (setuid(ses.authstate.pw_uid) < 0) { ++ dropbear_exit("Error changing user"); ++ } ++ } else { ++ /* ... but if the daemon is the same uid as the requested uid, we don't ++ * need to */ ++ ++ /* XXX - there is a minor issue here, in that if there are multiple ++ * usernames with the same uid, but differing groups, then the ++ * differing groups won't be set (as with initgroups()). The solution ++ * is for the sysadmin not to give out the UID twice */ ++ if (getuid() != ses.authstate.pw_uid) { ++ dropbear_exit("Couldn't change user as non-root"); ++ } ++ } ++} ++ +--- a/src/svr-authpubkey.c ++++ b/src/svr-authpubkey.c +@@ -444,12 +444,14 @@ static int checkpubkey(const char* keyal + buffer * line = NULL; + unsigned int len; + int line_num; ++#if !DROPBEAR_SVR_DROP_PRIVS + uid_t origuid; + gid_t origgid; ++#endif + + TRACE(("enter checkpubkey")) + +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + /* access the file as the authenticating user. */ + origuid = getuid(); + origgid = getgid(); +@@ -476,7 +478,7 @@ static int checkpubkey(const char* keyal + TRACE(("checkpubkey: failed opening %s: %s", filename, strerror(errno))) + } + } +-#if DROPBEAR_SVR_MULTIUSER ++#if !DROPBEAR_SVR_DROP_PRIVS + if ((seteuid(origuid)) < 0 || + (setegid(origgid)) < 0) { + dropbear_exit("Failed to revert euid"); +--- a/src/svr-chansession.c ++++ b/src/svr-chansession.c +@@ -980,30 +980,8 @@ static void execchild(const void *user_d + #endif /* DEBUG_VALGRIND */ + } + +-#if DROPBEAR_SVR_MULTIUSER +- /* We can only change uid/gid as root ... */ +- if (getuid() == 0) { +- +- if ((setgid(ses.authstate.pw_gid) < 0) || +- (initgroups(ses.authstate.pw_name, +- ses.authstate.pw_gid) < 0)) { +- dropbear_exit("Error changing user group"); +- } +- if (setuid(ses.authstate.pw_uid) < 0) { +- dropbear_exit("Error changing user"); +- } +- } else { +- /* ... but if the daemon is the same uid as the requested uid, we don't +- * need to */ +- +- /* XXX - there is a minor issue here, in that if there are multiple +- * usernames with the same uid, but differing groups, then the +- * differing groups won't be set (as with initgroups()). The solution +- * is for the sysadmin not to give out the UID twice */ +- if (getuid() != ses.authstate.pw_uid) { +- dropbear_exit("Couldn't change user as non-root"); +- } +- } ++#if !DROPBEAR_SVR_DROP_PRIVS ++ svr_switch_user(); + #endif + + /* set env vars */ +--- a/src/sysoptions.h ++++ b/src/sysoptions.h +@@ -403,6 +403,9 @@ + #define DROPBEAR_MULTI 0 + #endif + ++#if !DROPBEAR_SVR_MULTIUSER && DROPBEAR_SVR_DROP_PRIVS ++#error DROPBEAR_SVR_DROP_PRIVS needs DROPBEAR_SVR_MULTIUSER ++#endif + /* Fuzzing expects all key types to be enabled */ + #if DROPBEAR_FUZZ + #if defined(DROPBEAR_DSS) diff --git a/package/network/services/dropbear/patches/002-Remove-return-code-from-login_login.patch b/package/network/services/dropbear/patches/002-Remove-return-code-from-login_login.patch new file mode 100644 index 0000000000..9692d16d71 --- /dev/null +++ b/package/network/services/dropbear/patches/002-Remove-return-code-from-login_login.patch @@ -0,0 +1,91 @@ +From febe8493782965b05025b016091a8bffa5d03563 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 9 Dec 2025 09:04:04 +0900 +Subject: Remove return code from login_login + +Previously this was always 0, so not useful. + +(cherry picked from commit b47fe5df58f0b459bb49accdd8cb961d969209fb) +--- + src/loginrec.c | 19 +++++-------------- + src/loginrec.h | 6 +++--- + 2 files changed, 8 insertions(+), 17 deletions(-) + +--- a/src/loginrec.c ++++ b/src/loginrec.c +@@ -193,32 +193,24 @@ int wtmpx_get_entry(struct logininfo *li + * + * Call with a pointer to a struct logininfo initialised with + * login_init_entry() or login_alloc_entry() +- * +- * Returns: +- * >0 if successful +- * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +-int ++void + login_login (struct logininfo *li) + { + li->type = LTYPE_LOGIN; +- return login_write(li); ++ login_write(li); + } + + + /* login_logout(struct logininfo *) - Record a logout + * + * Call as with login_login() +- * +- * Returns: +- * >0 if successful +- * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +-int ++void + login_logout(struct logininfo *li) + { + li->type = LTYPE_LOGOUT; +- return login_write(li); ++ login_write(li); + } + + +@@ -309,7 +301,7 @@ login_set_current_time(struct logininfo + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +-int ++void + login_write (struct logininfo *li) + { + #ifndef HAVE_CYGWIN +@@ -340,7 +332,6 @@ login_write (struct logininfo *li) + #ifdef USE_WTMPX + wtmpx_write_entry(li); + #endif +- return 0; + } + + #ifdef LOGIN_NEEDS_UTMPX +--- a/src/loginrec.h ++++ b/src/loginrec.h +@@ -161,8 +161,8 @@ int login_init_entry(struct logininfo *l + void login_set_current_time(struct logininfo *li); + + /* record the entry */ +-int login_login (struct logininfo *li); +-int login_logout(struct logininfo *li); ++void login_login (struct logininfo *li); ++void login_logout(struct logininfo *li); + #ifdef LOGIN_NEEDS_UTMPX + int login_utmp_only(struct logininfo *li); + #endif +@@ -170,7 +170,7 @@ int login_utmp_only(struct logininfo *li + /** End of public functions */ + + /* record the entry */ +-int login_write (struct logininfo *li); ++void login_write (struct logininfo *li); + int login_log_entry(struct logininfo *li); + + /* produce various forms of the line filename */ diff --git a/package/network/services/dropbear/patches/003-Retain-utmp-saved-group-when-dropping-privileges.patch b/package/network/services/dropbear/patches/003-Retain-utmp-saved-group-when-dropping-privileges.patch new file mode 100644 index 0000000000..99c9dc5b7a --- /dev/null +++ b/package/network/services/dropbear/patches/003-Retain-utmp-saved-group-when-dropping-privileges.patch @@ -0,0 +1,260 @@ +From b20e7823a0c6a4480aa473e0a46d3ccab4b9b102 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 9 Dec 2025 09:05:30 +0900 +Subject: Retain utmp saved group when dropping privileges + +utmp is required to record logout. The saved group +is reset by the OS for the executed user shell. + +This requires setresgid() function which is not available on all +platforms. Notable platforms are netbsd and macos. Those platforms will +have to set DROPBEAR_SVR_DROP_PRIVS 0 unless an alternative approach is +found. + +(cherry picked from commit 73e4e70ea8e6b890c3918b52bb2e647313a09faa) +--- + .github/workflows/build.yml | 6 ++++ + configure | 7 +++++ + configure.ac | 1 + + src/auth.h | 2 ++ + src/config.h.in | 3 ++ + src/loginrec.c | 6 ---- + src/session.h | 6 ++++ + src/svr-auth.c | 61 +++++++++++++++++++++++++++++++++++-- + src/svr-chansession.c | 8 +++++ + src/sysoptions.h | 4 +++ + 10 files changed, 96 insertions(+), 8 deletions(-) + +--- a/.github/workflows/build.yml ++++ b/.github/workflows/build.yml +@@ -72,6 +72,9 @@ jobs: + # fails with: + # .../ranlib: file: libtomcrypt.a(cbc_setiv.o) has no symbols + ranlib: ranlib -no_warning_for_no_symbols ++ # macos doesn't have setresgid ++ localoptions: | ++ #define DROPBEAR_SVR_DROP_PRIVS 0 + + - name: macos 15 + os: macos-15 +@@ -84,6 +87,9 @@ jobs: + # fails with: + # .../ranlib: file: libtomcrypt.a(cbc_setiv.o) has no symbols + ranlib: ranlib -no_warning_for_no_symbols ++ # macos doesn't have setresgid ++ localoptions: | ++ #define DROPBEAR_SVR_DROP_PRIVS 0 + + # Check that debug code doesn't bitrot + - name: DEBUG_TRACE +--- a/configure ++++ b/configure +@@ -7597,6 +7597,13 @@ then : + + fi + ++ac_fn_c_check_func "$LINENO" "setresgid" "ac_cv_func_setresgid" ++if test "x$ac_cv_func_setresgid" = xyes ++then : ++ printf "%s\n" "#define HAVE_SETRESGID 1" >>confdefs.h ++ ++fi ++ + + # POSIX monotonic time + ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +--- a/configure.ac ++++ b/configure.ac +@@ -545,6 +545,7 @@ AC_CHECK_FUNCS(utmpname) + AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) + AC_CHECK_FUNCS(setutxent utmpxname) + AC_CHECK_FUNCS(logout updwtmp logwtmp) ++AC_CHECK_FUNCS(setresgid) + + # POSIX monotonic time + AC_CHECK_FUNCS(clock_gettime) +--- a/src/auth.h ++++ b/src/auth.h +@@ -41,6 +41,8 @@ void svr_auth_password(int valid_user); + void svr_auth_pubkey(int valid_user); + void svr_auth_pam(int valid_user); + void svr_switch_user(void); ++void svr_raise_gid_utmp(void); ++void svr_restore_gid(void); + + #if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT + int svr_pubkey_allows_agentfwd(void); +--- a/src/config.h.in ++++ b/src/config.h.in +@@ -222,6 +222,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_SECURITY_PAM_APPL_H + ++/* Define to 1 if you have the `setresgid' function. */ ++#undef HAVE_SETRESGID ++ + /* Define to 1 if you have the `setutent' function. */ + #undef HAVE_SETUTENT + +--- a/src/loginrec.c ++++ b/src/loginrec.c +@@ -304,12 +304,6 @@ login_set_current_time(struct logininfo + void + login_write (struct logininfo *li) + { +-#ifndef HAVE_CYGWIN +- if ((int)geteuid() != 0) { +- return 1; +- } +-#endif +- + /* set the timestamp */ + login_set_current_time(li); + #ifdef USE_LOGIN +--- a/src/session.h ++++ b/src/session.h +@@ -271,6 +271,12 @@ struct serversession { + /* The instance created by the plugin_new function */ + struct PluginInstance *plugin_instance; + #endif ++ ++#if DROPBEAR_SVR_DROP_PRIVS ++ /* Set to 1 when utmp_gid is valid */ ++ int have_utmp_gid; ++ gid_t utmp_gid; ++#endif + }; + + typedef enum { +--- a/src/svr-auth.c ++++ b/src/svr-auth.c +@@ -457,13 +457,14 @@ void send_msg_userauth_success() { + * delayed-zlib mode */ + ses.authstate.authdone = 1; + +-#if DROPBEAR_DROP_PRIVS ++#if DROPBEAR_SVR_DROP_PRIVS ++ /* Drop privileges as soon as authentication has happened. */ + svr_switch_user(); + #endif + ses.connect_time = 0; + + +-#if DROPBEAR_DROP_PRIVS ++#if DROPBEAR_SVR_DROP_PRIVS + /* If running as the user, we can rely on the OS + * to limit allowed ports */ + ses.allowprivport = 1; +@@ -482,6 +483,20 @@ void send_msg_userauth_success() { + + } + ++#if DROPBEAR_SVR_DROP_PRIVS ++/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ ++static int utmp_gid(gid_t *ret_gid) { ++ struct group *utmp_gr = getgrnam("utmp"); ++ if (!utmp_gr) { ++ TRACE(("No utmp group")); ++ return DROPBEAR_FAILURE; ++ } ++ ++ *ret_gid = utmp_gr->gr_gid; ++ return DROPBEAR_SUCCESS; ++} ++#endif ++ + /* Switch to the ses.authstate user. + * Fails if not running as root and the user differs. + * +@@ -499,6 +514,25 @@ void svr_switch_user(void) { + ses.authstate.pw_gid) < 0)) { + dropbear_exit("Error changing user group"); + } ++ ++#if DROPBEAR_SVR_DROP_PRIVS ++ /* Retain utmp saved group so that wtmp/utmp can be written */ ++ int ret = utmp_gid(&svr_ses.utmp_gid); ++ if (ret == DROPBEAR_SUCCESS) { ++ /* Set saved gid to utmp so that it can be ++ * restored for login_logout() etc. This saved ++ * group is cleared by the OS on execve() */ ++ int rc = setresgid(-1, -1, svr_ses.utmp_gid); ++ if (rc == 0) { ++ svr_ses.have_utmp_gid = 1; ++ } else { ++ /* Will not attempt to switch to utmp gid. ++ * login() etc may fail. */ ++ TRACE(("utmp setresgid failed")); ++ } ++ } ++#endif ++ + if (setuid(ses.authstate.pw_uid) < 0) { + dropbear_exit("Error changing user"); + } +@@ -516,3 +550,26 @@ void svr_switch_user(void) { + } + } + ++void svr_raise_gid_utmp(void) { ++#if DROPBEAR_SVR_DROP_PRIVS ++ if (!svr_ses.have_utmp_gid) { ++ return; ++ } ++ ++ if (setegid(svr_ses.utmp_gid) != 0) { ++ dropbear_log(LOG_WARNING, "failed setegid"); ++ } ++#endif ++} ++ ++void svr_restore_gid(void) { ++#if DROPBEAR_SVR_DROP_PRIVS ++ if (!svr_ses.have_utmp_gid) { ++ return; ++ } ++ ++ if (setegid(getgid()) != 0) { ++ dropbear_log(LOG_WARNING, "failed setegid"); ++ } ++#endif ++} +--- a/src/svr-chansession.c ++++ b/src/svr-chansession.c +@@ -326,7 +326,11 @@ static void cleanupchansess(const struct + if (chansess->tty) { + /* write the utmp/wtmp login record */ + li = chansess_login_alloc(chansess); ++ ++ svr_raise_gid_utmp(); + login_logout(li); ++ svr_restore_gid(); ++ + login_free_entry(li); + + pty_release(chansess->tty); +@@ -847,7 +851,11 @@ static int ptycommand(struct Channel *ch + * terminal used for stdout with the dup2 above, otherwise + * the wtmp login will not be recorded */ + li = chansess_login_alloc(chansess); ++ ++ svr_raise_gid_utmp(); + login_login(li); ++ svr_restore_gid(); ++ + login_free_entry(li); + + /* Can now dup2 stderr. Messages from login_login() have gone +--- a/src/sysoptions.h ++++ b/src/sysoptions.h +@@ -318,6 +318,10 @@ + #error "At least one hostkey or public-key algorithm must be enabled; RSA is recommended." + #endif + ++#if DROPBEAR_SVR_DROP_PRIVS && !defined(HAVE_SETRESGID) ++ #error "DROPBEAR_SVR_DROP_PRIVS requires setresgid()." ++#endif ++ + /* Source for randomness. This must be able to provide hundreds of bytes per SSH + * connection without blocking. */ + #ifndef DROPBEAR_URANDOM_DEV diff --git a/package/network/services/dropbear/patches/004-Limit-rekey-to-current-hostkey-type.patch b/package/network/services/dropbear/patches/004-Limit-rekey-to-current-hostkey-type.patch new file mode 100644 index 0000000000..f5e455595b --- /dev/null +++ b/package/network/services/dropbear/patches/004-Limit-rekey-to-current-hostkey-type.patch @@ -0,0 +1,64 @@ +From ae7f99902161237542f2c71089ff68b8f694006b Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 9 Dec 2025 09:08:37 +0900 +Subject: Limit rekey to current hostkey type + +During rekey dropbear process may be running with user privileges, that +can't write a new hostkey when auto-generating keys. +Only offer the original hostkey when rekeying, also for non-autogenerate +case. + +(cherry picked from commit a4043dac4e0e0237255200603672ddb0122017a4) +--- + src/runopts.h | 1 + + src/svr-kex.c | 8 ++++++++ + src/svr-runopts.c | 11 +++++++++++ + 3 files changed, 20 insertions(+) + +--- a/src/runopts.h ++++ b/src/runopts.h +@@ -66,6 +66,7 @@ extern runopts opts; + int readhostkey(const char * filename, sign_key * hostkey, + enum signkey_type *type); + void load_all_hostkeys(void); ++void disable_sig_except(enum signature_type sig_type); + + typedef struct svr_runopts { + +--- a/src/svr-kex.c ++++ b/src/svr-kex.c +@@ -96,6 +96,14 @@ void recv_msg_kexdh_init() { + } + #endif + ++ if (!ses.kexstate.donesecondkex) { ++ /* Disable other signature types. ++ * During future rekeying, privileges may have been dropped ++ * so other keys won't be loadable. ++ * This must occur after send_msg_ext_info() which uses the hostkey list */ ++ disable_sig_except(ses.newkeys->algo_signature); ++ } ++ + ses.requirenext = SSH_MSG_NEWKEYS; + TRACE(("leave recv_msg_kexdh_init")) + } +--- a/src/svr-runopts.c ++++ b/src/svr-runopts.c +@@ -502,6 +502,17 @@ static void disablekey(enum signature_ty + } + } + ++void disable_sig_except(enum signature_type allow_type) { ++ int i; ++ TRACE(("Disabling other sigs except %d", allow_type)); ++ for (i = 0; sigalgs[i].name != NULL; i++) { ++ enum signature_type sig_type = sigalgs[i].val; ++ if (sig_type != allow_type) { ++ sigalgs[i].usable = 0; ++ } ++ } ++} ++ + static void loadhostkey_helper(const char *name, void** src, void** dst, int fatal_duplicate) { + if (*dst) { + if (fatal_duplicate) { diff --git a/package/network/services/dropbear/patches/005-Restore-seteuid-for-authorized_keys.patch b/package/network/services/dropbear/patches/005-Restore-seteuid-for-authorized_keys.patch new file mode 100644 index 0000000000..bef5948fb0 --- /dev/null +++ b/package/network/services/dropbear/patches/005-Restore-seteuid-for-authorized_keys.patch @@ -0,0 +1,41 @@ +From 3e487854fcf09a5ef57a620ebe606f586a6efdc3 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Fri, 12 Dec 2025 12:31:40 +0900 +Subject: Restore seteuid for authorized_keys + +Authorized_keys reading is pre-authentication so should not be +modified in the post-auth drop-privilege change. + +Fixes: e0251be2354e ("Drop privileges after user authentication") +(cherry picked from commit d193731630a62482855b450daa1d5a5e13a90125) +--- + src/svr-authpubkey.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/src/svr-authpubkey.c ++++ b/src/svr-authpubkey.c +@@ -444,14 +444,12 @@ static int checkpubkey(const char* keyal + buffer * line = NULL; + unsigned int len; + int line_num; +-#if !DROPBEAR_SVR_DROP_PRIVS + uid_t origuid; + gid_t origgid; +-#endif + + TRACE(("enter checkpubkey")) + +-#if !DROPBEAR_SVR_DROP_PRIVS ++#if DROPBEAR_SVR_MULTIUSER + /* access the file as the authenticating user. */ + origuid = getuid(); + origgid = getgid(); +@@ -478,7 +476,7 @@ static int checkpubkey(const char* keyal + TRACE(("checkpubkey: failed opening %s: %s", filename, strerror(errno))) + } + } +-#if !DROPBEAR_SVR_DROP_PRIVS ++#if DROPBEAR_SVR_MULTIUSER + if ((seteuid(origuid)) < 0 || + (setegid(origgid)) < 0) { + dropbear_exit("Failed to revert euid"); diff --git a/package/network/services/dropbear/patches/006-scp-CVE-2019-6111-fix.patch b/package/network/services/dropbear/patches/006-scp-CVE-2019-6111-fix.patch new file mode 100644 index 0000000000..5cbcbd96ba --- /dev/null +++ b/package/network/services/dropbear/patches/006-scp-CVE-2019-6111-fix.patch @@ -0,0 +1,153 @@ +From 5938a084b0aad887c0f7fa62bf3644d029e4d47d Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 9 Dec 2025 22:59:19 +0900 +Subject: scp CVE-2019-6111 fix + +Cherry-pick from OpenSSH portable + +391ffc4b9d31 ("upstream: check in scp client that filenames sent during") + +upstream: check in scp client that filenames sent during + +remote->local directory copies satisfy the wildcard specified by the user. + +This checking provides some protection against a malicious server +sending unexpected filenames, but it comes at a risk of rejecting wanted +files due to differences between client and server wildcard expansion rules. + +For this reason, this also adds a new -T flag to disable the check. + +reported by Harry Sintonen +fix approach suggested by markus@; +has been in snaps for ~1wk courtesy deraadt@ + +(cherry picked from commit 48a17cff6aa104b8e806ddb2191f83f1024060f1) +--- + src/scp.c | 38 +++++++++++++++++++++++++++++--------- + 1 file changed, 29 insertions(+), 9 deletions(-) + +--- a/src/scp.c ++++ b/src/scp.c +@@ -76,6 +76,8 @@ + #include "includes.h" + /*RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");*/ + ++#include ++ + #include "atomicio.h" + #include "compat.h" + #include "scpmisc.h" +@@ -291,14 +293,14 @@ void verifydir(char *); + + uid_t userid; + int errs, remin, remout; +-int pflag, iamremote, iamrecursive, targetshouldbedirectory; ++int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory; + + #define CMDNEEDS 64 + char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ + + int response(void); + void rsource(char *, struct stat *); +-void sink(int, char *[]); ++void sink(int, char *[], const char *); + void source(int, char *[]); + void tolocal(int, char *[]); + void toremote(char *, int, char *[]); +@@ -325,8 +327,8 @@ main(int argc, char **argv) + args.list = NULL; + addargs(&args, "%s", ssh_program); + +- fflag = tflag = 0; +- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) ++ fflag = Tflag = tflag = 0; ++ while ((ch = getopt(argc, argv, "dfl:prtTvBCc:i:P:q1246S:o:F:")) != -1) + switch (ch) { + /* User-visible flags. */ + case '1': +@@ -389,9 +391,12 @@ main(int argc, char **argv) + setmode(0, O_BINARY); + #endif + break; ++ case 'T': ++ Tflag = 1; ++ break; + default: + usage(); +- } ++ } + argc -= optind; + argv += optind; + +@@ -409,7 +414,7 @@ main(int argc, char **argv) + } + if (tflag) { + /* Receive data. */ +- sink(argc, argv); ++ sink(argc, argv, NULL); + exit(errs != 0); + } + if (argc < 2) +@@ -589,7 +594,7 @@ tolocal(int argc, char **argv) + continue; + } + xfree(bp); +- sink(1, argv + argc - 1); ++ sink(1, argv + argc - 1, src); + (void) close(remin); + remin = remout = -1; + } +@@ -822,7 +827,7 @@ bwlimit(int amount) + } + + void +-sink(int argc, char **argv) ++sink(int argc, char **argv, const char *src) + { + static BUF buffer; + struct stat stb; +@@ -836,6 +841,7 @@ sink(int argc, char **argv) + off_t size, statbytes; + int setimes, targisdir, wrerrno = 0; + char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; ++ char *src_copy = NULL, *restrict_pattern = NULL; + struct timeval tv[2]; + + #define atime tv[0] +@@ -857,6 +863,17 @@ sink(int argc, char **argv) + (void) atomicio(vwrite, remout, "", 1); + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) + targisdir = 1; ++ if (src != NULL && !iamrecursive && !Tflag) { ++ /* ++ * Prepare to try to restrict incoming filenames to match ++ * the requested destination file glob. ++ */ ++ if ((src_copy = strdup(src)) == NULL) ++ fatal("strdup failed"); ++ if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) { ++ *restrict_pattern++ = '\0'; ++ } ++ } + for (first = 1;; first = 0) { + cp = buf; + if (atomicio(read, remin, cp, 1) != 1) +@@ -939,6 +956,9 @@ sink(int argc, char **argv) + run_err("error: unexpected filename: %s", cp); + exit(1); + } ++ if (restrict_pattern != NULL && ++ fnmatch(restrict_pattern, cp, 0) != 0) ++ SCREWUP("filename does not match request"); + if (targisdir) { + static char *namebuf = NULL; + static size_t cursize = 0; +@@ -977,7 +997,7 @@ sink(int argc, char **argv) + goto bad; + } + vect[0] = xstrdup(np); +- sink(1, vect); ++ sink(1, vect, src); + if (setimes) { + setimes = 0; + if (utimes(vect[0], tv) < 0) diff --git a/package/network/services/dropbear/patches/110-change_user.patch b/package/network/services/dropbear/patches/110-change_user.patch index 9ef8f0cfbc..5fbcd663bc 100644 --- a/package/network/services/dropbear/patches/110-change_user.patch +++ b/package/network/services/dropbear/patches/110-change_user.patch @@ -1,6 +1,6 @@ ---- a/src/svr-chansession.c -+++ b/src/svr-chansession.c -@@ -984,12 +984,12 @@ static void execchild(const void *user_d +--- a/src/svr-auth.c ++++ b/src/svr-auth.c +@@ -509,9 +509,9 @@ void svr_switch_user(void) { /* We can only change uid/gid as root ... */ if (getuid() == 0) { @@ -11,6 +11,11 @@ + ses.authstate.pw_gid) < 0))) { dropbear_exit("Error changing user group"); } + +@@ -533,7 +533,7 @@ void svr_switch_user(void) { + } + #endif + - if (setuid(ses.authstate.pw_uid) < 0) { + if ((ses.authstate.pw_uid != 0) && (setuid(ses.authstate.pw_uid) < 0)) { dropbear_exit("Error changing user"); From e382fc552a5afaa18e98b8971cf515c1e7ef5248 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 25 Oct 2025 22:44:22 +0200 Subject: [PATCH 125/128] wireless-regdb: Update to version 2025.10.07 e51d568 wireless-regdb: update regulatory rules for Botswana (BW) for 2022 5afc632 wireless-regdb: update regulatory rules for Sint Marteen (SX) for 2018 b484a31 wireless-regdb: Update regulatory info including bandwidth for Costa Rica (CR) for 2023 39e5e04 wireless-regdb: Permit lower 6 GHz band for Kazakhstan (KZ) a827d3a wireless-regdb: update regulatory database based on preceding changes Link: https://github.com/openwrt/openwrt/pull/20544 Signed-off-by: Hauke Mehrtens (cherry picked from commit b4a8ba2e88681af12287eea2d18c4f7de25e280e) --- package/firmware/wireless-regdb/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireless-regdb/Makefile index d45c95e5e3..25382eb656 100644 --- a/package/firmware/wireless-regdb/Makefile +++ b/package/firmware/wireless-regdb/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wireless-regdb -PKG_VERSION:=2025.07.10 +PKG_VERSION:=2025.10.07 PKG_RELEASE:=1 PKG_LICENSE:=ISC PKG_LICENSE_FILES:=LICENSE PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@KERNEL/software/network/wireless-regdb/ -PKG_HASH:=a8340bcdcd1b5db6c79149879d122b170f3bb075381718d4f429ad831a6fa28d +PKG_HASH:=d4c872a44154604c869f5851f7d21d818d492835d370af7f58de8847973801c3 PKG_MAINTAINER:=Felix Fietkau From d9c5716d1d75e652d57b42a514b20145a24eee18 Mon Sep 17 00:00:00 2001 From: Markus Petri Date: Thu, 4 Dec 2025 21:28:51 +0100 Subject: [PATCH 126/128] vrx518_tc: fix rx_len_adj Fix rx_len_adj to avoid leaking the ethernet FCS into the actual frame data in single line mode (the default) Fixes: https://github.com/openwrt/openwrt/issues/20983 Signed-off-by: Markus Petri Link: https://github.com/openwrt/openwrt/pull/21045 Signed-off-by: Hauke Mehrtens (cherry picked from commit 487178f8b003bf2e06b9f989b46f8b5c36181910) --- .../patches/208-dcdp-ptm_tc-fix-rx_len_adj.patch | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 package/kernel/lantiq/vrx518_tc/patches/208-dcdp-ptm_tc-fix-rx_len_adj.patch diff --git a/package/kernel/lantiq/vrx518_tc/patches/208-dcdp-ptm_tc-fix-rx_len_adj.patch b/package/kernel/lantiq/vrx518_tc/patches/208-dcdp-ptm_tc-fix-rx_len_adj.patch new file mode 100644 index 0000000000..855da162c3 --- /dev/null +++ b/package/kernel/lantiq/vrx518_tc/patches/208-dcdp-ptm_tc-fix-rx_len_adj.patch @@ -0,0 +1,14 @@ +Fixes leaking the ethernet FCS into the frame payload on the RX +path. + +--- a/dcdp/ptm_tc.c ++++ b/dcdp/ptm_tc.c +@@ -923,7 +923,7 @@ static void ptm_fw_init(struct ptm_ep_pr + rx_gitf_cfg.rx_inserted_bytes_1h = 0; + rx_gitf_cfg.rx_inserted_bytes_2l = 0; + rx_gitf_cfg.rx_inserted_bytes_2h = 0; +- rx_gitf_cfg.rx_len_adj = -2; ++ rx_gitf_cfg.rx_len_adj = is_bonding ? -2 : -6; + for (i = 0; i < 4; i++) { + dst_addr = __RX_GIF0_CFG_STATS_CFG + + (i * DW_SZ(rx_gitf_cfg)); From 4f7e6e554be2aef6a55be36f9f954d56705eb2ee Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 18 Dec 2025 21:39:34 +0100 Subject: [PATCH 127/128] OpenWrt v24.10.5: adjust config defaults Signed-off-by: Hauke Mehrtens --- feeds.conf.default | 8 ++++---- include/version.mk | 6 +++--- package/base-files/image-config.in | 4 ++-- version | 1 + version.date | 1 + 5 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 version create mode 100644 version.date diff --git a/feeds.conf.default b/feeds.conf.default index 581de056c4..6ecfb632aa 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,4 +1,4 @@ -src-git packages https://git.openwrt.org/feed/packages.git;openwrt-24.10 -src-git luci https://git.openwrt.org/project/luci.git;openwrt-24.10 -src-git routing https://git.openwrt.org/feed/routing.git;openwrt-24.10 -src-git telephony https://git.openwrt.org/feed/telephony.git;openwrt-24.10 +src-git packages https://git.openwrt.org/feed/packages.git^953b6d47b4e9f0ad3c39547c6d3f9a828f10e206 +src-git luci https://git.openwrt.org/project/luci.git^d88390be4ec9722cb427fee03368fc8c8582627d +src-git routing https://git.openwrt.org/feed/routing.git^178a40d321d6c11f18528f34777f4e24ce62b19a +src-git telephony https://git.openwrt.org/feed/telephony.git^92892fa285360b8981f62bf4e0a097e6449e7e33 diff --git a/include/version.mk b/include/version.mk index a6ebe58779..90cfa76bce 100644 --- a/include/version.mk +++ b/include/version.mk @@ -23,13 +23,13 @@ PKG_CONFIG_DEPENDS += \ sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1)))) VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER)) -VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),24.10-SNAPSHOT) +VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),24.10.5) VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE)) -VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION)) +VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),r29087-d9c5716d1d) VERSION_REPO:=$(call qstrip,$(CONFIG_VERSION_REPO)) -VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/releases/24.10-SNAPSHOT) +VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/releases/24.10.5) VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST)) VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),OpenWrt) diff --git a/package/base-files/image-config.in b/package/base-files/image-config.in index 80db993d46..cff98b426c 100644 --- a/package/base-files/image-config.in +++ b/package/base-files/image-config.in @@ -190,7 +190,7 @@ if VERSIONOPT config VERSION_REPO string prompt "Release repository" - default "https://downloads.openwrt.org/releases/24.10-SNAPSHOT" + default "https://downloads.openwrt.org/releases/24.10.5" help This is the repository address embedded in the image, it defaults to the trunk snapshot repo; the url may contain the following placeholders: @@ -266,7 +266,7 @@ if VERSIONOPT config VERSION_CODE_FILENAMES bool prompt "Revision code in filenames" - default y + default n help Enable this to include the revision identifier or the configured version code into the firmware image, SDK- and Image Builder archive diff --git a/version b/version new file mode 100644 index 0000000000..4c09a7d50c --- /dev/null +++ b/version @@ -0,0 +1 @@ +r29087-d9c5716d1d diff --git a/version.date b/version.date new file mode 100644 index 0000000000..6b018de5d1 --- /dev/null +++ b/version.date @@ -0,0 +1 @@ +1766005702 From 4919ffd4f715fb31efd3e5aa28571e873200d03a Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 18 Dec 2025 21:39:37 +0100 Subject: [PATCH 128/128] OpenWrt v24.10.5: revert to branch defaults Signed-off-by: Hauke Mehrtens --- feeds.conf.default | 8 ++++---- include/version.mk | 6 +++--- package/base-files/image-config.in | 4 ++-- version | 1 - version.date | 1 - 5 files changed, 9 insertions(+), 11 deletions(-) delete mode 100644 version delete mode 100644 version.date diff --git a/feeds.conf.default b/feeds.conf.default index 6ecfb632aa..581de056c4 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,4 +1,4 @@ -src-git packages https://git.openwrt.org/feed/packages.git^953b6d47b4e9f0ad3c39547c6d3f9a828f10e206 -src-git luci https://git.openwrt.org/project/luci.git^d88390be4ec9722cb427fee03368fc8c8582627d -src-git routing https://git.openwrt.org/feed/routing.git^178a40d321d6c11f18528f34777f4e24ce62b19a -src-git telephony https://git.openwrt.org/feed/telephony.git^92892fa285360b8981f62bf4e0a097e6449e7e33 +src-git packages https://git.openwrt.org/feed/packages.git;openwrt-24.10 +src-git luci https://git.openwrt.org/project/luci.git;openwrt-24.10 +src-git routing https://git.openwrt.org/feed/routing.git;openwrt-24.10 +src-git telephony https://git.openwrt.org/feed/telephony.git;openwrt-24.10 diff --git a/include/version.mk b/include/version.mk index 90cfa76bce..a6ebe58779 100644 --- a/include/version.mk +++ b/include/version.mk @@ -23,13 +23,13 @@ PKG_CONFIG_DEPENDS += \ sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1)))) VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER)) -VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),24.10.5) +VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),24.10-SNAPSHOT) VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE)) -VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),r29087-d9c5716d1d) +VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION)) VERSION_REPO:=$(call qstrip,$(CONFIG_VERSION_REPO)) -VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/releases/24.10.5) +VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/releases/24.10-SNAPSHOT) VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST)) VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),OpenWrt) diff --git a/package/base-files/image-config.in b/package/base-files/image-config.in index cff98b426c..80db993d46 100644 --- a/package/base-files/image-config.in +++ b/package/base-files/image-config.in @@ -190,7 +190,7 @@ if VERSIONOPT config VERSION_REPO string prompt "Release repository" - default "https://downloads.openwrt.org/releases/24.10.5" + default "https://downloads.openwrt.org/releases/24.10-SNAPSHOT" help This is the repository address embedded in the image, it defaults to the trunk snapshot repo; the url may contain the following placeholders: @@ -266,7 +266,7 @@ if VERSIONOPT config VERSION_CODE_FILENAMES bool prompt "Revision code in filenames" - default n + default y help Enable this to include the revision identifier or the configured version code into the firmware image, SDK- and Image Builder archive diff --git a/version b/version deleted file mode 100644 index 4c09a7d50c..0000000000 --- a/version +++ /dev/null @@ -1 +0,0 @@ -r29087-d9c5716d1d diff --git a/version.date b/version.date deleted file mode 100644 index 6b018de5d1..0000000000 --- a/version.date +++ /dev/null @@ -1 +0,0 @@ -1766005702