diff --git a/config/Config-kernel.in b/config/Config-kernel.in index f1ee919ee3..34c606a848 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -1108,6 +1108,22 @@ config KERNEL_NET_L3_MASTER_DEV This module provides glue between core networking code and device drivers to support L3 master devices like VRF. +config KERNEL_WIRELESS_EXT + def_bool n + +config KERNEL_WEXT_CORE + def_bool KERNEL_WIRELESS_EXT + +config KERNEL_WEXT_PRIV + def_bool KERNEL_WIRELESS_EXT + +config KERNEL_WEXT_PROC + def_bool KERNEL_WIRELESS_EXT + +config KERNEL_WEXT_SPY + def_bool KERNEL_WIRELESS_EXT + + # # NFS related symbols # diff --git a/include/kernel-5.10 b/include/kernel-5.10 index f5dff37bda..3dee01cdcf 100644 --- a/include/kernel-5.10 +++ b/include/kernel-5.10 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.10 = .143 -LINUX_KERNEL_HASH-5.10.143 = fa2c9edef272d39dca52e057e1d41433cf1b6ab6a00d24a00333c0b735054e91 +LINUX_VERSION-5.10 = .144 +LINUX_KERNEL_HASH-5.10.144 = 20c6d26f4d9d0d15d628982bc5e35862b3016d1832f5a545b3bdb131203cd3ca diff --git a/include/kernel-5.15 b/include/kernel-5.15 index 8aaf057ce4..1d10e56bb2 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .68 -LINUX_KERNEL_HASH-5.15.68 = 17bbb3cb5c9ba18583b6679cc28f828aec49c72abbfc6fbde310b0cb17218b7e +LINUX_VERSION-5.15 = .69 +LINUX_KERNEL_HASH-5.15.69 = e32839ca761e5251f25708f7939b37b101d28fc29515a97bfc0c838a21efdf34 diff --git a/package/base-files/files/lib/functions/uci-defaults.sh b/package/base-files/files/lib/functions/uci-defaults.sh index 4f5b9634bb..86f16b5125 100644 --- a/package/base-files/files/lib/functions/uci-defaults.sh +++ b/package/base-files/files/lib/functions/uci-defaults.sh @@ -96,7 +96,7 @@ ucidef_set_interfaces_lan_wan() { ucidef_set_bridge_device() { json_select_object bridge - json_add_string name "${1:switch0}" + json_add_string name "${1:-switch0}" json_select .. } diff --git a/package/boot/arm-trusted-firmware-mvebu/Makefile b/package/boot/arm-trusted-firmware-mvebu/Makefile index dba4836a6b..3b7fd7a7cc 100644 --- a/package/boot/arm-trusted-firmware-mvebu/Makefile +++ b/package/boot/arm-trusted-firmware-mvebu/Makefile @@ -108,12 +108,12 @@ TFA_TARGETS:= \ udpu TFA_MAKE_FLAGS += \ - CROSS_CM3=$(STAGING_DIR_IMAGE)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION)/bin/arm-none-eabi- \ + CROSS_CM3=$(BUILD_DIR)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION)/bin/arm-none-eabi- \ BL33=$(STAGING_DIR_IMAGE)/$(UBOOT)-u-boot.bin \ - MV_DDR_PATH=$(STAGING_DIR_IMAGE)/$(MV_DDR_NAME) \ - WTP=$(STAGING_DIR_IMAGE)/$(A3700_UTILS_NAME) \ - WTMI_IMG=$(STAGING_DIR_IMAGE)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE)/wtmi_app.bin \ - CRYPTOPP_PATH=$(STAGING_DIR_IMAGE)/$(CRYPTOPP_NAME) \ + MV_DDR_PATH=$(BUILD_DIR)/$(MV_DDR_NAME) \ + WTP=$(BUILD_DIR)/$(A3700_UTILS_NAME) \ + WTMI_IMG=$(BUILD_DIR)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE)/wtmi_app.bin \ + CRYPTOPP_PATH=$(BUILD_DIR)/$(CRYPTOPP_NAME) \ USE_COHERENT_MEM=0 \ FIP_ALIGN=0x100 \ DDR_TOPOLOGY=$(DDR_TOPOLOGY) \ @@ -190,11 +190,11 @@ endef define Build/Clean rm -rf \ - $(STAGING_DIR_IMAGE)/$(CRYPTOPP_NAME) \ - $(STAGING_DIR_IMAGE)/$(A3700_UTILS_NAME) \ - $(STAGING_DIR_IMAGE)/$(MV_DDR_NAME) \ - $(STAGING_DIR_IMAGE)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE) \ - $(STAGING_DIR_IMAGE)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION) + $(BUILD_DIR)/$(CRYPTOPP_NAME) \ + $(BUILD_DIR)/$(A3700_UTILS_NAME) \ + $(BUILD_DIR)/$(MV_DDR_NAME) \ + $(BUILD_DIR)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE) \ + $(BUILD_DIR)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION) endef define Build/Prepare @@ -207,23 +207,22 @@ define Build/Prepare $(call Build/Prepare/Default,) - mkdir -p $(STAGING_DIR_IMAGE) - $(TAR) -C $(STAGING_DIR_IMAGE) -xf $(DL_DIR)/$(CRYPTOPP_SOURCE) - $(TAR) -C $(STAGING_DIR_IMAGE) -xf $(DL_DIR)/$(A3700_UTILS_SOURCE) - $(call PatchDir/Default,$(STAGING_DIR_IMAGE)/$(A3700_UTILS_NAME),./patches-a3700-utils) - $(TAR) -C $(STAGING_DIR_IMAGE) -xf $(DL_DIR)/$(MV_DDR_SOURCE) - $(call PatchDir/Default,$(STAGING_DIR_IMAGE)/$(MV_DDR_NAME),./patches-mv-ddr-marvell) - $(TAR) -C $(STAGING_DIR_IMAGE) -xf $(DL_DIR)/$(MOX_BB_SOURCE) - $(call PatchDir/Default,$(STAGING_DIR_IMAGE)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE),./patches-mox-boot-builder) - $(TAR) -C $(STAGING_DIR_IMAGE) -xf $(DL_DIR)/$(CM3_GCC_SOURCE) + $(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(CRYPTOPP_SOURCE) + $(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(A3700_UTILS_SOURCE) + $(call PatchDir/Default,$(BUILD_DIR)/$(A3700_UTILS_NAME),./patches-a3700-utils) + $(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(MV_DDR_SOURCE) + $(call PatchDir/Default,$(BUILD_DIR)/$(MV_DDR_NAME),./patches-mv-ddr-marvell) + $(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(MOX_BB_SOURCE) + $(call PatchDir/Default,$(BUILD_DIR)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE),./patches-mox-boot-builder) + $(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(CM3_GCC_SOURCE) endef define Build/Compile +$(MAKE) \ - CROSS_CM3=$(STAGING_DIR_IMAGE)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION)/bin/arm-none-eabi- \ + CROSS_CM3=$(BUILD_DIR)/$(CM3_GCC_NAME)-$(CM3_GCC_RELEASE)-$(CM3_GCC_VERSION)/bin/arm-none-eabi- \ WTMI_VERSION=$(MOX_BB_RELEASE) \ CRYPTOPP_PATH=$PWD/cryptopp/ \ - -C $(STAGING_DIR_IMAGE)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE) \ + -C $(BUILD_DIR)/$(MOX_BB_NAME)-$(MOX_BB_RELEASE) \ wtmi_app.bin $(call Build/Compile/Default) endef diff --git a/package/firmware/ath10k-ct-firmware/Makefile b/package/firmware/ath10k-ct-firmware/Makefile index b210f1a5e4..78846fbe9d 100644 --- a/package/firmware/ath10k-ct-firmware/Makefile +++ b/package/firmware/ath10k-ct-firmware/Makefile @@ -4,6 +4,8 @@ PKG_NAME:=ath10k-ct-firmware PKG_VERSION:=2020-11-08 PKG_RELEASE:=1 +DL_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) + include $(INCLUDE_DIR)/package.mk CT_FIRMWARE_FILE = $(1)-$($(1)_FIRMWARE_FILE_CT) diff --git a/package/firmware/b43legacy-firmware/Makefile b/package/firmware/b43legacy-firmware/Makefile index 9ca65a8a32..43c530cc71 100644 --- a/package/firmware/b43legacy-firmware/Makefile +++ b/package/firmware/b43legacy-firmware/Makefile @@ -11,6 +11,8 @@ PKG_NAME:=b43legacy-firmware PKG_VERSION:=3.130.20.0 PKG_RELEASE:=1 +DL_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) + PKG_SOURCE:=wl_apsta-$(PKG_VERSION).o PKG_SOURCE_URL:=@OPENWRT PKG_HASH:=7dba610b1d96dd14e901bcbce14cd6ecd1b1ac6f5c0035b0d6b6dc46a7c3ef90 diff --git a/package/firmware/prism54-firmware/Makefile b/package/firmware/prism54-firmware/Makefile index b74cb682fc..9a0bbba3cd 100644 --- a/package/firmware/prism54-firmware/Makefile +++ b/package/firmware/prism54-firmware/Makefile @@ -8,6 +8,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=prism54-firmware PKG_RELEASE:=1 +DL_SUBDIR:=$(PKG_NAME)-$(PKG_RELEASE) + # P54 SoftMAC firmware (jbnore.free.fr seems to be rather slow, so we use daemonizer.de) PRG_URL:=https://daemonizer.de/prism54/prism54-fw/ diff --git a/package/kernel/acx-mac80211/Makefile b/package/kernel/acx-mac80211/Makefile index 8bb84e5a6a..240f171d1e 100644 --- a/package/kernel/acx-mac80211/Makefile +++ b/package/kernel/acx-mac80211/Makefile @@ -17,6 +17,8 @@ PKG_SOURCE_DATE:=2014-02-16 PKG_SOURCE_VERSION:=b6fc31491020cb01d2cd1acc170cfa03ced7e726 PKG_MIRROR_HASH:=58590245715f0e5fb4b57aab6d91071dfb6a97d3273f5aee0b97b1edee030ed0 +DL_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_DATE) + PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_MAC80211_DEBUGFS \ CONFIG_PACKAGE_MAC80211_MESH \ diff --git a/package/kernel/broadcom-wl/Makefile b/package/kernel/broadcom-wl/Makefile index 7188c4900e..dec5bcb98d 100644 --- a/package/kernel/broadcom-wl/Makefile +++ b/package/kernel/broadcom-wl/Makefile @@ -40,7 +40,7 @@ endef define KernelPackage/brcm-wl/Default $(call Package/broadcom-wl/Default) SECTION:=kernel - DEPENDS:=@(TARGET_bcm47xx||TARGET_bcm63xx) +wireless-tools + DEPENDS:=@(TARGET_bcm47xx||TARGET_bcm63xx) +wireless-tools +@KERNEL_WIRELESS_EXT TITLE:=Kernel driver for BCM43xx chipsets FILES:=$(PKG_BUILD_DIR)/driver$(1)/wl.ko $(PKG_BUILD_DIR)/glue/wl_glue.ko AUTOLOAD:=$(call AutoProbe,wl) diff --git a/package/kernel/linux/modules/virt.mk b/package/kernel/linux/modules/virt.mk index 5ed0d5dbbf..59a2d79563 100644 --- a/package/kernel/linux/modules/virt.mk +++ b/package/kernel/linux/modules/virt.mk @@ -72,3 +72,46 @@ define KernelPackage/kvm-amd/description endef $(eval $(call KernelPackage,kvm-amd)) + + +define KernelPackage/vfio + SUBMENU:=Virtualization + TITLE:=VFIO Non-Privileged userspace driver framework + DEPENDS:=@TARGET_x86_64 + KCONFIG:= \ + CONFIG_VFIO \ + CONFIG_VFIO_NOIOMMU=n \ + CONFIG_VFIO_MDEV=n + FILES:= \ + $(LINUX_DIR)/drivers/vfio/vfio.ko \ + $(LINUX_DIR)/drivers/vfio/vfio_virqfd.ko \ + $(LINUX_DIR)/drivers/vfio/vfio_iommu_type1.ko + AUTOLOAD:=$(call AutoProbe,vfio vfio_iommu_type1 vfio_virqfd) +endef + +define KernelPackage/vfio/description + VFIO provides a framework for secure userspace device drivers. +endef + +$(eval $(call KernelPackage,vfio)) + + +define KernelPackage/vfio-pci + SUBMENU:=Virtualization + TITLE:=Generic VFIO support for any PCI device + DEPENDS:=@TARGET_x86_64 @PCI_SUPPORT +kmod-vfio +kmod-irqbypass + KCONFIG:= \ + CONFIG_VFIO_PCI \ + CONFIG_VFIO_PCI_IGD=y + FILES:= \ + $(LINUX_DIR)/drivers/vfio/pci/vfio-pci-core.ko@ge5.15 \ + $(LINUX_DIR)/drivers/vfio/pci/vfio-pci.ko + AUTOLOAD:=$(call AutoProbe,vfio-pci) +endef + +define KernelPackage/vfio-pci/description + Support for the generic PCI VFIO bus driver which can connect any PCI + device to the VFIO framework. +endef + +$(eval $(call KernelPackage,vfio-pci)) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index d467d20c61..e8a7690bb3 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -56,7 +56,6 @@ config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m) config-y:= \ WLAN \ - CFG80211_WEXT \ CFG80211_CERTIFICATION_ONUS \ MAC80211_RC_MINSTREL \ MAC80211_RC_MINSTREL_HT \ @@ -177,6 +176,7 @@ define KernelPackage/hermes $(call KernelPackage/mac80211/Default) TITLE:=Hermes 802.11b chipset support DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic + DEFAULT:=n FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco.ko AUTOLOAD:=$(call AutoProbe,orinoco) endef diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk index a915f94bf9..eca4a574be 100644 --- a/package/kernel/mac80211/intel.mk +++ b/package/kernel/mac80211/intel.mk @@ -125,6 +125,7 @@ define KernelPackage/libipw $(call KernelPackage/mac80211/Default) TITLE:=libipw for ipw2100 and ipw2200 DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-ecb +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN + DEFAULT:=n FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko AUTOLOAD:=$(call AutoProbe,libipw) endef diff --git a/package/kernel/mac80211/marvell.mk b/package/kernel/mac80211/marvell.mk index a0e67091e5..254395932d 100644 --- a/package/kernel/mac80211/marvell.mk +++ b/package/kernel/mac80211/marvell.mk @@ -13,6 +13,7 @@ define KernelPackage/libertas-usb $(call KernelPackage/mac80211/Default) DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware TITLE:=Marvell 88W8015 Wireless Driver + DEFAULT:=n FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko @@ -23,6 +24,7 @@ define KernelPackage/libertas-sdio $(call KernelPackage/mac80211/Default) DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware TITLE:=Marvell 88W8686 Wireless Driver + DEFAULT:=n FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko @@ -33,6 +35,7 @@ define KernelPackage/libertas-spi $(call KernelPackage/mac80211/Default) SUBMENU:=Wireless Drivers DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware + DEFAULT:=n KCONFIG := \ CONFIG_SPI=y \ CONFIG_SPI_MASTER=y diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in index 4cfcaafade..21ed42fa07 100644 --- a/package/network/services/hostapd/Config.in +++ b/package/network/services/hostapd/Config.in @@ -65,6 +65,7 @@ config WPA_WOLFSSL config DRIVER_WEXT_SUPPORT bool + select KERNEL_WIRELESS_EXT default n config DRIVER_11N_SUPPORT diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index 7c6c5e3814..521e7df82e 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -250,8 +250,62 @@ ap_free_sta(hapd, sta); break; } -@@ -1329,6 +1331,7 @@ void ap_sta_set_authorized(struct hostap - buf, ip_addr, keyid_buf); +@@ -1298,12 +1300,25 @@ void ap_sta_set_authorized(struct hostap + sta->addr, authorized, dev_addr); + + if (authorized) { ++ static const char * const auth_algs[] = { ++ [WLAN_AUTH_OPEN] = "open", ++ [WLAN_AUTH_SHARED_KEY] = "shared", ++ [WLAN_AUTH_FT] = "ft", ++ [WLAN_AUTH_SAE] = "sae", ++ [WLAN_AUTH_FILS_SK] = "fils-sk", ++ [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", ++ [WLAN_AUTH_FILS_PK] = "fils-pk", ++ [WLAN_AUTH_PASN] = "pasn", ++ }; ++ const char *auth_alg = NULL; + const char *keyid; + char keyid_buf[100]; + char ip_addr[100]; ++ char alg_buf[100]; + + keyid_buf[0] = '\0'; + ip_addr[0] = '\0'; ++ alg_buf[0] = '\0'; + #ifdef CONFIG_P2P + if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { + os_snprintf(ip_addr, sizeof(ip_addr), +@@ -1313,22 +1328,31 @@ void ap_sta_set_authorized(struct hostap + } + #endif /* CONFIG_P2P */ + ++ if (sta->auth_alg < ARRAY_SIZE(auth_algs)) ++ auth_alg = auth_algs[sta->auth_alg]; ++ ++ if (auth_alg) ++ os_snprintf(alg_buf, sizeof(alg_buf), ++ " auth_alg=%s", auth_alg); ++ + keyid = ap_sta_wpa_get_keyid(hapd, sta); + if (keyid) { + os_snprintf(keyid_buf, sizeof(keyid_buf), + " keyid=%s", keyid); + } + +- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); ++ hostapd_ubus_notify_authorized(hapd, sta, auth_alg); ++ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); + + if (hapd->msg_ctx_parent && + hapd->msg_ctx_parent != hapd->msg_ctx) + wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, +- AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); ++ AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); + hostapd_ubus_notify(hapd, "disassoc", sta->addr); diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 622eab8838..85281f4197 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -1983,6 +1983,20 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); } +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg) +{ + if (!hapd->ubus.obj.has_subscribers) + return; + + blob_buf_init(&b, 0); + blobmsg_add_macaddr(&b, "address", sta->addr); + if (auth_alg) + blobmsg_add_string(&b, "auth-alg", auth_alg); + + ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); +} + void hostapd_ubus_notify_beacon_report( struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, struct rrm_measurement_beacon_report *rep, size_t len) diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h index 5a33b624d0..b0f7c44ab5 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.h +++ b/package/network/services/hostapd/src/src/ap/ubus.h @@ -65,6 +65,8 @@ void hostapd_ubus_free(struct hapd_interfaces *interfaces); int hostapd_ubus_notify_bss_transition_query( struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, const u8 *candidate_list, u16 candidate_list_len); +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg); #else @@ -140,6 +142,13 @@ static inline int hostapd_ubus_notify_bss_transition_query( { return 0; } + +static inline void +hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg) +{ +} + #endif #endif diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index 4735181712..9d17e0343a 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -11,9 +11,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git -PKG_SOURCE_DATE:=2022-08-19 -PKG_SOURCE_VERSION:=0dad3e6660594592071ae49a77a907e2b11a98fe -PKG_MIRROR_HASH:=2162ee3158328ffe39018e50f34d74b47a6c7a26460e30d7984ca16cbc859d80 +PKG_SOURCE_DATE:=2022-09-22 +PKG_SOURCE_VERSION:=4a43b0d40ba50a21de1d47e7bf0f759be9cf646a +PKG_MIRROR_HASH:=4df2c5ac8cb60e4df06a4ef9a87c3a5196f0a8739ee39e6a2587c15527612250 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=GPL-2.0 diff --git a/rules.mk b/rules.mk index c893f61b0f..2072658e78 100644 --- a/rules.mk +++ b/rules.mk @@ -109,7 +109,7 @@ $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1), ) endef -DL_DIR:=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl) +DL_DIR=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)$(if $(DL_SUBDIR),/$(DL_SUBDIR)) OUTPUT_DIR:=$(if $(call qstrip,$(CONFIG_BINARY_FOLDER)),$(call qstrip,$(CONFIG_BINARY_FOLDER)),$(TOPDIR)/bin) BIN_DIR:=$(OUTPUT_DIR)/targets/$(BOARD)/$(SUBTARGET) INCLUDE_DIR:=$(TOPDIR)/include diff --git a/scripts/dl_cleanup.py b/scripts/dl_cleanup.py index f7232b78c9..b15a9bb1a7 100755 --- a/scripts/dl_cleanup.py +++ b/scripts/dl_cleanup.py @@ -149,15 +149,18 @@ class Entry: self.fileext = "" self.filenoext = "" - for ext in extensions: - if filename.endswith(ext): - filename = filename[0 : 0 - len(ext)] - self.filenoext = filename - self.fileext = ext - break + if os.path.isdir(self.getPath()): + self.filenoext = filename else: - print(self.filename, "has an unknown file-extension") - raise EntryParseError("ext") + for ext in extensions: + if filename.endswith(ext): + filename = filename[0 : 0 - len(ext)] + self.filenoext = filename + self.fileext = ext + break + else: + print(self.filename, "has an unknown file-extension") + raise EntryParseError("ext") for (regex, parseVersion) in versionRegex: match = regex.match(filename) if match: @@ -184,7 +187,10 @@ class Entry: path = self.getPath() print("Deleting", path) if not opt_dryrun: - os.unlink(path) + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.unlink(path) def deleteBuildDir(self): paths = self.getBuildPaths() @@ -301,6 +307,9 @@ def main(argv): lastVersion = None versions = progmap[prog] for version in versions: + if lastVersion: + if os.path.isdir(lastVersion.getPath()) and not os.path.isdir(version.getPath()): + continue if lastVersion is None or version >= lastVersion: lastVersion = version if lastVersion: diff --git a/target/linux/bcm4908/config-5.10 b/target/linux/bcm4908/config-5.10 index 4009f80038..762ce49eeb 100644 --- a/target/linux/bcm4908/config-5.10 +++ b/target/linux/bcm4908/config-5.10 @@ -133,6 +133,7 @@ CONFIG_MEMFD_CREATE=y CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MTD_BRCM_U_BOOT=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_CORE=y diff --git a/target/linux/bcm4908/patches-5.10/040-v6.1-mtd-parsers-add-Broadcom-s-U-Boot-parser.patch b/target/linux/bcm4908/patches-5.10/040-v6.1-mtd-parsers-add-Broadcom-s-U-Boot-parser.patch new file mode 100644 index 0000000000..4d4059b17f --- /dev/null +++ b/target/linux/bcm4908/patches-5.10/040-v6.1-mtd-parsers-add-Broadcom-s-U-Boot-parser.patch @@ -0,0 +1,137 @@ +From 002181f5b150e60c77f21de7ad4dd10e4614cd91 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 11 Jul 2022 17:30:41 +0200 +Subject: [PATCH] mtd: parsers: add Broadcom's U-Boot parser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Broadcom stores environment variables blocks inside U-Boot partition +itself. This driver finds & registers them. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220711153041.6036-2-zajec5@gmail.com +--- + drivers/mtd/parsers/Kconfig | 10 ++++ + drivers/mtd/parsers/Makefile | 1 + + drivers/mtd/parsers/brcm_u-boot.c | 84 +++++++++++++++++++++++++++++++ + 3 files changed, 95 insertions(+) + create mode 100644 drivers/mtd/parsers/brcm_u-boot.c + +--- a/drivers/mtd/parsers/Kconfig ++++ b/drivers/mtd/parsers/Kconfig +@@ -20,6 +20,16 @@ config MTD_BCM63XX_PARTS + This provides partition parsing for BCM63xx devices with CFE + bootloaders. + ++config MTD_BRCM_U_BOOT ++ tristate "Broadcom's U-Boot partition parser" ++ depends on ARCH_BCM4908 || COMPILE_TEST ++ help ++ Broadcom uses a custom way of storing U-Boot environment variables. ++ They are placed inside U-Boot partition itself at unspecified offset. ++ It's possible to locate them by looking for a custom header with a ++ magic value. This driver does that and creates subpartitions for ++ each found environment variables block. ++ + config MTD_CMDLINE_PARTS + tristate "Command line partition table parsing" + depends on MTD +--- a/drivers/mtd/parsers/Makefile ++++ b/drivers/mtd/parsers/Makefile +@@ -2,6 +2,7 @@ + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o + obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o ++obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o + obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o +--- /dev/null ++++ b/drivers/mtd/parsers/brcm_u-boot.c +@@ -0,0 +1,84 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright © 2022 Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BRCM_U_BOOT_MAX_OFFSET 0x200000 ++#define BRCM_U_BOOT_STEP 0x1000 ++ ++#define BRCM_U_BOOT_MAX_PARTS 2 ++ ++#define BRCM_U_BOOT_MAGIC 0x75456e76 /* uEnv */ ++ ++struct brcm_u_boot_header { ++ __le32 magic; ++ __le32 length; ++} __packed; ++ ++static const char *names[BRCM_U_BOOT_MAX_PARTS] = { ++ "u-boot-env", ++ "u-boot-env-backup", ++}; ++ ++static int brcm_u_boot_parse(struct mtd_info *mtd, ++ const struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data) ++{ ++ struct brcm_u_boot_header header; ++ struct mtd_partition *parts; ++ size_t bytes_read; ++ size_t offset; ++ int err; ++ int i = 0; ++ ++ parts = kcalloc(BRCM_U_BOOT_MAX_PARTS, sizeof(*parts), GFP_KERNEL); ++ if (!parts) ++ return -ENOMEM; ++ ++ for (offset = 0; ++ offset < min_t(size_t, mtd->size, BRCM_U_BOOT_MAX_OFFSET); ++ offset += BRCM_U_BOOT_STEP) { ++ err = mtd_read(mtd, offset, sizeof(header), &bytes_read, (uint8_t *)&header); ++ if (err && !mtd_is_bitflip(err)) { ++ pr_err("Failed to read from %s at 0x%zx: %d\n", mtd->name, offset, err); ++ continue; ++ } ++ ++ if (le32_to_cpu(header.magic) != BRCM_U_BOOT_MAGIC) ++ continue; ++ ++ parts[i].name = names[i]; ++ parts[i].offset = offset; ++ parts[i].size = sizeof(header) + le32_to_cpu(header.length); ++ i++; ++ pr_info("offset:0x%zx magic:0x%08x BINGO\n", offset, header.magic); ++ ++ if (i == BRCM_U_BOOT_MAX_PARTS) ++ break; ++ } ++ ++ *pparts = parts; ++ ++ return i; ++}; ++ ++static const struct of_device_id brcm_u_boot_of_match_table[] = { ++ { .compatible = "brcm,u-boot" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, brcm_u_boot_of_match_table); ++ ++static struct mtd_part_parser brcm_u_boot_mtd_parser = { ++ .parse_fn = brcm_u_boot_parse, ++ .name = "brcm_u-boot", ++ .of_match_table = brcm_u_boot_of_match_table, ++}; ++module_mtd_part_parser(brcm_u_boot_mtd_parser); ++ ++MODULE_LICENSE("GPL"); diff --git a/target/linux/bcm4908/patches-5.10/170-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch b/target/linux/bcm4908/patches-5.10/077-v5.14-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch similarity index 89% rename from target/linux/bcm4908/patches-5.10/170-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch rename to target/linux/bcm4908/patches-5.10/077-v5.14-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch index 7e82230f9a..02290c8e64 100644 --- a/target/linux/bcm4908/patches-5.10/170-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch +++ b/target/linux/bcm4908/patches-5.10/077-v5.14-net-broadcom-bcm4908_enet-reset-DMA-rings-sw-indexes.patch @@ -1,5 +1,6 @@ +From ddeacc4f6494e07cbb6f033627926623f3e7a9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 22 Jun 2021 07:05:04 +0200 +Date: Tue, 22 Jun 2021 07:24:15 +0200 Subject: [PATCH] net: broadcom: bcm4908_enet: reset DMA rings sw indexes properly MIME-Version: 1.0 @@ -15,6 +16,7 @@ down & up sequence. Fixes: 4feffeadbcb2 ("net: broadcom: bcm4908enet: add BCM4908 controller driver") Signed-off-by: Rafał Miłecki +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm4908_enet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/linux/bcm4908/patches-5.10/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch b/target/linux/bcm4908/patches-5.10/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch new file mode 100644 index 0000000000..702b7641fd --- /dev/null +++ b/target/linux/bcm4908/patches-5.10/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch @@ -0,0 +1,55 @@ +From e93a766da57fff3273bcb618edf5dfca1fb86b89 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 15 Sep 2022 15:30:13 +0200 +Subject: [PATCH] net: broadcom: bcm4908_enet: handle -EPROBE_DEFER when + getting MAC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reading MAC from OF may return -EPROBE_DEFER if underlaying NVMEM device +isn't ready yet. In such case pass that error code up and "wait" to be +probed later. + +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20220915133013.2243-1-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -714,7 +714,9 @@ static int bcm4908_enet_probe(struct pla + return err; + + SET_NETDEV_DEV(netdev, &pdev->dev); +- of_get_mac_address(dev->of_node, netdev->dev_addr); ++ err = of_get_mac_address(dev->of_node, netdev->dev_addr); ++ if (err == -EPROBE_DEFER) ++ goto err_dma_free; + if (!is_valid_ether_addr(netdev->dev_addr)) + eth_hw_addr_random(netdev); + netdev->netdev_ops = &bcm4908_enet_netdev_ops; +@@ -725,14 +727,17 @@ static int bcm4908_enet_probe(struct pla + netif_napi_add(netdev, &enet->rx_ring.napi, bcm4908_enet_poll_rx, NAPI_POLL_WEIGHT); + + err = register_netdev(netdev); +- if (err) { +- bcm4908_enet_dma_free(enet); +- return err; +- } ++ if (err) ++ goto err_dma_free; + + platform_set_drvdata(pdev, enet); + + return 0; ++ ++err_dma_free: ++ bcm4908_enet_dma_free(enet); ++ ++ return err; + } + + static int bcm4908_enet_remove(struct platform_device *pdev) diff --git a/target/linux/generic/backport-5.10/801-v6.1-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.10/801-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch similarity index 100% rename from target/linux/generic/backport-5.10/801-v6.1-nvmem-add-driver-handling-U-Boot-environment-variabl.patch rename to target/linux/generic/backport-5.10/801-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch diff --git a/target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch new file mode 100644 index 0000000000..3a6b76a221 --- /dev/null +++ b/target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch @@ -0,0 +1,29 @@ +From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 15 Sep 2022 22:06:29 +0200 +Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +DT binding allows specifying NVMEM cells as NVMEM device (provider) +subnodes. Looks for such subnodes when building NVMEM cells. + +This allows NVMEM consumers to use U-Boot environment variables. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +--- + drivers/nvmem/u-boot-env.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u + return -ENOMEM; + priv->cells[idx].offset = data_offset + value - data; + priv->cells[idx].bytes = strlen(value); ++ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); + } + + if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch new file mode 100644 index 0000000000..6b40557116 --- /dev/null +++ b/target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch @@ -0,0 +1,30 @@ +From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 18 Aug 2022 06:38:37 +0200 +Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes: +drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32 + +Reported-by: kernel test robot +Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +--- + drivers/nvmem/u-boot-env.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo + data_offset = offsetof(struct u_boot_env_image_redundant, data); + break; + } +- crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset)); ++ crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); + crc32_data_len = priv->mtd->size - crc32_data_offset; + data_len = priv->mtd->size - data_offset; + diff --git a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch new file mode 100644 index 0000000000..7b97181403 --- /dev/null +++ b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch @@ -0,0 +1,161 @@ +commit 8610037e8106b48c79cfe0afb92b2b2466e51c3d +Author: Joe Damato +Date: Tue Mar 1 23:55:47 2022 -0800 + + page_pool: Add allocation stats + + Add per-pool statistics counters for the allocation path of a page pool. + These stats are incremented in softirq context, so no locking or per-cpu + variables are needed. + + This code is disabled by default and a kernel config option is provided for + users who wish to enable them. + + The statistics added are: + - fast: successful fast path allocations + - slow: slow path order-0 allocations + - slow_high_order: slow path high order allocations + - empty: ptr ring is empty, so a slow path allocation was forced. + - refill: an allocation which triggered a refill of the cache + - waive: pages obtained from the ptr ring that cannot be added to + the cache due to a NUMA mismatch. + + Signed-off-by: Joe Damato + Acked-by: Jesper Dangaard Brouer + Reviewed-by: Ilias Apalodimas + Signed-off-by: David S. Miller + +--- a/include/net/page_pool.h ++++ b/include/net/page_pool.h +@@ -82,6 +82,19 @@ struct page_pool_params { + unsigned int offset; /* DMA addr offset */ + }; + ++#ifdef CONFIG_PAGE_POOL_STATS ++struct page_pool_alloc_stats { ++ u64 fast; /* fast path allocations */ ++ u64 slow; /* slow-path order 0 allocations */ ++ u64 slow_high_order; /* slow-path high order allocations */ ++ u64 empty; /* failed refills due to empty ptr ring, forcing ++ * slow path allocation ++ */ ++ u64 refill; /* allocations via successful refill */ ++ u64 waive; /* failed refills due to numa zone mismatch */ ++}; ++#endif ++ + struct page_pool { + struct page_pool_params p; + +@@ -132,6 +145,11 @@ struct page_pool { + refcount_t user_cnt; + + u64 destroy_cnt; ++ ++#ifdef CONFIG_PAGE_POOL_STATS ++ /* these stats are incremented while in softirq context */ ++ struct page_pool_alloc_stats alloc_stats; ++#endif + }; + + struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp); +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -434,6 +434,19 @@ config NET_DEVLINK + config PAGE_POOL + bool + ++config PAGE_POOL_STATS ++ default n ++ bool "Page pool stats" ++ depends on PAGE_POOL ++ help ++ Enable page pool statistics to track page allocation and recycling ++ in page pools. This option incurs additional CPU cost in allocation ++ and recycle paths and additional memory cost to store the statistics. ++ These statistics are only available if this option is enabled and if ++ the driver using the page pool supports exporting this data. ++ ++ If unsure, say N. ++ + config FAILOVER + tristate "Generic failover module" + help +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -26,6 +26,13 @@ + + #define BIAS_MAX LONG_MAX + ++#ifdef CONFIG_PAGE_POOL_STATS ++/* alloc_stat_inc is intended to be used in softirq context */ ++#define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) ++#else ++#define alloc_stat_inc(pool, __stat) ++#endif ++ + static int page_pool_init(struct page_pool *pool, + const struct page_pool_params *params) + { +@@ -117,8 +124,10 @@ static struct page *page_pool_refill_all + int pref_nid; /* preferred NUMA node */ + + /* Quicker fallback, avoid locks when ring is empty */ +- if (__ptr_ring_empty(r)) ++ if (__ptr_ring_empty(r)) { ++ alloc_stat_inc(pool, empty); + return NULL; ++ } + + /* Softirq guarantee CPU and thus NUMA node is stable. This, + * assumes CPU refilling driver RX-ring will also run RX-NAPI. +@@ -148,14 +157,17 @@ static struct page *page_pool_refill_all + * This limit stress on page buddy alloactor. + */ + page_pool_return_page(pool, page); ++ alloc_stat_inc(pool, waive); + page = NULL; + break; + } + } while (pool->alloc.count < PP_ALLOC_CACHE_REFILL); + + /* Return last page */ +- if (likely(pool->alloc.count > 0)) ++ if (likely(pool->alloc.count > 0)) { + page = pool->alloc.cache[--pool->alloc.count]; ++ alloc_stat_inc(pool, refill); ++ } + + spin_unlock(&r->consumer_lock); + return page; +@@ -170,6 +182,7 @@ static struct page *__page_pool_get_cach + if (likely(pool->alloc.count)) { + /* Fast-path */ + page = pool->alloc.cache[--pool->alloc.count]; ++ alloc_stat_inc(pool, fast); + } else { + page = page_pool_refill_alloc_cache(pool); + } +@@ -241,6 +254,7 @@ static struct page *__page_pool_alloc_pa + return NULL; + } + ++ alloc_stat_inc(pool, slow_high_order); + page_pool_set_pp_info(pool, page); + + /* Track how many pages are held 'in-flight' */ +@@ -295,10 +309,12 @@ static struct page *__page_pool_alloc_pa + } + + /* Return last page */ +- if (likely(pool->alloc.count > 0)) ++ if (likely(pool->alloc.count > 0)) { + page = pool->alloc.cache[--pool->alloc.count]; +- else ++ alloc_stat_inc(pool, slow); ++ } else { + page = NULL; ++ } + + /* When page just alloc'ed is should/must have refcnt 1. */ + return page; diff --git a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch new file mode 100644 index 0000000000..8330ae811d --- /dev/null +++ b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch @@ -0,0 +1,137 @@ +commit ad6fa1e1ab1b8164f1ba296b1b4dc556a483bcad +Author: Joe Damato +Date: Tue Mar 1 23:55:48 2022 -0800 + + page_pool: Add recycle stats + + Add per-cpu stats tracking page pool recycling events: + - cached: recycling placed page in the page pool cache + - cache_full: page pool cache was full + - ring: page placed into the ptr ring + - ring_full: page released from page pool because the ptr ring was full + - released_refcnt: page released (and not recycled) because refcnt > 1 + + Signed-off-by: Joe Damato + Acked-by: Jesper Dangaard Brouer + Reviewed-by: Ilias Apalodimas + Signed-off-by: David S. Miller + +--- a/include/net/page_pool.h ++++ b/include/net/page_pool.h +@@ -93,6 +93,18 @@ struct page_pool_alloc_stats { + u64 refill; /* allocations via successful refill */ + u64 waive; /* failed refills due to numa zone mismatch */ + }; ++ ++struct page_pool_recycle_stats { ++ u64 cached; /* recycling placed page in the cache. */ ++ u64 cache_full; /* cache was full */ ++ u64 ring; /* recycling placed page back into ptr ring */ ++ u64 ring_full; /* page was released from page-pool because ++ * PTR ring was full. ++ */ ++ u64 released_refcnt; /* page released because of elevated ++ * refcnt ++ */ ++}; + #endif + + struct page_pool { +@@ -136,6 +148,10 @@ struct page_pool { + */ + struct ptr_ring ring; + ++#ifdef CONFIG_PAGE_POOL_STATS ++ /* recycle stats are per-cpu to avoid locking */ ++ struct page_pool_recycle_stats __percpu *recycle_stats; ++#endif + atomic_t pages_state_release_cnt; + + /* A page_pool is strictly tied to a single RX-queue being +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -29,8 +29,15 @@ + #ifdef CONFIG_PAGE_POOL_STATS + /* alloc_stat_inc is intended to be used in softirq context */ + #define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) ++/* recycle_stat_inc is safe to use when preemption is possible. */ ++#define recycle_stat_inc(pool, __stat) \ ++ do { \ ++ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ ++ this_cpu_inc(s->__stat); \ ++ } while (0) + #else + #define alloc_stat_inc(pool, __stat) ++#define recycle_stat_inc(pool, __stat) + #endif + + static int page_pool_init(struct page_pool *pool, +@@ -80,6 +87,12 @@ static int page_pool_init(struct page_po + pool->p.flags & PP_FLAG_PAGE_FRAG) + return -EINVAL; + ++#ifdef CONFIG_PAGE_POOL_STATS ++ pool->recycle_stats = alloc_percpu(struct page_pool_recycle_stats); ++ if (!pool->recycle_stats) ++ return -ENOMEM; ++#endif ++ + if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) + return -ENOMEM; + +@@ -412,7 +425,12 @@ static bool page_pool_recycle_in_ring(st + else + ret = ptr_ring_produce_bh(&pool->ring, page); + +- return (ret == 0) ? true : false; ++ if (!ret) { ++ recycle_stat_inc(pool, ring); ++ return true; ++ } ++ ++ return false; + } + + /* Only allow direct recycling in special circumstances, into the +@@ -423,11 +441,14 @@ static bool page_pool_recycle_in_ring(st + static bool page_pool_recycle_in_cache(struct page *page, + struct page_pool *pool) + { +- if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE)) ++ if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE)) { ++ recycle_stat_inc(pool, cache_full); + return false; ++ } + + /* Caller MUST have verified/know (page_ref_count(page) == 1) */ + pool->alloc.cache[pool->alloc.count++] = page; ++ recycle_stat_inc(pool, cached); + return true; + } + +@@ -482,6 +503,7 @@ __page_pool_put_page(struct page_pool *p + * doing refcnt based recycle tricks, meaning another process + * will be invoking put_page. + */ ++ recycle_stat_inc(pool, released_refcnt); + /* Do not replace this with page_pool_return_page() */ + page_pool_release_page(pool, page); + put_page(page); +@@ -495,6 +517,7 @@ void page_pool_put_page(struct page_pool + page = __page_pool_put_page(pool, page, dma_sync_size, allow_direct); + if (page && !page_pool_recycle_in_ring(pool, page)) { + /* Cache full, fallback to free pages */ ++ recycle_stat_inc(pool, ring_full); + page_pool_return_page(pool, page); + } + } +@@ -641,6 +664,9 @@ static void page_pool_free(struct page_p + if (pool->p.flags & PP_FLAG_DMA_MAP) + put_device(pool->p.dev); + ++#ifdef CONFIG_PAGE_POOL_STATS ++ free_percpu(pool->recycle_stats); ++#endif + kfree(pool); + } + diff --git a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch new file mode 100644 index 0000000000..8afbd5d120 --- /dev/null +++ b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch @@ -0,0 +1,74 @@ +commit 6b95e3388b1ea0ca63500c5a6e39162dbf828433 +Author: Joe Damato +Date: Tue Mar 1 23:55:49 2022 -0800 + + page_pool: Add function to batch and return stats + + Adds a function page_pool_get_stats which can be used by drivers to obtain + stats for a specified page_pool. + + Signed-off-by: Joe Damato + Acked-by: Jesper Dangaard Brouer + Reviewed-by: Ilias Apalodimas + Signed-off-by: David S. Miller + +--- a/include/net/page_pool.h ++++ b/include/net/page_pool.h +@@ -105,6 +105,23 @@ struct page_pool_recycle_stats { + * refcnt + */ + }; ++ ++/* This struct wraps the above stats structs so users of the ++ * page_pool_get_stats API can pass a single argument when requesting the ++ * stats for the page pool. ++ */ ++struct page_pool_stats { ++ struct page_pool_alloc_stats alloc_stats; ++ struct page_pool_recycle_stats recycle_stats; ++}; ++ ++/* ++ * Drivers that wish to harvest page pool stats and report them to users ++ * (perhaps via ethtool, debugfs, or another mechanism) can allocate a ++ * struct page_pool_stats call page_pool_get_stats to get stats for the specified pool. ++ */ ++bool page_pool_get_stats(struct page_pool *pool, ++ struct page_pool_stats *stats); + #endif + + struct page_pool { +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -35,6 +35,31 @@ + struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ + this_cpu_inc(s->__stat); \ + } while (0) ++ ++bool page_pool_get_stats(struct page_pool *pool, ++ struct page_pool_stats *stats) ++{ ++ int cpu = 0; ++ ++ if (!stats) ++ return false; ++ ++ memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats)); ++ ++ for_each_possible_cpu(cpu) { ++ const struct page_pool_recycle_stats *pcpu = ++ per_cpu_ptr(pool->recycle_stats, cpu); ++ ++ stats->recycle_stats.cached += pcpu->cached; ++ stats->recycle_stats.cache_full += pcpu->cache_full; ++ stats->recycle_stats.ring += pcpu->ring; ++ stats->recycle_stats.ring_full += pcpu->ring_full; ++ stats->recycle_stats.released_refcnt += pcpu->released_refcnt; ++ } ++ ++ return true; ++} ++EXPORT_SYMBOL(page_pool_get_stats); + #else + #define alloc_stat_inc(pool, __stat) + #define recycle_stat_inc(pool, __stat) diff --git a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch new file mode 100644 index 0000000000..90f307772a --- /dev/null +++ b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch @@ -0,0 +1,53 @@ +commit 590032a4d2133ecc10d3078a8db1d85a4842f12c +Author: Lorenzo Bianconi +Date: Mon Apr 11 16:05:26 2022 +0200 + + page_pool: Add recycle stats to page_pool_put_page_bulk + + Add missing recycle stats to page_pool_put_page_bulk routine. + + Reviewed-by: Joe Damato + Signed-off-by: Lorenzo Bianconi + Reviewed-by: Ilias Apalodimas + Link: https://lore.kernel.org/r/3712178b51c007cfaed910ea80e68f00c916b1fa.1649685634.git.lorenzo@kernel.org + Signed-off-by: Paolo Abeni + +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -36,6 +36,12 @@ + this_cpu_inc(s->__stat); \ + } while (0) + ++#define recycle_stat_add(pool, __stat, val) \ ++ do { \ ++ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ ++ this_cpu_add(s->__stat, val); \ ++ } while (0) ++ + bool page_pool_get_stats(struct page_pool *pool, + struct page_pool_stats *stats) + { +@@ -63,6 +69,7 @@ EXPORT_SYMBOL(page_pool_get_stats); + #else + #define alloc_stat_inc(pool, __stat) + #define recycle_stat_inc(pool, __stat) ++#define recycle_stat_add(pool, __stat, val) + #endif + + static int page_pool_init(struct page_pool *pool, +@@ -569,9 +576,13 @@ void page_pool_put_page_bulk(struct page + /* Bulk producer into ptr_ring page_pool cache */ + page_pool_ring_lock(pool); + for (i = 0; i < bulk_len; i++) { +- if (__ptr_ring_produce(&pool->ring, data[i])) +- break; /* ring full */ ++ if (__ptr_ring_produce(&pool->ring, data[i])) { ++ /* ring full */ ++ recycle_stat_inc(pool, ring_full); ++ break; ++ } + } ++ recycle_stat_add(pool, ring, i); + page_pool_ring_unlock(pool); + + /* Hopefully all pages was return into ptr_ring */ diff --git a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch new file mode 100644 index 0000000000..0694c5cfcb --- /dev/null +++ b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch @@ -0,0 +1,144 @@ +commit f3c5264f452a5b0ac1de1f2f657efbabdea3c76a +Author: Lorenzo Bianconi +Date: Tue Apr 12 18:31:58 2022 +0200 + + net: page_pool: introduce ethtool stats + + Introduce page_pool APIs to report stats through ethtool and reduce + duplicated code in each driver. + + Signed-off-by: Lorenzo Bianconi + Reviewed-by: Jakub Kicinski + Reviewed-by: Ilias Apalodimas + Signed-off-by: David S. Miller + +--- a/include/net/page_pool.h ++++ b/include/net/page_pool.h +@@ -115,6 +115,10 @@ struct page_pool_stats { + struct page_pool_recycle_stats recycle_stats; + }; + ++int page_pool_ethtool_stats_get_count(void); ++u8 *page_pool_ethtool_stats_get_strings(u8 *data); ++u64 *page_pool_ethtool_stats_get(u64 *data, void *stats); ++ + /* + * Drivers that wish to harvest page pool stats and report them to users + * (perhaps via ethtool, debugfs, or another mechanism) can allocate a +@@ -122,6 +126,23 @@ struct page_pool_stats { + */ + bool page_pool_get_stats(struct page_pool *pool, + struct page_pool_stats *stats); ++#else ++ ++static inline int page_pool_ethtool_stats_get_count(void) ++{ ++ return 0; ++} ++ ++static inline u8 *page_pool_ethtool_stats_get_strings(u8 *data) ++{ ++ return data; ++} ++ ++static inline u64 *page_pool_ethtool_stats_get(u64 *data, void *stats) ++{ ++ return data; ++} ++ + #endif + + struct page_pool { +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -18,6 +18,7 @@ + #include + #include /* for __put_page() */ + #include ++#include + + #include + +@@ -42,6 +43,20 @@ + this_cpu_add(s->__stat, val); \ + } while (0) + ++static const char pp_stats[][ETH_GSTRING_LEN] = { ++ "rx_pp_alloc_fast", ++ "rx_pp_alloc_slow", ++ "rx_pp_alloc_slow_ho", ++ "rx_pp_alloc_empty", ++ "rx_pp_alloc_refill", ++ "rx_pp_alloc_waive", ++ "rx_pp_recycle_cached", ++ "rx_pp_recycle_cache_full", ++ "rx_pp_recycle_ring", ++ "rx_pp_recycle_ring_full", ++ "rx_pp_recycle_released_ref", ++}; ++ + bool page_pool_get_stats(struct page_pool *pool, + struct page_pool_stats *stats) + { +@@ -50,7 +65,13 @@ bool page_pool_get_stats(struct page_poo + if (!stats) + return false; + +- memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats)); ++ /* The caller is responsible to initialize stats. */ ++ stats->alloc_stats.fast += pool->alloc_stats.fast; ++ stats->alloc_stats.slow += pool->alloc_stats.slow; ++ stats->alloc_stats.slow_high_order += pool->alloc_stats.slow_high_order; ++ stats->alloc_stats.empty += pool->alloc_stats.empty; ++ stats->alloc_stats.refill += pool->alloc_stats.refill; ++ stats->alloc_stats.waive += pool->alloc_stats.waive; + + for_each_possible_cpu(cpu) { + const struct page_pool_recycle_stats *pcpu = +@@ -66,6 +87,46 @@ bool page_pool_get_stats(struct page_poo + return true; + } + EXPORT_SYMBOL(page_pool_get_stats); ++ ++u8 *page_pool_ethtool_stats_get_strings(u8 *data) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(pp_stats); i++) { ++ memcpy(data, pp_stats[i], ETH_GSTRING_LEN); ++ data += ETH_GSTRING_LEN; ++ } ++ ++ return data; ++} ++EXPORT_SYMBOL(page_pool_ethtool_stats_get_strings); ++ ++int page_pool_ethtool_stats_get_count(void) ++{ ++ return ARRAY_SIZE(pp_stats); ++} ++EXPORT_SYMBOL(page_pool_ethtool_stats_get_count); ++ ++u64 *page_pool_ethtool_stats_get(u64 *data, void *stats) ++{ ++ struct page_pool_stats *pool_stats = stats; ++ ++ *data++ = pool_stats->alloc_stats.fast; ++ *data++ = pool_stats->alloc_stats.slow; ++ *data++ = pool_stats->alloc_stats.slow_high_order; ++ *data++ = pool_stats->alloc_stats.empty; ++ *data++ = pool_stats->alloc_stats.refill; ++ *data++ = pool_stats->alloc_stats.waive; ++ *data++ = pool_stats->recycle_stats.cached; ++ *data++ = pool_stats->recycle_stats.cache_full; ++ *data++ = pool_stats->recycle_stats.ring; ++ *data++ = pool_stats->recycle_stats.ring_full; ++ *data++ = pool_stats->recycle_stats.released_refcnt; ++ ++ return data; ++} ++EXPORT_SYMBOL(page_pool_ethtool_stats_get); ++ + #else + #define alloc_stat_inc(pool, __stat) + #define recycle_stat_inc(pool, __stat) diff --git a/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch b/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch new file mode 100644 index 0000000000..9c5a14c41b --- /dev/null +++ b/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch @@ -0,0 +1,97 @@ +commit 2e88d4ff03013937028f5397268b21e10cf68713 +Author: Lorenzo Bianconi +Date: Fri Jan 21 11:09:45 2022 +0100 + + xdp: introduce flags field in xdp_buff/xdp_frame + + Introduce flags field in xdp_frame and xdp_buffer data structures + to define additional buffer features. At the moment the only + supported buffer feature is frags bit (XDP_FLAGS_HAS_FRAGS). + frags bit is used to specify if this is a linear buffer + (XDP_FLAGS_HAS_FRAGS not set) or a frags frame (XDP_FLAGS_HAS_FRAGS + set). In the latter case the driver is expected to initialize the + skb_shared_info structure at the end of the first buffer to link together + subsequent buffers belonging to the same frame. + + Acked-by: Toke Hoiland-Jorgensen + Acked-by: John Fastabend + Acked-by: Jesper Dangaard Brouer + Signed-off-by: Lorenzo Bianconi + Link: https://lore.kernel.org/r/e389f14f3a162c0a5bc6a2e1aa8dd01a90be117d.1642758637.git.lorenzo@kernel.org + Signed-off-by: Alexei Starovoitov + +--- a/include/net/xdp.h ++++ b/include/net/xdp.h +@@ -66,6 +66,10 @@ struct xdp_txq_info { + struct net_device *dev; + }; + ++enum xdp_buff_flags { ++ XDP_FLAGS_HAS_FRAGS = BIT(0), /* non-linear xdp buff */ ++}; ++ + struct xdp_buff { + void *data; + void *data_end; +@@ -74,13 +78,30 @@ struct xdp_buff { + struct xdp_rxq_info *rxq; + struct xdp_txq_info *txq; + u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/ ++ u32 flags; /* supported values defined in xdp_buff_flags */ + }; + ++static __always_inline bool xdp_buff_has_frags(struct xdp_buff *xdp) ++{ ++ return !!(xdp->flags & XDP_FLAGS_HAS_FRAGS); ++} ++ ++static __always_inline void xdp_buff_set_frags_flag(struct xdp_buff *xdp) ++{ ++ xdp->flags |= XDP_FLAGS_HAS_FRAGS; ++} ++ ++static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp) ++{ ++ xdp->flags &= ~XDP_FLAGS_HAS_FRAGS; ++} ++ + static __always_inline void + xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq) + { + xdp->frame_sz = frame_sz; + xdp->rxq = rxq; ++ xdp->flags = 0; + } + + static __always_inline void +@@ -122,8 +143,14 @@ struct xdp_frame { + */ + struct xdp_mem_info mem; + struct net_device *dev_rx; /* used by cpumap */ ++ u32 flags; /* supported values defined in xdp_buff_flags */ + }; + ++static __always_inline bool xdp_frame_has_frags(struct xdp_frame *frame) ++{ ++ return !!(frame->flags & XDP_FLAGS_HAS_FRAGS); ++} ++ + #define XDP_BULK_QUEUE_SIZE 16 + struct xdp_frame_bulk { + int count; +@@ -180,6 +207,7 @@ void xdp_convert_frame_to_buff(struct xd + xdp->data_end = frame->data + frame->len; + xdp->data_meta = frame->data - frame->metasize; + xdp->frame_sz = frame->frame_sz; ++ xdp->flags = frame->flags; + } + + static inline +@@ -206,6 +234,7 @@ int xdp_update_frame_from_buff(struct xd + xdp_frame->headroom = headroom - sizeof(*xdp_frame); + xdp_frame->metasize = metasize; + xdp_frame->frame_sz = xdp->frame_sz; ++ xdp_frame->flags = xdp->flags; + + return 0; + } diff --git a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch new file mode 100644 index 0000000000..5a04948002 --- /dev/null +++ b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch @@ -0,0 +1,134 @@ +commit 7c48cb0176c6d6d3b55029f7ff4ffa05faee6446 +Author: Lorenzo Bianconi +Date: Fri Jan 21 11:09:50 2022 +0100 + + xdp: add frags support to xdp_return_{buff/frame} + + Take into account if the received xdp_buff/xdp_frame is non-linear + recycling/returning the frame memory to the allocator or into + xdp_frame_bulk. + + Acked-by: Toke Hoiland-Jorgensen + Acked-by: John Fastabend + Signed-off-by: Lorenzo Bianconi + Link: https://lore.kernel.org/r/a961069febc868508ce1bdf5e53a343eb4e57cb2.1642758637.git.lorenzo@kernel.org + Signed-off-by: Alexei Starovoitov + +--- a/include/net/xdp.h ++++ b/include/net/xdp.h +@@ -275,10 +275,24 @@ void __xdp_release_frame(void *data, str + static inline void xdp_release_frame(struct xdp_frame *xdpf) + { + struct xdp_mem_info *mem = &xdpf->mem; ++ struct skb_shared_info *sinfo; ++ int i; + + /* Curr only page_pool needs this */ +- if (mem->type == MEM_TYPE_PAGE_POOL) +- __xdp_release_frame(xdpf->data, mem); ++ if (mem->type != MEM_TYPE_PAGE_POOL) ++ return; ++ ++ if (likely(!xdp_frame_has_frags(xdpf))) ++ goto out; ++ ++ sinfo = xdp_get_shared_info_from_frame(xdpf); ++ for (i = 0; i < sinfo->nr_frags; i++) { ++ struct page *page = skb_frag_page(&sinfo->frags[i]); ++ ++ __xdp_release_frame(page_address(page), mem); ++ } ++out: ++ __xdp_release_frame(xdpf->data, mem); + } + + int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -376,12 +376,38 @@ static void __xdp_return(void *data, str + + void xdp_return_frame(struct xdp_frame *xdpf) + { ++ struct skb_shared_info *sinfo; ++ int i; ++ ++ if (likely(!xdp_frame_has_frags(xdpf))) ++ goto out; ++ ++ sinfo = xdp_get_shared_info_from_frame(xdpf); ++ for (i = 0; i < sinfo->nr_frags; i++) { ++ struct page *page = skb_frag_page(&sinfo->frags[i]); ++ ++ __xdp_return(page_address(page), &xdpf->mem, false, NULL); ++ } ++out: + __xdp_return(xdpf->data, &xdpf->mem, false, NULL); + } + EXPORT_SYMBOL_GPL(xdp_return_frame); + + void xdp_return_frame_rx_napi(struct xdp_frame *xdpf) + { ++ struct skb_shared_info *sinfo; ++ int i; ++ ++ if (likely(!xdp_frame_has_frags(xdpf))) ++ goto out; ++ ++ sinfo = xdp_get_shared_info_from_frame(xdpf); ++ for (i = 0; i < sinfo->nr_frags; i++) { ++ struct page *page = skb_frag_page(&sinfo->frags[i]); ++ ++ __xdp_return(page_address(page), &xdpf->mem, true, NULL); ++ } ++out: + __xdp_return(xdpf->data, &xdpf->mem, true, NULL); + } + EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); +@@ -417,7 +443,7 @@ void xdp_return_frame_bulk(struct xdp_fr + struct xdp_mem_allocator *xa; + + if (mem->type != MEM_TYPE_PAGE_POOL) { +- __xdp_return(xdpf->data, &xdpf->mem, false, NULL); ++ xdp_return_frame(xdpf); + return; + } + +@@ -436,12 +462,38 @@ void xdp_return_frame_bulk(struct xdp_fr + bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); + } + ++ if (unlikely(xdp_frame_has_frags(xdpf))) { ++ struct skb_shared_info *sinfo; ++ int i; ++ ++ sinfo = xdp_get_shared_info_from_frame(xdpf); ++ for (i = 0; i < sinfo->nr_frags; i++) { ++ skb_frag_t *frag = &sinfo->frags[i]; ++ ++ bq->q[bq->count++] = skb_frag_address(frag); ++ if (bq->count == XDP_BULK_QUEUE_SIZE) ++ xdp_flush_frame_bulk(bq); ++ } ++ } + bq->q[bq->count++] = xdpf->data; + } + EXPORT_SYMBOL_GPL(xdp_return_frame_bulk); + + void xdp_return_buff(struct xdp_buff *xdp) + { ++ struct skb_shared_info *sinfo; ++ int i; ++ ++ if (likely(!xdp_buff_has_frags(xdp))) ++ goto out; ++ ++ sinfo = xdp_get_shared_info_from_buff(xdp); ++ for (i = 0; i < sinfo->nr_frags; i++) { ++ struct page *page = skb_frag_page(&sinfo->frags[i]); ++ ++ __xdp_return(page_address(page), &xdp->rxq->mem, true, xdp); ++ } ++out: + __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp); + } + diff --git a/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch b/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch new file mode 100644 index 0000000000..5ded882f90 --- /dev/null +++ b/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch @@ -0,0 +1,29 @@ +commit d16697cb6261d4cc23422e6b1cb2759df8aa76d0 +Author: Lorenzo Bianconi +Date: Fri Jan 21 11:09:44 2022 +0100 + + net: skbuff: add size metadata to skb_shared_info for xdp + + Introduce xdp_frags_size field in skb_shared_info data structure + to store xdp_buff/xdp_frame frame paged size (xdp_frags_size will + be used in xdp frags support). In order to not increase + skb_shared_info size we will use a hole due to skb_shared_info + alignment. + + Acked-by: Toke Hoiland-Jorgensen + Acked-by: John Fastabend + Acked-by: Jesper Dangaard Brouer + Signed-off-by: Lorenzo Bianconi + Link: https://lore.kernel.org/r/8a849819a3e0a143d540f78a3a5add76e17e980d.1642758637.git.lorenzo@kernel.org + Signed-off-by: Alexei Starovoitov + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -567,6 +567,7 @@ struct skb_shared_info { + * Warning : all fields before dataref are cleared in __alloc_skb() + */ + atomic_t dataref; ++ unsigned int xdp_frags_size; + + /* Intermediate layers must ensure that destructor_arg + * remains valid until skb destructor */ diff --git a/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch b/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch new file mode 100644 index 0000000000..9b16fc00b7 --- /dev/null +++ b/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch @@ -0,0 +1,62 @@ +commit 5142239a22219921a7863cf00c9ab853c00689d8 +Author: Lorenzo Bianconi +Date: Fri Mar 11 10:14:18 2022 +0100 + + net: veth: Account total xdp_frame len running ndo_xdp_xmit + + Even if this is a theoretical issue since it is not possible to perform + XDP_REDIRECT on a non-linear xdp_frame, veth driver does not account + paged area in ndo_xdp_xmit function pointer. + Introduce xdp_get_frame_len utility routine to get the xdp_frame full + length and account total frame size running XDP_REDIRECT of a + non-linear xdp frame into a veth device. + + Signed-off-by: Lorenzo Bianconi + Signed-off-by: Daniel Borkmann + Acked-by: Toke Hoiland-Jorgensen + Acked-by: John Fastabend + Link: https://lore.kernel.org/bpf/54f9fd3bb65d190daf2c0bbae2f852ff16cfbaa0.1646989407.git.lorenzo@kernel.org + +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -501,7 +501,7 @@ static int veth_xdp_xmit(struct net_devi + struct xdp_frame *frame = frames[i]; + void *ptr = veth_xdp_to_ptr(frame); + +- if (unlikely(frame->len > max_len || ++ if (unlikely(xdp_get_frame_len(frame) > max_len || + __ptr_ring_produce(&rq->xdp_ring, ptr))) + break; + nxmit++; +@@ -862,7 +862,7 @@ static int veth_xdp_rcv(struct veth_rq * + /* ndo_xdp_xmit */ + struct xdp_frame *frame = veth_ptr_to_xdp(ptr); + +- stats->xdp_bytes += frame->len; ++ stats->xdp_bytes += xdp_get_frame_len(frame); + frame = veth_xdp_rcv_one(rq, frame, bq, stats); + if (frame) { + /* XDP_PASS */ +--- a/include/net/xdp.h ++++ b/include/net/xdp.h +@@ -295,6 +295,20 @@ out: + __xdp_release_frame(xdpf->data, mem); + } + ++static __always_inline unsigned int xdp_get_frame_len(struct xdp_frame *xdpf) ++{ ++ struct skb_shared_info *sinfo; ++ unsigned int len = xdpf->len; ++ ++ if (likely(!xdp_frame_has_frags(xdpf))) ++ goto out; ++ ++ sinfo = xdp_get_shared_info_from_frame(xdpf); ++ len += sinfo->xdp_frags_size; ++out: ++ return len; ++} ++ + int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, + struct net_device *dev, u32 queue_index, unsigned int napi_id); + void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq); diff --git a/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch b/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch new file mode 100644 index 0000000000..8080d621da --- /dev/null +++ b/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch @@ -0,0 +1,35 @@ +commit 7cda76d858a4e71ac4a04066c093679a12e1312c +Author: Lorenzo Bianconi +Date: Fri Mar 11 10:14:20 2022 +0100 + + veth: Allow jumbo frames in xdp mode + + Allow increasing the MTU over page boundaries on veth devices + if the attached xdp program declares to support xdp fragments. + + Signed-off-by: Lorenzo Bianconi + Signed-off-by: Daniel Borkmann + Acked-by: Toke Høiland-Jørgensen + Acked-by: John Fastabend + Link: https://lore.kernel.org/bpf/d5dc039c3d4123426e7023a488c449181a7bc57f.1646989407.git.lorenzo@kernel.org + +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -1470,9 +1470,14 @@ static int veth_xdp_set(struct net_devic + goto err; + } + +- max_mtu = PAGE_SIZE - VETH_XDP_HEADROOM - +- peer->hard_header_len - +- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ max_mtu = SKB_WITH_OVERHEAD(PAGE_SIZE - VETH_XDP_HEADROOM) - ++ peer->hard_header_len; ++ /* Allow increasing the max_mtu if the program supports ++ * XDP fragments. ++ */ ++ //if (prog->aux->xdp_has_frags) ++ max_mtu += PAGE_SIZE * MAX_SKB_FRAGS; ++ + if (peer->mtu > max_mtu) { + NL_SET_ERR_MSG_MOD(extack, "Peer MTU is too large to set XDP"); + err = -ERANGE; diff --git a/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch b/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch new file mode 100644 index 0000000000..f9aa6fb67b --- /dev/null +++ b/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch @@ -0,0 +1,330 @@ +From 23233e577ef973c2c5d0dd757a0a4605e34ecb57 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:19:36 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on page_pool for single page + buffers + +Rely on page_pool allocator for single page buffers in order to keep +them dma mapped and add skb recycling support. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/Kconfig | 1 + + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 185 +++++++++++++++----- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++ + 3 files changed, 156 insertions(+), 40 deletions(-) + +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -16,6 +16,7 @@ config NET_MEDIATEK_SOC + depends on NET_DSA || !NET_DSA + select PHYLINK + select DIMLIB ++ select PAGE_POOL + help + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1388,6 +1388,68 @@ static void mtk_update_rx_cpu_idx(struct + } + } + ++static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, ++ struct xdp_rxq_info *xdp_q, ++ int id, int size) ++{ ++ struct page_pool_params pp_params = { ++ .order = 0, ++ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, ++ .pool_size = size, ++ .nid = NUMA_NO_NODE, ++ .dev = eth->dma_dev, ++ .dma_dir = DMA_FROM_DEVICE, ++ .offset = MTK_PP_HEADROOM, ++ .max_len = MTK_PP_MAX_BUF_SIZE, ++ }; ++ struct page_pool *pp; ++ int err; ++ ++ pp = page_pool_create(&pp_params); ++ if (IS_ERR(pp)) ++ return pp; ++ ++ err = xdp_rxq_info_reg(xdp_q, ð->dummy_dev, id, ++ eth->rx_napi.napi_id); ++ if (err < 0) ++ goto err_free_pp; ++ ++ err = xdp_rxq_info_reg_mem_model(xdp_q, MEM_TYPE_PAGE_POOL, pp); ++ if (err) ++ goto err_unregister_rxq; ++ ++ return pp; ++ ++err_unregister_rxq: ++ xdp_rxq_info_unreg(xdp_q); ++err_free_pp: ++ page_pool_destroy(pp); ++ ++ return ERR_PTR(err); ++} ++ ++static void *mtk_page_pool_get_buff(struct page_pool *pp, dma_addr_t *dma_addr, ++ gfp_t gfp_mask) ++{ ++ struct page *page; ++ ++ page = page_pool_alloc_pages(pp, gfp_mask | __GFP_NOWARN); ++ if (!page) ++ return NULL; ++ ++ *dma_addr = page_pool_get_dma_addr(page) + MTK_PP_HEADROOM; ++ return page_address(page); ++} ++ ++static void mtk_rx_put_buff(struct mtk_rx_ring *ring, void *data, bool napi) ++{ ++ if (ring->page_pool) ++ page_pool_put_full_page(ring->page_pool, ++ virt_to_head_page(data), napi); ++ else ++ skb_free_frag(data); ++} ++ + static int mtk_poll_rx(struct napi_struct *napi, int budget, + struct mtk_eth *eth) + { +@@ -1401,9 +1463,9 @@ static int mtk_poll_rx(struct napi_struc + + while (done < budget) { + unsigned int pktlen, *rxdcsum; ++ u32 hash, reason, reserve_len; + struct net_device *netdev; + dma_addr_t dma_addr; +- u32 hash, reason; + int mac = 0; + + ring = mtk_get_rx_ring(eth); +@@ -1434,36 +1496,54 @@ static int mtk_poll_rx(struct napi_struc + goto release_desc; + + /* alloc new buffer */ +- if (ring->frag_size <= PAGE_SIZE) +- new_data = napi_alloc_frag(ring->frag_size); +- else +- new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); +- if (unlikely(!new_data)) { +- netdev->stats.rx_dropped++; +- goto release_desc; +- } +- dma_addr = dma_map_single(eth->dma_dev, +- new_data + NET_SKB_PAD + +- eth->ip_align, +- ring->buf_size, +- DMA_FROM_DEVICE); +- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) { +- skb_free_frag(new_data); +- netdev->stats.rx_dropped++; +- goto release_desc; +- } ++ if (ring->page_pool) { ++ new_data = mtk_page_pool_get_buff(ring->page_pool, ++ &dma_addr, ++ GFP_ATOMIC); ++ if (unlikely(!new_data)) { ++ netdev->stats.rx_dropped++; ++ goto release_desc; ++ } ++ } else { ++ if (ring->frag_size <= PAGE_SIZE) ++ new_data = napi_alloc_frag(ring->frag_size); ++ else ++ new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); ++ ++ if (unlikely(!new_data)) { ++ netdev->stats.rx_dropped++; ++ goto release_desc; ++ } + +- dma_unmap_single(eth->dma_dev, trxd.rxd1, +- ring->buf_size, DMA_FROM_DEVICE); ++ dma_addr = dma_map_single(eth->dma_dev, ++ new_data + NET_SKB_PAD + eth->ip_align, ++ ring->buf_size, DMA_FROM_DEVICE); ++ if (unlikely(dma_mapping_error(eth->dma_dev, ++ dma_addr))) { ++ skb_free_frag(new_data); ++ netdev->stats.rx_dropped++; ++ goto release_desc; ++ } ++ ++ dma_unmap_single(eth->dma_dev, trxd.rxd1, ++ ring->buf_size, DMA_FROM_DEVICE); ++ } + + /* receive data */ + skb = build_skb(data, ring->frag_size); + if (unlikely(!skb)) { +- skb_free_frag(data); ++ mtk_rx_put_buff(ring, data, true); + netdev->stats.rx_dropped++; + goto skip_rx; + } +- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); ++ ++ if (ring->page_pool) { ++ reserve_len = MTK_PP_HEADROOM; ++ skb_mark_for_recycle(skb); ++ } else { ++ reserve_len = NET_SKB_PAD + NET_IP_ALIGN; ++ } ++ skb_reserve(skb, reserve_len); + + pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); + skb->dev = netdev; +@@ -1517,7 +1597,6 @@ static int mtk_poll_rx(struct napi_struc + skip_rx: + ring->data[idx] = new_data; + rxd->rxd1 = (unsigned int)dma_addr; +- + release_desc: + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + rxd->rxd2 = RX_DMA_LSO; +@@ -1525,7 +1604,6 @@ release_desc: + rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); + + ring->calc_idx = idx; +- + done++; + } + +@@ -1889,13 +1967,15 @@ static int mtk_rx_alloc(struct mtk_eth * + if (!ring->data) + return -ENOMEM; + +- for (i = 0; i < rx_dma_size; i++) { +- if (ring->frag_size <= PAGE_SIZE) +- ring->data[i] = netdev_alloc_frag(ring->frag_size); +- else +- ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL); +- if (!ring->data[i]) +- return -ENOMEM; ++ if (!eth->hwlro) { ++ struct page_pool *pp; ++ ++ pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no, ++ rx_dma_size); ++ if (IS_ERR(pp)) ++ return PTR_ERR(pp); ++ ++ ring->page_pool = pp; + } + + ring->dma = dma_alloc_coherent(eth->dma_dev, +@@ -1906,16 +1986,33 @@ static int mtk_rx_alloc(struct mtk_eth * + + for (i = 0; i < rx_dma_size; i++) { + struct mtk_rx_dma_v2 *rxd; +- +- dma_addr_t dma_addr = dma_map_single(eth->dma_dev, +- ring->data[i] + NET_SKB_PAD + eth->ip_align, +- ring->buf_size, +- DMA_FROM_DEVICE); +- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) +- return -ENOMEM; ++ dma_addr_t dma_addr; ++ void *data; + + rxd = ring->dma + i * eth->soc->txrx.rxd_size; ++ if (ring->page_pool) { ++ data = mtk_page_pool_get_buff(ring->page_pool, ++ &dma_addr, GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ } else { ++ if (ring->frag_size <= PAGE_SIZE) ++ data = netdev_alloc_frag(ring->frag_size); ++ else ++ data = mtk_max_lro_buf_alloc(GFP_KERNEL); ++ ++ if (!data) ++ return -ENOMEM; ++ ++ dma_addr = dma_map_single(eth->dma_dev, ++ data + NET_SKB_PAD + eth->ip_align, ++ ring->buf_size, DMA_FROM_DEVICE); ++ if (unlikely(dma_mapping_error(eth->dma_dev, ++ dma_addr))) ++ return -ENOMEM; ++ } + rxd->rxd1 = (unsigned int)dma_addr; ++ ring->data[i] = data; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + rxd->rxd2 = RX_DMA_LSO; +@@ -1931,6 +2028,7 @@ static int mtk_rx_alloc(struct mtk_eth * + rxd->rxd8 = 0; + } + } ++ + ring->dma_size = rx_dma_size; + ring->calc_idx_update = false; + ring->calc_idx = rx_dma_size - 1; +@@ -1982,7 +2080,7 @@ static void mtk_rx_clean(struct mtk_eth + + dma_unmap_single(eth->dma_dev, rxd->rxd1, + ring->buf_size, DMA_FROM_DEVICE); +- skb_free_frag(ring->data[i]); ++ mtk_rx_put_buff(ring, ring->data[i], false); + } + kfree(ring->data); + ring->data = NULL; +@@ -1994,6 +2092,13 @@ static void mtk_rx_clean(struct mtk_eth + ring->dma, ring->phys); + ring->dma = NULL; + } ++ ++ if (ring->page_pool) { ++ if (xdp_rxq_info_is_reg(&ring->xdp_q)) ++ xdp_rxq_info_unreg(&ring->xdp_q); ++ page_pool_destroy(ring->page_pool); ++ ring->page_pool = NULL; ++ } + } + + static int mtk_hwlro_rx_init(struct mtk_eth *eth) +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -18,6 +18,8 @@ + #include + #include + #include ++#include ++#include + #include "mtk_ppe.h" + + #define MTK_QDMA_PAGE_SIZE 2048 +@@ -49,6 +51,11 @@ + #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) + #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1)) + ++#define MTK_PP_HEADROOM XDP_PACKET_HEADROOM ++#define MTK_PP_PAD (MTK_PP_HEADROOM + \ ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#define MTK_PP_MAX_BUF_SIZE (PAGE_SIZE - MTK_PP_PAD) ++ + #define MTK_QRX_OFFSET 0x10 + + #define MTK_MAX_RX_RING_NUM 4 +@@ -742,6 +749,9 @@ struct mtk_rx_ring { + bool calc_idx_update; + u16 calc_idx; + u32 crx_idx_reg; ++ /* page_pool */ ++ struct page_pool *page_pool; ++ struct xdp_rxq_info xdp_q; + }; + + enum mkt_eth_capabilities { diff --git a/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch b/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch new file mode 100644 index 0000000000..b930152dd1 --- /dev/null +++ b/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch @@ -0,0 +1,291 @@ +From 7c26c20da5d420cde55618263be4aa2f6de53056 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:19:37 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add basic XDP support + +Introduce basic XDP support to mtk_eth_soc driver. +Supported XDP verdicts: +- XDP_PASS +- XDP_DROP +- XDP_REDIRECT + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 162 +++++++++++++++++--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 + + 2 files changed, 145 insertions(+), 19 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1388,6 +1388,11 @@ static void mtk_update_rx_cpu_idx(struct + } + } + ++static bool mtk_page_pool_enabled(struct mtk_eth *eth) ++{ ++ return !eth->hwlro; ++} ++ + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, + struct xdp_rxq_info *xdp_q, + int id, int size) +@@ -1450,11 +1455,52 @@ static void mtk_rx_put_buff(struct mtk_r + skb_free_frag(data); + } + ++static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, ++ struct xdp_buff *xdp, struct net_device *dev) ++{ ++ struct bpf_prog *prog; ++ u32 act = XDP_PASS; ++ ++ rcu_read_lock(); ++ ++ prog = rcu_dereference(eth->prog); ++ if (!prog) ++ goto out; ++ ++ act = bpf_prog_run_xdp(prog, xdp); ++ switch (act) { ++ case XDP_PASS: ++ goto out; ++ case XDP_REDIRECT: ++ if (unlikely(xdp_do_redirect(dev, xdp, prog))) { ++ act = XDP_DROP; ++ break; ++ } ++ goto out; ++ default: ++ bpf_warn_invalid_xdp_action(act); ++ fallthrough; ++ case XDP_ABORTED: ++ trace_xdp_exception(dev, prog, act); ++ fallthrough; ++ case XDP_DROP: ++ break; ++ } ++ ++ page_pool_put_full_page(ring->page_pool, ++ virt_to_head_page(xdp->data), true); ++out: ++ rcu_read_unlock(); ++ ++ return act; ++} ++ + static int mtk_poll_rx(struct napi_struct *napi, int budget, + struct mtk_eth *eth) + { + struct dim_sample dim_sample = {}; + struct mtk_rx_ring *ring; ++ bool xdp_flush = false; + int idx; + struct sk_buff *skb; + u8 *data, *new_data; +@@ -1463,9 +1509,9 @@ static int mtk_poll_rx(struct napi_struc + + while (done < budget) { + unsigned int pktlen, *rxdcsum; +- u32 hash, reason, reserve_len; + struct net_device *netdev; + dma_addr_t dma_addr; ++ u32 hash, reason; + int mac = 0; + + ring = mtk_get_rx_ring(eth); +@@ -1495,8 +1541,14 @@ static int mtk_poll_rx(struct napi_struc + if (unlikely(test_bit(MTK_RESETTING, ð->state))) + goto release_desc; + ++ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); ++ + /* alloc new buffer */ + if (ring->page_pool) { ++ struct page *page = virt_to_head_page(data); ++ struct xdp_buff xdp; ++ u32 ret; ++ + new_data = mtk_page_pool_get_buff(ring->page_pool, + &dma_addr, + GFP_ATOMIC); +@@ -1504,6 +1556,34 @@ static int mtk_poll_rx(struct napi_struc + netdev->stats.rx_dropped++; + goto release_desc; + } ++ ++ dma_sync_single_for_cpu(eth->dma_dev, ++ page_pool_get_dma_addr(page) + MTK_PP_HEADROOM, ++ pktlen, page_pool_get_dma_dir(ring->page_pool)); ++ ++ xdp_init_buff(&xdp, PAGE_SIZE, &ring->xdp_q); ++ xdp_prepare_buff(&xdp, data, MTK_PP_HEADROOM, pktlen, ++ false); ++ xdp_buff_clear_frags_flag(&xdp); ++ ++ ret = mtk_xdp_run(eth, ring, &xdp, netdev); ++ if (ret == XDP_REDIRECT) ++ xdp_flush = true; ++ ++ if (ret != XDP_PASS) ++ goto skip_rx; ++ ++ skb = build_skb(data, PAGE_SIZE); ++ if (unlikely(!skb)) { ++ page_pool_put_full_page(ring->page_pool, ++ page, true); ++ netdev->stats.rx_dropped++; ++ goto skip_rx; ++ } ++ ++ skb_reserve(skb, xdp.data - xdp.data_hard_start); ++ skb_put(skb, xdp.data_end - xdp.data); ++ skb_mark_for_recycle(skb); + } else { + if (ring->frag_size <= PAGE_SIZE) + new_data = napi_alloc_frag(ring->frag_size); +@@ -1527,27 +1607,20 @@ static int mtk_poll_rx(struct napi_struc + + dma_unmap_single(eth->dma_dev, trxd.rxd1, + ring->buf_size, DMA_FROM_DEVICE); +- } + +- /* receive data */ +- skb = build_skb(data, ring->frag_size); +- if (unlikely(!skb)) { +- mtk_rx_put_buff(ring, data, true); +- netdev->stats.rx_dropped++; +- goto skip_rx; +- } ++ skb = build_skb(data, ring->frag_size); ++ if (unlikely(!skb)) { ++ netdev->stats.rx_dropped++; ++ skb_free_frag(data); ++ goto skip_rx; ++ } + +- if (ring->page_pool) { +- reserve_len = MTK_PP_HEADROOM; +- skb_mark_for_recycle(skb); +- } else { +- reserve_len = NET_SKB_PAD + NET_IP_ALIGN; ++ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); ++ skb_put(skb, pktlen); + } +- skb_reserve(skb, reserve_len); + +- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); + skb->dev = netdev; +- skb_put(skb, pktlen); ++ bytes += skb->len; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + rxdcsum = &trxd.rxd3; +@@ -1559,7 +1632,6 @@ static int mtk_poll_rx(struct napi_struc + else + skb_checksum_none_assert(skb); + skb->protocol = eth_type_trans(skb, netdev); +- bytes += pktlen; + + hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; + if (hash != MTK_RXD4_FOE_ENTRY) { +@@ -1622,6 +1694,9 @@ rx_done: + &dim_sample); + net_dim(ð->rx_dim, dim_sample); + ++ if (xdp_flush) ++ xdp_do_flush_map(); ++ + return done; + } + +@@ -1967,7 +2042,7 @@ static int mtk_rx_alloc(struct mtk_eth * + if (!ring->data) + return -ENOMEM; + +- if (!eth->hwlro) { ++ if (mtk_page_pool_enabled(eth)) { + struct page_pool *pp; + + pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no, +@@ -2707,6 +2782,48 @@ static int mtk_stop(struct net_device *d + return 0; + } + ++static int mtk_xdp_setup(struct net_device *dev, struct bpf_prog *prog, ++ struct netlink_ext_ack *extack) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ struct bpf_prog *old_prog; ++ bool need_update; ++ ++ if (eth->hwlro) { ++ NL_SET_ERR_MSG_MOD(extack, "XDP not supported with HWLRO"); ++ return -EOPNOTSUPP; ++ } ++ ++ if (dev->mtu > MTK_PP_MAX_BUF_SIZE) { ++ NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP"); ++ return -EOPNOTSUPP; ++ } ++ ++ need_update = !!eth->prog != !!prog; ++ if (netif_running(dev) && need_update) ++ mtk_stop(dev); ++ ++ old_prog = rcu_replace_pointer(eth->prog, prog, lockdep_rtnl_is_held()); ++ if (old_prog) ++ bpf_prog_put(old_prog); ++ ++ if (netif_running(dev) && need_update) ++ return mtk_open(dev); ++ ++ return 0; ++} ++ ++static int mtk_xdp(struct net_device *dev, struct netdev_bpf *xdp) ++{ ++ switch (xdp->command) { ++ case XDP_SETUP_PROG: ++ return mtk_xdp_setup(dev, xdp->prog, xdp->extack); ++ default: ++ return -EINVAL; ++ } ++} ++ + static void ethsys_reset(struct mtk_eth *eth, u32 reset_bits) + { + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, +@@ -3002,6 +3119,12 @@ static int mtk_change_mtu(struct net_dev + struct mtk_eth *eth = mac->hw; + u32 mcr_cur, mcr_new; + ++ if (rcu_access_pointer(eth->prog) && ++ length > MTK_PP_MAX_BUF_SIZE) { ++ netdev_err(dev, "Invalid MTU for XDP mode\n"); ++ return -EINVAL; ++ } ++ + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { + mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); + mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; +@@ -3329,6 +3452,7 @@ static const struct net_device_ops mtk_n + .ndo_poll_controller = mtk_poll_controller, + #endif + .ndo_setup_tc = mtk_eth_setup_tc, ++ .ndo_bpf = mtk_xdp, + }; + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1085,6 +1085,8 @@ struct mtk_eth { + + struct mtk_ppe *ppe; + struct rhashtable flow_table; ++ ++ struct bpf_prog __rcu *prog; + }; + + /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch b/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch new file mode 100644 index 0000000000..b68f44aae2 --- /dev/null +++ b/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch @@ -0,0 +1,110 @@ +From 916a6ee836d6b7b8ef1ed5f0515e256ca60e9968 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:19:38 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp ethtool counters + +Report xdp stats through ethtool + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 26 +++++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++++++++++ + 2 files changed, 36 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -34,6 +34,10 @@ MODULE_PARM_DESC(msg_level, "Message lev + #define MTK_ETHTOOL_STAT(x) { #x, \ + offsetof(struct mtk_hw_stats, x) / sizeof(u64) } + ++#define MTK_ETHTOOL_XDP_STAT(x) { #x, \ ++ offsetof(struct mtk_hw_stats, xdp_stats.x) / \ ++ sizeof(u64) } ++ + static const struct mtk_reg_map mtk_reg_map = { + .tx_irq_mask = 0x1a1c, + .tx_irq_status = 0x1a18, +@@ -141,6 +145,13 @@ static const struct mtk_ethtool_stats { + MTK_ETHTOOL_STAT(rx_long_errors), + MTK_ETHTOOL_STAT(rx_checksum_errors), + MTK_ETHTOOL_STAT(rx_flow_control_packets), ++ MTK_ETHTOOL_XDP_STAT(rx_xdp_redirect), ++ MTK_ETHTOOL_XDP_STAT(rx_xdp_pass), ++ MTK_ETHTOOL_XDP_STAT(rx_xdp_drop), ++ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx), ++ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx_errors), ++ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit), ++ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit_errors), + }; + + static const char * const mtk_clks_source_name[] = { +@@ -1458,6 +1469,9 @@ static void mtk_rx_put_buff(struct mtk_r + static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, + struct xdp_buff *xdp, struct net_device *dev) + { ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_hw_stats *hw_stats = mac->hw_stats; ++ u64 *count = &hw_stats->xdp_stats.rx_xdp_drop; + struct bpf_prog *prog; + u32 act = XDP_PASS; + +@@ -1470,13 +1484,16 @@ static u32 mtk_xdp_run(struct mtk_eth *e + act = bpf_prog_run_xdp(prog, xdp); + switch (act) { + case XDP_PASS: +- goto out; ++ count = &hw_stats->xdp_stats.rx_xdp_pass; ++ goto update_stats; + case XDP_REDIRECT: + if (unlikely(xdp_do_redirect(dev, xdp, prog))) { + act = XDP_DROP; + break; + } +- goto out; ++ ++ count = &hw_stats->xdp_stats.rx_xdp_redirect; ++ goto update_stats; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; +@@ -1489,6 +1506,11 @@ static u32 mtk_xdp_run(struct mtk_eth *e + + page_pool_put_full_page(ring->page_pool, + virt_to_head_page(xdp->data), true); ++ ++update_stats: ++ u64_stats_update_begin(&hw_stats->syncp); ++ *count = *count + 1; ++ u64_stats_update_end(&hw_stats->syncp); + out: + rcu_read_unlock(); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -567,6 +567,16 @@ struct mtk_tx_dma_v2 { + struct mtk_eth; + struct mtk_mac; + ++struct mtk_xdp_stats { ++ u64 rx_xdp_redirect; ++ u64 rx_xdp_pass; ++ u64 rx_xdp_drop; ++ u64 rx_xdp_tx; ++ u64 rx_xdp_tx_errors; ++ u64 tx_xdp_xmit; ++ u64 tx_xdp_xmit_errors; ++}; ++ + /* struct mtk_hw_stats - the structure that holds the traffic statistics. + * @stats_lock: make sure that stats operations are atomic + * @reg_offset: the status register offset of the SoC +@@ -590,6 +600,8 @@ struct mtk_hw_stats { + u64 rx_checksum_errors; + u64 rx_flow_control_packets; + ++ struct mtk_xdp_stats xdp_stats; ++ + spinlock_t stats_lock; + u32 reg_offset; + struct u64_stats_sync syncp; diff --git a/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch b/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch new file mode 100644 index 0000000000..42b3ea215d --- /dev/null +++ b/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch @@ -0,0 +1,340 @@ +From 5886d26fd25bbe26130e3e5f7474b9b3e98a3469 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:19:39 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add xmit XDP support + +Introduce XDP support for XDP_TX verdict and ndo_xdp_xmit function +pointer. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 192 +++++++++++++++++--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 +- + 2 files changed, 180 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -987,15 +987,26 @@ static void mtk_tx_unmap(struct mtk_eth + } + } + +- tx_buf->flags = 0; +- if (tx_buf->skb && +- (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) { +- if (napi) +- napi_consume_skb(tx_buf->skb, napi); ++ if (tx_buf->type == MTK_TYPE_SKB) { ++ if (tx_buf->data && ++ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ struct sk_buff *skb = tx_buf->data; ++ ++ if (napi) ++ napi_consume_skb(skb, napi); ++ else ++ dev_kfree_skb_any(skb); ++ } ++ } else if (tx_buf->data) { ++ struct xdp_frame *xdpf = tx_buf->data; ++ ++ if (napi && tx_buf->type == MTK_TYPE_XDP_TX) ++ xdp_return_frame_rx_napi(xdpf); + else +- dev_kfree_skb_any(tx_buf->skb); ++ xdp_return_frame(xdpf); + } +- tx_buf->skb = NULL; ++ tx_buf->flags = 0; ++ tx_buf->data = NULL; + } + + static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, +@@ -1012,7 +1023,7 @@ static void setup_tx_buf(struct mtk_eth + dma_unmap_addr_set(tx_buf, dma_addr1, mapped_addr); + dma_unmap_len_set(tx_buf, dma_len1, size); + } else { +- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; ++ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; + txd->txd1 = mapped_addr; + txd->txd2 = TX_DMA_PLEN0(size); + dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); +@@ -1188,7 +1199,7 @@ static int mtk_tx_map(struct sk_buff *sk + soc->txrx.txd_size); + if (new_desc) + memset(tx_buf, 0, sizeof(*tx_buf)); +- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; ++ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; + tx_buf->flags |= MTK_TX_FLAGS_PAGE0; + tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : + MTK_TX_FLAGS_FPORT1; +@@ -1202,7 +1213,8 @@ static int mtk_tx_map(struct sk_buff *sk + } + + /* store skb to cleanup */ +- itx_buf->skb = skb; ++ itx_buf->type = MTK_TYPE_SKB; ++ itx_buf->data = skb; + + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { + if (k & 0x1) +@@ -1414,13 +1426,14 @@ static struct page_pool *mtk_create_page + .pool_size = size, + .nid = NUMA_NO_NODE, + .dev = eth->dma_dev, +- .dma_dir = DMA_FROM_DEVICE, + .offset = MTK_PP_HEADROOM, + .max_len = MTK_PP_MAX_BUF_SIZE, + }; + struct page_pool *pp; + int err; + ++ pp_params.dma_dir = rcu_access_pointer(eth->prog) ? DMA_BIDIRECTIONAL ++ : DMA_FROM_DEVICE; + pp = page_pool_create(&pp_params); + if (IS_ERR(pp)) + return pp; +@@ -1466,6 +1479,122 @@ static void mtk_rx_put_buff(struct mtk_r + skb_free_frag(data); + } + ++static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, ++ struct net_device *dev, bool dma_map) ++{ ++ const struct mtk_soc_data *soc = eth->soc; ++ struct mtk_tx_ring *ring = ð->tx_ring; ++ struct mtk_tx_dma_desc_info txd_info = { ++ .size = xdpf->len, ++ .first = true, ++ .last = true, ++ }; ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_tx_dma *txd, *txd_pdma; ++ int err = 0, index = 0, n_desc = 1; ++ struct mtk_tx_buf *tx_buf; ++ ++ if (unlikely(test_bit(MTK_RESETTING, ð->state))) ++ return -EBUSY; ++ ++ if (unlikely(atomic_read(&ring->free_count) <= 1)) ++ return -EBUSY; ++ ++ spin_lock(ð->page_lock); ++ ++ txd = ring->next_free; ++ if (txd == ring->last_free) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); ++ memset(tx_buf, 0, sizeof(*tx_buf)); ++ ++ if (dma_map) { /* ndo_xdp_xmit */ ++ txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data, ++ txd_info.size, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) { ++ err = -ENOMEM; ++ goto out; ++ } ++ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; ++ } else { ++ struct page *page = virt_to_head_page(xdpf->data); ++ ++ txd_info.addr = page_pool_get_dma_addr(page) + ++ sizeof(*xdpf) + xdpf->headroom; ++ dma_sync_single_for_device(eth->dma_dev, txd_info.addr, ++ txd_info.size, ++ DMA_BIDIRECTIONAL); ++ } ++ mtk_tx_set_dma_desc(dev, txd, &txd_info); ++ ++ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; ++ ++ txd_pdma = qdma_to_pdma(ring, txd); ++ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, ++ index++); ++ ++ /* store xdpf for cleanup */ ++ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; ++ tx_buf->data = xdpf; ++ ++ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { ++ if (index & 1) ++ txd_pdma->txd2 |= TX_DMA_LS0; ++ else ++ txd_pdma->txd2 |= TX_DMA_LS1; ++ } ++ ++ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); ++ atomic_sub(n_desc, &ring->free_count); ++ ++ /* make sure that all changes to the dma ring are flushed before we ++ * continue ++ */ ++ wmb(); ++ ++ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { ++ mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); ++ } else { ++ int idx; ++ ++ idx = txd_to_idx(ring, txd, soc->txrx.txd_size); ++ mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), ++ MT7628_TX_CTX_IDX0); ++ } ++out: ++ spin_unlock(ð->page_lock); ++ ++ return err; ++} ++ ++static int mtk_xdp_xmit(struct net_device *dev, int num_frame, ++ struct xdp_frame **frames, u32 flags) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_hw_stats *hw_stats = mac->hw_stats; ++ struct mtk_eth *eth = mac->hw; ++ int i, nxmit = 0; ++ ++ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) ++ return -EINVAL; ++ ++ for (i = 0; i < num_frame; i++) { ++ if (mtk_xdp_submit_frame(eth, frames[i], dev, true)) ++ break; ++ nxmit++; ++ } ++ ++ u64_stats_update_begin(&hw_stats->syncp); ++ hw_stats->xdp_stats.tx_xdp_xmit += nxmit; ++ hw_stats->xdp_stats.tx_xdp_xmit_errors += num_frame - nxmit; ++ u64_stats_update_end(&hw_stats->syncp); ++ ++ return nxmit; ++} ++ + static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, + struct xdp_buff *xdp, struct net_device *dev) + { +@@ -1494,6 +1623,18 @@ static u32 mtk_xdp_run(struct mtk_eth *e + + count = &hw_stats->xdp_stats.rx_xdp_redirect; + goto update_stats; ++ case XDP_TX: { ++ struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); ++ ++ if (mtk_xdp_submit_frame(eth, xdpf, dev, false)) { ++ count = &hw_stats->xdp_stats.rx_xdp_tx_errors; ++ act = XDP_DROP; ++ break; ++ } ++ ++ count = &hw_stats->xdp_stats.rx_xdp_tx; ++ goto update_stats; ++ } + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; +@@ -1727,9 +1868,8 @@ static int mtk_poll_tx_qdma(struct mtk_e + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + struct mtk_tx_ring *ring = ð->tx_ring; +- struct mtk_tx_dma *desc; +- struct sk_buff *skb; + struct mtk_tx_buf *tx_buf; ++ struct mtk_tx_dma *desc; + u32 cpu, dma; + + cpu = ring->last_free_ptr; +@@ -1750,15 +1890,21 @@ static int mtk_poll_tx_qdma(struct mtk_e + if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) + mac = 1; + +- skb = tx_buf->skb; +- if (!skb) ++ if (!tx_buf->data) + break; + +- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->type == MTK_TYPE_SKB && ++ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ struct sk_buff *skb = tx_buf->data; ++ + bytes[mac] += skb->len; + done[mac]++; + budget--; ++ } else if (tx_buf->type == MTK_TYPE_XDP_TX || ++ tx_buf->type == MTK_TYPE_XDP_NDO) { ++ budget--; + } ++ + mtk_tx_unmap(eth, tx_buf, true); + + ring->last_free = desc; +@@ -1777,9 +1923,8 @@ static int mtk_poll_tx_pdma(struct mtk_e + unsigned int *done, unsigned int *bytes) + { + struct mtk_tx_ring *ring = ð->tx_ring; +- struct mtk_tx_dma *desc; +- struct sk_buff *skb; + struct mtk_tx_buf *tx_buf; ++ struct mtk_tx_dma *desc; + u32 cpu, dma; + + cpu = ring->cpu_idx; +@@ -1787,14 +1932,18 @@ static int mtk_poll_tx_pdma(struct mtk_e + + while ((cpu != dma) && budget) { + tx_buf = &ring->buf[cpu]; +- skb = tx_buf->skb; +- if (!skb) ++ if (!tx_buf->data) + break; + +- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->type == MTK_TYPE_SKB && ++ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ struct sk_buff *skb = tx_buf->data; + bytes[0] += skb->len; + done[0]++; + budget--; ++ } else if (tx_buf->type == MTK_TYPE_XDP_TX || ++ tx_buf->type == MTK_TYPE_XDP_NDO) { ++ budget--; + } + + mtk_tx_unmap(eth, tx_buf, true); +@@ -3475,6 +3624,7 @@ static const struct net_device_ops mtk_n + #endif + .ndo_setup_tc = mtk_eth_setup_tc, + .ndo_bpf = mtk_xdp, ++ .ndo_xdp_xmit = mtk_xdp_xmit, + }; + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -693,6 +693,12 @@ enum mtk_dev_state { + MTK_RESETTING + }; + ++enum mtk_tx_buf_type { ++ MTK_TYPE_SKB, ++ MTK_TYPE_XDP_TX, ++ MTK_TYPE_XDP_NDO, ++}; ++ + /* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at + * by the TX descriptor s + * @skb: The SKB pointer of the packet being sent +@@ -702,7 +708,9 @@ enum mtk_dev_state { + * @dma_len1: The length of the second segment + */ + struct mtk_tx_buf { +- struct sk_buff *skb; ++ enum mtk_tx_buf_type type; ++ void *data; ++ + u32 flags; + DEFINE_DMA_UNMAP_ADDR(dma_addr0); + DEFINE_DMA_UNMAP_LEN(dma_len0); diff --git a/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch b/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch new file mode 100644 index 0000000000..d372f022c7 --- /dev/null +++ b/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch @@ -0,0 +1,95 @@ +From 84b9cd389036d4a262d8cee794d56c04095358a7 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:19:40 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for + page_pool_get_stats + +Introduce support for the page_pool stats API into mtk_eth_soc driver. +Report page_pool stats through ethtool. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/Kconfig | 1 + + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 37 +++++++++++++++++++-- + 2 files changed, 35 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -17,6 +17,7 @@ config NET_MEDIATEK_SOC + select PHYLINK + select DIMLIB + select PAGE_POOL ++ select PAGE_POOL_STATS + help + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3485,11 +3485,18 @@ static void mtk_get_strings(struct net_d + int i; + + switch (stringset) { +- case ETH_SS_STATS: ++ case ETH_SS_STATS: { ++ struct mtk_mac *mac = netdev_priv(dev); ++ + for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) { + memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN); + data += ETH_GSTRING_LEN; + } ++ if (mtk_page_pool_enabled(mac->hw)) ++ page_pool_ethtool_stats_get_strings(data); ++ break; ++ } ++ default: + break; + } + } +@@ -3497,13 +3504,35 @@ static void mtk_get_strings(struct net_d + static int mtk_get_sset_count(struct net_device *dev, int sset) + { + switch (sset) { +- case ETH_SS_STATS: +- return ARRAY_SIZE(mtk_ethtool_stats); ++ case ETH_SS_STATS: { ++ int count = ARRAY_SIZE(mtk_ethtool_stats); ++ struct mtk_mac *mac = netdev_priv(dev); ++ ++ if (mtk_page_pool_enabled(mac->hw)) ++ count += page_pool_ethtool_stats_get_count(); ++ return count; ++ } + default: + return -EOPNOTSUPP; + } + } + ++static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data) ++{ ++ struct page_pool_stats stats = {}; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->rx_ring); i++) { ++ struct mtk_rx_ring *ring = ð->rx_ring[i]; ++ ++ if (!ring->page_pool) ++ continue; ++ ++ page_pool_get_stats(ring->page_pool, &stats); ++ } ++ page_pool_ethtool_stats_get(data, &stats); ++} ++ + static void mtk_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) + { +@@ -3531,6 +3560,8 @@ static void mtk_get_ethtool_stats(struct + + for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) + *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset); ++ if (mtk_page_pool_enabled(mac->hw)) ++ mtk_ethtool_pp_stats(mac->hw, data_dst); + } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); + } + diff --git a/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch b/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch new file mode 100644 index 0000000000..33a7616652 --- /dev/null +++ b/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch @@ -0,0 +1,113 @@ +From b16fe6d82b71fa0dd5c957bc22d66a694976d6eb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 27 Jul 2022 23:20:50 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_xdp_frame_map + utility routine + +This is a preliminary patch to add xdp multi-frag support to mtk_eth_soc +driver + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 68 +++++++++++++-------- + 1 file changed, 42 insertions(+), 26 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1479,6 +1479,41 @@ static void mtk_rx_put_buff(struct mtk_r + skb_free_frag(data); + } + ++static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev, ++ struct mtk_tx_dma_desc_info *txd_info, ++ struct mtk_tx_dma *txd, struct mtk_tx_buf *tx_buf, ++ void *data, u16 headroom, int index, bool dma_map) ++{ ++ struct mtk_tx_ring *ring = ð->tx_ring; ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_tx_dma *txd_pdma; ++ ++ if (dma_map) { /* ndo_xdp_xmit */ ++ txd_info->addr = dma_map_single(eth->dma_dev, data, ++ txd_info->size, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr))) ++ return -ENOMEM; ++ ++ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; ++ } else { ++ struct page *page = virt_to_head_page(data); ++ ++ txd_info->addr = page_pool_get_dma_addr(page) + ++ sizeof(struct xdp_frame) + headroom; ++ dma_sync_single_for_device(eth->dma_dev, txd_info->addr, ++ txd_info->size, DMA_BIDIRECTIONAL); ++ } ++ mtk_tx_set_dma_desc(dev, txd, txd_info); ++ ++ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; ++ ++ txd_pdma = qdma_to_pdma(ring, txd); ++ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size, ++ index); ++ ++ return 0; ++} ++ + static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, + struct net_device *dev, bool dma_map) + { +@@ -1489,9 +1524,8 @@ static int mtk_xdp_submit_frame(struct m + .first = true, + .last = true, + }; +- struct mtk_mac *mac = netdev_priv(dev); +- struct mtk_tx_dma *txd, *txd_pdma; + int err = 0, index = 0, n_desc = 1; ++ struct mtk_tx_dma *txd, *txd_pdma; + struct mtk_tx_buf *tx_buf; + + if (unlikely(test_bit(MTK_RESETTING, ð->state))) +@@ -1511,36 +1545,18 @@ static int mtk_xdp_submit_frame(struct m + tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); + memset(tx_buf, 0, sizeof(*tx_buf)); + +- if (dma_map) { /* ndo_xdp_xmit */ +- txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data, +- txd_info.size, DMA_TO_DEVICE); +- if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) { +- err = -ENOMEM; +- goto out; +- } +- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; +- } else { +- struct page *page = virt_to_head_page(xdpf->data); +- +- txd_info.addr = page_pool_get_dma_addr(page) + +- sizeof(*xdpf) + xdpf->headroom; +- dma_sync_single_for_device(eth->dma_dev, txd_info.addr, +- txd_info.size, +- DMA_BIDIRECTIONAL); +- } +- mtk_tx_set_dma_desc(dev, txd, &txd_info); +- +- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; +- +- txd_pdma = qdma_to_pdma(ring, txd); +- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, +- index++); ++ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, ++ xdpf->data, xdpf->headroom, index, ++ dma_map); ++ if (err < 0) ++ goto out; + + /* store xdpf for cleanup */ + tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; + tx_buf->data = xdpf; + + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { ++ txd_pdma = qdma_to_pdma(ring, txd); + if (index & 1) + txd_pdma->txd2 |= TX_DMA_LS0; + else diff --git a/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch b/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch new file mode 100644 index 0000000000..e75861bc82 --- /dev/null +++ b/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch @@ -0,0 +1,218 @@ +From 155738a4f319538a09f734ce1f5a2eac3ada1de2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 27 Jul 2022 23:20:51 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp multi-frag support + +Add the capability to map non-linear xdp frames in XDP_TX and +ndo_xdp_xmit callback. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 125 +++++++++++++------- + 1 file changed, 82 insertions(+), 43 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -987,23 +987,22 @@ static void mtk_tx_unmap(struct mtk_eth + } + } + +- if (tx_buf->type == MTK_TYPE_SKB) { +- if (tx_buf->data && +- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->type == MTK_TYPE_SKB) { + struct sk_buff *skb = tx_buf->data; + + if (napi) + napi_consume_skb(skb, napi); + else + dev_kfree_skb_any(skb); +- } +- } else if (tx_buf->data) { +- struct xdp_frame *xdpf = tx_buf->data; ++ } else { ++ struct xdp_frame *xdpf = tx_buf->data; + +- if (napi && tx_buf->type == MTK_TYPE_XDP_TX) +- xdp_return_frame_rx_napi(xdpf); +- else +- xdp_return_frame(xdpf); ++ if (napi && tx_buf->type == MTK_TYPE_XDP_TX) ++ xdp_return_frame_rx_napi(xdpf); ++ else ++ xdp_return_frame(xdpf); ++ } + } + tx_buf->flags = 0; + tx_buf->data = NULL; +@@ -1506,6 +1505,8 @@ static int mtk_xdp_frame_map(struct mtk_ + mtk_tx_set_dma_desc(dev, txd, txd_info); + + tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; ++ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; ++ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; + + txd_pdma = qdma_to_pdma(ring, txd); + setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size, +@@ -1517,43 +1518,69 @@ static int mtk_xdp_frame_map(struct mtk_ + static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, + struct net_device *dev, bool dma_map) + { ++ struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); + const struct mtk_soc_data *soc = eth->soc; + struct mtk_tx_ring *ring = ð->tx_ring; + struct mtk_tx_dma_desc_info txd_info = { + .size = xdpf->len, + .first = true, +- .last = true, ++ .last = !xdp_frame_has_frags(xdpf), + }; +- int err = 0, index = 0, n_desc = 1; +- struct mtk_tx_dma *txd, *txd_pdma; +- struct mtk_tx_buf *tx_buf; ++ int err, index = 0, n_desc = 1, nr_frags; ++ struct mtk_tx_dma *htxd, *txd, *txd_pdma; ++ struct mtk_tx_buf *htx_buf, *tx_buf; ++ void *data = xdpf->data; + + if (unlikely(test_bit(MTK_RESETTING, ð->state))) + return -EBUSY; + +- if (unlikely(atomic_read(&ring->free_count) <= 1)) ++ nr_frags = unlikely(xdp_frame_has_frags(xdpf)) ? sinfo->nr_frags : 0; ++ if (unlikely(atomic_read(&ring->free_count) <= 1 + nr_frags)) + return -EBUSY; + + spin_lock(ð->page_lock); + + txd = ring->next_free; + if (txd == ring->last_free) { +- err = -ENOMEM; +- goto out; ++ spin_unlock(ð->page_lock); ++ return -ENOMEM; + } ++ htxd = txd; + + tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); + memset(tx_buf, 0, sizeof(*tx_buf)); ++ htx_buf = tx_buf; + +- err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, +- xdpf->data, xdpf->headroom, index, +- dma_map); +- if (err < 0) +- goto out; ++ for (;;) { ++ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, ++ data, xdpf->headroom, index, dma_map); ++ if (err < 0) ++ goto unmap; ++ ++ if (txd_info.last) ++ break; + ++ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (index & 0x1)) { ++ txd = mtk_qdma_phys_to_virt(ring, txd->txd2); ++ txd_pdma = qdma_to_pdma(ring, txd); ++ if (txd == ring->last_free) ++ goto unmap; ++ ++ tx_buf = mtk_desc_to_tx_buf(ring, txd, ++ soc->txrx.txd_size); ++ memset(tx_buf, 0, sizeof(*tx_buf)); ++ n_desc++; ++ } ++ ++ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); ++ txd_info.size = skb_frag_size(&sinfo->frags[index]); ++ txd_info.last = index + 1 == nr_frags; ++ data = skb_frag_address(&sinfo->frags[index]); ++ ++ index++; ++ } + /* store xdpf for cleanup */ +- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; +- tx_buf->data = xdpf; ++ htx_buf->data = xdpf; + + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { + txd_pdma = qdma_to_pdma(ring, txd); +@@ -1580,7 +1607,24 @@ static int mtk_xdp_submit_frame(struct m + mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), + MT7628_TX_CTX_IDX0); + } +-out: ++ ++ spin_unlock(ð->page_lock); ++ ++ return 0; ++ ++unmap: ++ while (htxd != txd) { ++ txd_pdma = qdma_to_pdma(ring, htxd); ++ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size); ++ mtk_tx_unmap(eth, tx_buf, false); ++ ++ htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; ++ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ++ txd_pdma->txd2 = TX_DMA_DESP2_DEF; ++ ++ htxd = mtk_qdma_phys_to_virt(ring, htxd->txd2); ++ } ++ + spin_unlock(ð->page_lock); + + return err; +@@ -1909,18 +1953,15 @@ static int mtk_poll_tx_qdma(struct mtk_e + if (!tx_buf->data) + break; + +- if (tx_buf->type == MTK_TYPE_SKB && +- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { +- struct sk_buff *skb = tx_buf->data; ++ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->type == MTK_TYPE_SKB) { ++ struct sk_buff *skb = tx_buf->data; + +- bytes[mac] += skb->len; +- done[mac]++; +- budget--; +- } else if (tx_buf->type == MTK_TYPE_XDP_TX || +- tx_buf->type == MTK_TYPE_XDP_NDO) { ++ bytes[mac] += skb->len; ++ done[mac]++; ++ } + budget--; + } +- + mtk_tx_unmap(eth, tx_buf, true); + + ring->last_free = desc; +@@ -1951,17 +1992,15 @@ static int mtk_poll_tx_pdma(struct mtk_e + if (!tx_buf->data) + break; + +- if (tx_buf->type == MTK_TYPE_SKB && +- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { +- struct sk_buff *skb = tx_buf->data; +- bytes[0] += skb->len; +- done[0]++; +- budget--; +- } else if (tx_buf->type == MTK_TYPE_XDP_TX || +- tx_buf->type == MTK_TYPE_XDP_NDO) { ++ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { ++ if (tx_buf->type == MTK_TYPE_SKB) { ++ struct sk_buff *skb = tx_buf->data; ++ ++ bytes[0] += skb->len; ++ done[0]++; ++ } + budget--; + } +- + mtk_tx_unmap(eth, tx_buf, true); + + desc = ring->dma + cpu * eth->soc->txrx.txd_size; diff --git a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch b/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch index 87941ef766..a3842d35f5 100644 --- a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch +++ b/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch @@ -18,9 +18,9 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1469,10 +1469,19 @@ static int mtk_poll_rx(struct napi_struc +@@ -1845,10 +1845,19 @@ static int mtk_poll_rx(struct napi_struc skb->dev = netdev; - skb_put(skb, pktlen); + bytes += skb->len; - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { @@ -40,9 +40,9 @@ Signed-off-by: Paolo Abeni if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid) skb->ip_summed = CHECKSUM_UNNECESSARY; -@@ -1481,16 +1490,9 @@ static int mtk_poll_rx(struct napi_struc +@@ -1856,16 +1865,9 @@ static int mtk_poll_rx(struct napi_struc + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, netdev); - bytes += pktlen; - hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; - if (hash != MTK_RXD4_FOE_ENTRY) { @@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -307,6 +307,11 @@ +@@ -314,6 +314,11 @@ #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ #define RX_DMA_SPECIAL_TAG BIT(22) diff --git a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch b/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch new file mode 100644 index 0000000000..0de8ab4376 --- /dev/null +++ b/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch @@ -0,0 +1,31 @@ +From: Tom Rix +Date: Sat, 16 Jul 2022 17:46:54 -0400 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix off by one check of + ARRAY_SIZE + +In mtk_wed_tx_ring_setup(.., int idx, ..), idx is used as an index here + struct mtk_wed_ring *ring = &dev->tx_ring[idx]; + +The bounds of idx are checked here + BUG_ON(idx > ARRAY_SIZE(dev->tx_ring)); + +If idx is the size of the array, it will pass this check and overflow. +So change the check to >= . + +Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") +Signed-off-by: Tom Rix +Link: https://lore.kernel.org/r/20220716214654.1540240-1-trix@redhat.com +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -651,7 +651,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + * WDMA RX. + */ + +- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring)); ++ BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); + + if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) + return -ENOMEM; diff --git a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch b/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch new file mode 100644 index 0000000000..fc6e246468 --- /dev/null +++ b/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch @@ -0,0 +1,27 @@ +From: Lorenzo Bianconi +Date: Mon, 18 Jul 2022 11:51:53 +0200 +Subject: [PATCH] net: ethernet: mtk_ppe: fix possible NULL pointer dereference + in mtk_flow_get_wdma_info + +odev pointer can be NULL in mtk_flow_offload_replace routine according +to the flower action rules. Fix possible NULL pointer dereference in +mtk_flow_get_wdma_info. + +Fixes: a333215e10cb5 ("net: ethernet: mtk_eth_soc: implement flow offloading to WED devices") +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/4e1685bc4976e21e364055f6bee86261f8f9ee93.1658137753.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -93,6 +93,9 @@ mtk_flow_get_wdma_info(struct net_device + }; + struct net_device_path path = {}; + ++ if (!ctx.dev) ++ return -ENODEV; ++ + memcpy(ctx.daddr, addr, sizeof(ctx.daddr)); + + if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) diff --git a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch b/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch new file mode 100644 index 0000000000..c0720152d6 --- /dev/null +++ b/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch @@ -0,0 +1,64 @@ +From: Lorenzo Bianconi +Date: Fri, 22 Jul 2022 09:06:19 +0200 +Subject: [PATCH] net: ethernet: mtk-ppe: fix traffic offload with bridged wlan + +A typical flow offload scenario for OpenWrt users is routed traffic +received by the wan interface that is redirected to a wlan device +belonging to the lan bridge. Current implementation fails to +fill wdma offload info in mtk_flow_get_wdma_info() since odev device is +the local bridge. Fix the issue running dev_fill_forward_path routine in +mtk_flow_get_wdma_info in order to identify the wlan device. + +Tested-by: Paolo Valerio +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -88,32 +88,28 @@ mtk_flow_offload_mangle_eth(const struct + static int + mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info) + { +- struct net_device_path_ctx ctx = { +- .dev = dev, +- }; +- struct net_device_path path = {}; ++ struct net_device_path_stack stack; ++ struct net_device_path *path; ++ int err; + +- if (!ctx.dev) ++ if (!dev) + return -ENODEV; + +- memcpy(ctx.daddr, addr, sizeof(ctx.daddr)); +- + if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) + return -1; + +- if (!dev->netdev_ops->ndo_fill_forward_path) +- return -1; +- +- if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path)) +- return -1; ++ err = dev_fill_forward_path(dev, addr, &stack); ++ if (err) ++ return err; + +- if (path.type != DEV_PATH_MTK_WDMA) ++ path = &stack.path[stack.num_paths - 1]; ++ if (path->type != DEV_PATH_MTK_WDMA) + return -1; + +- info->wdma_idx = path.mtk_wdma.wdma_idx; +- info->queue = path.mtk_wdma.queue; +- info->bss = path.mtk_wdma.bss; +- info->wcid = path.mtk_wdma.wcid; ++ info->wdma_idx = path->mtk_wdma.wdma_idx; ++ info->queue = path->mtk_wdma.queue; ++ info->bss = path->mtk_wdma.bss; ++ info->wcid = path->mtk_wdma.wcid; + + return 0; + } diff --git a/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch b/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch new file mode 100644 index 0000000000..3c28e83551 --- /dev/null +++ b/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch @@ -0,0 +1,33 @@ +From c9daab322313087afde8c46f41df3c628410ae20 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 14:46:01 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: remove mtk_foe_entry_timestamp + +Get rid of mtk_foe_entry_timestamp routine since it is no longer used. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_ppe.h | 11 ----------- + 1 file changed, 11 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -302,17 +302,6 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s + __mtk_ppe_check_skb(ppe, skb, hash); + } + +-static inline int +-mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash) +-{ +- u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1); +- +- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) +- return -1; +- +- return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1); +-} +- + int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, + u8 pse_port, u8 *src_mac, u8 *dest_mac); + int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); diff --git a/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch b/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch new file mode 100644 index 0000000000..f4eb030ef6 --- /dev/null +++ b/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch @@ -0,0 +1,35 @@ +From 5e69163d3b9931098922b3fc2f8e786af8c1f37e Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 13 Sep 2022 15:03:05 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: enable XDP support just for + MT7986 SoC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Disable page_pool/XDP support for MT7621 SoC in order fix a regression +introduce adding XDP for MT7986 SoC. There is no a real use case for XDP +on MT7621 since it is a low-end cpu. Moreover this patch reduces the +memory footprint. + +Tested-by: Sergio Paracuellos +Tested-by: Arınç ÜNAL +Fixes: 23233e577ef9 ("net: ethernet: mtk_eth_soc: rely on page_pool for single page buffers") +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/2bf31e27b888c43228b0d84dd2ef5033338269e2.1663074002.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1412,7 +1412,7 @@ static void mtk_update_rx_cpu_idx(struct + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) + { +- return !eth->hwlro; ++ return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); + } + + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch b/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch index 1786bf0345..77cf63b809 100644 --- a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch +++ b/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch @@ -22,7 +22,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -1986,13 +1986,6 @@ int dsa_slave_create(struct dsa_port *po +@@ -1977,13 +1977,6 @@ int dsa_slave_create(struct dsa_port *po port->slave = slave_dev; dsa_slave_setup_tagger(slave_dev); @@ -36,7 +36,7 @@ Signed-off-by: David S. Miller netif_carrier_off(slave_dev); ret = dsa_slave_phy_setup(slave_dev); -@@ -2004,6 +1997,13 @@ int dsa_slave_create(struct dsa_port *po +@@ -1995,6 +1988,13 @@ int dsa_slave_create(struct dsa_port *po } rtnl_lock(); diff --git a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch b/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch index c2493a08fd..50aa5d8f0d 100644 --- a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch +++ b/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch @@ -16,7 +16,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -1997,14 +1997,12 @@ int dsa_slave_create(struct dsa_port *po +@@ -1988,14 +1988,12 @@ int dsa_slave_create(struct dsa_port *po } rtnl_lock(); diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch index d73b745586..7c6a3a3f8d 100644 --- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch +++ b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch @@ -68,7 +68,7 @@ Signed-off-by: David S. Miller static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) { return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED; -@@ -916,6 +926,13 @@ struct dsa_switch_ops { +@@ -949,6 +959,13 @@ struct dsa_switch_ops { int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags); int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); @@ -175,7 +175,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2320,6 +2320,36 @@ static int dsa_slave_netdevice_event(str +@@ -2311,6 +2311,36 @@ static int dsa_slave_netdevice_event(str err = dsa_port_lag_change(dp, info->lower_state_info); return notifier_from_errno(err); } @@ -212,7 +212,7 @@ Signed-off-by: David S. Miller case NETDEV_GOING_DOWN: { struct dsa_port *dp, *cpu_dp; struct dsa_switch_tree *dst; -@@ -2331,6 +2361,8 @@ static int dsa_slave_netdevice_event(str +@@ -2322,6 +2352,8 @@ static int dsa_slave_netdevice_event(str cpu_dp = dev->dsa_ptr; dst = cpu_dp->ds->dst; diff --git a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch b/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch index c93bc3b77d..d6b7dcfbeb 100644 --- a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch +++ b/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch @@ -27,7 +27,7 @@ Signed-off-by: Jakub Kicinski static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue); static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue); -@@ -1696,9 +1699,6 @@ static int __init_dma_rx_desc_rings(stru +@@ -1697,9 +1700,6 @@ static int __init_dma_rx_desc_rings(stru return -ENOMEM; } @@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski /* Setup the chained descriptor addresses */ if (priv->mode == STMMAC_CHAIN_MODE) { if (priv->extend_desc) -@@ -1804,12 +1804,6 @@ static int __init_dma_tx_desc_rings(stru +@@ -1805,12 +1805,6 @@ static int __init_dma_tx_desc_rings(stru tx_q->tx_skbuff[i] = NULL; } @@ -50,7 +50,7 @@ Signed-off-by: Jakub Kicinski return 0; } -@@ -2678,10 +2672,7 @@ static void stmmac_tx_err(struct stmmac_ +@@ -2679,10 +2673,7 @@ static void stmmac_tx_err(struct stmmac_ stmmac_stop_tx_dma(priv, chan); dma_free_tx_skbufs(priv, chan); stmmac_clear_tx_descriptors(priv, chan); @@ -62,7 +62,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, tx_q->dma_tx_phy, chan); stmmac_start_tx_dma(priv, chan); -@@ -3756,6 +3747,8 @@ static int stmmac_open(struct net_device +@@ -3757,6 +3748,8 @@ static int stmmac_open(struct net_device goto init_error; } @@ -71,7 +71,7 @@ Signed-off-by: Jakub Kicinski ret = stmmac_hw_setup(dev, true); if (ret < 0) { netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); -@@ -6395,6 +6388,7 @@ void stmmac_enable_rx_queue(struct stmma +@@ -6396,6 +6389,7 @@ void stmmac_enable_rx_queue(struct stmma return; } @@ -79,7 +79,7 @@ Signed-off-by: Jakub Kicinski stmmac_clear_rx_descriptors(priv, queue); stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -@@ -6456,6 +6450,7 @@ void stmmac_enable_tx_queue(struct stmma +@@ -6457,6 +6451,7 @@ void stmmac_enable_tx_queue(struct stmma return; } @@ -87,7 +87,7 @@ Signed-off-by: Jakub Kicinski stmmac_clear_tx_descriptors(priv, queue); stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -@@ -7383,6 +7378,25 @@ int stmmac_suspend(struct device *dev) +@@ -7384,6 +7379,25 @@ int stmmac_suspend(struct device *dev) } EXPORT_SYMBOL_GPL(stmmac_suspend); @@ -113,7 +113,7 @@ Signed-off-by: Jakub Kicinski /** * stmmac_reset_queues_param - reset queue parameters * @priv: device pointer -@@ -7393,22 +7407,11 @@ static void stmmac_reset_queues_param(st +@@ -7394,22 +7408,11 @@ static void stmmac_reset_queues_param(st u32 tx_cnt = priv->plat->tx_queues_to_use; u32 queue; diff --git a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch b/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch index e73422636c..2b148ff290 100644 --- a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch +++ b/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch @@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3808,8 +3808,6 @@ static int stmmac_release(struct net_dev +@@ -3809,8 +3809,6 @@ static int stmmac_release(struct net_dev struct stmmac_priv *priv = netdev_priv(dev); u32 chan; @@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski if (device_may_wakeup(priv->device)) phylink_speed_down(priv->phylink, false); /* Stop and disconnect the PHY */ -@@ -3821,6 +3819,8 @@ static int stmmac_release(struct net_dev +@@ -3822,6 +3820,8 @@ static int stmmac_release(struct net_dev for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) hrtimer_cancel(&priv->tx_queue[chan].txtimer); diff --git a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch b/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch index 5cb2663c82..980d821cf5 100644 --- a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch +++ b/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch @@ -189,7 +189,7 @@ Signed-off-by: Jakub Kicinski if (tx_q->dirty_tx != tx_q->cur_tx) return -EBUSY; /* still unfinished work */ -@@ -1293,7 +1293,7 @@ static void stmmac_display_rx_rings(stru +@@ -1294,7 +1294,7 @@ static void stmmac_display_rx_rings(stru /* Display RX rings */ for (queue = 0; queue < rx_cnt; queue++) { @@ -198,7 +198,7 @@ Signed-off-by: Jakub Kicinski pr_info("\tRX Queue %u rings\n", queue); -@@ -1306,7 +1306,7 @@ static void stmmac_display_rx_rings(stru +@@ -1307,7 +1307,7 @@ static void stmmac_display_rx_rings(stru } /* Display RX ring */ @@ -207,7 +207,7 @@ Signed-off-by: Jakub Kicinski rx_q->dma_rx_phy, desc_size); } } -@@ -1320,7 +1320,7 @@ static void stmmac_display_tx_rings(stru +@@ -1321,7 +1321,7 @@ static void stmmac_display_tx_rings(stru /* Display TX rings */ for (queue = 0; queue < tx_cnt; queue++) { @@ -216,7 +216,7 @@ Signed-off-by: Jakub Kicinski pr_info("\tTX Queue %d rings\n", queue); -@@ -1335,7 +1335,7 @@ static void stmmac_display_tx_rings(stru +@@ -1336,7 +1336,7 @@ static void stmmac_display_tx_rings(stru desc_size = sizeof(struct dma_desc); } @@ -225,7 +225,7 @@ Signed-off-by: Jakub Kicinski tx_q->dma_tx_phy, desc_size); } } -@@ -1376,21 +1376,21 @@ static int stmmac_set_bfsize(int mtu, in +@@ -1377,21 +1377,21 @@ static int stmmac_set_bfsize(int mtu, in */ static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue) { @@ -253,7 +253,7 @@ Signed-off-by: Jakub Kicinski } /** -@@ -1402,12 +1402,12 @@ static void stmmac_clear_rx_descriptors( +@@ -1403,12 +1403,12 @@ static void stmmac_clear_rx_descriptors( */ static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, u32 queue) { @@ -269,7 +269,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; if (priv->extend_desc) -@@ -1455,7 +1455,7 @@ static void stmmac_clear_descriptors(str +@@ -1456,7 +1456,7 @@ static void stmmac_clear_descriptors(str static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, int i, gfp_t flags, u32 queue) { @@ -278,7 +278,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (!buf->page) { -@@ -1480,7 +1480,7 @@ static int stmmac_init_rx_buffers(struct +@@ -1481,7 +1481,7 @@ static int stmmac_init_rx_buffers(struct buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset; stmmac_set_desc_addr(priv, p, buf->addr); @@ -287,7 +287,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_desc3(priv, p); return 0; -@@ -1494,7 +1494,7 @@ static int stmmac_init_rx_buffers(struct +@@ -1495,7 +1495,7 @@ static int stmmac_init_rx_buffers(struct */ static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i) { @@ -296,7 +296,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (buf->page) -@@ -1514,7 +1514,7 @@ static void stmmac_free_rx_buffer(struct +@@ -1515,7 +1515,7 @@ static void stmmac_free_rx_buffer(struct */ static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i) { @@ -305,7 +305,7 @@ Signed-off-by: Jakub Kicinski if (tx_q->tx_skbuff_dma[i].buf && tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) { -@@ -1559,17 +1559,17 @@ static void dma_free_rx_skbufs(struct st +@@ -1560,17 +1560,17 @@ static void dma_free_rx_skbufs(struct st { int i; @@ -326,7 +326,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; int ret; -@@ -1596,10 +1596,10 @@ static int stmmac_alloc_rx_buffers(struc +@@ -1597,10 +1597,10 @@ static int stmmac_alloc_rx_buffers(struc */ static void dma_free_rx_xskbufs(struct stmmac_priv *priv, u32 queue) { @@ -339,7 +339,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (!buf->xdp) -@@ -1612,10 +1612,10 @@ static void dma_free_rx_xskbufs(struct s +@@ -1613,10 +1613,10 @@ static void dma_free_rx_xskbufs(struct s static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, u32 queue) { @@ -352,7 +352,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf; dma_addr_t dma_addr; struct dma_desc *p; -@@ -1658,7 +1658,7 @@ static struct xsk_buff_pool *stmmac_get_ +@@ -1659,7 +1659,7 @@ static struct xsk_buff_pool *stmmac_get_ */ static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, u32 queue, gfp_t flags) { @@ -361,7 +361,7 @@ Signed-off-by: Jakub Kicinski int ret; netif_dbg(priv, probe, priv->dev, -@@ -1704,11 +1704,11 @@ static int __init_dma_rx_desc_rings(stru +@@ -1705,11 +1705,11 @@ static int __init_dma_rx_desc_rings(stru if (priv->extend_desc) stmmac_mode_init(priv, rx_q->dma_erx, rx_q->dma_rx_phy, @@ -375,7 +375,7 @@ Signed-off-by: Jakub Kicinski } return 0; -@@ -1735,7 +1735,7 @@ static int init_dma_rx_desc_rings(struct +@@ -1736,7 +1736,7 @@ static int init_dma_rx_desc_rings(struct err_init_rx_buffers: while (queue >= 0) { @@ -384,7 +384,7 @@ Signed-off-by: Jakub Kicinski if (rx_q->xsk_pool) dma_free_rx_xskbufs(priv, queue); -@@ -1764,7 +1764,7 @@ err_init_rx_buffers: +@@ -1765,7 +1765,7 @@ err_init_rx_buffers: */ static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, u32 queue) { @@ -393,7 +393,7 @@ Signed-off-by: Jakub Kicinski int i; netif_dbg(priv, probe, priv->dev, -@@ -1776,16 +1776,16 @@ static int __init_dma_tx_desc_rings(stru +@@ -1777,16 +1777,16 @@ static int __init_dma_tx_desc_rings(stru if (priv->extend_desc) stmmac_mode_init(priv, tx_q->dma_etx, tx_q->dma_tx_phy, @@ -413,7 +413,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; if (priv->extend_desc) -@@ -1855,12 +1855,12 @@ static int init_dma_desc_rings(struct ne +@@ -1856,12 +1856,12 @@ static int init_dma_desc_rings(struct ne */ static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue) { @@ -428,7 +428,7 @@ Signed-off-by: Jakub Kicinski stmmac_free_tx_buffer(priv, queue, i); if (tx_q->xsk_pool && tx_q->xsk_frames_done) { -@@ -1890,7 +1890,7 @@ static void stmmac_free_tx_skbufs(struct +@@ -1891,7 +1891,7 @@ static void stmmac_free_tx_skbufs(struct */ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) { @@ -437,7 +437,7 @@ Signed-off-by: Jakub Kicinski /* Release the DMA RX socket buffers */ if (rx_q->xsk_pool) -@@ -1903,11 +1903,11 @@ static void __free_dma_rx_desc_resources +@@ -1904,11 +1904,11 @@ static void __free_dma_rx_desc_resources /* Free DMA regions of consistent memory previously allocated */ if (!priv->extend_desc) @@ -451,7 +451,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_extended_desc), rx_q->dma_erx, rx_q->dma_rx_phy); -@@ -1936,7 +1936,7 @@ static void free_dma_rx_desc_resources(s +@@ -1937,7 +1937,7 @@ static void free_dma_rx_desc_resources(s */ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) { @@ -460,7 +460,7 @@ Signed-off-by: Jakub Kicinski size_t size; void *addr; -@@ -1954,7 +1954,7 @@ static void __free_dma_tx_desc_resources +@@ -1955,7 +1955,7 @@ static void __free_dma_tx_desc_resources addr = tx_q->dma_tx; } @@ -469,7 +469,7 @@ Signed-off-by: Jakub Kicinski dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); -@@ -1983,7 +1983,7 @@ static void free_dma_tx_desc_resources(s +@@ -1984,7 +1984,7 @@ static void free_dma_tx_desc_resources(s */ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) { @@ -478,7 +478,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[queue]; bool xdp_prog = stmmac_xdp_is_enabled(priv); struct page_pool_params pp_params = { 0 }; -@@ -1995,8 +1995,8 @@ static int __alloc_dma_rx_desc_resources +@@ -1996,8 +1996,8 @@ static int __alloc_dma_rx_desc_resources rx_q->priv_data = priv; pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; @@ -489,7 +489,7 @@ Signed-off-by: Jakub Kicinski pp_params.order = ilog2(num_pages); pp_params.nid = dev_to_node(priv->device); pp_params.dev = priv->device; -@@ -2011,7 +2011,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2012,7 +2012,7 @@ static int __alloc_dma_rx_desc_resources return ret; } @@ -498,7 +498,7 @@ Signed-off-by: Jakub Kicinski sizeof(*rx_q->buf_pool), GFP_KERNEL); if (!rx_q->buf_pool) -@@ -2019,7 +2019,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2020,7 +2020,7 @@ static int __alloc_dma_rx_desc_resources if (priv->extend_desc) { rx_q->dma_erx = dma_alloc_coherent(priv->device, @@ -507,7 +507,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_extended_desc), &rx_q->dma_rx_phy, GFP_KERNEL); -@@ -2028,7 +2028,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2029,7 +2029,7 @@ static int __alloc_dma_rx_desc_resources } else { rx_q->dma_rx = dma_alloc_coherent(priv->device, @@ -516,7 +516,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_desc), &rx_q->dma_rx_phy, GFP_KERNEL); -@@ -2085,20 +2085,20 @@ err_dma: +@@ -2086,20 +2086,20 @@ err_dma: */ static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) { @@ -540,7 +540,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct sk_buff *), GFP_KERNEL); if (!tx_q->tx_skbuff) -@@ -2111,7 +2111,7 @@ static int __alloc_dma_tx_desc_resources +@@ -2112,7 +2112,7 @@ static int __alloc_dma_tx_desc_resources else size = sizeof(struct dma_desc); @@ -549,7 +549,7 @@ Signed-off-by: Jakub Kicinski addr = dma_alloc_coherent(priv->device, size, &tx_q->dma_tx_phy, GFP_KERNEL); -@@ -2355,7 +2355,7 @@ static void stmmac_dma_operation_mode(st +@@ -2356,7 +2356,7 @@ static void stmmac_dma_operation_mode(st /* configure all channels */ for (chan = 0; chan < rx_channels_count; chan++) { @@ -558,7 +558,7 @@ Signed-off-by: Jakub Kicinski u32 buf_size; qmode = priv->plat->rx_queues_cfg[chan].mode_to_use; -@@ -2370,7 +2370,7 @@ static void stmmac_dma_operation_mode(st +@@ -2371,7 +2371,7 @@ static void stmmac_dma_operation_mode(st chan); } else { stmmac_set_dma_bfsize(priv, priv->ioaddr, @@ -567,7 +567,7 @@ Signed-off-by: Jakub Kicinski chan); } } -@@ -2386,7 +2386,7 @@ static void stmmac_dma_operation_mode(st +@@ -2387,7 +2387,7 @@ static void stmmac_dma_operation_mode(st static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) { struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); @@ -576,7 +576,7 @@ Signed-off-by: Jakub Kicinski struct xsk_buff_pool *pool = tx_q->xsk_pool; unsigned int entry = tx_q->cur_tx; struct dma_desc *tx_desc = NULL; -@@ -2461,7 +2461,7 @@ static bool stmmac_xdp_xmit_zc(struct st +@@ -2462,7 +2462,7 @@ static bool stmmac_xdp_xmit_zc(struct st stmmac_enable_dma_transmission(priv, priv->ioaddr); @@ -585,7 +585,7 @@ Signed-off-by: Jakub Kicinski entry = tx_q->cur_tx; } -@@ -2487,7 +2487,7 @@ static bool stmmac_xdp_xmit_zc(struct st +@@ -2488,7 +2488,7 @@ static bool stmmac_xdp_xmit_zc(struct st */ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) { @@ -594,7 +594,7 @@ Signed-off-by: Jakub Kicinski unsigned int bytes_compl = 0, pkts_compl = 0; unsigned int entry, xmits = 0, count = 0; -@@ -2500,7 +2500,7 @@ static int stmmac_tx_clean(struct stmmac +@@ -2501,7 +2501,7 @@ static int stmmac_tx_clean(struct stmmac entry = tx_q->dirty_tx; /* Try to clean all TX complete frame in 1 shot */ @@ -603,7 +603,7 @@ Signed-off-by: Jakub Kicinski struct xdp_frame *xdpf; struct sk_buff *skb; struct dma_desc *p; -@@ -2600,7 +2600,7 @@ static int stmmac_tx_clean(struct stmmac +@@ -2601,7 +2601,7 @@ static int stmmac_tx_clean(struct stmmac stmmac_release_tx_desc(priv, p, priv->mode); @@ -612,7 +612,7 @@ Signed-off-by: Jakub Kicinski } tx_q->dirty_tx = entry; -@@ -2665,7 +2665,7 @@ static int stmmac_tx_clean(struct stmmac +@@ -2666,7 +2666,7 @@ static int stmmac_tx_clean(struct stmmac */ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan) { @@ -621,7 +621,7 @@ Signed-off-by: Jakub Kicinski netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan)); -@@ -2732,8 +2732,8 @@ static int stmmac_napi_check(struct stmm +@@ -2733,8 +2733,8 @@ static int stmmac_napi_check(struct stmm { int status = stmmac_dma_interrupt_status(priv, priv->ioaddr, &priv->xstats, chan, dir); @@ -632,7 +632,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[chan]; struct napi_struct *rx_napi; struct napi_struct *tx_napi; -@@ -2909,7 +2909,7 @@ static int stmmac_init_dma_engine(struct +@@ -2910,7 +2910,7 @@ static int stmmac_init_dma_engine(struct /* DMA RX Channel Configuration */ for (chan = 0; chan < rx_channels_count; chan++) { @@ -641,7 +641,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, rx_q->dma_rx_phy, chan); -@@ -2923,7 +2923,7 @@ static int stmmac_init_dma_engine(struct +@@ -2924,7 +2924,7 @@ static int stmmac_init_dma_engine(struct /* DMA TX Channel Configuration */ for (chan = 0; chan < tx_channels_count; chan++) { @@ -650,7 +650,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, tx_q->dma_tx_phy, chan); -@@ -2938,7 +2938,7 @@ static int stmmac_init_dma_engine(struct +@@ -2939,7 +2939,7 @@ static int stmmac_init_dma_engine(struct static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) { @@ -659,7 +659,7 @@ Signed-off-by: Jakub Kicinski hrtimer_start(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), -@@ -2988,7 +2988,7 @@ static void stmmac_init_coalesce(struct +@@ -2989,7 +2989,7 @@ static void stmmac_init_coalesce(struct u32 chan; for (chan = 0; chan < tx_channel_count; chan++) { @@ -668,7 +668,7 @@ Signed-off-by: Jakub Kicinski priv->tx_coal_frames[chan] = STMMAC_TX_FRAMES; priv->tx_coal_timer[chan] = STMMAC_COAL_TX_TIMER; -@@ -3010,12 +3010,12 @@ static void stmmac_set_rings_length(stru +@@ -3011,12 +3011,12 @@ static void stmmac_set_rings_length(stru /* set TX ring length */ for (chan = 0; chan < tx_channels_count; chan++) stmmac_set_tx_ring_len(priv, priv->ioaddr, @@ -683,7 +683,7 @@ Signed-off-by: Jakub Kicinski } /** -@@ -3350,7 +3350,7 @@ static int stmmac_hw_setup(struct net_de +@@ -3351,7 +3351,7 @@ static int stmmac_hw_setup(struct net_de /* Enable TSO */ if (priv->tso) { for (chan = 0; chan < tx_cnt; chan++) { @@ -692,7 +692,7 @@ Signed-off-by: Jakub Kicinski /* TSO and TBS cannot co-exist */ if (tx_q->tbs & STMMAC_TBS_AVAIL) -@@ -3372,7 +3372,7 @@ static int stmmac_hw_setup(struct net_de +@@ -3373,7 +3373,7 @@ static int stmmac_hw_setup(struct net_de /* TBS */ for (chan = 0; chan < tx_cnt; chan++) { @@ -701,7 +701,7 @@ Signed-off-by: Jakub Kicinski int enable = tx_q->tbs & STMMAC_TBS_AVAIL; stmmac_enable_tbs(priv, priv->ioaddr, enable, chan); -@@ -3416,7 +3416,7 @@ static void stmmac_free_irq(struct net_d +@@ -3417,7 +3417,7 @@ static void stmmac_free_irq(struct net_d for (j = irq_idx - 1; j >= 0; j--) { if (priv->tx_irq[j] > 0) { irq_set_affinity_hint(priv->tx_irq[j], NULL); @@ -710,7 +710,7 @@ Signed-off-by: Jakub Kicinski } } irq_idx = priv->plat->rx_queues_to_use; -@@ -3425,7 +3425,7 @@ static void stmmac_free_irq(struct net_d +@@ -3426,7 +3426,7 @@ static void stmmac_free_irq(struct net_d for (j = irq_idx - 1; j >= 0; j--) { if (priv->rx_irq[j] > 0) { irq_set_affinity_hint(priv->rx_irq[j], NULL); @@ -719,7 +719,7 @@ Signed-off-by: Jakub Kicinski } } -@@ -3558,7 +3558,7 @@ static int stmmac_request_irq_multi_msi( +@@ -3559,7 +3559,7 @@ static int stmmac_request_irq_multi_msi( sprintf(int_name, "%s:%s-%d", dev->name, "rx", i); ret = request_irq(priv->rx_irq[i], stmmac_msi_intr_rx, @@ -728,7 +728,7 @@ Signed-off-by: Jakub Kicinski if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc rx-%d MSI %d (error: %d)\n", -@@ -3581,7 +3581,7 @@ static int stmmac_request_irq_multi_msi( +@@ -3582,7 +3582,7 @@ static int stmmac_request_irq_multi_msi( sprintf(int_name, "%s:%s-%d", dev->name, "tx", i); ret = request_irq(priv->tx_irq[i], stmmac_msi_intr_tx, @@ -737,7 +737,7 @@ Signed-off-by: Jakub Kicinski if (unlikely(ret < 0)) { netdev_err(priv->dev, "%s: alloc tx-%d MSI %d (error: %d)\n", -@@ -3712,21 +3712,21 @@ static int stmmac_open(struct net_device +@@ -3713,21 +3713,21 @@ static int stmmac_open(struct net_device bfsize = 0; if (bfsize < BUF_SIZE_16KiB) @@ -766,7 +766,7 @@ Signed-off-by: Jakub Kicinski int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en; /* Setup per-TXQ tbs flag before TX descriptor alloc */ -@@ -3775,7 +3775,7 @@ irq_error: +@@ -3776,7 +3776,7 @@ irq_error: phylink_stop(priv->phylink); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -775,7 +775,7 @@ Signed-off-by: Jakub Kicinski stmmac_hw_teardown(dev); init_error: -@@ -3817,7 +3817,7 @@ static int stmmac_release(struct net_dev +@@ -3818,7 +3818,7 @@ static int stmmac_release(struct net_dev stmmac_disable_all_queues(priv); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -784,7 +784,7 @@ Signed-off-by: Jakub Kicinski netif_tx_disable(dev); -@@ -3877,7 +3877,7 @@ static bool stmmac_vlan_insert(struct st +@@ -3878,7 +3878,7 @@ static bool stmmac_vlan_insert(struct st return false; stmmac_set_tx_owner(priv, p); @@ -793,7 +793,7 @@ Signed-off-by: Jakub Kicinski return true; } -@@ -3895,7 +3895,7 @@ static bool stmmac_vlan_insert(struct st +@@ -3896,7 +3896,7 @@ static bool stmmac_vlan_insert(struct st static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des, int total_len, bool last_segment, u32 queue) { @@ -802,7 +802,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *desc; u32 buff_size; int tmp_len; -@@ -3906,7 +3906,7 @@ static void stmmac_tso_allocator(struct +@@ -3907,7 +3907,7 @@ static void stmmac_tso_allocator(struct dma_addr_t curr_addr; tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, @@ -811,7 +811,7 @@ Signed-off-by: Jakub Kicinski WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); if (tx_q->tbs & STMMAC_TBS_AVAIL) -@@ -3934,7 +3934,7 @@ static void stmmac_tso_allocator(struct +@@ -3935,7 +3935,7 @@ static void stmmac_tso_allocator(struct static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue) { @@ -820,7 +820,7 @@ Signed-off-by: Jakub Kicinski int desc_size; if (likely(priv->extend_desc)) -@@ -3996,7 +3996,7 @@ static netdev_tx_t stmmac_tso_xmit(struc +@@ -3997,7 +3997,7 @@ static netdev_tx_t stmmac_tso_xmit(struc dma_addr_t des; int i; @@ -829,7 +829,7 @@ Signed-off-by: Jakub Kicinski first_tx = tx_q->cur_tx; /* Compute header lengths */ -@@ -4036,7 +4036,7 @@ static netdev_tx_t stmmac_tso_xmit(struc +@@ -4037,7 +4037,7 @@ static netdev_tx_t stmmac_tso_xmit(struc stmmac_set_mss(priv, mss_desc, mss); tx_q->mss = mss; tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, @@ -838,7 +838,7 @@ Signed-off-by: Jakub Kicinski WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); } -@@ -4148,7 +4148,7 @@ static netdev_tx_t stmmac_tso_xmit(struc +@@ -4149,7 +4149,7 @@ static netdev_tx_t stmmac_tso_xmit(struc * ndo_start_xmit will fill this descriptor the next time it's * called and stmmac_tx_clean may clean up to this descriptor. */ @@ -847,7 +847,7 @@ Signed-off-by: Jakub Kicinski if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) { netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n", -@@ -4236,7 +4236,7 @@ static netdev_tx_t stmmac_xmit(struct sk +@@ -4237,7 +4237,7 @@ static netdev_tx_t stmmac_xmit(struct sk int entry, first_tx; dma_addr_t des; @@ -856,7 +856,7 @@ Signed-off-by: Jakub Kicinski first_tx = tx_q->cur_tx; if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en) -@@ -4299,7 +4299,7 @@ static netdev_tx_t stmmac_xmit(struct sk +@@ -4300,7 +4300,7 @@ static netdev_tx_t stmmac_xmit(struct sk int len = skb_frag_size(frag); bool last_segment = (i == (nfrags - 1)); @@ -865,7 +865,7 @@ Signed-off-by: Jakub Kicinski WARN_ON(tx_q->tx_skbuff[entry]); if (likely(priv->extend_desc)) -@@ -4370,7 +4370,7 @@ static netdev_tx_t stmmac_xmit(struct sk +@@ -4371,7 +4371,7 @@ static netdev_tx_t stmmac_xmit(struct sk * ndo_start_xmit will fill this descriptor the next time it's * called and stmmac_tx_clean may clean up to this descriptor. */ @@ -874,7 +874,7 @@ Signed-off-by: Jakub Kicinski tx_q->cur_tx = entry; if (netif_msg_pktdata(priv)) { -@@ -4485,7 +4485,7 @@ static void stmmac_rx_vlan(struct net_de +@@ -4486,7 +4486,7 @@ static void stmmac_rx_vlan(struct net_de */ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) { @@ -883,7 +883,7 @@ Signed-off-by: Jakub Kicinski int dirty = stmmac_rx_dirty(priv, queue); unsigned int entry = rx_q->dirty_rx; -@@ -4535,7 +4535,7 @@ static inline void stmmac_rx_refill(stru +@@ -4536,7 +4536,7 @@ static inline void stmmac_rx_refill(stru dma_wmb(); stmmac_set_rx_owner(priv, p, use_rx_wd); @@ -892,7 +892,7 @@ Signed-off-by: Jakub Kicinski } rx_q->dirty_rx = entry; rx_q->rx_tail_addr = rx_q->dma_rx_phy + -@@ -4563,12 +4563,12 @@ static unsigned int stmmac_rx_buf1_len(s +@@ -4564,12 +4564,12 @@ static unsigned int stmmac_rx_buf1_len(s /* First descriptor, not last descriptor and not split header */ if (status & rx_not_ls) @@ -907,7 +907,7 @@ Signed-off-by: Jakub Kicinski } static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, -@@ -4584,7 +4584,7 @@ static unsigned int stmmac_rx_buf2_len(s +@@ -4585,7 +4585,7 @@ static unsigned int stmmac_rx_buf2_len(s /* Not last descriptor */ if (status & rx_not_ls) @@ -916,7 +916,7 @@ Signed-off-by: Jakub Kicinski plen = stmmac_get_rx_frame_len(priv, p, coe); -@@ -4595,7 +4595,7 @@ static unsigned int stmmac_rx_buf2_len(s +@@ -4596,7 +4596,7 @@ static unsigned int stmmac_rx_buf2_len(s static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, struct xdp_frame *xdpf, bool dma_map) { @@ -925,7 +925,7 @@ Signed-off-by: Jakub Kicinski unsigned int entry = tx_q->cur_tx; struct dma_desc *tx_desc; dma_addr_t dma_addr; -@@ -4658,7 +4658,7 @@ static int stmmac_xdp_xmit_xdpf(struct s +@@ -4659,7 +4659,7 @@ static int stmmac_xdp_xmit_xdpf(struct s stmmac_enable_dma_transmission(priv, priv->ioaddr); @@ -934,7 +934,7 @@ Signed-off-by: Jakub Kicinski tx_q->cur_tx = entry; return STMMAC_XDP_TX; -@@ -4832,7 +4832,7 @@ static void stmmac_dispatch_skb_zc(struc +@@ -4833,7 +4833,7 @@ static void stmmac_dispatch_skb_zc(struc static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) { @@ -943,7 +943,7 @@ Signed-off-by: Jakub Kicinski unsigned int entry = rx_q->dirty_rx; struct dma_desc *rx_desc = NULL; bool ret = true; -@@ -4875,7 +4875,7 @@ static bool stmmac_rx_refill_zc(struct s +@@ -4876,7 +4876,7 @@ static bool stmmac_rx_refill_zc(struct s dma_wmb(); stmmac_set_rx_owner(priv, rx_desc, use_rx_wd); @@ -952,7 +952,7 @@ Signed-off-by: Jakub Kicinski } if (rx_desc) { -@@ -4890,7 +4890,7 @@ static bool stmmac_rx_refill_zc(struct s +@@ -4891,7 +4891,7 @@ static bool stmmac_rx_refill_zc(struct s static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) { @@ -961,7 +961,7 @@ Signed-off-by: Jakub Kicinski unsigned int count = 0, error = 0, len = 0; int dirty = stmmac_rx_dirty(priv, queue); unsigned int next_entry = rx_q->cur_rx; -@@ -4912,7 +4912,7 @@ static int stmmac_rx_zc(struct stmmac_pr +@@ -4913,7 +4913,7 @@ static int stmmac_rx_zc(struct stmmac_pr desc_size = sizeof(struct dma_desc); } @@ -970,7 +970,7 @@ Signed-off-by: Jakub Kicinski rx_q->dma_rx_phy, desc_size); } while (count < limit) { -@@ -4959,7 +4959,7 @@ read_again: +@@ -4960,7 +4960,7 @@ read_again: /* Prefetch the next RX descriptor */ rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx, @@ -979,7 +979,7 @@ Signed-off-by: Jakub Kicinski next_entry = rx_q->cur_rx; if (priv->extend_desc) -@@ -5080,7 +5080,7 @@ read_again: +@@ -5081,7 +5081,7 @@ read_again: */ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) { @@ -988,7 +988,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[queue]; unsigned int count = 0, error = 0, len = 0; int status = 0, coe = priv->hw->rx_csum; -@@ -5093,7 +5093,7 @@ static int stmmac_rx(struct stmmac_priv +@@ -5094,7 +5094,7 @@ static int stmmac_rx(struct stmmac_priv int buf_sz; dma_dir = page_pool_get_dma_dir(rx_q->page_pool); @@ -997,7 +997,7 @@ Signed-off-by: Jakub Kicinski if (netif_msg_rx_status(priv)) { void *rx_head; -@@ -5107,7 +5107,7 @@ static int stmmac_rx(struct stmmac_priv +@@ -5108,7 +5108,7 @@ static int stmmac_rx(struct stmmac_priv desc_size = sizeof(struct dma_desc); } @@ -1006,7 +1006,7 @@ Signed-off-by: Jakub Kicinski rx_q->dma_rx_phy, desc_size); } while (count < limit) { -@@ -5151,7 +5151,7 @@ read_again: +@@ -5152,7 +5152,7 @@ read_again: break; rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx, @@ -1015,7 +1015,7 @@ Signed-off-by: Jakub Kicinski next_entry = rx_q->cur_rx; if (priv->extend_desc) -@@ -5285,7 +5285,7 @@ read_again: +@@ -5286,7 +5286,7 @@ read_again: buf1_len, dma_dir); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, buf->page, buf->page_offset, buf1_len, @@ -1024,7 +1024,7 @@ Signed-off-by: Jakub Kicinski /* Data payload appended into SKB */ page_pool_release_page(rx_q->page_pool, buf->page); -@@ -5297,7 +5297,7 @@ read_again: +@@ -5298,7 +5298,7 @@ read_again: buf2_len, dma_dir); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, buf->sec_page, 0, buf2_len, @@ -1033,7 +1033,7 @@ Signed-off-by: Jakub Kicinski /* Data payload appended into SKB */ page_pool_release_page(rx_q->page_pool, buf->sec_page); -@@ -5739,11 +5739,13 @@ static irqreturn_t stmmac_safety_interru +@@ -5740,11 +5740,13 @@ static irqreturn_t stmmac_safety_interru static irqreturn_t stmmac_msi_intr_tx(int irq, void *data) { struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)data; @@ -1048,7 +1048,7 @@ Signed-off-by: Jakub Kicinski if (unlikely(!data)) { netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -@@ -5783,10 +5785,12 @@ static irqreturn_t stmmac_msi_intr_tx(in +@@ -5784,10 +5786,12 @@ static irqreturn_t stmmac_msi_intr_tx(in static irqreturn_t stmmac_msi_intr_rx(int irq, void *data) { struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)data; @@ -1062,7 +1062,7 @@ Signed-off-by: Jakub Kicinski if (unlikely(!data)) { netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -@@ -5817,10 +5821,10 @@ static void stmmac_poll_controller(struc +@@ -5818,10 +5822,10 @@ static void stmmac_poll_controller(struc if (priv->plat->multi_msi_en) { for (i = 0; i < priv->plat->rx_queues_to_use; i++) @@ -1075,7 +1075,7 @@ Signed-off-by: Jakub Kicinski } else { disable_irq(dev->irq); stmmac_interrupt(dev->irq, dev); -@@ -6001,34 +6005,34 @@ static int stmmac_rings_status_show(stru +@@ -6002,34 +6006,34 @@ static int stmmac_rings_status_show(stru return 0; for (queue = 0; queue < rx_count; queue++) { @@ -1116,7 +1116,7 @@ Signed-off-by: Jakub Kicinski } } -@@ -6369,7 +6373,7 @@ void stmmac_disable_rx_queue(struct stmm +@@ -6370,7 +6374,7 @@ void stmmac_disable_rx_queue(struct stmm void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue) { @@ -1125,7 +1125,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[queue]; unsigned long flags; u32 buf_size; -@@ -6406,7 +6410,7 @@ void stmmac_enable_rx_queue(struct stmma +@@ -6407,7 +6411,7 @@ void stmmac_enable_rx_queue(struct stmma rx_q->queue_index); } else { stmmac_set_dma_bfsize(priv, priv->ioaddr, @@ -1134,7 +1134,7 @@ Signed-off-by: Jakub Kicinski rx_q->queue_index); } -@@ -6432,7 +6436,7 @@ void stmmac_disable_tx_queue(struct stmm +@@ -6433,7 +6437,7 @@ void stmmac_disable_tx_queue(struct stmm void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue) { @@ -1143,7 +1143,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[queue]; unsigned long flags; int ret; -@@ -6479,7 +6483,7 @@ void stmmac_xdp_release(struct net_devic +@@ -6480,7 +6484,7 @@ void stmmac_xdp_release(struct net_devic stmmac_disable_all_queues(priv); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -1152,7 +1152,7 @@ Signed-off-by: Jakub Kicinski /* Free the IRQ lines */ stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); -@@ -6538,7 +6542,7 @@ int stmmac_xdp_open(struct net_device *d +@@ -6539,7 +6543,7 @@ int stmmac_xdp_open(struct net_device *d /* DMA RX Channel Configuration */ for (chan = 0; chan < rx_cnt; chan++) { @@ -1161,7 +1161,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, rx_q->dma_rx_phy, chan); -@@ -6556,7 +6560,7 @@ int stmmac_xdp_open(struct net_device *d +@@ -6557,7 +6561,7 @@ int stmmac_xdp_open(struct net_device *d rx_q->queue_index); } else { stmmac_set_dma_bfsize(priv, priv->ioaddr, @@ -1170,7 +1170,7 @@ Signed-off-by: Jakub Kicinski rx_q->queue_index); } -@@ -6565,7 +6569,7 @@ int stmmac_xdp_open(struct net_device *d +@@ -6566,7 +6570,7 @@ int stmmac_xdp_open(struct net_device *d /* DMA TX Channel Configuration */ for (chan = 0; chan < tx_cnt; chan++) { @@ -1179,7 +1179,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, tx_q->dma_tx_phy, chan); -@@ -6598,7 +6602,7 @@ int stmmac_xdp_open(struct net_device *d +@@ -6599,7 +6603,7 @@ int stmmac_xdp_open(struct net_device *d irq_error: for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -1188,7 +1188,7 @@ Signed-off-by: Jakub Kicinski stmmac_hw_teardown(dev); init_error: -@@ -6625,8 +6629,8 @@ int stmmac_xsk_wakeup(struct net_device +@@ -6626,8 +6630,8 @@ int stmmac_xsk_wakeup(struct net_device queue >= priv->plat->tx_queues_to_use) return -EINVAL; @@ -1199,7 +1199,7 @@ Signed-off-by: Jakub Kicinski ch = &priv->channel[queue]; if (!rx_q->xsk_pool && !tx_q->xsk_pool) -@@ -6882,8 +6886,8 @@ int stmmac_reinit_ringparam(struct net_d +@@ -6883,8 +6887,8 @@ int stmmac_reinit_ringparam(struct net_d if (netif_running(dev)) stmmac_release(dev); @@ -1210,7 +1210,7 @@ Signed-off-by: Jakub Kicinski if (netif_running(dev)) ret = stmmac_open(dev); -@@ -7329,7 +7333,7 @@ int stmmac_suspend(struct device *dev) +@@ -7330,7 +7334,7 @@ int stmmac_suspend(struct device *dev) stmmac_disable_all_queues(priv); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -1219,7 +1219,7 @@ Signed-off-by: Jakub Kicinski if (priv->eee_enabled) { priv->tx_path_in_lpi_mode = false; -@@ -7380,7 +7384,7 @@ EXPORT_SYMBOL_GPL(stmmac_suspend); +@@ -7381,7 +7385,7 @@ EXPORT_SYMBOL_GPL(stmmac_suspend); static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue) { @@ -1228,7 +1228,7 @@ Signed-off-by: Jakub Kicinski rx_q->cur_rx = 0; rx_q->dirty_rx = 0; -@@ -7388,7 +7392,7 @@ static void stmmac_reset_rx_queue(struct +@@ -7389,7 +7393,7 @@ static void stmmac_reset_rx_queue(struct static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue) { diff --git a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch b/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch index c8544fcda3..be5643df7f 100644 --- a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch +++ b/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch @@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -1284,7 +1284,8 @@ static int stmmac_phy_setup(struct stmma +@@ -1285,7 +1285,8 @@ static int stmmac_phy_setup(struct stmma return 0; } @@ -27,7 +27,7 @@ Signed-off-by: Jakub Kicinski { u32 rx_cnt = priv->plat->rx_queues_to_use; unsigned int desc_size; -@@ -1293,7 +1294,7 @@ static void stmmac_display_rx_rings(stru +@@ -1294,7 +1295,7 @@ static void stmmac_display_rx_rings(stru /* Display RX rings */ for (queue = 0; queue < rx_cnt; queue++) { @@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski pr_info("\tRX Queue %u rings\n", queue); -@@ -1306,12 +1307,13 @@ static void stmmac_display_rx_rings(stru +@@ -1307,12 +1308,13 @@ static void stmmac_display_rx_rings(stru } /* Display RX ring */ @@ -52,7 +52,7 @@ Signed-off-by: Jakub Kicinski { u32 tx_cnt = priv->plat->tx_queues_to_use; unsigned int desc_size; -@@ -1320,7 +1322,7 @@ static void stmmac_display_tx_rings(stru +@@ -1321,7 +1323,7 @@ static void stmmac_display_tx_rings(stru /* Display TX rings */ for (queue = 0; queue < tx_cnt; queue++) { @@ -61,7 +61,7 @@ Signed-off-by: Jakub Kicinski pr_info("\tTX Queue %d rings\n", queue); -@@ -1335,18 +1337,19 @@ static void stmmac_display_tx_rings(stru +@@ -1336,18 +1338,19 @@ static void stmmac_display_tx_rings(stru desc_size = sizeof(struct dma_desc); } @@ -85,7 +85,7 @@ Signed-off-by: Jakub Kicinski } static int stmmac_set_bfsize(int mtu, int bufsize) -@@ -1370,44 +1373,50 @@ static int stmmac_set_bfsize(int mtu, in +@@ -1371,44 +1374,50 @@ static int stmmac_set_bfsize(int mtu, in /** * stmmac_clear_rx_descriptors - clear RX descriptors * @priv: driver private structure @@ -147,7 +147,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; if (priv->extend_desc) -@@ -1424,10 +1433,12 @@ static void stmmac_clear_tx_descriptors( +@@ -1425,10 +1434,12 @@ static void stmmac_clear_tx_descriptors( /** * stmmac_clear_descriptors - clear descriptors * @priv: driver private structure @@ -161,7 +161,7 @@ Signed-off-by: Jakub Kicinski { u32 rx_queue_cnt = priv->plat->rx_queues_to_use; u32 tx_queue_cnt = priv->plat->tx_queues_to_use; -@@ -1435,16 +1446,17 @@ static void stmmac_clear_descriptors(str +@@ -1436,16 +1447,17 @@ static void stmmac_clear_descriptors(str /* Clear the RX descriptors */ for (queue = 0; queue < rx_queue_cnt; queue++) @@ -181,7 +181,7 @@ Signed-off-by: Jakub Kicinski * @p: descriptor pointer * @i: descriptor index * @flags: gfp flag -@@ -1452,10 +1464,12 @@ static void stmmac_clear_descriptors(str +@@ -1453,10 +1465,12 @@ static void stmmac_clear_descriptors(str * Description: this function is called to allocate a receive buffer, perform * the DMA mapping and init the descriptor. */ @@ -196,7 +196,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (!buf->page) { -@@ -1480,7 +1494,7 @@ static int stmmac_init_rx_buffers(struct +@@ -1481,7 +1495,7 @@ static int stmmac_init_rx_buffers(struct buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset; stmmac_set_desc_addr(priv, p, buf->addr); @@ -205,7 +205,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_desc3(priv, p); return 0; -@@ -1489,12 +1503,13 @@ static int stmmac_init_rx_buffers(struct +@@ -1490,12 +1504,13 @@ static int stmmac_init_rx_buffers(struct /** * stmmac_free_rx_buffer - free RX dma buffers * @priv: private structure @@ -222,7 +222,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (buf->page) -@@ -1509,12 +1524,15 @@ static void stmmac_free_rx_buffer(struct +@@ -1510,12 +1525,15 @@ static void stmmac_free_rx_buffer(struct /** * stmmac_free_tx_buffer - free RX dma buffers * @priv: private structure @@ -240,7 +240,7 @@ Signed-off-by: Jakub Kicinski if (tx_q->tx_skbuff_dma[i].buf && tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) { -@@ -1553,23 +1571,28 @@ static void stmmac_free_tx_buffer(struct +@@ -1554,23 +1572,28 @@ static void stmmac_free_tx_buffer(struct /** * dma_free_rx_skbufs - free RX dma buffers * @priv: private structure @@ -276,7 +276,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; int ret; -@@ -1578,7 +1601,7 @@ static int stmmac_alloc_rx_buffers(struc +@@ -1579,7 +1602,7 @@ static int stmmac_alloc_rx_buffers(struc else p = rx_q->dma_rx + i; @@ -285,7 +285,7 @@ Signed-off-by: Jakub Kicinski queue); if (ret) return ret; -@@ -1592,14 +1615,17 @@ static int stmmac_alloc_rx_buffers(struc +@@ -1593,14 +1616,17 @@ static int stmmac_alloc_rx_buffers(struc /** * dma_free_rx_xskbufs - free RX dma buffers from XSK pool * @priv: private structure @@ -306,7 +306,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; if (!buf->xdp) -@@ -1610,12 +1636,14 @@ static void dma_free_rx_xskbufs(struct s +@@ -1611,12 +1637,14 @@ static void dma_free_rx_xskbufs(struct s } } @@ -324,7 +324,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_rx_buffer *buf; dma_addr_t dma_addr; struct dma_desc *p; -@@ -1650,22 +1678,25 @@ static struct xsk_buff_pool *stmmac_get_ +@@ -1651,22 +1679,25 @@ static struct xsk_buff_pool *stmmac_get_ /** * __init_dma_rx_desc_rings - init the RX descriptor ring (per queue) * @priv: driver private structure @@ -353,7 +353,7 @@ Signed-off-by: Jakub Kicinski xdp_rxq_info_unreg_mem_model(&rx_q->xdp_rxq); -@@ -1692,9 +1723,9 @@ static int __init_dma_rx_desc_rings(stru +@@ -1693,9 +1724,9 @@ static int __init_dma_rx_desc_rings(stru /* RX XDP ZC buffer pool may not be populated, e.g. * xdpsock TX-only. */ @@ -365,7 +365,7 @@ Signed-off-by: Jakub Kicinski if (ret < 0) return -ENOMEM; } -@@ -1704,17 +1735,19 @@ static int __init_dma_rx_desc_rings(stru +@@ -1705,17 +1736,19 @@ static int __init_dma_rx_desc_rings(stru if (priv->extend_desc) stmmac_mode_init(priv, rx_q->dma_erx, rx_q->dma_rx_phy, @@ -388,7 +388,7 @@ Signed-off-by: Jakub Kicinski { struct stmmac_priv *priv = netdev_priv(dev); u32 rx_count = priv->plat->rx_queues_to_use; -@@ -1726,7 +1759,7 @@ static int init_dma_rx_desc_rings(struct +@@ -1727,7 +1760,7 @@ static int init_dma_rx_desc_rings(struct "SKB addresses:\nskb\t\tskb data\tdma data\n"); for (queue = 0; queue < rx_count; queue++) { @@ -397,7 +397,7 @@ Signed-off-by: Jakub Kicinski if (ret) goto err_init_rx_buffers; } -@@ -1735,12 +1768,12 @@ static int init_dma_rx_desc_rings(struct +@@ -1736,12 +1769,12 @@ static int init_dma_rx_desc_rings(struct err_init_rx_buffers: while (queue >= 0) { @@ -413,7 +413,7 @@ Signed-off-by: Jakub Kicinski rx_q->buf_alloc_num = 0; rx_q->xsk_pool = NULL; -@@ -1757,14 +1790,17 @@ err_init_rx_buffers: +@@ -1758,14 +1791,17 @@ err_init_rx_buffers: /** * __init_dma_tx_desc_rings - init the TX descriptor ring (per queue) * @priv: driver private structure @@ -434,7 +434,7 @@ Signed-off-by: Jakub Kicinski int i; netif_dbg(priv, probe, priv->dev, -@@ -1776,16 +1812,16 @@ static int __init_dma_tx_desc_rings(stru +@@ -1777,16 +1813,16 @@ static int __init_dma_tx_desc_rings(stru if (priv->extend_desc) stmmac_mode_init(priv, tx_q->dma_etx, tx_q->dma_tx_phy, @@ -454,7 +454,7 @@ Signed-off-by: Jakub Kicinski struct dma_desc *p; if (priv->extend_desc) -@@ -1807,7 +1843,8 @@ static int __init_dma_tx_desc_rings(stru +@@ -1808,7 +1844,8 @@ static int __init_dma_tx_desc_rings(stru return 0; } @@ -464,7 +464,7 @@ Signed-off-by: Jakub Kicinski { struct stmmac_priv *priv = netdev_priv(dev); u32 tx_queue_cnt; -@@ -1816,7 +1853,7 @@ static int init_dma_tx_desc_rings(struct +@@ -1817,7 +1854,7 @@ static int init_dma_tx_desc_rings(struct tx_queue_cnt = priv->plat->tx_queues_to_use; for (queue = 0; queue < tx_queue_cnt; queue++) @@ -473,7 +473,7 @@ Signed-off-by: Jakub Kicinski return 0; } -@@ -1824,26 +1861,29 @@ static int init_dma_tx_desc_rings(struct +@@ -1825,26 +1862,29 @@ static int init_dma_tx_desc_rings(struct /** * init_dma_desc_rings - init the RX/TX descriptor rings * @dev: net device structure @@ -508,7 +508,7 @@ Signed-off-by: Jakub Kicinski return ret; } -@@ -1851,17 +1891,20 @@ static int init_dma_desc_rings(struct ne +@@ -1852,17 +1892,20 @@ static int init_dma_desc_rings(struct ne /** * dma_free_tx_skbufs - free TX dma buffers * @priv: private structure @@ -533,7 +533,7 @@ Signed-off-by: Jakub Kicinski if (tx_q->xsk_pool && tx_q->xsk_frames_done) { xsk_tx_completed(tx_q->xsk_pool, tx_q->xsk_frames_done); -@@ -1880,34 +1923,37 @@ static void stmmac_free_tx_skbufs(struct +@@ -1881,34 +1924,37 @@ static void stmmac_free_tx_skbufs(struct u32 queue; for (queue = 0; queue < tx_queue_cnt; queue++) @@ -578,7 +578,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_extended_desc), rx_q->dma_erx, rx_q->dma_rx_phy); -@@ -1919,29 +1965,33 @@ static void __free_dma_rx_desc_resources +@@ -1920,29 +1966,33 @@ static void __free_dma_rx_desc_resources page_pool_destroy(rx_q->page_pool); } @@ -617,7 +617,7 @@ Signed-off-by: Jakub Kicinski if (priv->extend_desc) { size = sizeof(struct dma_extended_desc); -@@ -1954,7 +2004,7 @@ static void __free_dma_tx_desc_resources +@@ -1955,7 +2005,7 @@ static void __free_dma_tx_desc_resources addr = tx_q->dma_tx; } @@ -626,7 +626,7 @@ Signed-off-by: Jakub Kicinski dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); -@@ -1962,28 +2012,32 @@ static void __free_dma_tx_desc_resources +@@ -1963,28 +2013,32 @@ static void __free_dma_tx_desc_resources kfree(tx_q->tx_skbuff); } @@ -663,7 +663,7 @@ Signed-off-by: Jakub Kicinski struct stmmac_channel *ch = &priv->channel[queue]; bool xdp_prog = stmmac_xdp_is_enabled(priv); struct page_pool_params pp_params = { 0 }; -@@ -1995,8 +2049,8 @@ static int __alloc_dma_rx_desc_resources +@@ -1996,8 +2050,8 @@ static int __alloc_dma_rx_desc_resources rx_q->priv_data = priv; pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; @@ -674,7 +674,7 @@ Signed-off-by: Jakub Kicinski pp_params.order = ilog2(num_pages); pp_params.nid = dev_to_node(priv->device); pp_params.dev = priv->device; -@@ -2011,7 +2065,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2012,7 +2066,7 @@ static int __alloc_dma_rx_desc_resources return ret; } @@ -683,7 +683,7 @@ Signed-off-by: Jakub Kicinski sizeof(*rx_q->buf_pool), GFP_KERNEL); if (!rx_q->buf_pool) -@@ -2019,7 +2073,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2020,7 +2074,7 @@ static int __alloc_dma_rx_desc_resources if (priv->extend_desc) { rx_q->dma_erx = dma_alloc_coherent(priv->device, @@ -692,7 +692,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_extended_desc), &rx_q->dma_rx_phy, GFP_KERNEL); -@@ -2028,7 +2082,7 @@ static int __alloc_dma_rx_desc_resources +@@ -2029,7 +2083,7 @@ static int __alloc_dma_rx_desc_resources } else { rx_q->dma_rx = dma_alloc_coherent(priv->device, @@ -701,7 +701,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct dma_desc), &rx_q->dma_rx_phy, GFP_KERNEL); -@@ -2053,7 +2107,8 @@ static int __alloc_dma_rx_desc_resources +@@ -2054,7 +2108,8 @@ static int __alloc_dma_rx_desc_resources return 0; } @@ -711,7 +711,7 @@ Signed-off-by: Jakub Kicinski { u32 rx_count = priv->plat->rx_queues_to_use; u32 queue; -@@ -2061,7 +2116,7 @@ static int alloc_dma_rx_desc_resources(s +@@ -2062,7 +2117,7 @@ static int alloc_dma_rx_desc_resources(s /* RX queues buffers and DMA */ for (queue = 0; queue < rx_count; queue++) { @@ -720,7 +720,7 @@ Signed-off-by: Jakub Kicinski if (ret) goto err_dma; } -@@ -2069,7 +2124,7 @@ static int alloc_dma_rx_desc_resources(s +@@ -2070,7 +2125,7 @@ static int alloc_dma_rx_desc_resources(s return 0; err_dma: @@ -729,7 +729,7 @@ Signed-off-by: Jakub Kicinski return ret; } -@@ -2077,28 +2132,31 @@ err_dma: +@@ -2078,28 +2133,31 @@ err_dma: /** * __alloc_dma_tx_desc_resources - alloc TX resources (per queue). * @priv: private structure @@ -765,7 +765,7 @@ Signed-off-by: Jakub Kicinski sizeof(struct sk_buff *), GFP_KERNEL); if (!tx_q->tx_skbuff) -@@ -2111,7 +2169,7 @@ static int __alloc_dma_tx_desc_resources +@@ -2112,7 +2170,7 @@ static int __alloc_dma_tx_desc_resources else size = sizeof(struct dma_desc); @@ -774,7 +774,7 @@ Signed-off-by: Jakub Kicinski addr = dma_alloc_coherent(priv->device, size, &tx_q->dma_tx_phy, GFP_KERNEL); -@@ -2128,7 +2186,8 @@ static int __alloc_dma_tx_desc_resources +@@ -2129,7 +2187,8 @@ static int __alloc_dma_tx_desc_resources return 0; } @@ -784,7 +784,7 @@ Signed-off-by: Jakub Kicinski { u32 tx_count = priv->plat->tx_queues_to_use; u32 queue; -@@ -2136,7 +2195,7 @@ static int alloc_dma_tx_desc_resources(s +@@ -2137,7 +2196,7 @@ static int alloc_dma_tx_desc_resources(s /* TX queues buffers and DMA */ for (queue = 0; queue < tx_count; queue++) { @@ -793,7 +793,7 @@ Signed-off-by: Jakub Kicinski if (ret) goto err_dma; } -@@ -2144,27 +2203,29 @@ static int alloc_dma_tx_desc_resources(s +@@ -2145,27 +2204,29 @@ static int alloc_dma_tx_desc_resources(s return 0; err_dma: @@ -827,7 +827,7 @@ Signed-off-by: Jakub Kicinski return ret; } -@@ -2172,16 +2233,18 @@ static int alloc_dma_desc_resources(stru +@@ -2173,16 +2234,18 @@ static int alloc_dma_desc_resources(stru /** * free_dma_desc_resources - free dma desc resources * @priv: private structure @@ -849,7 +849,7 @@ Signed-off-by: Jakub Kicinski } /** -@@ -2670,8 +2733,8 @@ static void stmmac_tx_err(struct stmmac_ +@@ -2671,8 +2734,8 @@ static void stmmac_tx_err(struct stmmac_ netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan)); stmmac_stop_tx_dma(priv, chan); @@ -860,7 +860,7 @@ Signed-off-by: Jakub Kicinski stmmac_reset_tx_queue(priv, chan); stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, tx_q->dma_tx_phy, chan); -@@ -3668,19 +3731,93 @@ static int stmmac_request_irq(struct net +@@ -3669,19 +3732,93 @@ static int stmmac_request_irq(struct net } /** @@ -957,7 +957,7 @@ Signed-off-by: Jakub Kicinski u32 chan; int ret; -@@ -3707,45 +3844,10 @@ static int stmmac_open(struct net_device +@@ -3708,45 +3845,10 @@ static int stmmac_open(struct net_device memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); priv->xstats.threshold = tc; @@ -1005,7 +1005,7 @@ Signed-off-by: Jakub Kicinski stmmac_reset_queues_param(priv); -@@ -3779,14 +3881,28 @@ irq_error: +@@ -3780,14 +3882,28 @@ irq_error: stmmac_hw_teardown(dev); init_error: @@ -1036,7 +1036,7 @@ Signed-off-by: Jakub Kicinski static void stmmac_fpe_stop_wq(struct stmmac_priv *priv) { set_bit(__FPE_REMOVING, &priv->fpe_task_state); -@@ -3833,7 +3949,7 @@ static int stmmac_release(struct net_dev +@@ -3834,7 +3950,7 @@ static int stmmac_release(struct net_dev stmmac_stop_all_dma(priv); /* Release and free the Rx/Tx resources */ @@ -1045,7 +1045,7 @@ Signed-off-by: Jakub Kicinski /* Disable the MAC Rx/Tx */ stmmac_mac_set(priv, priv->ioaddr, false); -@@ -6368,7 +6484,7 @@ void stmmac_disable_rx_queue(struct stmm +@@ -6369,7 +6485,7 @@ void stmmac_disable_rx_queue(struct stmm spin_unlock_irqrestore(&ch->lock, flags); stmmac_stop_rx_dma(priv, queue); @@ -1054,7 +1054,7 @@ Signed-off-by: Jakub Kicinski } void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue) -@@ -6379,21 +6495,21 @@ void stmmac_enable_rx_queue(struct stmma +@@ -6380,21 +6496,21 @@ void stmmac_enable_rx_queue(struct stmma u32 buf_size; int ret; @@ -1080,7 +1080,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, rx_q->dma_rx_phy, rx_q->queue_index); -@@ -6431,7 +6547,7 @@ void stmmac_disable_tx_queue(struct stmm +@@ -6432,7 +6548,7 @@ void stmmac_disable_tx_queue(struct stmm spin_unlock_irqrestore(&ch->lock, flags); stmmac_stop_tx_dma(priv, queue); @@ -1089,7 +1089,7 @@ Signed-off-by: Jakub Kicinski } void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue) -@@ -6441,21 +6557,21 @@ void stmmac_enable_tx_queue(struct stmma +@@ -6442,21 +6558,21 @@ void stmmac_enable_tx_queue(struct stmma unsigned long flags; int ret; @@ -1115,7 +1115,7 @@ Signed-off-by: Jakub Kicinski stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, tx_q->dma_tx_phy, tx_q->queue_index); -@@ -6492,7 +6608,7 @@ void stmmac_xdp_release(struct net_devic +@@ -6493,7 +6609,7 @@ void stmmac_xdp_release(struct net_devic stmmac_stop_all_dma(priv); /* Release and free the Rx/Tx resources */ @@ -1124,7 +1124,7 @@ Signed-off-by: Jakub Kicinski /* Disable the MAC Rx/Tx */ stmmac_mac_set(priv, priv->ioaddr, false); -@@ -6517,14 +6633,14 @@ int stmmac_xdp_open(struct net_device *d +@@ -6518,14 +6634,14 @@ int stmmac_xdp_open(struct net_device *d u32 chan; int ret; @@ -1141,7 +1141,7 @@ Signed-off-by: Jakub Kicinski if (ret < 0) { netdev_err(dev, "%s: DMA descriptors initialization failed\n", __func__); -@@ -6606,7 +6722,7 @@ irq_error: +@@ -6607,7 +6723,7 @@ irq_error: stmmac_hw_teardown(dev); init_error: @@ -1150,7 +1150,7 @@ Signed-off-by: Jakub Kicinski dma_desc_error: return ret; } -@@ -7475,7 +7591,7 @@ int stmmac_resume(struct device *dev) +@@ -7476,7 +7592,7 @@ int stmmac_resume(struct device *dev) stmmac_reset_queues_param(priv); stmmac_free_tx_skbufs(priv); diff --git a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch b/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch index c5b332878e..536c7334ec 100644 --- a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch +++ b/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch @@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5597,18 +5597,15 @@ static int stmmac_change_mtu(struct net_ +@@ -5598,18 +5598,15 @@ static int stmmac_change_mtu(struct net_ { struct stmmac_priv *priv = netdev_priv(dev); int txfifosz = priv->plat->tx_fifo_size; @@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski if (stmmac_xdp_is_enabled(priv) && new_mtu > ETH_DATA_LEN) { netdev_dbg(priv->dev, "Jumbo frames not supported for XDP\n"); return -EINVAL; -@@ -5620,8 +5617,29 @@ static int stmmac_change_mtu(struct net_ +@@ -5621,8 +5618,29 @@ static int stmmac_change_mtu(struct net_ if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) return -EINVAL; diff --git a/target/linux/generic/backport-5.15/802-v6.1-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.15/802-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch similarity index 100% rename from target/linux/generic/backport-5.15/802-v6.1-nvmem-add-driver-handling-U-Boot-environment-variabl.patch rename to target/linux/generic/backport-5.15/802-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch diff --git a/target/linux/generic/backport-5.15/802-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.15/802-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch new file mode 100644 index 0000000000..3a6b76a221 --- /dev/null +++ b/target/linux/generic/backport-5.15/802-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch @@ -0,0 +1,29 @@ +From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 15 Sep 2022 22:06:29 +0200 +Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +DT binding allows specifying NVMEM cells as NVMEM device (provider) +subnodes. Looks for such subnodes when building NVMEM cells. + +This allows NVMEM consumers to use U-Boot environment variables. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +--- + drivers/nvmem/u-boot-env.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u + return -ENOMEM; + priv->cells[idx].offset = data_offset + value - data; + priv->cells[idx].bytes = strlen(value); ++ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); + } + + if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-5.15/802-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.15/802-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch new file mode 100644 index 0000000000..6b40557116 --- /dev/null +++ b/target/linux/generic/backport-5.15/802-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch @@ -0,0 +1,30 @@ +From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 18 Aug 2022 06:38:37 +0200 +Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes: +drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32 + +Reported-by: kernel test robot +Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +--- + drivers/nvmem/u-boot-env.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo + data_offset = offsetof(struct u_boot_env_image_redundant, data); + break; + } +- crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset)); ++ crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); + crc32_data_len = priv->mtd->size - crc32_data_offset; + data_len = priv->mtd->size - data_offset; + diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 index f1ff9e2202..7879046cd5 100644 --- a/target/linux/generic/config-5.10 +++ b/target/linux/generic/config-5.10 @@ -1337,6 +1337,7 @@ CONFIG_DEFAULT_CUBIC=y CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_FQ is not set CONFIG_DEFAULT_FQ_CODEL=y +# CONFIG_DEFAULT_FQ_PIE is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 CONFIG_DEFAULT_INIT="" @@ -7106,15 +7107,15 @@ CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # CONFIG_WD80x3 is not set # CONFIG_WDAT_WDT is not set # CONFIG_WDTPCI is not set -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PRIV=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y +# CONFIG_WEXT_CORE is not set +# CONFIG_WEXT_PRIV is not set +# CONFIG_WEXT_PROC is not set +# CONFIG_WEXT_SPY is not set CONFIG_WILINK_PLATFORM_DATA=y # CONFIG_WIMAX is not set # CONFIG_WIREGUARD is not set CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_EXT is not set # CONFIG_WIRELESS_WDS is not set # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index db58b68d6a..1d21852814 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -328,6 +328,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARM64_ERRATUM_1508412 is not set # CONFIG_ARM64_ERRATUM_1530923 is not set # CONFIG_ARM64_ERRATUM_1542419 is not set +# CONFIG_ARM64_ERRATUM_2441009 is not set # CONFIG_ARM64_ERRATUM_819472 is not set # CONFIG_ARM64_ERRATUM_824069 is not set # CONFIG_ARM64_ERRATUM_826319 is not set @@ -337,7 +338,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARM64_ERRATUM_843419 is not set # CONFIG_ARM64_ERRATUM_845719 is not set # CONFIG_ARM64_ERRATUM_858921 is not set -# CONFIG_ARM64_ERRATUM_2441009 is not set # CONFIG_ARM64_HW_AFDBM is not set # CONFIG_ARM64_LSE_ATOMICS is not set # CONFIG_ARM64_MODULE_PLTS is not set @@ -930,7 +930,6 @@ CONFIG_CIFS_XATTR=y # CONFIG_CLEANCACHE is not set # CONFIG_CLKSRC_PISTACHIO is not set # CONFIG_CLKSRC_VERSATILE is not set -# CONFIG_CLKSRC_PISTACHIO is not set # CONFIG_CLK_GFM_LPASS_SM8250 is not set # CONFIG_CLK_HSDK is not set # CONFIG_CLK_QORIQ is not set @@ -1381,6 +1380,7 @@ CONFIG_DEFAULT_CUBIC=y CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_FQ is not set CONFIG_DEFAULT_FQ_CODEL=y +# CONFIG_DEFAULT_FQ_PIE is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 CONFIG_DEFAULT_INIT="" @@ -4483,6 +4483,7 @@ CONFIG_PACKET=y # CONFIG_PAGE_EXTENSION is not set # CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_PAGE_POOL_STATS is not set # CONFIG_PAGE_REPORTING is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_32KB is not set @@ -5976,7 +5977,6 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_FSL_AUD2HTX is not set # CONFIG_SND_SOC_FSL_AUDMIX is not set # CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_IMX_RPMSG is not set # CONFIG_SND_SOC_FSL_MICFIL is not set # CONFIG_SND_SOC_FSL_RPMSG is not set # CONFIG_SND_SOC_FSL_SAI is not set @@ -5991,6 +5991,7 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_IMX_CARD is not set # CONFIG_SND_SOC_IMX_ES8328 is not set # CONFIG_SND_SOC_IMX_HDMI is not set +# CONFIG_SND_SOC_IMX_RPMSG is not set # CONFIG_SND_SOC_IMX_SPDIF is not set # CONFIG_SND_SOC_IMX_WM8962 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set @@ -7440,15 +7441,15 @@ CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # CONFIG_WDAT_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_WERROR is not set -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PRIV=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y +# CONFIG_WEXT_CORE is not set +# CONFIG_WEXT_PRIV is not set +# CONFIG_WEXT_PROC is not set +# CONFIG_WEXT_SPY is not set CONFIG_WILINK_PLATFORM_DATA=y # CONFIG_WIMAX is not set # CONFIG_WIREGUARD is not set CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_EXT is not set # CONFIG_WIRELESS_WDS is not set # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set diff --git a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch index 237933a4df..206e16cb17 100644 --- a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch +++ b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch @@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau */ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2851,6 +2851,10 @@ static inline int pskb_trim(struct sk_bu +@@ -2852,6 +2852,10 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } @@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau /** * pskb_trim_unique - remove end from a paged unique (not cloned) buffer * @skb: buffer to alter -@@ -3001,16 +3005,6 @@ static inline struct sk_buff *dev_alloc_ +@@ -3002,16 +3006,6 @@ static inline struct sk_buff *dev_alloc_ } diff --git a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch index bb8b7d982d..7fc1c588b3 100644 --- a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2817,7 +2817,7 @@ static inline int pskb_network_may_pull( +@@ -2818,7 +2818,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD diff --git a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index 233d7b6563..41190fcfd4 100644 --- a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau #endif --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -890,6 +890,7 @@ struct sk_buff { +@@ -891,6 +891,7 @@ struct sk_buff { #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif diff --git a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch index 298122375f..49c6ea1c03 100644 --- a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2383,8 +2383,8 @@ static irqreturn_t mtk_handle_irq_rx(int +@@ -2789,8 +2789,8 @@ static irqreturn_t mtk_handle_irq_rx(int eth->rx_events++; if (likely(napi_schedule_prep(ð->rx_napi))) { @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -2396,8 +2396,8 @@ static irqreturn_t mtk_handle_irq_tx(int +@@ -2802,8 +2802,8 @@ static irqreturn_t mtk_handle_irq_tx(int eth->tx_events++; if (likely(napi_schedule_prep(ð->tx_napi))) { @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -3587,6 +3587,8 @@ static int mtk_probe(struct platform_dev +@@ -4074,6 +4074,8 @@ static int mtk_probe(struct platform_dev * for NAPI to work */ init_dummy_netdev(ð->dummy_dev); diff --git a/target/linux/generic/pending-5.15/781-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch b/target/linux/generic/pending-5.15/781-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch new file mode 100644 index 0000000000..008e20416d --- /dev/null +++ b/target/linux/generic/pending-5.15/781-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch @@ -0,0 +1,127 @@ +From patchwork Thu Sep 8 19:33:38 2022 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Lorenzo Bianconi +X-Patchwork-Id: 12970556 +X-Patchwork-Delegate: kuba@kernel.org +From: Lorenzo Bianconi +To: netdev@vger.kernel.org +Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, + Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, + linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, + Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, + ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, + devicetree@vger.kernel.org, robh@kernel.org +Subject: [PATCH net-next 03/12] net: ethernet: mtk_eth_soc: move gdma_to_ppe + and ppe_base definitions in mtk register map +Date: Thu, 8 Sep 2022 21:33:37 +0200 +Message-Id: + <95938fc9cbe0223714be2658a49ca58e9baace00.1662661555.git.lorenzo@kernel.org> +X-Mailer: git-send-email 2.37.3 +In-Reply-To: +References: +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +This is a preliminary patch to introduce mt7986 hw packet engine. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 +++++++++++---- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 ++- + drivers/net/ethernet/mediatek/mtk_ppe.h | 2 -- + 3 files changed, 13 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -73,6 +73,8 @@ static const struct mtk_reg_map mtk_reg_ + .fq_blen = 0x1b2c, + }, + .gdm1_cnt = 0x2400, ++ .gdma_to_ppe0 = 0x4444, ++ .ppe_base = 0x0c00, + }; + + static const struct mtk_reg_map mt7628_reg_map = { +@@ -126,6 +128,8 @@ static const struct mtk_reg_map mt7986_r + .fq_blen = 0x472c, + }, + .gdm1_cnt = 0x1c00, ++ .gdma_to_ppe0 = 0x3333, ++ .ppe_base = 0x2000, + }; + + /* strings used by ethtool */ +@@ -2924,6 +2928,7 @@ static int mtk_open(struct net_device *d + + /* we run 2 netdevs on the same dma ring so we only bring it up once */ + if (!refcount_read(ð->dma_refcnt)) { ++ const struct mtk_soc_data *soc = eth->soc; + u32 gdm_config = MTK_GDMA_TO_PDMA; + int err; + +@@ -2931,15 +2936,15 @@ static int mtk_open(struct net_device *d + if (err) + return err; + +- if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0) +- gdm_config = MTK_GDMA_TO_PPE; ++ if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0) ++ gdm_config = soc->reg_map->gdma_to_ppe0; + + mtk_gdm_config(eth, gdm_config); + + napi_enable(ð->tx_napi); + napi_enable(ð->rx_napi); + mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); +- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); ++ mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask); + refcount_set(ð->dma_refcnt, 1); + } + else +@@ -4045,7 +4050,9 @@ static int mtk_probe(struct platform_dev + } + + if (eth->soc->offload_version) { +- eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2); ++ u32 ppe_addr = eth->soc->reg_map->ppe_base; ++ ++ eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2); + if (!eth->ppe) { + err = -ENOMEM; + goto err_free_dev; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -105,7 +105,6 @@ + #define MTK_GDMA_TCS_EN BIT(21) + #define MTK_GDMA_UCS_EN BIT(20) + #define MTK_GDMA_TO_PDMA 0x0 +-#define MTK_GDMA_TO_PPE 0x4444 + #define MTK_GDMA_DROP_ALL 0x7777 + + /* Unicast Filter MAC Address Register - Low */ +@@ -952,6 +951,8 @@ struct mtk_reg_map { + u32 fq_blen; /* fq free page buffer length */ + } qdma; + u32 gdm1_cnt; ++ u32 gdma_to_ppe0; ++ u32 ppe_base; + }; + + /* struct mtk_eth_data - This is the structure holding all differences +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -8,8 +8,6 @@ + #include + #include + +-#define MTK_ETH_PPE_BASE 0xc00 +- + #define MTK_PPE_ENTRIES_SHIFT 3 + #define MTK_PPE_ENTRIES (1024 << MTK_PPE_ENTRIES_SHIFT) + #define MTK_PPE_HASH_MASK (MTK_PPE_ENTRIES - 1) diff --git a/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch b/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch new file mode 100644 index 0000000000..89a3aa9893 --- /dev/null +++ b/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch @@ -0,0 +1,199 @@ +From patchwork Thu Sep 8 19:33:38 2022 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Lorenzo Bianconi +X-Patchwork-Id: 12970557 +X-Patchwork-Delegate: kuba@kernel.org +From: Lorenzo Bianconi +To: netdev@vger.kernel.org +Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, + Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, + linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, + Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, + ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, + devicetree@vger.kernel.org, robh@kernel.org +Subject: [PATCH net-next 04/12] net: ethernet: mtk_eth_soc: move ppe table + hash offset to mtk_soc_data structure +Date: Thu, 8 Sep 2022 21:33:38 +0200 +Message-Id: + +X-Mailer: git-send-email 2.37.3 +In-Reply-To: +References: +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +This is a preliminary patch to introduce mt7986 hw packet engine. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 24 +++++++++++++++------ + drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +- + 4 files changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4150,6 +4150,7 @@ static const struct mtk_soc_data mt7621_ + .required_clks = MT7621_CLKS_BITMAP, + .required_pctl = false, + .offload_version = 2, ++ .hash_offset = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4168,6 +4169,7 @@ static const struct mtk_soc_data mt7622_ + .required_clks = MT7622_CLKS_BITMAP, + .required_pctl = false, + .offload_version = 2, ++ .hash_offset = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4185,6 +4187,7 @@ static const struct mtk_soc_data mt7623_ + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, + .offload_version = 2, ++ .hash_offset = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4218,6 +4221,7 @@ static const struct mtk_soc_data mt7986_ + .caps = MT7986_CAPS, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, ++ .hash_offset = 4, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -966,6 +966,7 @@ struct mtk_reg_map { + * the target SoC + * @required_pctl A bool value to show whether the SoC requires + * the extra setup for those pins used by GMAC. ++ * @hash_offset Flow table hash offset. + * @txd_size Tx DMA descriptor size. + * @rxd_size Rx DMA descriptor size. + * @rx_irq_done_mask Rx irq done register mask. +@@ -980,6 +981,7 @@ struct mtk_soc_data { + u32 required_clks; + bool required_pctl; + u8 offload_version; ++ u8 hash_offset; + netdev_features_t hw_features; + struct { + u32 txd_size; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct + enable * MTK_PPE_CACHE_CTL_EN); + } + +-static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e) ++static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e) + { + u32 hv1, hv2, hv3; + u32 hash; +@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk + hash = (hash >> 24) | ((hash & 0xffffff) << 8); + hash ^= hv1 ^ hv2 ^ hv3; + hash ^= hash >> 16; +- hash <<= 1; ++ hash <<= (ffs(eth->soc->hash_offset) - 1); + hash &= MTK_PPE_ENTRIES - 1; + + return hash; +@@ -540,15 +540,16 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { + int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); ++ const struct mtk_soc_data *soc = ppe->eth->soc; + u32 hash; + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) + return mtk_foe_entry_commit_l2(ppe, entry); + +- hash = mtk_ppe_hash_entry(&entry->data); ++ hash = mtk_ppe_hash_entry(ppe->eth, &entry->data); + entry->hash = 0xffff; + spin_lock_bh(&ppe_lock); +- hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]); ++ hlist_add_head(&entry->list, &ppe->foe_flow[hash / soc->hash_offset]); + spin_unlock_bh(&ppe_lock); + + return 0; +@@ -558,6 +559,7 @@ static void + mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, + u16 hash) + { ++ const struct mtk_soc_data *soc = ppe->eth->soc; + struct mtk_flow_entry *flow_info; + struct mtk_foe_entry foe, *hwe; + struct mtk_foe_mac_info *l2; +@@ -572,7 +574,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ + flow_info->l2_data.base_flow = entry; + flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; + flow_info->hash = hash; +- hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]); ++ hlist_add_head(&flow_info->list, ++ &ppe->foe_flow[hash / soc->hash_offset]); + hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); + + hwe = &ppe->foe_table[hash]; +@@ -596,7 +599,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) + { +- struct hlist_head *head = &ppe->foe_flow[hash / 2]; ++ const struct mtk_soc_data *soc = ppe->eth->soc; ++ struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset]; + struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; + struct mtk_flow_entry *entry; + struct mtk_foe_bridge key = {}; +@@ -680,9 +684,11 @@ int mtk_foe_entry_idle_time(struct mtk_p + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, + int version) + { ++ const struct mtk_soc_data *soc = eth->soc; + struct device *dev = eth->dev; + struct mtk_foe_entry *foe; + struct mtk_ppe *ppe; ++ u32 foe_flow_size; + + ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); + if (!ppe) +@@ -705,6 +711,12 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + + ppe->foe_table = foe; + ++ foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) * ++ sizeof(*ppe->foe_flow); ++ ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL); ++ if (!ppe->foe_flow) ++ return NULL; ++ + mtk_ppe_debugfs_init(ppe); + + return ppe; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -270,7 +270,7 @@ struct mtk_ppe { + dma_addr_t foe_phys; + + u16 foe_check_time[MTK_PPE_ENTRIES]; +- struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2]; ++ struct hlist_head *foe_flow; + + struct rhashtable l2_flows; + diff --git a/target/linux/generic/pending-5.15/790-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch b/target/linux/generic/pending-5.15/790-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch new file mode 100644 index 0000000000..0b207ff6a1 --- /dev/null +++ b/target/linux/generic/pending-5.15/790-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch @@ -0,0 +1,317 @@ +From patchwork Thu Sep 8 19:33:39 2022 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Lorenzo Bianconi +X-Patchwork-Id: 12970559 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +From: Lorenzo Bianconi +To: netdev@vger.kernel.org +Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, + Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, + linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, + Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, + ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, + devicetree@vger.kernel.org, robh@kernel.org +Subject: [PATCH net-next 05/12] net: ethernet: mtk_eth_soc: add the capability + to run multiple ppe +Date: Thu, 8 Sep 2022 21:33:39 +0200 +Message-Id: + +X-Mailer: git-send-email 2.37.3 +In-Reply-To: +References: +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +mt7986 chipset support multiple packet engines for wlan <-> eth +packet forwarding. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ++++++++++++------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- + drivers/net/ethernet/mediatek/mtk_ppe.c | 14 +++++--- + drivers/net/ethernet/mediatek/mtk_ppe.h | 9 +++-- + .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 8 ++--- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 13 +++---- + 6 files changed, 48 insertions(+), 33 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1871,7 +1871,7 @@ static int mtk_poll_rx(struct napi_struc + + reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); + if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) +- mtk_ppe_check_skb(eth->ppe, skb, hash); ++ mtk_ppe_check_skb(eth->ppe[0], skb, hash); + + if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +@@ -2929,15 +2929,19 @@ static int mtk_open(struct net_device *d + /* we run 2 netdevs on the same dma ring so we only bring it up once */ + if (!refcount_read(ð->dma_refcnt)) { + const struct mtk_soc_data *soc = eth->soc; +- u32 gdm_config = MTK_GDMA_TO_PDMA; ++ u32 gdm_config; ++ int i; + int err; + + err = mtk_start_dma(eth); + if (err) + return err; + +- if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0) +- gdm_config = soc->reg_map->gdma_to_ppe0; ++ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) ++ mtk_ppe_start(eth->ppe[i]); ++ ++ gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe0 ++ : MTK_GDMA_TO_PDMA; + + mtk_gdm_config(eth, gdm_config); + +@@ -2982,6 +2986,7 @@ static int mtk_stop(struct net_device *d + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; ++ int i; + + phylink_stop(mac->phylink); + +@@ -3009,8 +3014,8 @@ static int mtk_stop(struct net_device *d + + mtk_dma_free(eth); + +- if (eth->soc->offload_version) +- mtk_ppe_stop(eth->ppe); ++ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) ++ mtk_ppe_stop(eth->ppe[i]); + + return 0; + } +@@ -4050,12 +4055,19 @@ static int mtk_probe(struct platform_dev + } + + if (eth->soc->offload_version) { +- u32 ppe_addr = eth->soc->reg_map->ppe_base; ++ u32 num_ppe; + +- eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2); +- if (!eth->ppe) { +- err = -ENOMEM; +- goto err_free_dev; ++ num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; ++ num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); ++ for (i = 0; i < num_ppe; i++) { ++ u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; ++ ++ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, ++ eth->soc->offload_version, i); ++ if (!eth->ppe[i]) { ++ err = -ENOMEM; ++ goto err_free_dev; ++ } + } + + err = mtk_eth_offload_init(eth); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1111,7 +1111,7 @@ struct mtk_eth { + + int ip_align; + +- struct mtk_ppe *ppe; ++ struct mtk_ppe *ppe[2]; + struct rhashtable flow_table; + + struct bpf_prog __rcu *prog; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_p + } + + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, +- int version) ++ int version, int index) + { + const struct mtk_soc_data *soc = eth->soc; + struct device *dev = eth->dev; +@@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + if (!ppe->foe_flow) + return NULL; + +- mtk_ppe_debugfs_init(ppe); ++ mtk_ppe_debugfs_init(ppe, index); + + return ppe; + } +@@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struc + ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC; + } + +-int mtk_ppe_start(struct mtk_ppe *ppe) ++void mtk_ppe_start(struct mtk_ppe *ppe) + { + u32 val; + ++ if (!ppe) ++ return; ++ + mtk_ppe_init_foe_table(ppe); + ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); + +@@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe) + ppe_w32(ppe, MTK_PPE_GLO_CFG, val); + + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); +- +- return 0; + } + + int mtk_ppe_stop(struct mtk_ppe *ppe) +@@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) + u32 val; + int i; + ++ if (!ppe) ++ return 0; ++ + for (i = 0; i < MTK_PPE_ENTRIES; i++) + ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, + MTK_FOE_STATE_INVALID); +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -247,6 +247,7 @@ struct mtk_flow_entry { + }; + u8 type; + s8 wed_index; ++ u8 ppe_index; + u16 hash; + union { + struct mtk_foe_entry data; +@@ -265,6 +266,7 @@ struct mtk_ppe { + struct device *dev; + void __iomem *base; + int version; ++ char dirname[5]; + + struct mtk_foe_entry *foe_table; + dma_addr_t foe_phys; +@@ -277,8 +279,9 @@ struct mtk_ppe { + void *acct_table; + }; + +-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version); +-int mtk_ppe_start(struct mtk_ppe *ppe); ++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, ++ int version, int index); ++void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); +@@ -317,6 +320,6 @@ int mtk_foe_entry_set_wdma(struct mtk_fo + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); +-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe); ++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); + + #endif +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct ino + inode->i_private); + } + +-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe) ++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index) + { + static const struct file_operations fops_all = { + .open = mtk_ppe_debugfs_foe_open_all, +@@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe + .llseek = seq_lseek, + .release = single_release, + }; +- + static const struct file_operations fops_bind = { + .open = mtk_ppe_debugfs_foe_open_bind, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }; +- + struct dentry *root; + +- root = debugfs_create_dir("mtk_ppe", NULL); ++ snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index); ++ ++ root = debugfs_create_dir(ppe->dirname, NULL); + if (!root) + return -ENOMEM; + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth + memcpy(&entry->data, &foe, sizeof(entry->data)); + entry->wed_index = wed_index; + +- err = mtk_foe_entry_commit(eth->ppe, entry); ++ err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); + if (err < 0) + goto free; + +@@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth + return 0; + + clear: +- mtk_foe_entry_clear(eth->ppe, entry); ++ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry); + free: + kfree(entry); + if (wed_index >= 0) +@@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth + if (!entry) + return -ENOENT; + +- mtk_foe_entry_clear(eth->ppe, entry); ++ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry); + rhashtable_remove_fast(ð->flow_table, &entry->node, + mtk_flow_ht_params); + if (entry->wed_index >= 0) +@@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *e + if (!entry) + return -ENOENT; + +- idle = mtk_foe_entry_idle_time(eth->ppe, entry); ++ idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); + f->stats.lastused = jiffies - idle * HZ; + + return 0; +@@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device + struct flow_block_cb *block_cb; + flow_setup_cb_t *cb; + +- if (!eth->ppe || !eth->ppe->foe_table) ++ if (!eth->soc->offload_version) + return -EOPNOTSUPP; + + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) +@@ -589,8 +589,5 @@ int mtk_eth_setup_tc(struct net_device * + + int mtk_eth_offload_init(struct mtk_eth *eth) + { +- if (!eth->ppe || !eth->ppe->foe_table) +- return 0; +- + return rhashtable_init(ð->flow_table, &mtk_flow_ht_params); + } diff --git a/target/linux/generic/pending-5.15/791-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch b/target/linux/generic/pending-5.15/791-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch new file mode 100644 index 0000000000..e984f4b68b --- /dev/null +++ b/target/linux/generic/pending-5.15/791-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch @@ -0,0 +1,80 @@ +From 0dcbe607cec32ccae23b02a641b8bd6191a328ae Mon Sep 17 00:00:00 2001 +Message-Id: <0dcbe607cec32ccae23b02a641b8bd6191a328ae.1662243796.git.lorenzo@kernel.org> +In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> +References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Tue, 23 Aug 2022 23:09:05 +0200 +Subject: [PATCH net-next 2/4] net: ethernet: mtk_eth_soc: move wdma_base + definitions in mtk register map + +This is a preliminary patch to introduce mt7986 wed support. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++------ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 +--- + 2 files changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -75,6 +75,10 @@ static const struct mtk_reg_map mtk_reg_ + .gdm1_cnt = 0x2400, + .gdma_to_ppe0 = 0x4444, + .ppe_base = 0x0c00, ++ .wdma_base = { ++ [0] = 0x2800, ++ [1] = 0x2c00, ++ }, + }; + + static const struct mtk_reg_map mt7628_reg_map = { +@@ -130,6 +134,10 @@ static const struct mtk_reg_map mt7986_r + .gdm1_cnt = 0x1c00, + .gdma_to_ppe0 = 0x3333, + .ppe_base = 0x2000, ++ .wdma_base = { ++ [0] = 0x4800, ++ [1] = 0x4c00, ++ }, + }; + + /* strings used by ethtool */ +@@ -3967,16 +3975,12 @@ static int mtk_probe(struct platform_dev + for (i = 0;; i++) { + struct device_node *np = of_parse_phandle(pdev->dev.of_node, + "mediatek,wed", i); +- static const u32 wdma_regs[] = { +- MTK_WDMA0_BASE, +- MTK_WDMA1_BASE +- }; + void __iomem *wdma; + +- if (!np || i >= ARRAY_SIZE(wdma_regs)) ++ if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) + break; + +- wdma = eth->base + wdma_regs[i]; ++ wdma = eth->base + eth->soc->reg_map->wdma_base[i]; + mtk_wed_add_hw(np, eth, wdma, i); + } + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -268,9 +268,6 @@ + #define TX_DMA_FPORT_MASK_V2 0xf + #define TX_DMA_SWC_V2 BIT(30) + +-#define MTK_WDMA0_BASE 0x2800 +-#define MTK_WDMA1_BASE 0x2c00 +- + /* QDMA descriptor txd4 */ + #define TX_DMA_CHKSUM (0x7 << 29) + #define TX_DMA_TSO BIT(28) +@@ -953,6 +950,7 @@ struct mtk_reg_map { + u32 gdm1_cnt; + u32 gdma_to_ppe0; + u32 ppe_base; ++ u32 wdma_base[2]; + }; + + /* struct mtk_eth_data - This is the structure holding all differences diff --git a/target/linux/generic/pending-5.15/792-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch b/target/linux/generic/pending-5.15/792-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch new file mode 100644 index 0000000000..16bc8e29fc --- /dev/null +++ b/target/linux/generic/pending-5.15/792-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch @@ -0,0 +1,251 @@ +From e3c27d869fccc1f2b8d0b4cde4763ab223874e8c Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> +References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sun, 21 Aug 2022 17:51:17 +0200 +Subject: [PATCH net-next 3/4] net: ethernet: mtk_eth_soc: add foe_entry_size + to mtk_eth_soc + +Introduce foe_entry_size to mtk_eth_soc data structure since mt7986 +relies on a bigger mtk_foe_entry data structure. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 + + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 55 +++++++++++-------- + drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +- + .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- + 5 files changed, 48 insertions(+), 24 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4167,6 +4167,7 @@ static const struct mtk_soc_data mt7621_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4186,6 +4187,7 @@ static const struct mtk_soc_data mt7622_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4204,6 +4206,7 @@ static const struct mtk_soc_data mt7623_ + .required_pctl = true, + .offload_version = 2, + .hash_offset = 2, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -965,6 +965,7 @@ struct mtk_reg_map { + * @required_pctl A bool value to show whether the SoC requires + * the extra setup for those pins used by GMAC. + * @hash_offset Flow table hash offset. ++ * @foe_entry_size Foe table entry size. + * @txd_size Tx DMA descriptor size. + * @rxd_size Rx DMA descriptor size. + * @rx_irq_done_mask Rx irq done register mask. +@@ -980,6 +981,7 @@ struct mtk_soc_data { + bool required_pctl; + u8 offload_version; + u8 hash_offset; ++ u16 foe_entry_size; + netdev_features_t hw_features; + struct { + u32 txd_size; +@@ -1140,6 +1142,14 @@ struct mtk_mac { + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; + ++static inline struct mtk_foe_entry * ++mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) ++{ ++ const struct mtk_soc_data *soc = ppe->eth->soc; ++ ++ return ppe->foe_table + hash * soc->foe_entry_size; ++} ++ + /* read the hardware status register */ + void mtk_stats_update_mac(struct mtk_mac *mac); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -410,9 +410,10 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + + hlist_del_init(&entry->list); + if (entry->hash != 0xffff) { +- ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE; +- ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, +- MTK_FOE_STATE_BIND); ++ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); ++ ++ hwe->ib1 &= ~MTK_FOE_IB1_STATE; ++ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND); + dma_wmb(); + } + entry->hash = 0xffff; +@@ -451,7 +452,7 @@ mtk_flow_entry_update_l2(struct mtk_ppe + int cur_idle; + u32 ib1; + +- hwe = &ppe->foe_table[cur->hash]; ++ hwe = mtk_foe_get_entry(ppe, cur->hash); + ib1 = READ_ONCE(hwe->ib1); + + if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { +@@ -473,8 +474,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe + static void + mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { ++ struct mtk_foe_entry foe = {}; + struct mtk_foe_entry *hwe; +- struct mtk_foe_entry foe; + + spin_lock_bh(&ppe_lock); + +@@ -486,8 +487,8 @@ mtk_flow_entry_update(struct mtk_ppe *pp + if (entry->hash == 0xffff) + goto out; + +- hwe = &ppe->foe_table[entry->hash]; +- memcpy(&foe, hwe, sizeof(foe)); ++ hwe = mtk_foe_get_entry(ppe, entry->hash); ++ memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); + if (!mtk_flow_entry_match(entry, &foe)) { + entry->hash = 0xffff; + goto out; +@@ -511,8 +512,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; + entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); + +- hwe = &ppe->foe_table[hash]; +- memcpy(&hwe->data, &entry->data, sizeof(hwe->data)); ++ hwe = mtk_foe_get_entry(ppe, hash); ++ memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); + wmb(); + hwe->ib1 = entry->ib1; + +@@ -561,7 +562,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ + { + const struct mtk_soc_data *soc = ppe->eth->soc; + struct mtk_flow_entry *flow_info; +- struct mtk_foe_entry foe, *hwe; ++ struct mtk_foe_entry foe = {}, *hwe; + struct mtk_foe_mac_info *l2; + u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; + int type; +@@ -578,8 +579,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ + &ppe->foe_flow[hash / soc->hash_offset]); + hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); + +- hwe = &ppe->foe_table[hash]; +- memcpy(&foe, hwe, sizeof(foe)); ++ hwe = mtk_foe_get_entry(ppe, hash); ++ memcpy(&foe, hwe, soc->foe_entry_size); + foe.ib1 &= ib1_mask; + foe.ib1 |= entry->data.ib1 & ~ib1_mask; + +@@ -601,7 +602,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe + { + const struct mtk_soc_data *soc = ppe->eth->soc; + struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset]; +- struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; ++ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); + struct mtk_flow_entry *entry; + struct mtk_foe_bridge key = {}; + struct hlist_node *n; +@@ -686,9 +687,9 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + { + const struct mtk_soc_data *soc = eth->soc; + struct device *dev = eth->dev; +- struct mtk_foe_entry *foe; + struct mtk_ppe *ppe; + u32 foe_flow_size; ++ void *foe; + + ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); + if (!ppe) +@@ -704,7 +705,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + ppe->dev = dev; + ppe->version = version; + +- foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe), ++ foe = dmam_alloc_coherent(ppe->dev, ++ MTK_PPE_ENTRIES * soc->foe_entry_size, + &ppe->foe_phys, GFP_KERNEL); + if (!foe) + return NULL; +@@ -727,15 +729,21 @@ static void mtk_ppe_init_foe_table(struc + static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 }; + int i, k; + +- memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table)); ++ memset(ppe->foe_table, 0, ++ MTK_PPE_ENTRIES * ppe->eth->soc->foe_entry_size); + + if (!IS_ENABLED(CONFIG_SOC_MT7621)) + return; + + /* skip all entries that cross the 1024 byte boundary */ +- for (i = 0; i < MTK_PPE_ENTRIES; i += 128) +- for (k = 0; k < ARRAY_SIZE(skip); k++) +- ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC; ++ for (i = 0; i < MTK_PPE_ENTRIES; i += 128) { ++ for (k = 0; k < ARRAY_SIZE(skip); k++) { ++ struct mtk_foe_entry *hwe; ++ ++ hwe = mtk_foe_get_entry(ppe, i + skip[k]); ++ hwe->ib1 |= MTK_FOE_IB1_STATIC; ++ } ++ } + } + + void mtk_ppe_start(struct mtk_ppe *ppe) +@@ -822,9 +830,12 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) + if (!ppe) + return 0; + +- for (i = 0; i < MTK_PPE_ENTRIES; i++) +- ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, +- MTK_FOE_STATE_INVALID); ++ for (i = 0; i < MTK_PPE_ENTRIES; i++) { ++ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, i); ++ ++ hwe->ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, ++ MTK_FOE_STATE_INVALID); ++ } + + mtk_ppe_cache_enable(ppe, false); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -268,7 +268,7 @@ struct mtk_ppe { + int version; + char dirname[5]; + +- struct mtk_foe_entry *foe_table; ++ void *foe_table; + dma_addr_t foe_phys; + + u16 foe_check_time[MTK_PPE_ENTRIES]; +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -79,7 +79,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file + int i; + + for (i = 0; i < MTK_PPE_ENTRIES; i++) { +- struct mtk_foe_entry *entry = &ppe->foe_table[i]; ++ struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i); + struct mtk_foe_mac_info *l2; + struct mtk_flow_addr_info ai = {}; + unsigned char h_source[ETH_ALEN]; diff --git a/target/linux/generic/pending-5.15/793-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch b/target/linux/generic/pending-5.15/793-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch new file mode 100644 index 0000000000..77daf6c8bf --- /dev/null +++ b/target/linux/generic/pending-5.15/793-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch @@ -0,0 +1,27 @@ +From 12ff69304c83c679ca01ef3db963ab0db9de19fb Mon Sep 17 00:00:00 2001 +Message-Id: <12ff69304c83c679ca01ef3db963ab0db9de19fb.1662332102.git.lorenzo@kernel.org> +In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 00:43:43 +0200 +Subject: [PATCH net-next 2/6] net: ethernet: mtk_eth_soc: fix typo in + __mtk_foe_entry_clear + +Set ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear routine. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -413,7 +413,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); + + hwe->ib1 &= ~MTK_FOE_IB1_STATE; +- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND); ++ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND); + dma_wmb(); + } + entry->hash = 0xffff; diff --git a/target/linux/generic/pending-5.15/794-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch b/target/linux/generic/pending-5.15/794-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch new file mode 100644 index 0000000000..7ab6d486b2 --- /dev/null +++ b/target/linux/generic/pending-5.15/794-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch @@ -0,0 +1,28 @@ +From 4253e6e2b795a18ab534adcd5c313d3fc4150975 Mon Sep 17 00:00:00 2001 +Message-Id: <4253e6e2b795a18ab534adcd5c313d3fc4150975.1662332102.git.lorenzo@kernel.org> +In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 00:48:52 +0200 +Subject: [PATCH net-next 3/6] net: ethernet: mtk_eth_soc: check max allowed + value in mtk_ppe_check_skb + +Check theoretical OOB accesses in mtk_ppe_check_skb routine + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -294,6 +294,9 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s + if (!ppe) + return; + ++ if (hash > MTK_PPE_HASH_MASK) ++ return; ++ + now = (u16)jiffies; + diff = now - ppe->foe_check_time[hash]; + if (diff < HZ / 10) diff --git a/target/linux/generic/pending-5.15/795-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch b/target/linux/generic/pending-5.15/795-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch new file mode 100644 index 0000000000..a8c88daf1f --- /dev/null +++ b/target/linux/generic/pending-5.15/795-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch @@ -0,0 +1,189 @@ +From e5ecb4f619197b93fa682d722452dc8412864cdb Mon Sep 17 00:00:00 2001 +Message-Id: +From: Lorenzo Bianconi +Date: Fri, 26 Aug 2022 01:12:57 +0200 +Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_wed: add + mtk_wed_configure_irq and mtk_wed_dma_{enable/disable} + +Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable +utility routines. +This is a preliminary patch to introduce mt7986 wed support. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 87 +++++++++++++------- + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 6 +- + 2 files changed, 64 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + } + + static void +-mtk_wed_stop(struct mtk_wed_device *dev) ++mtk_wed_dma_disable(struct mtk_wed_device *dev) + { ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); ++ ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); ++ ++ wed_clr(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_TX_DMA_EN | ++ MTK_WED_GLO_CFG_RX_DMA_EN); ++ + regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); ++ wdma_m32(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_TX_DMA_EN | ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++} ++ ++static void ++mtk_wed_stop(struct mtk_wed_device *dev) ++{ ++ mtk_wed_dma_disable(dev); + mtk_wed_set_ext_int(dev, false); + + wed_clr(dev, MTK_WED_CTRL, +@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); + wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); + wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); +- +- wed_clr(dev, MTK_WED_GLO_CFG, +- MTK_WED_GLO_CFG_TX_DMA_EN | +- MTK_WED_GLO_CFG_RX_DMA_EN); +- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, +- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | +- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); +- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, +- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); + } + + static void +@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; + wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); + +- wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES); ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); + + offset = dev->hw->index ? 0x04000400 : 0; + wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); +@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_d + } + + static void +-mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) ++mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) + { +- u32 wdma_mask; +- u32 val; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +- if (!dev->tx_wdma[i].desc) +- mtk_wed_wdma_ring_setup(dev, i, 16); +- +- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); +- +- mtk_wed_hw_init(dev); ++ u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); + ++ /* wed control cr set */ + wed_set(dev, MTK_WED_CTRL, + MTK_WED_CTRL_WDMA_INT_AGENT_EN | + MTK_WED_CTRL_WPDMA_INT_AGENT_EN | + MTK_WED_CTRL_WED_TX_BM_EN | + MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, ++ MTK_WED_PCIE_INT_TRIGGER_STATUS); + + wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, + MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | + MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); + +- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, +- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); +- ++ /* initail wdma interrupt agent */ + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); + wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); + + wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); + wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); +- + wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); + wed_w32(dev, MTK_WED_INT_MASK, irq_mask); ++} ++ ++static void ++mtk_wed_dma_enable(struct mtk_wed_device *dev) ++{ ++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); + + wed_set(dev, MTK_WED_GLO_CFG, + MTK_WED_GLO_CFG_TX_DMA_EN | +@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev + wed_set(dev, MTK_WED_WDMA_GLO_CFG, + MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); + ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_TX_DMA_EN | ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++} ++ ++static void ++mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) ++{ ++ u32 val; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) ++ if (!dev->tx_wdma[i].desc) ++ mtk_wed_wdma_ring_setup(dev, i, 16); ++ ++ mtk_wed_hw_init(dev); ++ mtk_wed_configure_irq(dev, irq_mask); ++ + mtk_wed_set_ext_int(dev, true); + val = dev->wlan.wpdma_phys | + MTK_PCIE_MIRROR_MAP_EN | +@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev + val |= BIT(0); + regmap_write(dev->hw->mirror, dev->hw->index * 4, val); + ++ mtk_wed_dma_enable(dev); + dev->running = true; + } + +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -224,7 +224,11 @@ struct mtk_wdma_desc { + #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) + + #define MTK_WDMA_GLO_CFG 0x204 +-#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26) ++#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) ++#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) ++#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) ++#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) ++#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) + + #define MTK_WDMA_RESET_IDX 0x208 + #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) diff --git a/target/linux/generic/pending-5.15/796-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch b/target/linux/generic/pending-5.15/796-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch new file mode 100644 index 0000000000..71bfcdbac8 --- /dev/null +++ b/target/linux/generic/pending-5.15/796-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch @@ -0,0 +1,942 @@ +From 463a71af080fbc77339bee2037fb1e081e3824f7 Mon Sep 17 00:00:00 2001 +Message-Id: <463a71af080fbc77339bee2037fb1e081e3824f7.1662886034.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Sat, 27 Aug 2022 16:15:14 +0200 +Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_wed: add wed support for + mt7986 chipset + +Introduce Wireless Etherne Dispatcher support on transmission side +for mt7986 chipset + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +- + drivers/net/ethernet/mediatek/mtk_wed.c | 371 ++++++++++++++---- + drivers/net/ethernet/mediatek/mtk_wed.h | 8 +- + .../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 + + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 81 +++- + include/linux/soc/mediatek/mtk_wed.h | 8 + + 6 files changed, 408 insertions(+), 97 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3892,6 +3892,7 @@ void mtk_eth_set_dma_device(struct mtk_e + + static int mtk_probe(struct platform_device *pdev) + { ++ struct resource *res = NULL; + struct device_node *mac_np; + struct mtk_eth *eth; + int err, i; +@@ -3972,16 +3973,31 @@ static int mtk_probe(struct platform_dev + } + } + +- for (i = 0;; i++) { +- struct device_node *np = of_parse_phandle(pdev->dev.of_node, +- "mediatek,wed", i); +- void __iomem *wdma; +- +- if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) +- break; +- +- wdma = eth->base + eth->soc->reg_map->wdma_base[i]; +- mtk_wed_add_hw(np, eth, wdma, i); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ } ++ ++ if (eth->soc->offload_version) { ++ for (i = 0;; i++) { ++ struct device_node *np; ++ phys_addr_t wdma_phy; ++ u32 wdma_base; ++ ++ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) ++ break; ++ ++ np = of_parse_phandle(pdev->dev.of_node, ++ "mediatek,wed", i); ++ if (!np) ++ break; ++ ++ wdma_base = eth->soc->reg_map->wdma_base[i]; ++ wdma_phy = res ? res->start + wdma_base : 0; ++ mtk_wed_add_hw(np, eth, eth->base + wdma_base, ++ wdma_phy, i); ++ } + } + + for (i = 0; i < 3; i++) { +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -25,6 +25,11 @@ + + #define MTK_WED_TX_RING_SIZE 2048 + #define MTK_WED_WDMA_RING_SIZE 1024 ++#define MTK_WED_MAX_GROUP_SIZE 0x100 ++#define MTK_WED_VLD_GROUP_SIZE 0x40 ++#define MTK_WED_PER_GROUP_PKT 128 ++ ++#define MTK_WED_FBUF_SIZE 128 + + static struct mtk_wed_hw *hw_list[2]; + static DEFINE_MUTEX(hw_lock); +@@ -150,10 +155,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi + + desc->buf0 = cpu_to_le32(buf_phys); + desc->buf1 = cpu_to_le32(buf_phys + txd_size); +- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | +- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, +- MTK_WED_BUF_SIZE - txd_size) | +- MTK_WDMA_DESC_CTRL_LAST_SEG1; ++ ++ if (dev->hw->version == 1) ++ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | ++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, ++ MTK_WED_BUF_SIZE - txd_size) | ++ MTK_WDMA_DESC_CTRL_LAST_SEG1; ++ else ++ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | ++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, ++ MTK_WED_BUF_SIZE - txd_size) | ++ MTK_WDMA_DESC_CTRL_LAST_SEG0; + desc->ctrl = cpu_to_le32(ctrl); + desc->info = 0; + desc++; +@@ -209,7 +221,7 @@ mtk_wed_free_ring(struct mtk_wed_device + if (!ring->desc) + return; + +- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc), ++ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size, + ring->desc, ring->desc_phys); + } + +@@ -229,6 +241,14 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + { + u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; + ++ if (dev->hw->version == 1) ++ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; ++ else ++ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | ++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | ++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | ++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; ++ + if (!dev->hw->num_flows) + mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; + +@@ -237,6 +257,20 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + } + + static void ++mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) ++{ ++ if (enable) { ++ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); ++ wed_w32(dev, MTK_WED_TXP_DW1, ++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103)); ++ } else { ++ wed_w32(dev, MTK_WED_TXP_DW1, ++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100)); ++ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); ++ } ++} ++ ++static void + mtk_wed_dma_disable(struct mtk_wed_device *dev) + { + wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, +@@ -249,12 +283,22 @@ mtk_wed_dma_disable(struct mtk_wed_devic + MTK_WED_GLO_CFG_TX_DMA_EN | + MTK_WED_GLO_CFG_RX_DMA_EN); + +- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); + wdma_m32(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_TX_DMA_EN | + MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); ++ ++ if (dev->hw->version == 1) { ++ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); ++ wdma_m32(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++ } else { ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); ++ ++ mtk_wed_set_512_support(dev, false); ++ } + } + + static void +@@ -293,7 +337,7 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_free_buffer(dev); + mtk_wed_free_tx_rings(dev); + +- if (of_dma_is_coherent(wlan_node)) ++ if (of_dma_is_coherent(wlan_node) && hw->hifsys) + regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, + BIT(hw->index), BIT(hw->index)); + +@@ -308,14 +352,69 @@ mtk_wed_detach(struct mtk_wed_device *de + mutex_unlock(&hw_lock); + } + ++#define PCIE_BASE_ADDR0 0x11280000 ++static void ++mtk_wed_bus_init(struct mtk_wed_device *dev) ++{ ++ struct device_node *np = dev->hw->eth->dev->of_node; ++ struct regmap *regs; ++ u32 val; ++ ++ regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); ++ if (IS_ERR(regs)) ++ return; ++ ++ regmap_update_bits(regs, 0, BIT(0), BIT(0)); ++ ++ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); ++ ++ /* pcie interrupt control: pola/source selection */ ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); ++ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ ++ /* pcie interrupt status trigger register */ ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); ++ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); ++ ++ /* pola setting */ ++ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++} ++ ++static void ++mtk_wed_set_wpdma(struct mtk_wed_device *dev) ++{ ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); ++ } else { ++ mtk_wed_bus_init(dev); ++ ++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); ++ } ++} ++ + static void + mtk_wed_hw_init_early(struct mtk_wed_device *dev) + { + u32 mask, set; +- u32 offset; + + mtk_wed_stop(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); ++ mtk_wed_set_wpdma(dev); + + mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | + MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | +@@ -325,17 +424,33 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; + wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); + +- wdma_set(dev, MTK_WDMA_GLO_CFG, +- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); +- +- offset = dev->hw->index ? 0x04000400 : 0; +- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); +- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); ++ if (dev->hw->version == 1) { ++ u32 offset = dev->hw->index ? 0x04000400 : 0; + +- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index)); +- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ ++ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); ++ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, ++ MTK_PCIE_BASE(dev->hw->index)); ++ } else { ++ wed_w32(dev, MTK_WED_WDMA_CFG_BASE, dev->hw->wdma_phy); ++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_ETH_DMAD_FMT); ++ wed_w32(dev, MTK_WED_WDMA_OFFSET0, ++ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_INTS, ++ MTK_WDMA_INT_STATUS) | ++ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_CFG, ++ MTK_WDMA_GLO_CFG)); ++ ++ wed_w32(dev, MTK_WED_WDMA_OFFSET1, ++ FIELD_PREP(MTK_WED_WDMA_OFST1_TX_CTRL, ++ MTK_WDMA_RING_TX(0)) | ++ FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL, ++ MTK_WDMA_RING_RX(0))); ++ } + } + + static void +@@ -355,37 +470,65 @@ mtk_wed_hw_init(struct mtk_wed_device *d + + wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); + +- wed_w32(dev, MTK_WED_TX_BM_TKID, +- FIELD_PREP(MTK_WED_TX_BM_TKID_START, +- dev->wlan.token_start) | +- FIELD_PREP(MTK_WED_TX_BM_TKID_END, +- dev->wlan.token_start + dev->wlan.nbuf - 1)); +- + wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); + +- wed_w32(dev, MTK_WED_TX_BM_DYN_THR, +- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | +- MTK_WED_TX_BM_DYN_THR_HI); ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_TX_BM_TKID, ++ FIELD_PREP(MTK_WED_TX_BM_TKID_START, ++ dev->wlan.token_start) | ++ FIELD_PREP(MTK_WED_TX_BM_TKID_END, ++ dev->wlan.token_start + ++ dev->wlan.nbuf - 1)); ++ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | ++ MTK_WED_TX_BM_DYN_THR_HI); ++ } else { ++ wed_w32(dev, MTK_WED_TX_BM_TKID_V2, ++ FIELD_PREP(MTK_WED_TX_BM_TKID_START, ++ dev->wlan.token_start) | ++ FIELD_PREP(MTK_WED_TX_BM_TKID_END, ++ dev->wlan.token_start + ++ dev->wlan.nbuf - 1)); ++ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | ++ MTK_WED_TX_BM_DYN_THR_HI_V2); ++ wed_w32(dev, MTK_WED_TX_TKID_CTRL, ++ MTK_WED_TX_TKID_CTRL_PAUSE | ++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, ++ dev->buf_ring.size / 128) | ++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, ++ dev->buf_ring.size / 128)); ++ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | ++ MTK_WED_TX_TKID_DYN_THR_HI); ++ } + + mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); + +- wed_set(dev, MTK_WED_CTRL, +- MTK_WED_CTRL_WED_TX_BM_EN | +- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ if (dev->hw->version == 1) ++ wed_set(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WED_TX_BM_EN | ++ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ else ++ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); + + wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); + } + + static void +-mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size) ++mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) + { ++ void *head = (void *)ring->desc; + int i; + + for (i = 0; i < size; i++) { +- desc[i].buf0 = 0; +- desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); +- desc[i].buf1 = 0; +- desc[i].info = 0; ++ struct mtk_wdma_desc *desc; ++ ++ desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); ++ desc->buf0 = 0; ++ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); ++ desc->buf1 = 0; ++ desc->info = 0; + } + } + +@@ -436,12 +579,10 @@ mtk_wed_reset_dma(struct mtk_wed_device + int i; + + for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) { +- struct mtk_wdma_desc *desc = dev->tx_ring[i].desc; +- +- if (!desc) ++ if (!dev->tx_ring[i].desc) + continue; + +- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE); ++ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); + } + + if (mtk_wed_poll_busy(dev)) +@@ -498,16 +639,16 @@ mtk_wed_reset_dma(struct mtk_wed_device + + static int + mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, +- int size) ++ int size, u32 desc_size) + { +- ring->desc = dma_alloc_coherent(dev->hw->dev, +- size * sizeof(*ring->desc), ++ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, + &ring->desc_phys, GFP_KERNEL); + if (!ring->desc) + return -ENOMEM; + ++ ring->desc_size = desc_size; + ring->size = size; +- mtk_wed_ring_reset(ring->desc, size); ++ mtk_wed_ring_reset(ring, size); + + return 0; + } +@@ -515,9 +656,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device + static int + mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) + { ++ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; + +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) + return -ENOMEM; + + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, +@@ -546,16 +688,41 @@ mtk_wed_configure_irq(struct mtk_wed_dev + MTK_WED_CTRL_WED_TX_BM_EN | + MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, +- MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, ++ MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ ++ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, ++ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | ++ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); + +- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, +- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | +- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); ++ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); ++ } else { ++ /* initail tx interrupt trigger */ ++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, ++ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR | ++ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG, ++ dev->wlan.tx_tbit[0]) | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG, ++ dev->wlan.tx_tbit[1])); ++ ++ /* initail txfree interrupt trigger */ ++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE, ++ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, ++ dev->wlan.txfree_tbit)); ++ ++ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); ++ wed_set(dev, MTK_WED_WDMA_INT_CTRL, ++ FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, ++ dev->wdma_idx)); ++ } + +- /* initail wdma interrupt agent */ + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); +- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); + + wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); + wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); +@@ -580,14 +747,28 @@ mtk_wed_dma_enable(struct mtk_wed_device + wdma_set(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_TX_DMA_EN | + MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); ++ ++ if (dev->hw->version == 1) { ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ } else { ++ wed_set(dev, MTK_WED_WPDMA_CTRL, ++ MTK_WED_WPDMA_CTRL_SDL1_FIXED); ++ ++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); ++ ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | ++ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); ++ } + } + + static void + mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) + { +- u32 val; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +@@ -598,14 +779,17 @@ mtk_wed_start(struct mtk_wed_device *dev + mtk_wed_configure_irq(dev, irq_mask); + + mtk_wed_set_ext_int(dev, true); +- val = dev->wlan.wpdma_phys | +- MTK_PCIE_MIRROR_MAP_EN | +- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); +- +- if (dev->hw->index) +- val |= BIT(1); +- val |= BIT(0); +- regmap_write(dev->hw->mirror, dev->hw->index * 4, val); ++ ++ if (dev->hw->version == 1) { ++ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | ++ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, ++ dev->hw->index); ++ ++ val |= BIT(0) | (BIT(1) * !!dev->hw->index); ++ regmap_write(dev->hw->mirror, dev->hw->index * 4, val); ++ } else { ++ mtk_wed_set_512_support(dev, true); ++ } + + mtk_wed_dma_enable(dev); + dev->running = true; +@@ -639,7 +823,9 @@ mtk_wed_attach(struct mtk_wed_device *de + goto out; + } + +- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index); ++ dev_info(&dev->wlan.pci_dev->dev, ++ "attaching wed device %d version %d\n", ++ hw->index, hw->version); + + dev->hw = hw; + dev->dev = hw->dev; +@@ -657,7 +843,9 @@ mtk_wed_attach(struct mtk_wed_device *de + } + + mtk_wed_hw_init_early(dev); +- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); ++ if (hw->hifsys) ++ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, ++ BIT(hw->index), 0); + + out: + mutex_unlock(&hw_lock); +@@ -684,7 +872,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + + BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); + +- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) ++ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, ++ sizeof(*ring->desc))) + return -ENOMEM; + + if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) +@@ -711,21 +900,21 @@ static int + mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) + { + struct mtk_wed_ring *ring = &dev->txfree_ring; +- int i; ++ int i, index = dev->hw->version == 1; + + /* + * For txfree event handling, the same DMA ring is shared between WED + * and WLAN. The WLAN driver accesses the ring index registers through + * WED + */ +- ring->reg_base = MTK_WED_RING_RX(1); ++ ring->reg_base = MTK_WED_RING_RX(index); + ring->wpdma = regs; + + for (i = 0; i < 12; i += 4) { + u32 val = readl(regs + i); + +- wed_w32(dev, MTK_WED_RING_RX(1) + i, val); +- wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val); ++ wed_w32(dev, MTK_WED_RING_RX(index) + i, val); ++ wed_w32(dev, MTK_WED_WPDMA_RING_RX(index) + i, val); + } + + return 0; +@@ -734,11 +923,19 @@ mtk_wed_txfree_ring_setup(struct mtk_wed + static u32 + mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) + { +- u32 val; ++ u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; ++ ++ if (dev->hw->version == 1) ++ ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; ++ else ++ ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | ++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | ++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | ++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; + + val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); + wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); +- val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK; ++ val &= ext_mask; + if (!dev->hw->num_flows) + val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; + if (val && net_ratelimit()) +@@ -813,7 +1010,8 @@ out: + } + + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index) ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index) + { + static const struct mtk_wed_ops wed_ops = { + .attach = mtk_wed_attach, +@@ -860,26 +1058,33 @@ void mtk_wed_add_hw(struct device_node * + hw = kzalloc(sizeof(*hw), GFP_KERNEL); + if (!hw) + goto unlock; ++ + hw->node = np; + hw->regs = regs; + hw->eth = eth; + hw->dev = &pdev->dev; ++ hw->wdma_phy = wdma_phy; + hw->wdma = wdma; + hw->index = index; + hw->irq = irq; +- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, +- "mediatek,pcie-mirror"); +- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, +- "mediatek,hifsys"); +- if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { +- kfree(hw); +- goto unlock; +- } ++ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; + +- if (!index) { +- regmap_write(hw->mirror, 0, 0); +- regmap_write(hw->mirror, 4, 0); ++ if (hw->version == 1) { ++ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, ++ "mediatek,pcie-mirror"); ++ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, ++ "mediatek,hifsys"); ++ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { ++ kfree(hw); ++ goto unlock; ++ } ++ ++ if (!index) { ++ regmap_write(hw->mirror, 0, 0); ++ regmap_write(hw->mirror, 4, 0); ++ } + } ++ + mtk_wed_hw_add_debugfs(hw); + + hw_list[index] = hw; +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -18,11 +18,13 @@ struct mtk_wed_hw { + struct regmap *hifsys; + struct device *dev; + void __iomem *wdma; ++ phys_addr_t wdma_phy; + struct regmap *mirror; + struct dentry *debugfs_dir; + struct mtk_wed_device *wed_dev; + u32 debugfs_reg; + u32 num_flows; ++ u8 version; + char dirname[5]; + int irq; + int index; +@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device * + } + + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index); ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index); + void mtk_wed_exit(void); + int mtk_wed_flow_add(int index); + void mtk_wed_flow_remove(int index); + #else + static inline void + mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index) ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index) + { + } + static inline void +--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c +@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void + DUMP_WDMA(WDMA_GLO_CFG), + DUMP_WDMA_RING(WDMA_RING_RX(0)), + DUMP_WDMA_RING(WDMA_RING_RX(1)), ++ ++ DUMP_STR("TX FREE"), ++ DUMP_WED(WED_RX_MIB(0)), + }; + struct mtk_wed_hw *hw = s->private; + struct mtk_wed_device *dev = hw->wed_dev; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -5,6 +5,7 @@ + #define __MTK_WED_REGS_H + + #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) ++#define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) + #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) + #define MTK_WDMA_DESC_CTRL_BURST BIT(16) + #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16) +@@ -41,6 +42,7 @@ struct mtk_wdma_desc { + #define MTK_WED_CTRL_RESERVE_EN BIT(12) + #define MTK_WED_CTRL_RESERVE_BUSY BIT(13) + #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) ++#define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) + #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) + + #define MTK_WED_EXT_INT_STATUS 0x020 +@@ -57,7 +59,8 @@ struct mtk_wdma_desc { + #define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20) + #define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21) +-#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22) ++#define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) ++#define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) + #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ + MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ +@@ -65,8 +68,7 @@ struct mtk_wdma_desc { + MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \ + MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \ + MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \ +- MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \ +- MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR) ++ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) + + #define MTK_WED_EXT_INT_MASK 0x028 + +@@ -81,6 +83,7 @@ struct mtk_wdma_desc { + #define MTK_WED_TX_BM_BASE 0x084 + + #define MTK_WED_TX_BM_TKID 0x088 ++#define MTK_WED_TX_BM_TKID_V2 0x0c8 + #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) + #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) + +@@ -94,7 +97,25 @@ struct mtk_wdma_desc { + + #define MTK_WED_TX_BM_DYN_THR 0x0a0 + #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0) ++#define MTK_WED_TX_BM_DYN_THR_LO_V2 GENMASK(8, 0) + #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16) ++#define MTK_WED_TX_BM_DYN_THR_HI_V2 GENMASK(24, 16) ++ ++#define MTK_WED_TX_TKID_CTRL 0x0c0 ++#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0) ++#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) ++#define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) ++ ++#define MTK_WED_TX_TKID_DYN_THR 0x0e0 ++#define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) ++#define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) ++ ++#define MTK_WED_TXP_DW0 0x120 ++#define MTK_WED_TXP_DW1 0x124 ++#define MTK_WED_WPDMA_WRITE_TXP GENMASK(31, 16) ++#define MTK_WED_TXDP_CTRL 0x130 ++#define MTK_WED_TXDP_DW9_OVERWR BIT(9) ++#define MTK_WED_RX_BM_TKID_MIB 0x1cc + + #define MTK_WED_INT_STATUS 0x200 + #define MTK_WED_INT_MASK 0x204 +@@ -125,6 +146,7 @@ struct mtk_wdma_desc { + #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) + + #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) ++#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) + + #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) + +@@ -155,21 +177,62 @@ struct mtk_wdma_desc { + #define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29) + #define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC BIT(4) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) ++#define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) ++#define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) ++ + #define MTK_WED_WPDMA_RESET_IDX 0x50c + #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16) + ++#define MTK_WED_WPDMA_CTRL 0x518 ++#define MTK_WED_WPDMA_CTRL_SDL1_FIXED BIT(31) ++ + #define MTK_WED_WPDMA_INT_CTRL 0x520 + #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) + + #define MTK_WED_WPDMA_INT_MASK 0x524 + ++#define MTK_WED_WPDMA_INT_CTRL_TX 0x530 ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0) ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1) ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) ++ ++#define MTK_WED_WPDMA_INT_CTRL_RX 0x534 ++ ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR BIT(1) ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG GENMASK(6, 2) ++ + #define MTK_WED_PCIE_CFG_BASE 0x560 + ++#define MTK_WED_PCIE_CFG_BASE 0x560 ++#define MTK_WED_PCIE_CFG_INTM 0x564 ++#define MTK_WED_PCIE_CFG_MSIS 0x568 + #define MTK_WED_PCIE_INT_TRIGGER 0x570 + #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) + ++#define MTK_WED_PCIE_INT_CTRL 0x57c ++#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) ++#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) ++#define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) ++ + #define MTK_WED_WPDMA_CFG_BASE 0x580 ++#define MTK_WED_WPDMA_CFG_INT_MASK 0x584 ++#define MTK_WED_WPDMA_CFG_TX 0x588 ++#define MTK_WED_WPDMA_CFG_TX_FREE 0x58c + + #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) + #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) +@@ -203,15 +266,24 @@ struct mtk_wdma_desc { + #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) + #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) + ++#define MTK_WED_WDMA_INT_CLR 0xa24 ++#define MTK_WED_WDMA_INT_CLR_RX_DONE GENMASK(17, 16) ++ + #define MTK_WED_WDMA_INT_TRIGGER 0xa28 + #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) + + #define MTK_WED_WDMA_INT_CTRL 0xa2c + #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) + ++#define MTK_WED_WDMA_CFG_BASE 0xaa0 + #define MTK_WED_WDMA_OFFSET0 0xaa4 + #define MTK_WED_WDMA_OFFSET1 0xaa8 + ++#define MTK_WED_WDMA_OFST0_GLO_INTS GENMASK(15, 0) ++#define MTK_WED_WDMA_OFST0_GLO_CFG GENMASK(31, 16) ++#define MTK_WED_WDMA_OFST1_TX_CTRL GENMASK(15, 0) ++#define MTK_WED_WDMA_OFST1_RX_CTRL GENMASK(31, 16) ++ + #define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4) + #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) + #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) +@@ -221,6 +293,7 @@ struct mtk_wdma_desc { + #define MTK_WED_RING_OFS_CPU_IDX 0x08 + #define MTK_WED_RING_OFS_DMA_IDX 0x0c + ++#define MTK_WDMA_RING_TX(_n) (0x000 + (_n) * 0x10) + #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) + + #define MTK_WDMA_GLO_CFG 0x204 +@@ -234,6 +307,8 @@ struct mtk_wdma_desc { + #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16) + ++#define MTK_WDMA_INT_STATUS 0x220 ++ + #define MTK_WDMA_INT_MASK 0x228 + #define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0) + #define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16) +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -14,6 +14,7 @@ struct mtk_wdma_desc; + struct mtk_wed_ring { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; ++ u32 desc_size; + int size; + + u32 reg_base; +@@ -45,10 +46,17 @@ struct mtk_wed_device { + struct pci_dev *pci_dev; + + u32 wpdma_phys; ++ u32 wpdma_int; ++ u32 wpdma_mask; ++ u32 wpdma_tx; ++ u32 wpdma_txfree; + + u16 token_start; + unsigned int nbuf; + ++ u8 tx_tbit[MTK_WED_TX_QUEUES]; ++ u8 txfree_tbit; ++ + u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); + int (*offload_enable)(struct mtk_wed_device *wed); + void (*offload_disable)(struct mtk_wed_device *wed); diff --git a/target/linux/generic/pending-5.15/797-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch b/target/linux/generic/pending-5.15/797-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch new file mode 100644 index 0000000000..70b7bad31f --- /dev/null +++ b/target/linux/generic/pending-5.15/797-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch @@ -0,0 +1,237 @@ +From 6e1df49f330dce7c58a39d6772f1385b6887bb03 Mon Sep 17 00:00:00 2001 +Message-Id: <6e1df49f330dce7c58a39d6772f1385b6887bb03.1662990860.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Thu, 8 Sep 2022 11:26:10 +0200 +Subject: [PATCH net-next] net: ethernet: mtk_eth_wed: add axi bus support + +Other than pcie bus, introduce support for axi bus to mtk wed driver. +Axi bus is used to connect mt7986-wmac soc chip available on mt7986 +device. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 116 +++++++++++++------ + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 2 + + include/linux/soc/mediatek/mtk_wed.h | 11 +- + 3 files changed, 91 insertions(+), 38 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -85,11 +85,31 @@ static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { + struct mtk_wed_hw *hw; ++ int i; ++ ++ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ++ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; ++ if (!hw) ++ return NULL; ++ ++ if (!hw->wed_dev) ++ goto out; ++ ++ if (hw->version == 1) ++ return NULL; ++ ++ /* MT7986 WED devices do not have any pcie slot restrictions */ ++ } ++ /* MT7986 PCIE or AXI */ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ hw = hw_list[i]; ++ if (hw && !hw->wed_dev) ++ goto out; ++ } + +- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; +- if (!hw || hw->wed_dev) +- return NULL; ++ return NULL; + ++out: + hw->wed_dev = dev; + return hw; + } +@@ -322,7 +342,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) + static void + mtk_wed_detach(struct mtk_wed_device *dev) + { +- struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node; + struct mtk_wed_hw *hw = dev->hw; + + mutex_lock(&hw_lock); +@@ -337,9 +356,14 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_free_buffer(dev); + mtk_wed_free_tx_rings(dev); + +- if (of_dma_is_coherent(wlan_node) && hw->hifsys) +- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, +- BIT(hw->index), BIT(hw->index)); ++ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ++ struct device_node *wlan_node; ++ ++ wlan_node = dev->wlan.pci_dev->dev.of_node; ++ if (of_dma_is_coherent(wlan_node) && hw->hifsys) ++ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, ++ BIT(hw->index), BIT(hw->index)); ++ } + + if (!hw_list[!hw->index]->wed_dev && + hw->eth->dma_dev != hw->eth->dev) +@@ -356,40 +380,54 @@ mtk_wed_detach(struct mtk_wed_device *de + static void + mtk_wed_bus_init(struct mtk_wed_device *dev) + { +- struct device_node *np = dev->hw->eth->dev->of_node; +- struct regmap *regs; +- u32 val; +- +- regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); +- if (IS_ERR(regs)) +- return; ++ switch (dev->wlan.bus_type) { ++ case MTK_WED_BUS_PCIE: { ++ struct device_node *np = dev->hw->eth->dev->of_node; ++ struct regmap *regs; ++ u32 val; ++ ++ regs = syscon_regmap_lookup_by_phandle(np, ++ "mediatek,wed-pcie"); ++ if (IS_ERR(regs)) ++ break; + +- regmap_update_bits(regs, 0, BIT(0), BIT(0)); ++ regmap_update_bits(regs, 0, BIT(0), BIT(0)); + +- wed_w32(dev, MTK_WED_PCIE_INT_CTRL, +- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); ++ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); + +- /* pcie interrupt control: pola/source selection */ +- wed_set(dev, MTK_WED_PCIE_INT_CTRL, +- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | +- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); +- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); +- +- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); +- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); +- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); +- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); +- +- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); +- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); +- +- /* pcie interrupt status trigger register */ +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); +- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); +- +- /* pola setting */ +- val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); +- wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++ /* pcie interrupt control: pola/source selection */ ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); ++ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ ++ /* pcie interrupt status trigger register */ ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); ++ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); ++ ++ /* pola setting */ ++ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++ break; ++ } ++ case MTK_WED_BUS_AXI: ++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, ++ MTK_WED_WPDMA_INT_CTRL_SIG_SRC | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0)); ++ break; ++ default: ++ break; ++ } + } + + static void +@@ -800,12 +838,14 @@ mtk_wed_attach(struct mtk_wed_device *de + __releases(RCU) + { + struct mtk_wed_hw *hw; ++ struct device *device; + int ret = 0; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "mtk_wed_attach without holding the RCU read lock"); + +- if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 || ++ if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE && ++ pci_domain_nr(dev->wlan.pci_dev->bus) > 1) || + !try_module_get(THIS_MODULE)) + ret = -ENODEV; + +@@ -823,8 +863,10 @@ mtk_wed_attach(struct mtk_wed_device *de + goto out; + } + +- dev_info(&dev->wlan.pci_dev->dev, +- "attaching wed device %d version %d\n", ++ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE ++ ? &dev->wlan.pci_dev->dev ++ : &dev->wlan.platform_dev->dev; ++ dev_info(device, "attaching wed device %d version %d\n", + hw->index, hw->version); + + dev->hw = hw; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -198,6 +198,8 @@ struct mtk_wdma_desc { + + #define MTK_WED_WPDMA_INT_CTRL 0x520 + #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) ++#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC BIT(22) ++#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL GENMASK(17, 16) + + #define MTK_WED_WPDMA_INT_MASK 0x524 + +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -11,6 +11,11 @@ + struct mtk_wed_hw; + struct mtk_wdma_desc; + ++enum mtk_wed_bus_tye { ++ MTK_WED_BUS_PCIE, ++ MTK_WED_BUS_AXI, ++}; ++ + struct mtk_wed_ring { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; +@@ -43,7 +48,11 @@ struct mtk_wed_device { + + /* filled by driver: */ + struct { +- struct pci_dev *pci_dev; ++ union { ++ struct platform_device *platform_dev; ++ struct pci_dev *pci_dev; ++ }; ++ enum mtk_wed_bus_tye bus_type; + + u32 wpdma_phys; + u32 wpdma_int; diff --git a/target/linux/generic/pending-5.15/798-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch b/target/linux/generic/pending-5.15/798-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch new file mode 100644 index 0000000000..2fb0b1dfd6 --- /dev/null +++ b/target/linux/generic/pending-5.15/798-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch @@ -0,0 +1,882 @@ +From 93408c858e5dc01d97c55efa721268f63fde2ae5 Mon Sep 17 00:00:00 2001 +Message-Id: <93408c858e5dc01d97c55efa721268f63fde2ae5.1662886034.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Sat, 3 Sep 2022 18:34:09 +0200 +Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: introduce flow + offloading support for mt7986 + +Introduce hw flow offload support for mt7986 chipset. PPE is not enabled +yet in mt7986 since mt76 support is not available yet. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 72 ++++++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 213 +++++++++++------- + drivers/net/ethernet/mediatek/mtk_ppe.h | 52 ++++- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 49 ++-- + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 8 + + 6 files changed, 289 insertions(+), 116 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1858,12 +1858,14 @@ static int mtk_poll_rx(struct napi_struc + bytes += skb->len; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); + hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; + if (hash != MTK_RXD5_FOE_ENTRY) + skb_set_hash(skb, jhash_1word(hash, 0), + PKT_HASH_TYPE_L4); + rxdcsum = &trxd.rxd3; + } else { ++ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); + hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; + if (hash != MTK_RXD4_FOE_ENTRY) + skb_set_hash(skb, jhash_1word(hash, 0), +@@ -1877,7 +1879,6 @@ static int mtk_poll_rx(struct napi_struc + skb_checksum_none_assert(skb); + skb->protocol = eth_type_trans(skb, netdev); + +- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); + if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) + mtk_ppe_check_skb(eth->ppe[0], skb, hash); + +@@ -4183,7 +4184,7 @@ static const struct mtk_soc_data mt7621_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4203,7 +4204,7 @@ static const struct mtk_soc_data mt7622_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4222,7 +4223,7 @@ static const struct mtk_soc_data mt7623_ + .required_pctl = true, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4254,9 +4255,11 @@ static const struct mtk_soc_data mt7986_ + .reg_map = &mt7986_reg_map, + .ana_rgc3 = 0x128, + .caps = MT7986_CAPS, ++ .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, + .hash_offset = 4, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1150,6 +1150,78 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u + return ppe->foe_table + hash * soc->foe_entry_size; + } + ++static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_TIMESTAMP_V2; ++ ++ return MTK_FOE_IB1_BIND_TIMESTAMP; ++} ++ ++static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_PPPOE_V2; ++ ++ return MTK_FOE_IB1_BIND_PPPOE; ++} ++ ++static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_VLAN_TAG_V2; ++ ++ return MTK_FOE_IB1_BIND_VLAN_TAG; ++} ++ ++static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; ++ ++ return MTK_FOE_IB1_BIND_VLAN_LAYER; ++} ++ ++static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); ++ ++ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); ++} ++ ++static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); ++ ++ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); ++} ++ ++static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_PACKET_TYPE_V2; ++ ++ return MTK_FOE_IB1_PACKET_TYPE; ++} ++ ++static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); ++ ++ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); ++} ++ ++static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB2_MULTICAST_V2; ++ ++ return MTK_FOE_IB2_MULTICAST; ++} ++ + /* read the hardware status register */ + void mtk_stats_update_mac(struct mtk_mac *mac); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -56,7 +56,7 @@ static u32 ppe_clear(struct mtk_ppe *ppe + + static u32 mtk_eth_timestamp(struct mtk_eth *eth) + { +- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; ++ return mtk_r32(eth, 0x0010) & mtk_get_ib1_ts_mask(eth); + } + + static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) +@@ -93,7 +93,7 @@ static u32 mtk_ppe_hash_entry(struct mtk + u32 hv1, hv2, hv3; + u32 hash; + +- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { ++ switch (mtk_get_ib1_pkt_type(eth, e->ib1)) { + case MTK_PPE_PKT_TYPE_IPV4_ROUTE: + case MTK_PPE_PKT_TYPE_IPV4_HNAPT: + hv1 = e->ipv4.orig.ports; +@@ -129,9 +129,9 @@ static u32 mtk_ppe_hash_entry(struct mtk + } + + static inline struct mtk_foe_mac_info * +-mtk_foe_entry_l2(struct mtk_foe_entry *entry) ++mtk_foe_entry_l2(struct mtk_eth *eth, struct mtk_foe_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) + return &entry->bridge.l2; +@@ -143,9 +143,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e + } + + static inline u32 * +-mtk_foe_entry_ib2(struct mtk_foe_entry *entry) ++mtk_foe_entry_ib2(struct mtk_eth *eth, struct mtk_foe_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) + return &entry->bridge.ib2; +@@ -156,27 +156,38 @@ mtk_foe_entry_ib2(struct mtk_foe_entry * + return &entry->ipv4.ib2; + } + +-int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +- u8 pse_port, u8 *src_mac, u8 *dest_mac) ++int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int type, int l4proto, u8 pse_port, u8 *src_mac, ++ u8 *dest_mac) + { + struct mtk_foe_mac_info *l2; + u32 ports_pad, val; + + memset(entry, 0, sizeof(*entry)); + +- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | +- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | +- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +- MTK_FOE_IB1_BIND_TTL | +- MTK_FOE_IB1_BIND_CACHE; +- entry->ib1 = val; +- +- val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | +- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) | +- FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | ++ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | ++ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | ++ MTK_FOE_IB1_BIND_CACHE_V2 | MTK_FOE_IB1_BIND_TTL_V2; ++ entry->ib1 = val; ++ ++ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); ++ } else { ++ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | ++ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | ++ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | ++ MTK_FOE_IB1_BIND_CACHE | MTK_FOE_IB1_BIND_TTL; ++ entry->ib1 = val; ++ ++ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); ++ } + + if (is_multicast_ether_addr(dest_mac)) +- val |= MTK_FOE_IB2_MULTICAST; ++ val |= mtk_get_ib2_multicast_mask(eth); + + ports_pad = 0xa5a5a500 | (l4proto & 0xff); + if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) +@@ -210,24 +221,30 @@ int mtk_foe_entry_prepare(struct mtk_foe + return 0; + } + +-int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port) ++int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, u8 port) + { +- u32 *ib2 = mtk_foe_entry_ib2(entry); +- u32 val; ++ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); ++ u32 val = *ib2; + +- val = *ib2; +- val &= ~MTK_FOE_IB2_DEST_PORT; +- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ val &= ~MTK_FOE_IB2_DEST_PORT_V2; ++ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); ++ } else { ++ val &= ~MTK_FOE_IB2_DEST_PORT; ++ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); ++ } + *ib2 = val; + + return 0; + } + +-int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress, ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, bool egress, + __be32 src_addr, __be16 src_port, + __be32 dest_addr, __be16 dest_port) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + struct mtk_ipv4_tuple *t; + + switch (type) { +@@ -262,11 +279,12 @@ int mtk_foe_entry_set_ipv4_tuple(struct + return 0; + } + +-int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, + __be32 *src_addr, __be16 src_port, + __be32 *dest_addr, __be16 dest_port) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + u32 *src, *dest; + int i; + +@@ -297,39 +315,41 @@ int mtk_foe_entry_set_ipv6_tuple(struct + return 0; + } + +-int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port) ++int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int port) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + + l2->etype = BIT(port); + +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER)) +- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth))) ++ entry->ib1 |= mtk_prep_ib1_vlan_layer(eth, 1); + else + l2->etype |= BIT(8); + +- entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG; ++ entry->ib1 &= ~mtk_get_ib1_vlan_tag_mask(eth); + + return 0; + } + +-int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid) ++int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int vid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + +- switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) { ++ switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) { + case 0: +- entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG | +- FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) | ++ mtk_prep_ib1_vlan_layer(eth, 1); + l2->vlan1 = vid; + return 0; + case 1: +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) { ++ if (!(entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) { + l2->vlan1 = vid; + l2->etype |= BIT(8); + } else { + l2->vlan2 = vid; +- entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ entry->ib1 += mtk_prep_ib1_vlan_layer(eth, 1); + } + return 0; + default: +@@ -337,34 +357,42 @@ int mtk_foe_entry_set_vlan(struct mtk_fo + } + } + +-int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid) ++int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int sid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) || +- (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) ++ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)) || ++ (entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) + l2->etype = ETH_P_PPP_SES; + +- entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE; ++ entry->ib1 |= mtk_get_ib1_ppoe_mask(eth); + l2->pppoe_id = sid; + + return 0; + } + +-int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, +- int bss, int wcid) ++int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int wdma_idx, int txq, int bss, int wcid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); +- u32 *ib2 = mtk_foe_entry_ib2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); ++ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- *ib2 &= ~MTK_FOE_IB2_PORT_MG; +- *ib2 |= MTK_FOE_IB2_WDMA_WINFO; +- if (wdma_idx) +- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; +- +- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | +- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | +- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | ++ MTK_FOE_IB2_WDMA_WINFO_V2; ++ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | ++ FIELD_PREP(MTK_FOE_WINFO_BSS, bss); ++ } else { ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG; ++ *ib2 |= MTK_FOE_IB2_WDMA_WINFO; ++ if (wdma_idx) ++ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; ++ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | ++ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | ++ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ } + + return 0; + } +@@ -376,14 +404,15 @@ static inline bool mtk_foe_entry_usable( + } + + static bool +-mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data) ++mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, ++ struct mtk_foe_entry *data) + { + int type, len; + + if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) + return false; + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); ++ type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); + if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) + len = offsetof(struct mtk_foe_entry, ipv6._rsv); + else +@@ -427,14 +456,12 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + + static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) + { +- u16 timestamp; +- u16 now; +- +- now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; +- timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; ++ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); ++ u16 now = mtk_eth_timestamp(ppe->eth); ++ u16 timestamp = ib1 & ib1_ts_mask; + + if (timestamp > now) +- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; ++ return ib1_ts_mask + 1 - timestamp + now; + else + return now - timestamp; + } +@@ -442,6 +469,7 @@ static int __mtk_foe_entry_idle_time(str + static void + mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { ++ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); + struct mtk_flow_entry *cur; + struct mtk_foe_entry *hwe; + struct hlist_node *tmp; +@@ -466,8 +494,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe + continue; + + idle = cur_idle; +- entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; ++ entry->data.ib1 &= ~ib1_ts_mask; ++ entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; + } + } + +@@ -489,7 +517,7 @@ mtk_flow_entry_update(struct mtk_ppe *pp + + hwe = mtk_foe_get_entry(ppe, entry->hash); + memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); +- if (!mtk_flow_entry_match(entry, &foe)) { ++ if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { + entry->hash = 0xffff; + goto out; + } +@@ -504,16 +532,22 @@ static void + __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, + u16 hash) + { ++ struct mtk_eth *eth = ppe->eth; ++ u16 timestamp = mtk_eth_timestamp(eth); + struct mtk_foe_entry *hwe; +- u16 timestamp; + +- timestamp = mtk_eth_timestamp(ppe->eth); +- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; ++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, ++ timestamp); ++ } else { ++ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; ++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, ++ timestamp); ++ } + + hwe = mtk_foe_get_entry(ppe, hash); +- memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); ++ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size); + wmb(); + hwe->ib1 = entry->ib1; + +@@ -540,8 +574,8 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * + + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); + const struct mtk_soc_data *soc = ppe->eth->soc; ++ int type = mtk_get_ib1_pkt_type(ppe->eth, entry->data.ib1); + u32 hash; + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) +@@ -564,7 +598,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ + struct mtk_flow_entry *flow_info; + struct mtk_foe_entry foe = {}, *hwe; + struct mtk_foe_mac_info *l2; +- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; ++ u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; + int type; + + flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), +@@ -584,16 +618,16 @@ mtk_foe_entry_commit_subflow(struct mtk_ + foe.ib1 &= ib1_mask; + foe.ib1 |= entry->data.ib1 & ~ib1_mask; + +- l2 = mtk_foe_entry_l2(&foe); ++ l2 = mtk_foe_entry_l2(ppe->eth, &foe); + memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1); ++ type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); + if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) + memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); + else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) + l2->etype = ETH_P_IPV6; + +- *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2; ++ *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; + + __mtk_foe_entry_commit(ppe, &foe, hash); + } +@@ -626,7 +660,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe + continue; + } + +- if (found || !mtk_flow_entry_match(entry, hwe)) { ++ if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { + if (entry->hash != 0xffff) + entry->hash = 0xffff; + continue; +@@ -771,6 +805,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | + FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, + MTK_PPE_ENTRIES_SHIFT); ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_PPE_TB_CFG_INFO_SEL; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + + ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, +@@ -778,15 +814,21 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + + mtk_ppe_cache_enable(ppe, true); + +- val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | +- MTK_PPE_FLOW_CFG_IP4_UDP_FRAG | +- MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | ++ val = MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | + MTK_PPE_FLOW_CFG_IP6_5T_ROUTE | + MTK_PPE_FLOW_CFG_IP6_6RD | + MTK_PPE_FLOW_CFG_IP4_NAT | + MTK_PPE_FLOW_CFG_IP4_NAPT | + MTK_PPE_FLOW_CFG_IP4_DSLITE | + MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | ++ MTK_PPE_MD_TOAP_BYP_CRSN1 | ++ MTK_PPE_MD_TOAP_BYP_CRSN2 | ++ MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY; ++ else ++ val |= MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | ++ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG; + ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); + + val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) | +@@ -820,6 +862,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + ppe_w32(ppe, MTK_PPE_GLO_CFG, val); + + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); ++ ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { ++ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); ++ ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); ++ } + } + + int mtk_ppe_stop(struct mtk_ppe *ppe) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -32,6 +32,15 @@ + #define MTK_FOE_IB1_UDP BIT(30) + #define MTK_FOE_IB1_STATIC BIT(31) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_FOE_IB1_BIND_TIMESTAMP_V2 GENMASK(7, 0) ++#define MTK_FOE_IB1_BIND_VLAN_LAYER_V2 GENMASK(16, 14) ++#define MTK_FOE_IB1_BIND_PPPOE_V2 BIT(17) ++#define MTK_FOE_IB1_BIND_VLAN_TAG_V2 BIT(18) ++#define MTK_FOE_IB1_BIND_CACHE_V2 BIT(20) ++#define MTK_FOE_IB1_BIND_TTL_V2 BIT(22) ++#define MTK_FOE_IB1_PACKET_TYPE_V2 GENMASK(27, 23) ++ + enum { + MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0, + MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1, +@@ -53,14 +62,25 @@ enum { + + #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) + ++#define MTK_FOE_IB2_RX_IDX GENMASK(18, 17) + #define MTK_FOE_IB2_PORT_AG GENMASK(23, 18) + + #define MTK_FOE_IB2_DSCP GENMASK(31, 24) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_FOE_IB2_PORT_MG_V2 BIT(7) ++#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) ++#define MTK_FOE_IB2_MULTICAST_V2 BIT(13) ++#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) ++#define MTK_FOE_IB2_PORT_AG_V2 GENMASK(23, 20) ++ + #define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0) + #define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6) + #define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14) + ++#define MTK_FOE_WINFO_BSS GENMASK(5, 0) ++#define MTK_FOE_WINFO_WCID GENMASK(15, 6) ++ + enum { + MTK_FOE_STATE_INVALID, + MTK_FOE_STATE_UNBIND, +@@ -81,6 +101,9 @@ struct mtk_foe_mac_info { + + u16 pppoe_id; + u16 src_mac_lo; ++ ++ u16 minfo; ++ u16 winfo; + }; + + /* software-only entry type */ +@@ -198,7 +221,7 @@ struct mtk_foe_entry { + struct mtk_foe_ipv4_dslite dslite; + struct mtk_foe_ipv6 ipv6; + struct mtk_foe_ipv6_6rd ipv6_6rd; +- u32 data[19]; ++ u32 data[23]; + }; + }; + +@@ -306,20 +329,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s + __mtk_ppe_check_skb(ppe, skb, hash); + } + +-int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +- u8 pse_port, u8 *src_mac, u8 *dest_mac); +-int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); +-int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig, ++int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int type, int l4proto, u8 pse_port, u8 *src_mac, ++ u8 *dest_mac); ++int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, u8 port); ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, bool orig, + __be32 src_addr, __be16 src_port, + __be32 dest_addr, __be16 dest_port); +-int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, + __be32 *src_addr, __be16 src_port, + __be32 *dest_addr, __be16 dest_port); +-int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); +-int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); +-int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); +-int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, +- int bss, int wcid); ++int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int port); ++int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int vid); ++int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int sid); ++int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int wdma_idx, int txq, int bss, int wcid); + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -52,18 +52,19 @@ static const struct rhashtable_params mt + }; + + static int +-mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, +- bool egress) ++mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, ++ struct mtk_flow_data *data, bool egress) + { +- return mtk_foe_entry_set_ipv4_tuple(foe, egress, ++ return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress, + data->v4.src_addr, data->src_port, + data->v4.dst_addr, data->dst_port); + } + + static int +-mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data) ++mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, ++ struct mtk_flow_data *data) + { +- return mtk_foe_entry_set_ipv6_tuple(foe, ++ return mtk_foe_entry_set_ipv6_tuple(eth, foe, + data->v6.src_addr.s6_addr32, data->src_port, + data->v6.dst_addr.s6_addr32, data->dst_port); + } +@@ -190,16 +191,29 @@ mtk_flow_set_output_device(struct mtk_et + int pse_port, dsa_port; + + if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { +- mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss, +- info.wcid); +- pse_port = 3; ++ mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, ++ info.bss, info.wcid); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ switch (info.wdma_idx) { ++ case 0: ++ pse_port = 8; ++ break; ++ case 1: ++ pse_port = 9; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } else { ++ pse_port = 3; ++ } + *wed_index = info.wdma_idx; + goto out; + } + + dsa_port = mtk_flow_get_dsa_port(&dev); + if (dsa_port >= 0) +- mtk_foe_entry_set_dsa(foe, dsa_port); ++ mtk_foe_entry_set_dsa(eth, foe, dsa_port); + + if (dev == eth->netdev[0]) + pse_port = 1; +@@ -209,7 +223,7 @@ mtk_flow_set_output_device(struct mtk_et + return -EOPNOTSUPP; + + out: +- mtk_foe_entry_set_pse_port(foe, pse_port); ++ mtk_foe_entry_set_pse_port(eth, foe, pse_port); + + return 0; + } +@@ -333,9 +347,8 @@ mtk_flow_offload_replace(struct mtk_eth + !is_valid_ether_addr(data.eth.h_dest)) + return -EINVAL; + +- err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0, +- data.eth.h_source, +- data.eth.h_dest); ++ err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0, ++ data.eth.h_source, data.eth.h_dest); + if (err) + return err; + +@@ -360,7 +373,7 @@ mtk_flow_offload_replace(struct mtk_eth + data.v4.src_addr = addrs.key->src; + data.v4.dst_addr = addrs.key->dst; + +- mtk_flow_set_ipv4_addr(&foe, &data, false); ++ mtk_flow_set_ipv4_addr(eth, &foe, &data, false); + } + + if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { +@@ -371,7 +384,7 @@ mtk_flow_offload_replace(struct mtk_eth + data.v6.src_addr = addrs.key->src; + data.v6.dst_addr = addrs.key->dst; + +- mtk_flow_set_ipv6_addr(&foe, &data); ++ mtk_flow_set_ipv6_addr(eth, &foe, &data); + } + + flow_action_for_each(i, act, &rule->action) { +@@ -401,7 +414,7 @@ mtk_flow_offload_replace(struct mtk_eth + } + + if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { +- err = mtk_flow_set_ipv4_addr(&foe, &data, true); ++ err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true); + if (err) + return err; + } +@@ -413,10 +426,10 @@ mtk_flow_offload_replace(struct mtk_eth + if (data.vlan.proto != htons(ETH_P_8021Q)) + return -EOPNOTSUPP; + +- mtk_foe_entry_set_vlan(&foe, data.vlan.id); ++ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id); + } + if (data.pppoe.num == 1) +- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid); ++ mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid); + + err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest, + &wed_index); +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -21,6 +21,9 @@ + #define MTK_PPE_GLO_CFG_BUSY BIT(31) + + #define MTK_PPE_FLOW_CFG 0x204 ++#define MTK_PPE_MD_TOAP_BYP_CRSN0 BIT(1) ++#define MTK_PPE_MD_TOAP_BYP_CRSN1 BIT(2) ++#define MTK_PPE_MD_TOAP_BYP_CRSN2 BIT(3) + #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6) + #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7) + #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8) +@@ -54,6 +57,7 @@ + #define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14) + #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) + #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) ++#define MTK_PPE_TB_CFG_INFO_SEL BIT(20) + + enum { + MTK_PPE_SCAN_MODE_DISABLED, +@@ -112,6 +116,8 @@ enum { + #define MTK_PPE_DEFAULT_CPU_PORT 0x248 + #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4)) + ++#define MTK_PPE_DEFAULT_CPU_PORT1 0x24c ++ + #define MTK_PPE_MTU_DROP 0x308 + + #define MTK_PPE_VLAN_MTU0 0x30c +@@ -141,4 +147,6 @@ enum { + #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) + #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) + ++#define MTK_PPE_SBW_CTRL 0x374 ++ + #endif diff --git a/target/linux/generic/pending-5.15/799-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/pending-5.15/799-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch new file mode 100644 index 0000000000..5b94c3ad3a --- /dev/null +++ b/target/linux/generic/pending-5.15/799-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch @@ -0,0 +1,26 @@ +From b94b02a270471337bef73c44fa3493a521e31a61 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 13:56:13 +0200 +Subject: [PATCH net-next 5/5] net: ethernet: mtk_eth_soc: enable flow + offloading support for mt7986 + +Enable hw packet engine and wireless packet dispatcher for mt7986 + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4258,6 +4258,7 @@ static const struct mtk_soc_data mt7986_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, ++ .offload_version = 2, + .hash_offset = 4, + .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi index 17adda1554..601c859617 100644 --- a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi @@ -397,6 +397,28 @@ #reset-cells = <1>; }; + wed_pcie: wed-pcie@10003000 { + compatible = "mediatek,mt7986-wed-pcie", + "syscon"; + reg = <0 0x10003000 0 0x10>; + }; + + wed0: wed@15010000 { + compatible = "mediatek,mt7986-wed", + "syscon"; + reg = <0 0x15010000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + + wed1: wed@15011000 { + compatible = "mediatek,mt7986-wed", + "syscon"; + reg = <0 0x15011000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + eth: ethernet@15100000 { compatible = "mediatek,mt7986-eth"; reg = <0 0x15100000 0 0x80000>; @@ -431,6 +453,8 @@ <&apmixedsys CLK_APMIXED_SGMPLL>; mediatek,ethsys = <ðsys>; mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; + mediatek,wed-pcie = <&wed_pcie>; + mediatek,wed = <&wed0>, <&wed1>; #reset-cells = <1>; #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network index 29f4b875f8..e76792164d 100644 --- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network @@ -21,8 +21,7 @@ mediatek_setup_interfaces() ucidef_add_switch "switch0" \ "0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0" ;; - ubnt,unifi-6-lr|\ - ubnt,unifi-6-lr-ubootmod) + ubnt,unifi-6-lr*) ucidef_set_interface_lan "eth0" ;; xiaomi,redmi-router-ax6s) diff --git a/target/linux/mediatek/patches-5.15/510-net-mediatek-add-flow-offload-for-mt7623.patch b/target/linux/mediatek/patches-5.15/510-net-mediatek-add-flow-offload-for-mt7623.patch index 9b0d411bba..1f1f6e0e39 100644 --- a/target/linux/mediatek/patches-5.15/510-net-mediatek-add-flow-offload-for-mt7623.patch +++ b/target/linux/mediatek/patches-5.15/510-net-mediatek-add-flow-offload-for-mt7623.patch @@ -14,7 +14,7 @@ Signed-off-by: Frank Wunderlich --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3639,6 +3639,7 @@ static const struct mtk_soc_data mt2701_ +@@ -4166,6 +4166,7 @@ static const struct mtk_soc_data mt2701_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, diff --git a/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch b/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch index 7544787701..9667930aa1 100644 --- a/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch +++ b/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch @@ -20,7 +20,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -196,13 +196,35 @@ static int _mtk_mdio_write(struct mtk_et +@@ -219,13 +219,35 @@ static int _mtk_mdio_write(struct mtk_et if (ret < 0) return ret; @@ -63,7 +63,7 @@ Signed-off-by: David S. Miller ret = mtk_mdio_busy_wait(eth); if (ret < 0) -@@ -219,12 +241,33 @@ static int _mtk_mdio_read(struct mtk_eth +@@ -242,12 +264,33 @@ static int _mtk_mdio_read(struct mtk_eth if (ret < 0) return ret; @@ -103,7 +103,7 @@ Signed-off-by: David S. Miller ret = mtk_mdio_busy_wait(eth); if (ret < 0) -@@ -621,6 +664,7 @@ static int mtk_mdio_init(struct mtk_eth +@@ -644,6 +687,7 @@ static int mtk_mdio_init(struct mtk_eth eth->mii_bus->name = "mdio"; eth->mii_bus->read = mtk_mdio_read; eth->mii_bus->write = mtk_mdio_write; @@ -113,7 +113,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -327,9 +327,12 @@ +@@ -330,9 +330,12 @@ #define PHY_IAC_ADDR_MASK GENMASK(24, 20) #define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x)) #define PHY_IAC_CMD_MASK GENMASK(19, 18) diff --git a/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch index 43526f3c4a..d8ce3051b7 100644 --- a/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch +++ b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch @@ -14,7 +14,7 @@ Signed-off-by: René van Dorst --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3230,6 +3230,7 @@ static const struct net_device_ops mtk_n +@@ -3736,6 +3736,7 @@ static const struct net_device_ops mtk_n static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) { @@ -22,7 +22,7 @@ Signed-off-by: René van Dorst const __be32 *_id = of_get_property(np, "reg", NULL); phy_interface_t phy_mode; struct phylink *phylink; -@@ -3349,6 +3350,9 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -3855,6 +3856,9 @@ static int mtk_add_mac(struct mtk_eth *e else eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; diff --git a/target/linux/realtek/patches-5.10/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch b/target/linux/realtek/patches-5.10/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch index 0f4ab38d4d..0ecff843fb 100644 --- a/target/linux/realtek/patches-5.10/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch +++ b/target/linux/realtek/patches-5.10/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch @@ -42,7 +42,7 @@ #define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32)) #define IRR_SHIFT(idx) ((idx * 4) % 32) -@@ -65,19 +84,33 @@ static inline void write_irr(void __iomem *irr0, int idx, u32 value) +@@ -65,19 +84,33 @@ static inline void write_irr(void __iome writel(irr, irr0 + offset); } @@ -82,7 +82,7 @@ raw_spin_unlock_irqrestore(&irq_lock, flags); } -@@ -85,16 +118,12 @@ static void realtek_ictl_unmask_irq(struct irq_data *i) +@@ -85,16 +118,12 @@ static void realtek_ictl_unmask_irq(stru static void realtek_ictl_mask_irq(struct irq_data *i) { unsigned long flags; @@ -101,7 +101,7 @@ raw_spin_unlock_irqrestore(&irq_lock, flags); } -@@ -116,11 +145,17 @@ static int __maybe_unused realtek_ictl_irq_affinity(struct irq_data *i, +@@ -116,11 +145,17 @@ static int __maybe_unused realtek_ictl_i cpumask_and(&cpu_enable, &cpu_configure, dest); cpumask_andnot(&cpu_disable, &cpu_configure, dest); @@ -121,7 +121,7 @@ irq_data_update_effective_affinity(i, &cpu_enable); -@@ -149,6 +184,7 @@ static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +@@ -149,6 +184,7 @@ static int intc_map(struct irq_domain *d output->child_mask |= BIT(hw); write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1); @@ -129,7 +129,7 @@ raw_spin_unlock_irqrestore(&irq_lock, flags); -@@ -279,9 +315,11 @@ static int __init realtek_rtl_of_init(struct device_node *node, struct device_no +@@ -279,9 +315,11 @@ static int __init realtek_rtl_of_init(st cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable); /* Disable all cascaded interrupts and clear routing */ diff --git a/target/linux/x86/64/config-5.10 b/target/linux/x86/64/config-5.10 index 472cf07669..f91b3fe76f 100644 --- a/target/linux/x86/64/config-5.10 +++ b/target/linux/x86/64/config-5.10 @@ -38,6 +38,8 @@ CONFIG_AGP=y CONFIG_AGP_INTEL=y # CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set +CONFIG_AMD_IOMMU=y +# CONFIG_AMD_IOMMU_V2 is not set CONFIG_ARCH_CPUIDLE_HALTPOLL=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y @@ -221,6 +223,7 @@ CONFIG_HW_RANDOM_VIRTIO=y CONFIG_HYPERV=y CONFIG_HYPERVISOR_GUEST=y CONFIG_HYPERV_BALLOON=y +CONFIG_HYPERV_IOMMU=y CONFIG_HYPERV_KEYBOARD=y CONFIG_HYPERV_NET=y CONFIG_HYPERV_STORAGE=y @@ -240,6 +243,11 @@ CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y CONFIG_INTEL_GTT=y CONFIG_INTEL_IDLE=y # CONFIG_INTEL_IDXD is not set +CONFIG_INTEL_IOMMU=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +# CONFIG_INTEL_IOMMU_SVM is not set # CONFIG_INTEL_IPS is not set # CONFIG_INTEL_MEI_HDCP is not set # CONFIG_INTEL_MENLOW is not set @@ -249,12 +257,22 @@ CONFIG_INTEL_SOC_DTS_IOSF_CORE=y CONFIG_INTEL_SOC_DTS_THERMAL=y # CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set # CONFIG_INTEL_TURBO_MAX_3 is not set +# CONFIG_INTEL_TXT is not set # CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set CONFIG_INTERVAL_TREE=y +CONFIG_IOASID=y +CONFIG_IOMMU_API=y # CONFIG_IOMMU_DEBUG is not set +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y CONFIG_IOMMU_HELPER=y +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_SUPPORT=y CONFIG_IOSF_MBI=y # CONFIG_IOSF_MBI_DEBUG is not set +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_REMAP=y # CONFIG_ISCSI_IBFT is not set CONFIG_ISO9660_FS=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y @@ -401,6 +419,7 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y # CONFIG_TOSHIBA_BT_RFKILL is not set CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set # CONFIG_UCLAMP_TASK is not set CONFIG_UCS2_STRING=y # CONFIG_UNWINDER_ORC is not set diff --git a/target/linux/x86/64/config-5.15 b/target/linux/x86/64/config-5.15 index ec9a73c9e2..7068b3b66c 100644 --- a/target/linux/x86/64/config-5.15 +++ b/target/linux/x86/64/config-5.15 @@ -41,6 +41,8 @@ CONFIG_AGP=y CONFIG_AGP_INTEL=y # CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set +CONFIG_AMD_IOMMU=y +# CONFIG_AMD_IOMMU_V2 is not set # CONFIG_AMD_PMC is not set # CONFIG_AMD_PTDMA is not set # CONFIG_AMD_SFH_HID is not set @@ -234,6 +236,7 @@ CONFIG_HW_RANDOM_VIRTIO=y CONFIG_HYPERV=y CONFIG_HYPERVISOR_GUEST=y CONFIG_HYPERV_BALLOON=y +CONFIG_HYPERV_IOMMU=y CONFIG_HYPERV_KEYBOARD=y CONFIG_HYPERV_NET=y CONFIG_HYPERV_STORAGE=y @@ -255,6 +258,11 @@ CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y CONFIG_INTEL_GTT=y CONFIG_INTEL_IDLE=y # CONFIG_INTEL_IDXD_COMPAT is not set +CONFIG_INTEL_IOMMU=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +# CONFIG_INTEL_IOMMU_SVM is not set # CONFIG_INTEL_IPS is not set # CONFIG_INTEL_MEI_HDCP is not set # CONFIG_INTEL_MENLOW is not set @@ -265,12 +273,22 @@ CONFIG_INTEL_SOC_DTS_IOSF_CORE=y CONFIG_INTEL_SOC_DTS_THERMAL=y # CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set # CONFIG_INTEL_TURBO_MAX_3 is not set +# CONFIG_INTEL_TXT is not set # CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set CONFIG_INTERVAL_TREE=y +CONFIG_IOASID=y +CONFIG_IOMMU_API=y # CONFIG_IOMMU_DEBUG is not set +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y CONFIG_IOMMU_HELPER=y +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_SUPPORT=y CONFIG_IOSF_MBI=y # CONFIG_IOSF_MBI_DEBUG is not set +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_REMAP=y # CONFIG_ISCSI_IBFT is not set CONFIG_ISO9660_FS=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y @@ -422,6 +440,7 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y # CONFIG_TOSHIBA_BT_RFKILL is not set CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set # CONFIG_UCLAMP_TASK is not set CONFIG_UCS2_STRING=y # CONFIG_UNWINDER_ORC is not set