Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
fd2b54a16b
@ -1651,6 +1651,7 @@ endef
|
|||||||
$(eval $(call KernelPackage,qrtr-mhi))
|
$(eval $(call KernelPackage,qrtr-mhi))
|
||||||
|
|
||||||
define KernelPackage/unix-diag
|
define KernelPackage/unix-diag
|
||||||
|
SUBMENU:=$(NETWORK_SUPPORT_MENU)
|
||||||
TITLE:=UNIX socket monitoring interface
|
TITLE:=UNIX socket monitoring interface
|
||||||
KCONFIG:=CONFIG_UNIX_DIAG
|
KCONFIG:=CONFIG_UNIX_DIAG
|
||||||
FILES:= $(LINUX_DIR)/net/unix/unix_diag.ko
|
FILES:= $(LINUX_DIR)/net/unix/unix_diag.ko
|
||||||
@ -1660,6 +1661,7 @@ endef
|
|||||||
$(eval $(call KernelPackage,unix-diag))
|
$(eval $(call KernelPackage,unix-diag))
|
||||||
|
|
||||||
define KernelPackage/packet-diag
|
define KernelPackage/packet-diag
|
||||||
|
SUBMENU:=$(NETWORK_SUPPORT_MENU)
|
||||||
TITLE:=Packet sockets monitoring interface
|
TITLE:=Packet sockets monitoring interface
|
||||||
KCONFIG:=CONFIG_PACKET_DIAG
|
KCONFIG:=CONFIG_PACKET_DIAG
|
||||||
FILES:= $(LINUX_DIR)/net/packet/af_packet_diag.ko
|
FILES:= $(LINUX_DIR)/net/packet/af_packet_diag.ko
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
From b77c0ecdc7915e5c5c515da1aa6cfaf6f4eb8351 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mathew McBride <matt@traverse.com.au>
|
|
||||||
Date: Wed, 28 Sep 2022 16:39:31 +1000
|
|
||||||
Subject: [PATCH] arm: disable code size reduction measures
|
|
||||||
(gc-sections,-f*-sections)
|
|
||||||
|
|
||||||
This interferes with the EFI boot stub on armv7l.
|
|
||||||
|
|
||||||
Signed-off-by: Mathew McBride <matt@traverse.com.au>
|
|
||||||
---
|
|
||||||
arch/arm/Kconfig | 1 -
|
|
||||||
1 file changed, 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/arch/arm/Kconfig
|
|
||||||
+++ b/arch/arm/Kconfig
|
|
||||||
@@ -128,7 +128,6 @@ config ARM
|
|
||||||
select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
|
|
||||||
select IRQ_FORCED_THREADING
|
|
||||||
select LOCK_MM_AND_FIND_VMA
|
|
||||||
- select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
|
||||||
select MODULES_USE_ELF_REL
|
|
||||||
select NEED_DMA_MAP_STATE
|
|
||||||
select OF_EARLY_FLATTREE if OF
|
|
@ -343,7 +343,7 @@ Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20057,6 +20057,14 @@ T: git git://linuxtv.org/media_tree.git
|
@@ -20058,6 +20058,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
|
F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
|
||||||
F: drivers/media/i2c/imx415.c
|
F: drivers/media/i2c/imx415.c
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20065,6 +20065,14 @@ T: git git://linuxtv.org/media_tree.git
|
@@ -20066,6 +20066,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||||
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
||||||
F: drivers/media/i2c/imx477.c
|
F: drivers/media/i2c/imx477.c
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20062,6 +20062,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
@@ -20063,6 +20063,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
@ -138,7 +138,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20106,6 +20106,14 @@ T: git git://linuxtv.org/media_tree.git
|
@@ -20107,6 +20107,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||||
F: Documentation/devicetree/bindings/media/i2c/imx519.yaml
|
F: Documentation/devicetree/bindings/media/i2c/imx519.yaml
|
||||||
F: drivers/media/i2c/imx519.c
|
F: drivers/media/i2c/imx519.c
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20111,7 +20111,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
@@ -20112,7 +20112,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
@ -291,7 +291,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
+ };
|
+ };
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20012,7 +20012,7 @@ M: Sakari Ailus <sakari.ailus@linux.inte
|
@@ -20013,7 +20013,7 @@ M: Sakari Ailus <sakari.ailus@linux.inte
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
@ -67,7 +67,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
|||||||
+...
|
+...
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -18619,6 +18619,13 @@ S: Supported
|
@@ -18620,6 +18620,13 @@ S: Supported
|
||||||
F: drivers/iio/light/rohm-bu27008.c
|
F: drivers/iio/light/rohm-bu27008.c
|
||||||
F: drivers/iio/light/rohm-bu27034.c
|
F: drivers/iio/light/rohm-bu27034.c
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -15871,6 +15871,14 @@ S: Maintained
|
@@ -15872,6 +15872,14 @@ S: Maintained
|
||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
F: drivers/media/i2c/ov5695.c
|
F: drivers/media/i2c/ov5695.c
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
|
|||||||
drivers cannot. If you rely on getting the inactive state, use .duty_cycle=0,
|
drivers cannot. If you rely on getting the inactive state, use .duty_cycle=0,
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -17437,7 +17437,7 @@ F: drivers/video/backlight/pwm_bl.c
|
@@ -17438,7 +17438,7 @@ F: drivers/video/backlight/pwm_bl.c
|
||||||
F: include/dt-bindings/pwm/
|
F: include/dt-bindings/pwm/
|
||||||
F: include/linux/pwm.h
|
F: include/linux/pwm.h
|
||||||
F: include/linux/pwm_backlight.h
|
F: include/linux/pwm_backlight.h
|
||||||
|
@ -23,7 +23,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -18032,6 +18032,13 @@ L: linux-wireless@vger.kernel.org
|
@@ -18033,6 +18033,13 @@ L: linux-wireless@vger.kernel.org
|
||||||
S: Orphan
|
S: Orphan
|
||||||
F: drivers/net/wireless/legacy/ray*
|
F: drivers/net/wireless/legacy/ray*
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
|
|||||||
+ };
|
+ };
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -18037,6 +18037,7 @@ M: Jacopo Mondi <jacopo.mondi@ideasonboa
|
@@ -18038,6 +18038,7 @@ M: Jacopo Mondi <jacopo.mondi@ideasonboa
|
||||||
L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
|
L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -94,7 +94,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
|||||||
+
|
+
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -18027,6 +18027,11 @@ F: drivers/ras/
|
@@ -18028,6 +18028,11 @@ F: drivers/ras/
|
||||||
F: include/linux/ras.h
|
F: include/linux/ras.h
|
||||||
F: include/ras/ras_event.h
|
F: include/ras/ras_event.h
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -18031,6 +18031,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
|
@@ -18032,6 +18032,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
|
||||||
M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
|
M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
|
F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
|
||||||
|
@ -150,7 +150,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
|||||||
+
|
+
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20127,6 +20127,13 @@ F: Documentation/devicetree/bindings/med
|
@@ -20128,6 +20128,13 @@ F: Documentation/devicetree/bindings/med
|
||||||
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
||||||
F: drivers/media/i2c/imx477.c
|
F: drivers/media/i2c/imx477.c
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20133,6 +20133,7 @@ L: linux-media@vger.kernel.org
|
@@ -20134,6 +20134,7 @@ L: linux-media@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml
|
F: Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml
|
||||||
|
@ -0,0 +1,172 @@
|
|||||||
|
From ed0f941022515ff40473ea5335769a5dc2524a3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yuntao Liu <liuyuntao12@huawei.com>
|
||||||
|
Date: Mon, 3 Jun 2024 16:37:50 +0100
|
||||||
|
Subject: [PATCH] ARM: 9404/1: arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||||
|
|
||||||
|
The current arm32 architecture does not yet support the
|
||||||
|
HAVE_LD_DEAD_CODE_DATA_ELIMINATION feature. arm32 is widely used in
|
||||||
|
embedded scenarios, and enabling this feature would be beneficial for
|
||||||
|
reducing the size of the kernel image.
|
||||||
|
|
||||||
|
In order to make this work, we keep the necessary tables by annotating
|
||||||
|
them with KEEP, also it requires further changes to linker script to KEEP
|
||||||
|
some tables and wildcard compiler generated sections into the right place.
|
||||||
|
When using ld.lld for linking, KEEP is not recognized within the OVERLAY
|
||||||
|
command, and Ard proposed a concise method to solve this problem.
|
||||||
|
|
||||||
|
It boots normally with defconfig, vexpress_defconfig and tinyconfig.
|
||||||
|
|
||||||
|
The size comparison of zImage is as follows:
|
||||||
|
defconfig vexpress_defconfig tinyconfig
|
||||||
|
5137712 5138024 424192 no dce
|
||||||
|
5032560 4997824 298384 dce
|
||||||
|
2.0% 2.7% 29.7% shrink
|
||||||
|
|
||||||
|
When using smaller config file, there is a significant reduction in the
|
||||||
|
size of the zImage.
|
||||||
|
|
||||||
|
We also tested this patch on a commercially available single-board
|
||||||
|
computer, and the comparison is as follows:
|
||||||
|
a15eb_config
|
||||||
|
2161384 no dce
|
||||||
|
2092240 dce
|
||||||
|
3.2% shrink
|
||||||
|
|
||||||
|
The zImage size has been reduced by approximately 3.2%, which is 70KB on
|
||||||
|
2.1M.
|
||||||
|
|
||||||
|
Signed-off-by: Yuntao Liu <liuyuntao12@huawei.com>
|
||||||
|
Tested-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||||
|
---
|
||||||
|
arch/arm/Kconfig | 1 +
|
||||||
|
arch/arm/boot/compressed/vmlinux.lds.S | 2 +-
|
||||||
|
arch/arm/include/asm/vmlinux.lds.h | 2 +-
|
||||||
|
arch/arm/kernel/entry-armv.S | 3 +++
|
||||||
|
arch/arm/kernel/vmlinux-xip.lds.S | 4 ++--
|
||||||
|
arch/arm/kernel/vmlinux.lds.S | 6 +++---
|
||||||
|
drivers/firmware/efi/libstub/Makefile | 4 ++++
|
||||||
|
7 files changed, 15 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/Kconfig
|
||||||
|
+++ b/arch/arm/Kconfig
|
||||||
|
@@ -111,6 +111,7 @@ config ARM
|
||||||
|
select HAVE_KERNEL_XZ
|
||||||
|
select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
|
||||||
|
select HAVE_KRETPROBES if HAVE_KPROBES
|
||||||
|
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||||
|
select HAVE_MOD_ARCH_SPECIFIC
|
||||||
|
select HAVE_NMI
|
||||||
|
select HAVE_OPTPROBES if !THUMB2_KERNEL
|
||||||
|
--- a/arch/arm/boot/compressed/vmlinux.lds.S
|
||||||
|
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
|
||||||
|
@@ -125,7 +125,7 @@ SECTIONS
|
||||||
|
|
||||||
|
. = BSS_START;
|
||||||
|
__bss_start = .;
|
||||||
|
- .bss : { *(.bss) }
|
||||||
|
+ .bss : { *(.bss .bss.*) }
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(8); /* the stack must be 64-bit aligned */
|
||||||
|
--- a/arch/arm/include/asm/vmlinux.lds.h
|
||||||
|
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
||||||
|
@@ -42,7 +42,7 @@
|
||||||
|
#define PROC_INFO \
|
||||||
|
. = ALIGN(4); \
|
||||||
|
__proc_info_begin = .; \
|
||||||
|
- *(.proc.info.init) \
|
||||||
|
+ KEEP(*(.proc.info.init)) \
|
||||||
|
__proc_info_end = .;
|
||||||
|
|
||||||
|
#define IDMAP_TEXT \
|
||||||
|
--- a/arch/arm/kernel/entry-armv.S
|
||||||
|
+++ b/arch/arm/kernel/entry-armv.S
|
||||||
|
@@ -1073,6 +1073,7 @@ vector_addrexcptn:
|
||||||
|
.globl vector_fiq
|
||||||
|
|
||||||
|
.section .vectors, "ax", %progbits
|
||||||
|
+ .reloc .text, R_ARM_NONE, .
|
||||||
|
W(b) vector_rst
|
||||||
|
W(b) vector_und
|
||||||
|
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_swi )
|
||||||
|
@@ -1086,6 +1087,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vec
|
||||||
|
|
||||||
|
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
||||||
|
.section .vectors.bhb.loop8, "ax", %progbits
|
||||||
|
+ .reloc .text, R_ARM_NONE, .
|
||||||
|
W(b) vector_rst
|
||||||
|
W(b) vector_bhb_loop8_und
|
||||||
|
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi )
|
||||||
|
@@ -1098,6 +1100,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vec
|
||||||
|
W(b) vector_bhb_loop8_fiq
|
||||||
|
|
||||||
|
.section .vectors.bhb.bpiall, "ax", %progbits
|
||||||
|
+ .reloc .text, R_ARM_NONE, .
|
||||||
|
W(b) vector_rst
|
||||||
|
W(b) vector_bhb_bpiall_und
|
||||||
|
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi )
|
||||||
|
--- a/arch/arm/kernel/vmlinux-xip.lds.S
|
||||||
|
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
|
||||||
|
@@ -63,7 +63,7 @@ SECTIONS
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||||
|
__start___ex_table = .;
|
||||||
|
- ARM_MMU_KEEP(*(__ex_table))
|
||||||
|
+ ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||||
|
__stop___ex_table = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@ SECTIONS
|
||||||
|
}
|
||||||
|
.init.arch.info : {
|
||||||
|
__arch_info_begin = .;
|
||||||
|
- *(.arch.info.init)
|
||||||
|
+ KEEP(*(.arch.info.init))
|
||||||
|
__arch_info_end = .;
|
||||||
|
}
|
||||||
|
.init.tagtable : {
|
||||||
|
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||||
|
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||||
|
@@ -74,7 +74,7 @@ SECTIONS
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||||
|
__start___ex_table = .;
|
||||||
|
- ARM_MMU_KEEP(*(__ex_table))
|
||||||
|
+ ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||||
|
__stop___ex_table = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -99,7 +99,7 @@ SECTIONS
|
||||||
|
}
|
||||||
|
.init.arch.info : {
|
||||||
|
__arch_info_begin = .;
|
||||||
|
- *(.arch.info.init)
|
||||||
|
+ KEEP(*(.arch.info.init))
|
||||||
|
__arch_info_end = .;
|
||||||
|
}
|
||||||
|
.init.tagtable : {
|
||||||
|
@@ -116,7 +116,7 @@ SECTIONS
|
||||||
|
#endif
|
||||||
|
.init.pv_table : {
|
||||||
|
__pv_table_begin = .;
|
||||||
|
- *(.pv_table)
|
||||||
|
+ KEEP(*(.pv_table))
|
||||||
|
__pv_table_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/drivers/firmware/efi/libstub/Makefile
|
||||||
|
+++ b/drivers/firmware/efi/libstub/Makefile
|
||||||
|
@@ -67,6 +67,10 @@ OBJECT_FILES_NON_STANDARD := y
|
||||||
|
# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
|
||||||
|
KCOV_INSTRUMENT := n
|
||||||
|
|
||||||
|
+# The .data section would be renamed to .data.efistub, therefore, remove
|
||||||
|
+# `-fdata-sections` flag from KBUILD_CFLAGS_KERNEL
|
||||||
|
+KBUILD_CFLAGS_KERNEL := $(filter-out -fdata-sections, $(KBUILD_CFLAGS_KERNEL))
|
||||||
|
+
|
||||||
|
lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
|
||||||
|
file.o mem.o random.o randomalloc.o pci.o \
|
||||||
|
skip_spaces.o lib-cmdline.o lib-ctype.o \
|
@ -0,0 +1,31 @@
|
|||||||
|
From 1824520e7477bedf76bd08c32261c755e6405cd9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Date: Mon, 12 Aug 2024 02:56:41 +0100
|
||||||
|
Subject: [PATCH] mtd: spinand: set bitflip_threshold to 75% of ECC strength
|
||||||
|
|
||||||
|
Reporting an unclean read from SPI-NAND only when the maximum number
|
||||||
|
of correctable bitflip errors has been hit seems a bit late.
|
||||||
|
UBI LEB scrubbing, which depends on the lower MTD device reporting
|
||||||
|
correctable bitflips, then only kicks in when it's almost too late.
|
||||||
|
|
||||||
|
Set bitflip_threshold to 75% of the ECC strength, which is also the
|
||||||
|
default for raw NAND.
|
||||||
|
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
|
||||||
|
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||||
|
Link: https://lore.kernel.org/linux-mtd/2117e387260b0a96f95b8e1652ff79e0e2d71d53.1723427450.git.daniel@makrotopia.org
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/spi/core.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/spi/core.c
|
||||||
|
+++ b/drivers/mtd/nand/spi/core.c
|
||||||
|
@@ -1287,6 +1287,7 @@ static int spinand_init(struct spinand_d
|
||||||
|
/* Propagate ECC information to mtd_info */
|
||||||
|
mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
|
||||||
|
mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
|
||||||
|
+ mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
|
||||||
|
|
||||||
|
ret = spinand_create_dirmaps(spinand);
|
||||||
|
if (ret) {
|
@ -1,6 +1,6 @@
|
|||||||
From 446daf20b0a6790751459cdde0ff9fc8813e54d1 Mon Sep 17 00:00:00 2001
|
From e2a9fcb36e851adb5b25c4acea53a290fd48a636 Mon Sep 17 00:00:00 2001
|
||||||
From: Robert Marko <robimarko@gmail.com>
|
From: Robert Marko <robimarko@gmail.com>
|
||||||
Date: Mon, 29 Jul 2024 14:09:16 +0200
|
Date: Mon, 5 Aug 2024 19:51:02 +0200
|
||||||
Subject: [PATCH] mtd: spinand: winbond: add support for W25N01KV
|
Subject: [PATCH] mtd: spinand: winbond: add support for W25N01KV
|
||||||
|
|
||||||
Add support for Winbond W25N01KV 1Gbit SPI-NAND.
|
Add support for Winbond W25N01KV 1Gbit SPI-NAND.
|
||||||
@ -8,13 +8,15 @@ Add support for Winbond W25N01KV 1Gbit SPI-NAND.
|
|||||||
It has 4-bit on-die ECC.
|
It has 4-bit on-die ECC.
|
||||||
|
|
||||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||||
|
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||||
|
Link: https://lore.kernel.org/linux-mtd/20240805175125.6658-1-robimarko@gmail.com
|
||||||
---
|
---
|
||||||
drivers/mtd/nand/spi/winbond.c | 26 ++++++++++++++++++++++++++
|
drivers/mtd/nand/spi/winbond.c | 26 ++++++++++++++++++++++++++
|
||||||
1 file changed, 26 insertions(+)
|
1 file changed, 26 insertions(+)
|
||||||
|
|
||||||
--- a/drivers/mtd/nand/spi/winbond.c
|
--- a/drivers/mtd/nand/spi/winbond.c
|
||||||
+++ b/drivers/mtd/nand/spi/winbond.c
|
+++ b/drivers/mtd/nand/spi/winbond.c
|
||||||
@@ -76,6 +76,18 @@ static int w25m02gv_select_target(struct
|
@@ -74,6 +74,18 @@ static int w25m02gv_select_target(struct
|
||||||
return spi_mem_exec_op(spinand->spimem, &op);
|
return spi_mem_exec_op(spinand->spimem, &op);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
|
|||||||
static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
|
static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||||
struct mtd_oob_region *region)
|
struct mtd_oob_region *region)
|
||||||
{
|
{
|
||||||
@@ -100,6 +112,11 @@ static int w25n02kv_ooblayout_free(struc
|
@@ -98,6 +110,11 @@ static int w25n02kv_ooblayout_free(struc
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
|
|||||||
static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
|
static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
|
||||||
.ecc = w25n02kv_ooblayout_ecc,
|
.ecc = w25n02kv_ooblayout_ecc,
|
||||||
.free = w25n02kv_ooblayout_free,
|
.free = w25n02kv_ooblayout_free,
|
||||||
@@ -163,6 +180,15 @@ static const struct spinand_info winbond
|
@@ -160,6 +177,15 @@ static const struct spinand_info winbond
|
||||||
&update_cache_variants),
|
&update_cache_variants),
|
||||||
0,
|
0,
|
||||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
@ -0,0 +1,101 @@
|
|||||||
|
From 8928756d53d5b99dcd18073dc7738b8ebdbe7d96 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:42 +0200
|
||||||
|
Subject: [PATCH 1/6] net: move skb_gro_receive_list from udp to core
|
||||||
|
|
||||||
|
This helper function will be used for TCP fraglist GRO support
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
include/net/gro.h | 1 +
|
||||||
|
net/core/gro.c | 27 +++++++++++++++++++++++++++
|
||||||
|
net/ipv4/udp_offload.c | 27 ---------------------------
|
||||||
|
3 files changed, 28 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/net/gro.h
|
||||||
|
+++ b/include/net/gro.h
|
||||||
|
@@ -439,6 +439,7 @@ static inline __wsum ip6_gro_compute_pse
|
||||||
|
}
|
||||||
|
|
||||||
|
int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb);
|
||||||
|
+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb);
|
||||||
|
|
||||||
|
/* Pass the currently batched GRO_NORMAL SKBs up to the stack. */
|
||||||
|
static inline void gro_normal_list(struct napi_struct *napi)
|
||||||
|
--- a/net/core/gro.c
|
||||||
|
+++ b/net/core/gro.c
|
||||||
|
@@ -228,6 +228,33 @@ done:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ if (unlikely(p->len + skb->len >= 65536))
|
||||||
|
+ return -E2BIG;
|
||||||
|
+
|
||||||
|
+ if (NAPI_GRO_CB(p)->last == p)
|
||||||
|
+ skb_shinfo(p)->frag_list = skb;
|
||||||
|
+ else
|
||||||
|
+ NAPI_GRO_CB(p)->last->next = skb;
|
||||||
|
+
|
||||||
|
+ skb_pull(skb, skb_gro_offset(skb));
|
||||||
|
+
|
||||||
|
+ NAPI_GRO_CB(p)->last = skb;
|
||||||
|
+ NAPI_GRO_CB(p)->count++;
|
||||||
|
+ p->data_len += skb->len;
|
||||||
|
+
|
||||||
|
+ /* sk ownership - if any - completely transferred to the aggregated packet */
|
||||||
|
+ skb->destructor = NULL;
|
||||||
|
+ skb->sk = NULL;
|
||||||
|
+ p->truesize += skb->truesize;
|
||||||
|
+ p->len += skb->len;
|
||||||
|
+
|
||||||
|
+ NAPI_GRO_CB(skb)->same_flow = 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
--- a/net/ipv4/udp_offload.c
|
||||||
|
+++ b/net/ipv4/udp_offload.c
|
||||||
|
@@ -474,33 +474,6 @@ out:
|
||||||
|
return segs;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
|
||||||
|
-{
|
||||||
|
- if (unlikely(p->len + skb->len >= 65536))
|
||||||
|
- return -E2BIG;
|
||||||
|
-
|
||||||
|
- if (NAPI_GRO_CB(p)->last == p)
|
||||||
|
- skb_shinfo(p)->frag_list = skb;
|
||||||
|
- else
|
||||||
|
- NAPI_GRO_CB(p)->last->next = skb;
|
||||||
|
-
|
||||||
|
- skb_pull(skb, skb_gro_offset(skb));
|
||||||
|
-
|
||||||
|
- NAPI_GRO_CB(p)->last = skb;
|
||||||
|
- NAPI_GRO_CB(p)->count++;
|
||||||
|
- p->data_len += skb->len;
|
||||||
|
-
|
||||||
|
- /* sk ownership - if any - completely transferred to the aggregated packet */
|
||||||
|
- skb->destructor = NULL;
|
||||||
|
- skb->sk = NULL;
|
||||||
|
- p->truesize += skb->truesize;
|
||||||
|
- p->len += skb->len;
|
||||||
|
-
|
||||||
|
- NAPI_GRO_CB(skb)->same_flow = 1;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
|
||||||
|
#define UDP_GRO_CNT_MAX 64
|
||||||
|
static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
|
@ -0,0 +1,177 @@
|
|||||||
|
From bee88cd5bd83d40b8aec4d6cb729378f707f6197 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:43 +0200
|
||||||
|
Subject: [PATCH 2/6] net: add support for segmenting TCP fraglist GSO packets
|
||||||
|
|
||||||
|
Preparation for adding TCP fraglist GRO support. It expects packets to be
|
||||||
|
combined in a similar way as UDP fraglist GSO packets.
|
||||||
|
For IPv4 packets, NAT is handled in the same way as UDP fraglist GSO.
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
net/ipv4/tcp_offload.c | 67 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
net/ipv6/tcpv6_offload.c | 58 ++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 125 insertions(+)
|
||||||
|
|
||||||
|
--- a/net/ipv4/tcp_offload.c
|
||||||
|
+++ b/net/ipv4/tcp_offload.c
|
||||||
|
@@ -31,6 +31,70 @@ static void tcp_gso_tstamp(struct sk_buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void __tcpv4_gso_segment_csum(struct sk_buff *seg,
|
||||||
|
+ __be32 *oldip, __be32 newip,
|
||||||
|
+ __be16 *oldport, __be16 newport)
|
||||||
|
+{
|
||||||
|
+ struct tcphdr *th;
|
||||||
|
+ struct iphdr *iph;
|
||||||
|
+
|
||||||
|
+ if (*oldip == newip && *oldport == newport)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ th = tcp_hdr(seg);
|
||||||
|
+ iph = ip_hdr(seg);
|
||||||
|
+
|
||||||
|
+ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true);
|
||||||
|
+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
|
||||||
|
+ *oldport = newport;
|
||||||
|
+
|
||||||
|
+ csum_replace4(&iph->check, *oldip, newip);
|
||||||
|
+ *oldip = newip;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs)
|
||||||
|
+{
|
||||||
|
+ const struct tcphdr *th;
|
||||||
|
+ const struct iphdr *iph;
|
||||||
|
+ struct sk_buff *seg;
|
||||||
|
+ struct tcphdr *th2;
|
||||||
|
+ struct iphdr *iph2;
|
||||||
|
+
|
||||||
|
+ seg = segs;
|
||||||
|
+ th = tcp_hdr(seg);
|
||||||
|
+ iph = ip_hdr(seg);
|
||||||
|
+ th2 = tcp_hdr(seg->next);
|
||||||
|
+ iph2 = ip_hdr(seg->next);
|
||||||
|
+
|
||||||
|
+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
|
||||||
|
+ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
|
||||||
|
+ return segs;
|
||||||
|
+
|
||||||
|
+ while ((seg = seg->next)) {
|
||||||
|
+ th2 = tcp_hdr(seg);
|
||||||
|
+ iph2 = ip_hdr(seg);
|
||||||
|
+
|
||||||
|
+ __tcpv4_gso_segment_csum(seg,
|
||||||
|
+ &iph2->saddr, iph->saddr,
|
||||||
|
+ &th2->source, th->source);
|
||||||
|
+ __tcpv4_gso_segment_csum(seg,
|
||||||
|
+ &iph2->daddr, iph->daddr,
|
||||||
|
+ &th2->dest, th->dest);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return segs;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb,
|
||||||
|
+ netdev_features_t features)
|
||||||
|
+{
|
||||||
|
+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
|
||||||
|
+ if (IS_ERR(skb))
|
||||||
|
+ return skb;
|
||||||
|
+
|
||||||
|
+ return __tcpv4_gso_segment_list_csum(skb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
|
||||||
|
netdev_features_t features)
|
||||||
|
{
|
||||||
|
@@ -40,6 +104,9 @@ static struct sk_buff *tcp4_gso_segment(
|
||||||
|
if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
|
||||||
|
+ return __tcp4_gso_segment_list(skb, features);
|
||||||
|
+
|
||||||
|
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
|
||||||
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
|
struct tcphdr *th = tcp_hdr(skb);
|
||||||
|
--- a/net/ipv6/tcpv6_offload.c
|
||||||
|
+++ b/net/ipv6/tcpv6_offload.c
|
||||||
|
@@ -40,6 +40,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void __tcpv6_gso_segment_csum(struct sk_buff *seg,
|
||||||
|
+ __be16 *oldport, __be16 newport)
|
||||||
|
+{
|
||||||
|
+ struct tcphdr *th;
|
||||||
|
+
|
||||||
|
+ if (*oldport == newport)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ th = tcp_hdr(seg);
|
||||||
|
+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
|
||||||
|
+ *oldport = newport;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs)
|
||||||
|
+{
|
||||||
|
+ const struct tcphdr *th;
|
||||||
|
+ const struct ipv6hdr *iph;
|
||||||
|
+ struct sk_buff *seg;
|
||||||
|
+ struct tcphdr *th2;
|
||||||
|
+ struct ipv6hdr *iph2;
|
||||||
|
+
|
||||||
|
+ seg = segs;
|
||||||
|
+ th = tcp_hdr(seg);
|
||||||
|
+ iph = ipv6_hdr(seg);
|
||||||
|
+ th2 = tcp_hdr(seg->next);
|
||||||
|
+ iph2 = ipv6_hdr(seg->next);
|
||||||
|
+
|
||||||
|
+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
|
||||||
|
+ ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
|
||||||
|
+ ipv6_addr_equal(&iph->daddr, &iph2->daddr))
|
||||||
|
+ return segs;
|
||||||
|
+
|
||||||
|
+ while ((seg = seg->next)) {
|
||||||
|
+ th2 = tcp_hdr(seg);
|
||||||
|
+ iph2 = ipv6_hdr(seg);
|
||||||
|
+
|
||||||
|
+ iph2->saddr = iph->saddr;
|
||||||
|
+ iph2->daddr = iph->daddr;
|
||||||
|
+ __tcpv6_gso_segment_csum(seg, &th2->source, th->source);
|
||||||
|
+ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return segs;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb,
|
||||||
|
+ netdev_features_t features)
|
||||||
|
+{
|
||||||
|
+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
|
||||||
|
+ if (IS_ERR(skb))
|
||||||
|
+ return skb;
|
||||||
|
+
|
||||||
|
+ return __tcpv6_gso_segment_list_csum(skb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
|
||||||
|
netdev_features_t features)
|
||||||
|
{
|
||||||
|
@@ -51,6 +106,9 @@ static struct sk_buff *tcp6_gso_segment(
|
||||||
|
if (!pskb_may_pull(skb, sizeof(*th)))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
|
||||||
|
+ return __tcp6_gso_segment_list(skb, features);
|
||||||
|
+
|
||||||
|
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
|
||||||
|
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||||
|
struct tcphdr *th = tcp_hdr(skb);
|
@ -0,0 +1,75 @@
|
|||||||
|
From 8d95dc474f85481652a0e422d2f1f079de81f63c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:44 +0200
|
||||||
|
Subject: [PATCH 3/6] net: add code for TCP fraglist GRO
|
||||||
|
|
||||||
|
This implements fraglist GRO similar to how it's handled in UDP, however
|
||||||
|
no functional changes are added yet. The next change adds a heuristic for
|
||||||
|
using fraglist GRO instead of regular GRO.
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
net/ipv4/tcp_offload.c | 21 +++++++++++++++++++++
|
||||||
|
net/ipv6/tcpv6_offload.c | 9 +++++++++
|
||||||
|
2 files changed, 30 insertions(+)
|
||||||
|
|
||||||
|
--- a/net/ipv4/tcp_offload.c
|
||||||
|
+++ b/net/ipv4/tcp_offload.c
|
||||||
|
@@ -342,6 +342,18 @@ found:
|
||||||
|
flush |= p->decrypted ^ skb->decrypted;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ if (unlikely(NAPI_GRO_CB(p)->is_flist)) {
|
||||||
|
+ flush |= (__force int)(flags ^ tcp_flag_word(th2));
|
||||||
|
+ flush |= skb->ip_summed != p->ip_summed;
|
||||||
|
+ flush |= skb->csum_level != p->csum_level;
|
||||||
|
+ flush |= NAPI_GRO_CB(p)->count >= 64;
|
||||||
|
+
|
||||||
|
+ if (flush || skb_gro_receive_list(p, skb))
|
||||||
|
+ mss = 1;
|
||||||
|
+
|
||||||
|
+ goto out_check_final;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (flush || skb_gro_receive(p, skb)) {
|
||||||
|
mss = 1;
|
||||||
|
goto out_check_final;
|
||||||
|
@@ -406,6 +418,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
|
||||||
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
|
struct tcphdr *th = tcp_hdr(skb);
|
||||||
|
|
||||||
|
+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
|
||||||
|
+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4;
|
||||||
|
+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
|
||||||
|
+
|
||||||
|
+ __skb_incr_checksum_unnecessary(skb);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr,
|
||||||
|
iph->daddr, 0);
|
||||||
|
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
|
||||||
|
--- a/net/ipv6/tcpv6_offload.c
|
||||||
|
+++ b/net/ipv6/tcpv6_offload.c
|
||||||
|
@@ -32,6 +32,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
|
||||||
|
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||||
|
struct tcphdr *th = tcp_hdr(skb);
|
||||||
|
|
||||||
|
+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
|
||||||
|
+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6;
|
||||||
|
+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
|
||||||
|
+
|
||||||
|
+ __skb_incr_checksum_unnecessary(skb);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,
|
||||||
|
&iph->daddr, 0);
|
||||||
|
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
|
@ -0,0 +1,88 @@
|
|||||||
|
From 80e85fbdf19ecc4dfa31ecf639adb55555db02fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:45 +0200
|
||||||
|
Subject: [PATCH 4/6] net: create tcp_gro_lookup helper function
|
||||||
|
|
||||||
|
This pulls the flow port matching out of tcp_gro_receive, so that it can be
|
||||||
|
reused for the next change, which adds the TCP fraglist GRO heuristic.
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
include/net/tcp.h | 1 +
|
||||||
|
net/ipv4/tcp_offload.c | 41 +++++++++++++++++++++++++----------------
|
||||||
|
2 files changed, 26 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/net/tcp.h
|
||||||
|
+++ b/include/net/tcp.h
|
||||||
|
@@ -2101,6 +2101,7 @@ void tcp_v4_destroy_sock(struct sock *sk
|
||||||
|
|
||||||
|
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
|
||||||
|
netdev_features_t features);
|
||||||
|
+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th);
|
||||||
|
struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb);
|
||||||
|
INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff));
|
||||||
|
INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb));
|
||||||
|
--- a/net/ipv4/tcp_offload.c
|
||||||
|
+++ b/net/ipv4/tcp_offload.c
|
||||||
|
@@ -251,6 +251,27 @@ out:
|
||||||
|
return segs;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th)
|
||||||
|
+{
|
||||||
|
+ struct tcphdr *th2;
|
||||||
|
+ struct sk_buff *p;
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(p, head, list) {
|
||||||
|
+ if (!NAPI_GRO_CB(p)->same_flow)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ th2 = tcp_hdr(p);
|
||||||
|
+ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
|
||||||
|
+ NAPI_GRO_CB(p)->same_flow = 0;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return p;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct sk_buff *pp = NULL;
|
||||||
|
@@ -288,24 +309,12 @@ struct sk_buff *tcp_gro_receive(struct l
|
||||||
|
len = skb_gro_len(skb);
|
||||||
|
flags = tcp_flag_word(th);
|
||||||
|
|
||||||
|
- list_for_each_entry(p, head, list) {
|
||||||
|
- if (!NAPI_GRO_CB(p)->same_flow)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- th2 = tcp_hdr(p);
|
||||||
|
-
|
||||||
|
- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
|
||||||
|
- NAPI_GRO_CB(p)->same_flow = 0;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- goto found;
|
||||||
|
- }
|
||||||
|
- p = NULL;
|
||||||
|
- goto out_check_final;
|
||||||
|
+ p = tcp_gro_lookup(head, th);
|
||||||
|
+ if (!p)
|
||||||
|
+ goto out_check_final;
|
||||||
|
|
||||||
|
-found:
|
||||||
|
/* Include the IP ID check below from the inner most IP hdr */
|
||||||
|
+ th2 = tcp_hdr(p);
|
||||||
|
flush = NAPI_GRO_CB(p)->flush;
|
||||||
|
flush |= (__force int)(flags & TCP_FLAG_CWR);
|
||||||
|
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
|
@ -0,0 +1,166 @@
|
|||||||
|
From 7516b27c555c1711ec17a5d891befb6986e573a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:46 +0200
|
||||||
|
Subject: [PATCH 5/6] net: create tcp_gro_header_pull helper function
|
||||||
|
|
||||||
|
Pull the code out of tcp_gro_receive in order to access the tcp header
|
||||||
|
from tcp4/6_gro_receive.
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
include/net/tcp.h | 4 ++-
|
||||||
|
net/ipv4/tcp_offload.c | 55 +++++++++++++++++++++++++---------------
|
||||||
|
net/ipv6/tcpv6_offload.c | 18 +++++++++----
|
||||||
|
3 files changed, 50 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/net/tcp.h
|
||||||
|
+++ b/include/net/tcp.h
|
||||||
|
@@ -2101,8 +2101,10 @@ void tcp_v4_destroy_sock(struct sock *sk
|
||||||
|
|
||||||
|
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
|
||||||
|
netdev_features_t features);
|
||||||
|
+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb);
|
||||||
|
struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th);
|
||||||
|
-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb);
|
||||||
|
+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
|
||||||
|
+ struct tcphdr *th);
|
||||||
|
INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff));
|
||||||
|
INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb));
|
||||||
|
INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff));
|
||||||
|
--- a/net/ipv4/tcp_offload.c
|
||||||
|
+++ b/net/ipv4/tcp_offload.c
|
||||||
|
@@ -272,40 +272,46 @@ struct sk_buff *tcp_gro_lookup(struct li
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
- struct sk_buff *pp = NULL;
|
||||||
|
- struct sk_buff *p;
|
||||||
|
+ unsigned int thlen, hlen, off;
|
||||||
|
struct tcphdr *th;
|
||||||
|
- struct tcphdr *th2;
|
||||||
|
- unsigned int len;
|
||||||
|
- unsigned int thlen;
|
||||||
|
- __be32 flags;
|
||||||
|
- unsigned int mss = 1;
|
||||||
|
- unsigned int hlen;
|
||||||
|
- unsigned int off;
|
||||||
|
- int flush = 1;
|
||||||
|
- int i;
|
||||||
|
|
||||||
|
off = skb_gro_offset(skb);
|
||||||
|
hlen = off + sizeof(*th);
|
||||||
|
th = skb_gro_header(skb, hlen, off);
|
||||||
|
if (unlikely(!th))
|
||||||
|
- goto out;
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
thlen = th->doff * 4;
|
||||||
|
if (thlen < sizeof(*th))
|
||||||
|
- goto out;
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
hlen = off + thlen;
|
||||||
|
if (skb_gro_header_hard(skb, hlen)) {
|
||||||
|
th = skb_gro_header_slow(skb, hlen, off);
|
||||||
|
if (unlikely(!th))
|
||||||
|
- goto out;
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
skb_gro_pull(skb, thlen);
|
||||||
|
|
||||||
|
+ return th;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
|
||||||
|
+ struct tcphdr *th)
|
||||||
|
+{
|
||||||
|
+ unsigned int thlen = th->doff * 4;
|
||||||
|
+ struct sk_buff *pp = NULL;
|
||||||
|
+ struct sk_buff *p;
|
||||||
|
+ struct tcphdr *th2;
|
||||||
|
+ unsigned int len;
|
||||||
|
+ __be32 flags;
|
||||||
|
+ unsigned int mss = 1;
|
||||||
|
+ int flush = 1;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
len = skb_gro_len(skb);
|
||||||
|
flags = tcp_flag_word(th);
|
||||||
|
|
||||||
|
@@ -384,7 +390,6 @@ out_check_final:
|
||||||
|
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
|
||||||
|
pp = p;
|
||||||
|
|
||||||
|
-out:
|
||||||
|
NAPI_GRO_CB(skb)->flush |= (flush != 0);
|
||||||
|
|
||||||
|
return pp;
|
||||||
|
@@ -411,15 +416,23 @@ EXPORT_SYMBOL(tcp_gro_complete);
|
||||||
|
INDIRECT_CALLABLE_SCOPE
|
||||||
|
struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
+ struct tcphdr *th;
|
||||||
|
+
|
||||||
|
/* Don't bother verifying checksum if we're going to flush anyway. */
|
||||||
|
if (!NAPI_GRO_CB(skb)->flush &&
|
||||||
|
skb_gro_checksum_validate(skb, IPPROTO_TCP,
|
||||||
|
- inet_gro_compute_pseudo)) {
|
||||||
|
- NAPI_GRO_CB(skb)->flush = 1;
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ inet_gro_compute_pseudo))
|
||||||
|
+ goto flush;
|
||||||
|
|
||||||
|
- return tcp_gro_receive(head, skb);
|
||||||
|
+ th = tcp_gro_pull_header(skb);
|
||||||
|
+ if (!th)
|
||||||
|
+ goto flush;
|
||||||
|
+
|
||||||
|
+ return tcp_gro_receive(head, skb, th);
|
||||||
|
+
|
||||||
|
+flush:
|
||||||
|
+ NAPI_GRO_CB(skb)->flush = 1;
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
|
||||||
|
--- a/net/ipv6/tcpv6_offload.c
|
||||||
|
+++ b/net/ipv6/tcpv6_offload.c
|
||||||
|
@@ -16,15 +16,23 @@
|
||||||
|
INDIRECT_CALLABLE_SCOPE
|
||||||
|
struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
+ struct tcphdr *th;
|
||||||
|
+
|
||||||
|
/* Don't bother verifying checksum if we're going to flush anyway. */
|
||||||
|
if (!NAPI_GRO_CB(skb)->flush &&
|
||||||
|
skb_gro_checksum_validate(skb, IPPROTO_TCP,
|
||||||
|
- ip6_gro_compute_pseudo)) {
|
||||||
|
- NAPI_GRO_CB(skb)->flush = 1;
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ ip6_gro_compute_pseudo))
|
||||||
|
+ goto flush;
|
||||||
|
+
|
||||||
|
+ th = tcp_gro_pull_header(skb);
|
||||||
|
+ if (!th)
|
||||||
|
+ goto flush;
|
||||||
|
+
|
||||||
|
+ return tcp_gro_receive(head, skb, th);
|
||||||
|
|
||||||
|
- return tcp_gro_receive(head, skb);
|
||||||
|
+flush:
|
||||||
|
+ NAPI_GRO_CB(skb)->flush = 1;
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff)
|
@ -0,0 +1,140 @@
|
|||||||
|
From c9d1d23e5239f41700be69133a5769ac5ebc88a8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 2 May 2024 10:44:47 +0200
|
||||||
|
Subject: [PATCH 6/6] net: add heuristic for enabling TCP fraglist GRO
|
||||||
|
|
||||||
|
When forwarding TCP after GRO, software segmentation is very expensive,
|
||||||
|
especially when the checksum needs to be recalculated.
|
||||||
|
One case where that's currently unavoidable is when routing packets over
|
||||||
|
PPPoE. Performance improves significantly when using fraglist GRO
|
||||||
|
implemented in the same way as for UDP.
|
||||||
|
|
||||||
|
When NETIF_F_GRO_FRAGLIST is enabled, perform a lookup for an established
|
||||||
|
socket in the same netns as the receiving device. While this may not
|
||||||
|
cover all relevant use cases in multi-netns configurations, it should be
|
||||||
|
good enough for most configurations that need this.
|
||||||
|
|
||||||
|
Here's a measurement of running 2 TCP streams through a MediaTek MT7622
|
||||||
|
device (2-core Cortex-A53), which runs NAT with flow offload enabled from
|
||||||
|
one ethernet port to PPPoE on another ethernet port + cake qdisc set to
|
||||||
|
1Gbps.
|
||||||
|
|
||||||
|
rx-gro-list off: 630 Mbit/s, CPU 35% idle
|
||||||
|
rx-gro-list on: 770 Mbit/s, CPU 40% idle
|
||||||
|
|
||||||
|
Acked-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
net/ipv4/tcp_offload.c | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
net/ipv6/tcpv6_offload.c | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 67 insertions(+)
|
||||||
|
|
||||||
|
--- a/net/ipv4/tcp_offload.c
|
||||||
|
+++ b/net/ipv4/tcp_offload.c
|
||||||
|
@@ -413,6 +413,36 @@ void tcp_gro_complete(struct sk_buff *sk
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tcp_gro_complete);
|
||||||
|
|
||||||
|
+static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
|
||||||
|
+ struct tcphdr *th)
|
||||||
|
+{
|
||||||
|
+ const struct iphdr *iph;
|
||||||
|
+ struct sk_buff *p;
|
||||||
|
+ struct sock *sk;
|
||||||
|
+ struct net *net;
|
||||||
|
+ int iif, sdif;
|
||||||
|
+
|
||||||
|
+ if (likely(!(skb->dev->features & NETIF_F_GRO_FRAGLIST)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ p = tcp_gro_lookup(head, th);
|
||||||
|
+ if (p) {
|
||||||
|
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ inet_get_iif_sdif(skb, &iif, &sdif);
|
||||||
|
+ iph = skb_gro_network_header(skb);
|
||||||
|
+ net = dev_net(skb->dev);
|
||||||
|
+ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
|
||||||
|
+ iph->saddr, th->source,
|
||||||
|
+ iph->daddr, ntohs(th->dest),
|
||||||
|
+ iif, sdif);
|
||||||
|
+ NAPI_GRO_CB(skb)->is_flist = !sk;
|
||||||
|
+ if (sk)
|
||||||
|
+ sock_put(sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
INDIRECT_CALLABLE_SCOPE
|
||||||
|
struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
@@ -428,6 +458,8 @@ struct sk_buff *tcp4_gro_receive(struct
|
||||||
|
if (!th)
|
||||||
|
goto flush;
|
||||||
|
|
||||||
|
+ tcp4_check_fraglist_gro(head, skb, th);
|
||||||
|
+
|
||||||
|
return tcp_gro_receive(head, skb, th);
|
||||||
|
|
||||||
|
flush:
|
||||||
|
--- a/net/ipv6/tcpv6_offload.c
|
||||||
|
+++ b/net/ipv6/tcpv6_offload.c
|
||||||
|
@@ -7,12 +7,45 @@
|
||||||
|
*/
|
||||||
|
#include <linux/indirect_call_wrapper.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
+#include <net/inet6_hashtables.h>
|
||||||
|
#include <net/gro.h>
|
||||||
|
#include <net/protocol.h>
|
||||||
|
#include <net/tcp.h>
|
||||||
|
#include <net/ip6_checksum.h>
|
||||||
|
#include "ip6_offload.h"
|
||||||
|
|
||||||
|
+static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
|
||||||
|
+ struct tcphdr *th)
|
||||||
|
+{
|
||||||
|
+#if IS_ENABLED(CONFIG_IPV6)
|
||||||
|
+ const struct ipv6hdr *hdr;
|
||||||
|
+ struct sk_buff *p;
|
||||||
|
+ struct sock *sk;
|
||||||
|
+ struct net *net;
|
||||||
|
+ int iif, sdif;
|
||||||
|
+
|
||||||
|
+ if (likely(!(skb->dev->features & NETIF_F_GRO_FRAGLIST)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ p = tcp_gro_lookup(head, th);
|
||||||
|
+ if (p) {
|
||||||
|
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ inet6_get_iif_sdif(skb, &iif, &sdif);
|
||||||
|
+ hdr = skb_gro_network_header(skb);
|
||||||
|
+ net = dev_net(skb->dev);
|
||||||
|
+ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
|
||||||
|
+ &hdr->saddr, th->source,
|
||||||
|
+ &hdr->daddr, ntohs(th->dest),
|
||||||
|
+ iif, sdif);
|
||||||
|
+ NAPI_GRO_CB(skb)->is_flist = !sk;
|
||||||
|
+ if (sk)
|
||||||
|
+ sock_put(sk);
|
||||||
|
+#endif /* IS_ENABLED(CONFIG_IPV6) */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
INDIRECT_CALLABLE_SCOPE
|
||||||
|
struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
@@ -28,6 +61,8 @@ struct sk_buff *tcp6_gro_receive(struct
|
||||||
|
if (!th)
|
||||||
|
goto flush;
|
||||||
|
|
||||||
|
+ tcp6_check_fraglist_gro(head, skb, th);
|
||||||
|
+
|
||||||
|
return tcp_gro_receive(head, skb, th);
|
||||||
|
|
||||||
|
flush:
|
@ -1,5 +1,6 @@
|
|||||||
|
From 17bd3bd82f9f79f3feba15476c2b2c95a9b11ff8 Mon Sep 17 00:00:00 2001
|
||||||
From: Felix Fietkau <nbd@nbd.name>
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
Date: Thu, 26 Sep 2024 10:41:30 +0200
|
Date: Thu, 26 Sep 2024 10:53:14 +0200
|
||||||
Subject: [PATCH] net: gso: fix tcp fraglist segmentation after pull from
|
Subject: [PATCH] net: gso: fix tcp fraglist segmentation after pull from
|
||||||
frag_list
|
frag_list
|
||||||
|
|
||||||
@ -30,9 +31,14 @@ Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediat
|
|||||||
Link: https://lore.kernel.org/netdev/20240922150450.3873767-1-willemdebruijn.kernel@gmail.com/
|
Link: https://lore.kernel.org/netdev/20240922150450.3873767-1-willemdebruijn.kernel@gmail.com/
|
||||||
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
|
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
|
||||||
Cc: stable@vger.kernel.org
|
Cc: stable@vger.kernel.org
|
||||||
Cc: Willem de Bruijn <willemb@google.com>
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||||
|
Link: https://patch.msgid.link/20240926085315.51524-1-nbd@nbd.name
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
---
|
---
|
||||||
|
net/ipv4/tcp_offload.c | 10 ++++++++--
|
||||||
|
net/ipv6/tcpv6_offload.c | 10 ++++++++--
|
||||||
|
2 files changed, 16 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
--- a/net/ipv4/tcp_offload.c
|
--- a/net/ipv4/tcp_offload.c
|
||||||
+++ b/net/ipv4/tcp_offload.c
|
+++ b/net/ipv4/tcp_offload.c
|
@ -0,0 +1,59 @@
|
|||||||
|
From daa624d3c2ddffdcbad140a9625a4064371db44f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Tue, 11 Mar 2025 22:25:30 +0100
|
||||||
|
Subject: [PATCH] net: ipv6: fix TCP GSO segmentation with NAT
|
||||||
|
|
||||||
|
When updating the source/destination address, the TCP/UDP checksum needs to
|
||||||
|
be updated as well.
|
||||||
|
|
||||||
|
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Link: https://patch.msgid.link/20250311212530.91519-1-nbd@nbd.name
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
net/ipv6/tcpv6_offload.c | 21 +++++++++++++++------
|
||||||
|
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/ipv6/tcpv6_offload.c
|
||||||
|
+++ b/net/ipv6/tcpv6_offload.c
|
||||||
|
@@ -93,14 +93,23 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __tcpv6_gso_segment_csum(struct sk_buff *seg,
|
||||||
|
+ struct in6_addr *oldip,
|
||||||
|
+ const struct in6_addr *newip,
|
||||||
|
__be16 *oldport, __be16 newport)
|
||||||
|
{
|
||||||
|
- struct tcphdr *th;
|
||||||
|
+ struct tcphdr *th = tcp_hdr(seg);
|
||||||
|
+
|
||||||
|
+ if (!ipv6_addr_equal(oldip, newip)) {
|
||||||
|
+ inet_proto_csum_replace16(&th->check, seg,
|
||||||
|
+ oldip->s6_addr32,
|
||||||
|
+ newip->s6_addr32,
|
||||||
|
+ true);
|
||||||
|
+ *oldip = *newip;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (*oldport == newport)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- th = tcp_hdr(seg);
|
||||||
|
inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
|
||||||
|
*oldport = newport;
|
||||||
|
}
|
||||||
|
@@ -128,10 +137,10 @@ static struct sk_buff *__tcpv6_gso_segme
|
||||||
|
th2 = tcp_hdr(seg);
|
||||||
|
iph2 = ipv6_hdr(seg);
|
||||||
|
|
||||||
|
- iph2->saddr = iph->saddr;
|
||||||
|
- iph2->daddr = iph->daddr;
|
||||||
|
- __tcpv6_gso_segment_csum(seg, &th2->source, th->source);
|
||||||
|
- __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
|
||||||
|
+ __tcpv6_gso_segment_csum(seg, &iph2->saddr, &iph->saddr,
|
||||||
|
+ &th2->source, th->source);
|
||||||
|
+ __tcpv6_gso_segment_csum(seg, &iph2->daddr, &iph->daddr,
|
||||||
|
+ &th2->dest, th->dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return segs;
|
@ -1,5 +1,6 @@
|
|||||||
|
From 84443741faab9045d53f022a9ac6a6633067a481 Mon Sep 17 00:00:00 2001
|
||||||
From: Felix Fietkau <nbd@nbd.name>
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
Date: Wed, 14 Feb 2024 15:24:41 +0100
|
Date: Wed, 14 Feb 2024 15:42:35 +0100
|
||||||
Subject: [PATCH] netfilter: nf_tables: fix bidirectional offload regression
|
Subject: [PATCH] netfilter: nf_tables: fix bidirectional offload regression
|
||||||
|
|
||||||
Commit 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
|
Commit 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
|
||||||
@ -9,8 +10,12 @@ Add the missing flag that was left out as an exercise for the reader :)
|
|||||||
|
|
||||||
Cc: Vlad Buslov <vladbu@nvidia.com>
|
Cc: Vlad Buslov <vladbu@nvidia.com>
|
||||||
Fixes: 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
|
Fixes: 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
|
||||||
|
Reported-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
---
|
---
|
||||||
|
net/netfilter/nft_flow_offload.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
--- a/net/netfilter/nft_flow_offload.c
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
+++ b/net/netfilter/nft_flow_offload.c
|
+++ b/net/netfilter/nft_flow_offload.c
|
@ -1,13 +1,15 @@
|
|||||||
From 3b5a603bf66236b956287909556fd7ad4904450c Mon Sep 17 00:00:00 2001
|
From cb77d0ad460e2c97a00c02ed78afdf45476e5e5f Mon Sep 17 00:00:00 2001
|
||||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||||
Date: Wed, 24 Jan 2024 19:38:01 +0100
|
Date: Wed, 31 Jan 2024 03:27:29 +0100
|
||||||
Subject: [PATCH 3/3] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO
|
Subject: [PATCH] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO node
|
||||||
node
|
|
||||||
|
|
||||||
Add clock-frequency to MDIO node to set the MDC rate to 6.25Mhz instead
|
Add clock-frequency to MDIO node to set the MDC rate to 6.25Mhz instead
|
||||||
of using the default value of 390KHz from MDIO default divider.
|
of using the default value of 390KHz from MDIO default divider.
|
||||||
|
|
||||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20240131022731.2118-1-ansuelsmth@gmail.com
|
||||||
|
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||||
---
|
---
|
||||||
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 ++
|
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 ++
|
||||||
1 file changed, 2 insertions(+)
|
1 file changed, 2 insertions(+)
|
@ -0,0 +1,85 @@
|
|||||||
|
From e184e8609f8c1cd9fef703f667245b6ebd89c2ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||||
|
Date: Tue, 3 Oct 2023 14:34:24 +0100
|
||||||
|
Subject: [PATCH] net: sfp: re-implement ignoring the hardware TX_FAULT signal
|
||||||
|
|
||||||
|
Re-implement how we ignore the hardware TX_FAULT signal. Rather than
|
||||||
|
having a separate boolean for this, use a bitmask of the hardware
|
||||||
|
signals that we wish to ignore. This gives more flexibility in the
|
||||||
|
future to ignore other signals such as RX_LOS.
|
||||||
|
|
||||||
|
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||||
|
Tested-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||||
|
Link: https://lore.kernel.org/r/E1qnfXc-008UDY-91@rmk-PC.armlinux.org.uk
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/sfp.c | 16 ++++++++--------
|
||||||
|
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/sfp.c
|
||||||
|
+++ b/drivers/net/phy/sfp.c
|
||||||
|
@@ -257,6 +257,7 @@ struct sfp {
|
||||||
|
unsigned int state_hw_drive;
|
||||||
|
unsigned int state_hw_mask;
|
||||||
|
unsigned int state_soft_mask;
|
||||||
|
+ unsigned int state_ignore_mask;
|
||||||
|
unsigned int state;
|
||||||
|
|
||||||
|
struct delayed_work poll;
|
||||||
|
@@ -280,7 +281,6 @@ struct sfp {
|
||||||
|
unsigned int rs_state_mask;
|
||||||
|
|
||||||
|
bool have_a2;
|
||||||
|
- bool tx_fault_ignore;
|
||||||
|
|
||||||
|
const struct sfp_quirk *quirk;
|
||||||
|
|
||||||
|
@@ -347,7 +347,7 @@ static void sfp_fixup_long_startup(struc
|
||||||
|
|
||||||
|
static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
|
||||||
|
{
|
||||||
|
- sfp->tx_fault_ignore = true;
|
||||||
|
+ sfp->state_ignore_mask |= SFP_F_TX_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For 10GBASE-T short-reach modules
|
||||||
|
@@ -796,7 +796,8 @@ static void sfp_soft_start_poll(struct s
|
||||||
|
|
||||||
|
mutex_lock(&sfp->st_mutex);
|
||||||
|
// Poll the soft state for hardware pins we want to ignore
|
||||||
|
- sfp->state_soft_mask = ~sfp->state_hw_mask & mask;
|
||||||
|
+ sfp->state_soft_mask = ~sfp->state_hw_mask & ~sfp->state_ignore_mask &
|
||||||
|
+ mask;
|
||||||
|
|
||||||
|
if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
|
||||||
|
!sfp->need_poll)
|
||||||
|
@@ -2321,7 +2322,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
|
sfp->module_t_start_up = T_START_UP;
|
||||||
|
sfp->module_t_wait = T_WAIT;
|
||||||
|
|
||||||
|
- sfp->tx_fault_ignore = false;
|
||||||
|
+ sfp->state_ignore_mask = 0;
|
||||||
|
|
||||||
|
if (sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SFI ||
|
||||||
|
sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SR ||
|
||||||
|
@@ -2344,6 +2345,8 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
|
|
||||||
|
if (sfp->quirk && sfp->quirk->fixup)
|
||||||
|
sfp->quirk->fixup(sfp);
|
||||||
|
+
|
||||||
|
+ sfp->state_hw_mask &= ~sfp->state_ignore_mask;
|
||||||
|
mutex_unlock(&sfp->st_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -2844,10 +2847,7 @@ static void sfp_check_state(struct sfp *
|
||||||
|
mutex_lock(&sfp->st_mutex);
|
||||||
|
state = sfp_get_state(sfp);
|
||||||
|
changed = state ^ sfp->state;
|
||||||
|
- if (sfp->tx_fault_ignore)
|
||||||
|
- changed &= SFP_F_PRESENT | SFP_F_LOS;
|
||||||
|
- else
|
||||||
|
- changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
+ changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
|
||||||
|
for (i = 0; i < GPIO_MAX; i++)
|
||||||
|
if (changed & BIT(i))
|
@ -0,0 +1,35 @@
|
|||||||
|
From 0805d67bc0ef95411228e802f31975cfb7555056 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Date: Tue, 23 Apr 2024 11:00:25 +0200
|
||||||
|
Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add quirk for ATS SFP-GE-T 1000Base-TX module.
|
||||||
|
|
||||||
|
This copper module comes with broken TX_FAULT indicator which must be
|
||||||
|
ignored for it to work.
|
||||||
|
|
||||||
|
Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
[ rebased on top of net-next ]
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20240423090025.29231-1-kabel@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/sfp.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/sfp.c
|
||||||
|
+++ b/drivers/net/phy/sfp.c
|
||||||
|
@@ -486,6 +486,9 @@ static const struct sfp_quirk sfp_quirks
|
||||||
|
// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
|
||||||
|
SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
|
||||||
|
|
||||||
|
+ // OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
|
||||||
|
+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
|
||||||
|
+
|
||||||
|
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
|
||||||
|
SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
|
||||||
|
SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
|
@ -1,5 +1,6 @@
|
|||||||
|
From 88806efc034a9830f483963326b99930ad519af1 Mon Sep 17 00:00:00 2001
|
||||||
From: Felix Fietkau <nbd@nbd.name>
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
Date: Tue, 15 Oct 2024 10:13:55 +0200
|
Date: Tue, 15 Oct 2024 10:17:55 +0200
|
||||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory corruption during fq
|
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory corruption during fq
|
||||||
dma init
|
dma init
|
||||||
|
|
||||||
@ -9,11 +10,16 @@ memory. Fix the loop iteration count accordingly.
|
|||||||
|
|
||||||
Fixes: c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer size soc specific")
|
Fixes: c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer size soc specific")
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/20241015081755.31060-1-nbd@nbd.name
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
---
|
---
|
||||||
|
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
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
@@ -1182,7 +1182,7 @@ static int mtk_init_fq_dma(struct mtk_et
|
@@ -1181,7 +1181,7 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||||
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
|
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
From 637f41476384c76d3cd7dcf5947caf2c8b8d7a9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Date: Sat, 26 Oct 2024 14:52:25 +0100
|
||||||
|
Subject: [PATCH] net: ethernet: mtk_wed: fix path of MT7988 WO firmware
|
||||||
|
|
||||||
|
linux-firmware commit 808cba84 ("mtk_wed: add firmware for mt7988
|
||||||
|
Wireless Ethernet Dispatcher") added mt7988_wo_{0,1}.bin in the
|
||||||
|
'mediatek/mt7988' directory while driver current expects the files in
|
||||||
|
the 'mediatek' directory.
|
||||||
|
|
||||||
|
Change path in the driver header now that the firmware has been added.
|
||||||
|
|
||||||
|
Fixes: e2f64db13aa1 ("net: ethernet: mtk_wed: introduce WED support for MT7988")
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||||
|
Link: https://patch.msgid.link/Zxz0GWTR5X5LdWPe@pidgin.makrotopia.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/mtk_wed_wo.h | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
|
||||||
|
@@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx {
|
||||||
|
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
|
||||||
|
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
|
||||||
|
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
|
||||||
|
-#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
|
||||||
|
-#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
|
||||||
|
+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin"
|
||||||
|
+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin"
|
||||||
|
|
||||||
|
#define MTK_WO_MCU_CFG_LS_BASE 0
|
||||||
|
#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
|
@ -0,0 +1,557 @@
|
|||||||
|
From ac4aa9dbc702329c447d968325b055af84ae1b59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Date: Tue, 9 Apr 2024 03:24:12 +0100
|
||||||
|
Subject: [PATCH] phy: add driver for MediaTek XFI T-PHY
|
||||||
|
|
||||||
|
Add driver for MediaTek's XFI T-PHY which can be found in the MT7988
|
||||||
|
SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on
|
||||||
|
the internal side to be used with either USXGMII PCS or LynxI PCS,
|
||||||
|
depending on the selected PHY interface mode.
|
||||||
|
|
||||||
|
The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
|
||||||
|
PHY_INTERFACE_MODE_* corresponding to the supported modes:
|
||||||
|
|
||||||
|
* USXGMII \
|
||||||
|
* 10GBase-R }- USXGMII PCS - XGDM \
|
||||||
|
* 5GBase-R / \
|
||||||
|
}- Ethernet MAC
|
||||||
|
* 2500Base-X \ /
|
||||||
|
* 1000Base-X }- LynxI PCS - GDM /
|
||||||
|
* Cisco SGMII (MAC side) /
|
||||||
|
|
||||||
|
I chose the name XFI T-PHY because names of functions dealing with the
|
||||||
|
phy in the vendor driver are prefixed "xfi_pextp_".
|
||||||
|
|
||||||
|
The register space used by the phy is called "pextp" in the vendor
|
||||||
|
sources, which could be read as "_P_CI _ex_press _T_-_P_hy", and that
|
||||||
|
is quite misleading as this phy isn't used for anything related to
|
||||||
|
PCIe, so I wanted to find a better name.
|
||||||
|
|
||||||
|
XFI is still somehow related (as in: you would find the relevant
|
||||||
|
places using grep in the vendor driver when looking for that) and the
|
||||||
|
term seemed to at least somehow be aligned with the function of that
|
||||||
|
phy: Dealing with (up to) 10 Gbit/s Ethernet serialized differential
|
||||||
|
signals.
|
||||||
|
|
||||||
|
In order to work-around a performance issue present on the first of
|
||||||
|
two XFI T-PHYs found in MT7988, special tuning is applied which can
|
||||||
|
be selected by adding the 'mediatek,usxgmii-performance-errata'
|
||||||
|
property to the device tree node, similar to how the vendor driver is
|
||||||
|
doing that too.
|
||||||
|
|
||||||
|
There is no documentation for most registers used for the
|
||||||
|
analog/tuning part, however, most of the registers have been partially
|
||||||
|
reverse-engineered from MediaTek's SDK implementation (see links, an
|
||||||
|
opaque sequence of 32-bit register writes) and descriptions for all
|
||||||
|
relevant digital registers and bits such as resets and muxes have been
|
||||||
|
supplied by MediaTek.
|
||||||
|
|
||||||
|
Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/b72d6cba92bf9e29fb035c03052fa1e86664a25b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||||
|
Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/dec96a1d9b82cdcda4a56453fd0b453d4cab4b85/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||||
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
Link: https://lore.kernel.org/r/8719c82634df7e8e984f1a608be3ba2f2d494fb4.1712625857.git.daniel@makrotopia.org
|
||||||
|
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||||
|
---
|
||||||
|
MAINTAINERS | 1 +
|
||||||
|
drivers/phy/mediatek/Kconfig | 11 +
|
||||||
|
drivers/phy/mediatek/Makefile | 1 +
|
||||||
|
drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 451 ++++++++++++++++++++++++
|
||||||
|
4 files changed, 464 insertions(+)
|
||||||
|
create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
|
||||||
|
|
||||||
|
--- a/MAINTAINERS
|
||||||
|
+++ b/MAINTAINERS
|
||||||
|
@@ -13366,6 +13366,7 @@ L: netdev@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/net/phy/mediatek-ge-soc.c
|
||||||
|
F: drivers/net/phy/mediatek-ge.c
|
||||||
|
+F: drivers/phy/mediatek/phy-mtk-xfi-tphy.c
|
||||||
|
|
||||||
|
MEDIATEK I2C CONTROLLER DRIVER
|
||||||
|
M: Qii Wang <qii.wang@mediatek.com>
|
||||||
|
--- a/drivers/phy/mediatek/Kconfig
|
||||||
|
+++ b/drivers/phy/mediatek/Kconfig
|
||||||
|
@@ -13,6 +13,17 @@ config PHY_MTK_PCIE
|
||||||
|
callback for PCIe GEN3 port, it supports software efuse
|
||||||
|
initialization.
|
||||||
|
|
||||||
|
+config PHY_MTK_XFI_TPHY
|
||||||
|
+ tristate "MediaTek 10GE SerDes XFI T-PHY driver"
|
||||||
|
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||||
|
+ depends on OF
|
||||||
|
+ select GENERIC_PHY
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here to add support for MediaTek XFI T-PHY driver.
|
||||||
|
+ The driver provides access to the Ethernet SerDes T-PHY supporting
|
||||||
|
+ 1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
|
||||||
|
+ via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
|
||||||
|
+
|
||||||
|
config PHY_MTK_TPHY
|
||||||
|
tristate "MediaTek T-PHY Driver"
|
||||||
|
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||||
|
--- a/drivers/phy/mediatek/Makefile
|
||||||
|
+++ b/drivers/phy/mediatek/Makefile
|
||||||
|
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-p
|
||||||
|
obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
|
||||||
|
obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
|
||||||
|
obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
|
||||||
|
+obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
|
||||||
|
|
||||||
|
phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
|
||||||
|
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
|
||||||
|
@@ -0,0 +1,451 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
+/*
|
||||||
|
+ * MediaTek 10GE SerDes XFI T-PHY driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2024 Daniel Golle <daniel@makrotopia.org>
|
||||||
|
+ * Bc-bocun Chen <bc-bocun.chen@mediatek.com>
|
||||||
|
+ * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0)
|
||||||
|
+ * Copyright (c) 2022 MediaTek Inc.
|
||||||
|
+ * Author: Henry Yen <henry.yen@mediatek.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/device.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
+#include <linux/io.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/reset.h>
|
||||||
|
+#include <linux/phy.h>
|
||||||
|
+#include <linux/phy/phy.h>
|
||||||
|
+
|
||||||
|
+#include "phy-mtk-io.h"
|
||||||
|
+
|
||||||
|
+#define MTK_XFI_TPHY_NUM_CLOCKS 2
|
||||||
|
+
|
||||||
|
+#define REG_DIG_GLB_70 0x0070
|
||||||
|
+#define XTP_PCS_RX_EQ_IN_PROGRESS(x) FIELD_PREP(GENMASK(25, 24), (x))
|
||||||
|
+#define XTP_PCS_MODE_MASK GENMASK(17, 16)
|
||||||
|
+#define XTP_PCS_MODE(x) FIELD_PREP(GENMASK(17, 16), (x))
|
||||||
|
+#define XTP_PCS_RST_B BIT(15)
|
||||||
|
+#define XTP_FRC_PCS_RST_B BIT(14)
|
||||||
|
+#define XTP_PCS_PWD_SYNC_MASK GENMASK(13, 12)
|
||||||
|
+#define XTP_PCS_PWD_SYNC(x) FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
|
||||||
|
+#define XTP_PCS_PWD_ASYNC_MASK GENMASK(11, 10)
|
||||||
|
+#define XTP_PCS_PWD_ASYNC(x) FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
|
||||||
|
+#define XTP_FRC_PCS_PWD_ASYNC BIT(8)
|
||||||
|
+#define XTP_PCS_UPDT BIT(4)
|
||||||
|
+#define XTP_PCS_IN_FR_RG BIT(0)
|
||||||
|
+
|
||||||
|
+#define REG_DIG_GLB_F4 0x00f4
|
||||||
|
+#define XFI_DPHY_PCS_SEL BIT(0)
|
||||||
|
+#define XFI_DPHY_PCS_SEL_SGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
|
||||||
|
+#define XFI_DPHY_PCS_SEL_USXGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
|
||||||
|
+#define XFI_DPHY_AD_SGDT_FRC_EN BIT(5)
|
||||||
|
+
|
||||||
|
+#define REG_DIG_LN_TRX_40 0x3040
|
||||||
|
+#define XTP_LN_FRC_TX_DATA_EN BIT(29)
|
||||||
|
+#define XTP_LN_TX_DATA_EN BIT(28)
|
||||||
|
+
|
||||||
|
+#define REG_DIG_LN_TRX_B0 0x30b0
|
||||||
|
+#define XTP_LN_FRC_TX_MACCK_EN BIT(5)
|
||||||
|
+#define XTP_LN_TX_MACCK_EN BIT(4)
|
||||||
|
+
|
||||||
|
+#define REG_ANA_GLB_D0 0x90d0
|
||||||
|
+#define XTP_GLB_USXGMII_SEL_MASK GENMASK(3, 1)
|
||||||
|
+#define XTP_GLB_USXGMII_SEL(x) FIELD_PREP(GENMASK(3, 1), (x))
|
||||||
|
+#define XTP_GLB_USXGMII_EN BIT(0)
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * struct mtk_xfi_tphy - run-time data of the XFI phy instance
|
||||||
|
+ * @base: IO memory area to access phy registers.
|
||||||
|
+ * @dev: Kernel device used to output prefixed debug info.
|
||||||
|
+ * @reset: Reset control corresponding to the phy instance.
|
||||||
|
+ * @clocks: All clocks required for the phy to operate.
|
||||||
|
+ * @da_war: Enables work-around for 10GBase-R mode.
|
||||||
|
+ */
|
||||||
|
+struct mtk_xfi_tphy {
|
||||||
|
+ void __iomem *base;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct reset_control *reset;
|
||||||
|
+ struct clk_bulk_data clocks[MTK_XFI_TPHY_NUM_CLOCKS];
|
||||||
|
+ bool da_war;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_setup() - Setup phy for specified interface mode.
|
||||||
|
+ * @xfi_tphy: XFI phy instance.
|
||||||
|
+ * @interface: Ethernet interface mode
|
||||||
|
+ *
|
||||||
|
+ * The setup function is the condensed result of combining the 5 functions which
|
||||||
|
+ * setup the phy in MediaTek's GPL licensed public SDK sources. They can be found
|
||||||
|
+ * in mtk_sgmii.c[1] as well as mtk_usxgmii.c[2].
|
||||||
|
+ *
|
||||||
|
+ * Many magic values have been replaced by register and bit definitions, however,
|
||||||
|
+ * that has not been possible in all cases. While the vendor driver uses a
|
||||||
|
+ * sequence of 32-bit writes, here we try to only modify the actually required
|
||||||
|
+ * bits.
|
||||||
|
+ *
|
||||||
|
+ * [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/b72d6cba92bf9e29fb035c03052fa1e86664a25b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||||
|
+ *
|
||||||
|
+ * [2]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/dec96a1d9b82cdcda4a56453fd0b453d4cab4b85/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
+ */
|
||||||
|
+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
|
||||||
|
+ phy_interface_t interface)
|
||||||
|
+{
|
||||||
|
+ bool is_1g, is_2p5g, is_5g, is_10g, da_war, use_lynxi_pcs;
|
||||||
|
+
|
||||||
|
+ /* shorthands for specific clock speeds depending on interface mode */
|
||||||
|
+ is_1g = interface == PHY_INTERFACE_MODE_1000BASEX ||
|
||||||
|
+ interface == PHY_INTERFACE_MODE_SGMII;
|
||||||
|
+ is_2p5g = interface == PHY_INTERFACE_MODE_2500BASEX;
|
||||||
|
+ is_5g = interface == PHY_INTERFACE_MODE_5GBASER;
|
||||||
|
+ is_10g = interface == PHY_INTERFACE_MODE_10GBASER ||
|
||||||
|
+ interface == PHY_INTERFACE_MODE_USXGMII;
|
||||||
|
+
|
||||||
|
+ /* Is overriding 10GBase-R tuning value required? */
|
||||||
|
+ da_war = xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER);
|
||||||
|
+
|
||||||
|
+ /* configure input mux to either
|
||||||
|
+ * - USXGMII PCS (64b/66b coding) for 5G/10G
|
||||||
|
+ * - LynxI PCS (8b/10b coding) for 1G/2.5G
|
||||||
|
+ */
|
||||||
|
+ use_lynxi_pcs = is_1g || is_2p5g;
|
||||||
|
+
|
||||||
|
+ dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
|
||||||
|
+
|
||||||
|
+ /* Setup PLL setting */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000);
|
||||||
|
+
|
||||||
|
+ /* Setup RXFE BW setting */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
|
||||||
|
+
|
||||||
|
+ /* Setup RX CDR setting */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 :
|
||||||
|
+ 0x7000400);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 :
|
||||||
|
+ 0x1000100);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 :
|
||||||
|
+ is_5g ? 0x30100 :
|
||||||
|
+ 0x100);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 :
|
||||||
|
+ is_5g ? 0x40000 :
|
||||||
|
+ 0x20000);
|
||||||
|
+
|
||||||
|
+ /* Setting RXFE adaptation range setting */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 :
|
||||||
|
+ 0x6e0000);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
|
||||||
|
+
|
||||||
|
+ if (is_10g)
|
||||||
|
+ writel(0x01423342, xfi_tphy->base + 0x00f8);
|
||||||
|
+ else if (is_5g)
|
||||||
|
+ writel(0x00a132a1, xfi_tphy->base + 0x00f8);
|
||||||
|
+ else if (is_2p5g)
|
||||||
|
+ writel(0x009c329c, xfi_tphy->base + 0x00f8);
|
||||||
|
+ else
|
||||||
|
+ writel(0x00fa32fa, xfi_tphy->base + 0x00f8);
|
||||||
|
+
|
||||||
|
+ /* Force SGDT_OUT off and select PCS */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_F4,
|
||||||
|
+ XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
|
||||||
|
+ XFI_DPHY_AD_SGDT_FRC_EN |
|
||||||
|
+ (use_lynxi_pcs ? XFI_DPHY_PCS_SEL_SGMII :
|
||||||
|
+ XFI_DPHY_PCS_SEL_USXGMII));
|
||||||
|
+
|
||||||
|
+ /* Force GLB_CKDET_OUT */
|
||||||
|
+ mtk_phy_set_bits(xfi_tphy->base + 0x0030, 0xc00);
|
||||||
|
+
|
||||||
|
+ /* Force AEQ on */
|
||||||
|
+ writel(XTP_PCS_RX_EQ_IN_PROGRESS(2) | XTP_PCS_PWD_SYNC(2) | XTP_PCS_PWD_ASYNC(2),
|
||||||
|
+ xfi_tphy->base + REG_DIG_GLB_70);
|
||||||
|
+
|
||||||
|
+ usleep_range(1, 5);
|
||||||
|
+ writel(XTP_LN_FRC_TX_DATA_EN, xfi_tphy->base + REG_DIG_LN_TRX_40);
|
||||||
|
+
|
||||||
|
+ /* Setup TX DA default value */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x30b0, 0x30, 0x20);
|
||||||
|
+ writel(0x00008a01, xfi_tphy->base + 0x3028);
|
||||||
|
+ writel(0x0000a884, xfi_tphy->base + 0x302c);
|
||||||
|
+ writel(0x00083002, xfi_tphy->base + 0x3024);
|
||||||
|
+
|
||||||
|
+ /* Setup RG default value */
|
||||||
|
+ if (use_lynxi_pcs) {
|
||||||
|
+ writel(0x00011110, xfi_tphy->base + 0x3010);
|
||||||
|
+ writel(0x40704000, xfi_tphy->base + 0x3048);
|
||||||
|
+ } else {
|
||||||
|
+ writel(0x00022220, xfi_tphy->base + 0x3010);
|
||||||
|
+ writel(0x0f020a01, xfi_tphy->base + 0x5064);
|
||||||
|
+ writel(0x06100600, xfi_tphy->base + 0x50b4);
|
||||||
|
+ if (interface == PHY_INTERFACE_MODE_USXGMII)
|
||||||
|
+ writel(0x40704000, xfi_tphy->base + 0x3048);
|
||||||
|
+ else
|
||||||
|
+ writel(0x47684100, xfi_tphy->base + 0x3048);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (is_1g)
|
||||||
|
+ writel(0x0000c000, xfi_tphy->base + 0x3064);
|
||||||
|
+
|
||||||
|
+ /* Setup RX EQ initial value */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x3050, 0xa8000000,
|
||||||
|
+ (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xa8000000 : 0x0);
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0x3054, 0xaa,
|
||||||
|
+ (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xaa : 0x0);
|
||||||
|
+
|
||||||
|
+ if (!use_lynxi_pcs)
|
||||||
|
+ writel(0x00000f00, xfi_tphy->base + 0x306c);
|
||||||
|
+ else if (is_2p5g)
|
||||||
|
+ writel(0x22000f00, xfi_tphy->base + 0x306c);
|
||||||
|
+ else
|
||||||
|
+ writel(0x20200f00, xfi_tphy->base + 0x306c);
|
||||||
|
+
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0xa008, 0x10000, da_war ? 0x10000 : 0x0);
|
||||||
|
+
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + 0xa060, 0x50000, use_lynxi_pcs ? 0x50000 : 0x40000);
|
||||||
|
+
|
||||||
|
+ /* Setup PHYA speed */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + REG_ANA_GLB_D0,
|
||||||
|
+ XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
|
||||||
|
+ is_10g ? XTP_GLB_USXGMII_SEL(0) :
|
||||||
|
+ is_5g ? XTP_GLB_USXGMII_SEL(1) :
|
||||||
|
+ is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
|
||||||
|
+ XTP_GLB_USXGMII_SEL(3));
|
||||||
|
+ mtk_phy_set_bits(xfi_tphy->base + REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
|
||||||
|
+
|
||||||
|
+ /* Release reset */
|
||||||
|
+ mtk_phy_set_bits(xfi_tphy->base + REG_DIG_GLB_70,
|
||||||
|
+ XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
|
||||||
|
+ usleep_range(150, 500);
|
||||||
|
+
|
||||||
|
+ /* Switch to P0 */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
|
||||||
|
+ XTP_PCS_IN_FR_RG |
|
||||||
|
+ XTP_FRC_PCS_PWD_ASYNC |
|
||||||
|
+ XTP_PCS_PWD_ASYNC_MASK |
|
||||||
|
+ XTP_PCS_PWD_SYNC_MASK |
|
||||||
|
+ XTP_PCS_UPDT,
|
||||||
|
+ XTP_PCS_IN_FR_RG |
|
||||||
|
+ XTP_FRC_PCS_PWD_ASYNC |
|
||||||
|
+ XTP_PCS_UPDT);
|
||||||
|
+ usleep_range(1, 5);
|
||||||
|
+
|
||||||
|
+ mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
|
||||||
|
+ usleep_range(15, 50);
|
||||||
|
+
|
||||||
|
+ if (use_lynxi_pcs) {
|
||||||
|
+ /* Switch to Gen2 */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
|
||||||
|
+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
|
||||||
|
+ XTP_PCS_MODE(1) | XTP_PCS_UPDT);
|
||||||
|
+ } else {
|
||||||
|
+ /* Switch to Gen3 */
|
||||||
|
+ mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
|
||||||
|
+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
|
||||||
|
+ XTP_PCS_MODE(2) | XTP_PCS_UPDT);
|
||||||
|
+ }
|
||||||
|
+ usleep_range(1, 5);
|
||||||
|
+
|
||||||
|
+ mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
|
||||||
|
+
|
||||||
|
+ usleep_range(100, 500);
|
||||||
|
+
|
||||||
|
+ /* Enable MAC CK */
|
||||||
|
+ mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
|
||||||
|
+ mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
|
||||||
|
+
|
||||||
|
+ /* Enable TX data */
|
||||||
|
+ mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_40,
|
||||||
|
+ XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
|
||||||
|
+ usleep_range(400, 1000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_set_mode() - Setup phy for specified interface mode.
|
||||||
|
+ *
|
||||||
|
+ * @phy: Phy instance.
|
||||||
|
+ * @mode: Only PHY_MODE_ETHERNET is supported.
|
||||||
|
+ * @submode: An Ethernet interface mode.
|
||||||
|
+ *
|
||||||
|
+ * Validate selected mode and call function mtk_xfi_tphy_setup().
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * * %0 - OK
|
||||||
|
+ * * %-EINVAL - invalid mode
|
||||||
|
+ */
|
||||||
|
+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
|
||||||
|
+ submode)
|
||||||
|
+{
|
||||||
|
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
||||||
|
+
|
||||||
|
+ if (mode != PHY_MODE_ETHERNET)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ switch (submode) {
|
||||||
|
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||||
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||||
|
+ case PHY_INTERFACE_MODE_SGMII:
|
||||||
|
+ case PHY_INTERFACE_MODE_5GBASER:
|
||||||
|
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||||
|
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||||
|
+ mtk_xfi_tphy_setup(xfi_tphy, submode);
|
||||||
|
+ return 0;
|
||||||
|
+ default:
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_reset() - Reset the phy.
|
||||||
|
+ *
|
||||||
|
+ * @phy: Phy instance.
|
||||||
|
+ *
|
||||||
|
+ * Reset the phy using the external reset controller.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * %0 - OK
|
||||||
|
+ */
|
||||||
|
+static int mtk_xfi_tphy_reset(struct phy *phy)
|
||||||
|
+{
|
||||||
|
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
||||||
|
+
|
||||||
|
+ reset_control_assert(xfi_tphy->reset);
|
||||||
|
+ usleep_range(100, 500);
|
||||||
|
+ reset_control_deassert(xfi_tphy->reset);
|
||||||
|
+ usleep_range(1, 10);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_power_on() - Power-on the phy.
|
||||||
|
+ *
|
||||||
|
+ * @phy: Phy instance.
|
||||||
|
+ *
|
||||||
|
+ * Prepare and enable all clocks required for the phy to operate.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * See clk_bulk_prepare_enable().
|
||||||
|
+ */
|
||||||
|
+static int mtk_xfi_tphy_power_on(struct phy *phy)
|
||||||
|
+{
|
||||||
|
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
||||||
|
+
|
||||||
|
+ return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_power_off() - Power-off the phy.
|
||||||
|
+ *
|
||||||
|
+ * @phy: Phy instance.
|
||||||
|
+ *
|
||||||
|
+ * Disable and unprepare all clocks previously enabled.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * See clk_bulk_prepare_disable().
|
||||||
|
+ */
|
||||||
|
+static int mtk_xfi_tphy_power_off(struct phy *phy)
|
||||||
|
+{
|
||||||
|
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
||||||
|
+
|
||||||
|
+ clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct phy_ops mtk_xfi_tphy_ops = {
|
||||||
|
+ .power_on = mtk_xfi_tphy_power_on,
|
||||||
|
+ .power_off = mtk_xfi_tphy_power_off,
|
||||||
|
+ .set_mode = mtk_xfi_tphy_set_mode,
|
||||||
|
+ .reset = mtk_xfi_tphy_reset,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * mtk_xfi_tphy_probe() - Probe phy instance from Device Tree.
|
||||||
|
+ * @pdev: Matching platform device.
|
||||||
|
+ *
|
||||||
|
+ * The probe function gets IO resource, clocks, reset controller and
|
||||||
|
+ * whether the DA work-around for 10GBase-R is required from Device Tree and
|
||||||
|
+ * allocates memory for holding that information in a struct mtk_xfi_tphy.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * * %0 - OK
|
||||||
|
+ * * %-ENODEV - Missing associated Device Tree node (should never happen).
|
||||||
|
+ * * %-ENOMEM - Out of memory.
|
||||||
|
+ * * Any error value which devm_platform_ioremap_resource(),
|
||||||
|
+ * devm_clk_bulk_get(), devm_reset_control_get_exclusive(),
|
||||||
|
+ * devm_phy_create() or devm_of_phy_provider_register() may return.
|
||||||
|
+ */
|
||||||
|
+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node;
|
||||||
|
+ struct phy_provider *phy_provider;
|
||||||
|
+ struct mtk_xfi_tphy *xfi_tphy;
|
||||||
|
+ struct phy *phy;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (!np)
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
|
||||||
|
+ if (!xfi_tphy)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ xfi_tphy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
|
+ if (IS_ERR(xfi_tphy->base))
|
||||||
|
+ return PTR_ERR(xfi_tphy->base);
|
||||||
|
+
|
||||||
|
+ xfi_tphy->dev = &pdev->dev;
|
||||||
|
+ xfi_tphy->clocks[0].id = "topxtal";
|
||||||
|
+ xfi_tphy->clocks[1].id = "xfipll";
|
||||||
|
+ ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||||
|
+ if (IS_ERR(xfi_tphy->reset))
|
||||||
|
+ return PTR_ERR(xfi_tphy->reset);
|
||||||
|
+
|
||||||
|
+ xfi_tphy->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
|
||||||
|
+
|
||||||
|
+ phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
|
||||||
|
+ if (IS_ERR(phy))
|
||||||
|
+ return PTR_ERR(phy);
|
||||||
|
+
|
||||||
|
+ phy_set_drvdata(phy, xfi_tphy);
|
||||||
|
+ phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
|
||||||
|
+
|
||||||
|
+ return PTR_ERR_OR_ZERO(phy_provider);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id mtk_xfi_tphy_match[] = {
|
||||||
|
+ { .compatible = "mediatek,mt7988-xfi-tphy", },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
|
||||||
|
+
|
||||||
|
+static struct platform_driver mtk_xfi_tphy_driver = {
|
||||||
|
+ .probe = mtk_xfi_tphy_probe,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "mtk-xfi-tphy",
|
||||||
|
+ .of_match_table = mtk_xfi_tphy_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+module_platform_driver(mtk_xfi_tphy_driver);
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");
|
||||||
|
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||||
|
+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen@mediatek.com>");
|
||||||
|
+MODULE_LICENSE("GPL");
|
@ -36,7 +36,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
/* SFP module presence detection is poor: the three MOD DEF signals are
|
/* SFP module presence detection is poor: the three MOD DEF signals are
|
||||||
* the same length on the PCB, which means it's possible for MOD DEF 0 to
|
* the same length on the PCB, which means it's possible for MOD DEF 0 to
|
||||||
@@ -273,7 +273,7 @@ struct sfp {
|
@@ -274,7 +274,7 @@ struct sfp {
|
||||||
struct sfp_eeprom_id id;
|
struct sfp_eeprom_id id;
|
||||||
unsigned int module_power_mW;
|
unsigned int module_power_mW;
|
||||||
unsigned int module_t_start_up;
|
unsigned int module_t_start_up;
|
||||||
@ -86,16 +86,16 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
static void sfp_fixup_rollball_cc(struct sfp *sfp)
|
static void sfp_fixup_rollball_cc(struct sfp *sfp)
|
||||||
{
|
{
|
||||||
sfp_fixup_rollball(sfp);
|
sfp_fixup_rollball(sfp);
|
||||||
@@ -2319,7 +2317,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
@@ -2323,7 +2321,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
mask |= SFP_F_RS1;
|
mask |= SFP_F_RS1;
|
||||||
|
|
||||||
sfp->module_t_start_up = T_START_UP;
|
sfp->module_t_start_up = T_START_UP;
|
||||||
- sfp->module_t_wait = T_WAIT;
|
- sfp->module_t_wait = T_WAIT;
|
||||||
+ sfp->phy_t_retry = T_PHY_RETRY;
|
+ sfp->phy_t_retry = T_PHY_RETRY;
|
||||||
|
|
||||||
sfp->tx_fault_ignore = false;
|
sfp->state_ignore_mask = 0;
|
||||||
|
|
||||||
@@ -2553,10 +2551,9 @@ static void sfp_sm_main(struct sfp *sfp,
|
@@ -2559,10 +2557,9 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||||
|
|
||||||
/* We need to check the TX_FAULT state, which is not defined
|
/* We need to check the TX_FAULT state, which is not defined
|
||||||
* while TX_DISABLE is asserted. The earliest we want to do
|
* while TX_DISABLE is asserted. The earliest we want to do
|
||||||
@ -108,7 +108,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SFP_S_WAIT:
|
case SFP_S_WAIT:
|
||||||
@@ -2570,8 +2567,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
@@ -2576,8 +2573,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||||
* deasserting.
|
* deasserting.
|
||||||
*/
|
*/
|
||||||
timeout = sfp->module_t_start_up;
|
timeout = sfp->module_t_start_up;
|
||||||
@ -119,7 +119,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
else
|
else
|
||||||
timeout = 1;
|
timeout = 1;
|
||||||
|
|
||||||
@@ -2614,7 +2611,11 @@ static void sfp_sm_main(struct sfp *sfp,
|
@@ -2620,7 +2617,11 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||||
ret = sfp_sm_probe_for_phy(sfp);
|
ret = sfp_sm_probe_for_phy(sfp);
|
||||||
if (ret == -ENODEV) {
|
if (ret == -ENODEV) {
|
||||||
if (--sfp->sm_phy_retries) {
|
if (--sfp->sm_phy_retries) {
|
||||||
|
@ -30,7 +30,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/sfp.c
|
--- a/drivers/net/phy/sfp.c
|
||||||
+++ b/drivers/net/phy/sfp.c
|
+++ b/drivers/net/phy/sfp.c
|
||||||
@@ -273,6 +273,7 @@ struct sfp {
|
@@ -274,6 +274,7 @@ struct sfp {
|
||||||
struct sfp_eeprom_id id;
|
struct sfp_eeprom_id id;
|
||||||
unsigned int module_power_mW;
|
unsigned int module_power_mW;
|
||||||
unsigned int module_t_start_up;
|
unsigned int module_t_start_up;
|
||||||
@ -51,15 +51,15 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
|
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
|
||||||
@@ -2317,6 +2324,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
@@ -2321,6 +2328,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
mask |= SFP_F_RS1;
|
mask |= SFP_F_RS1;
|
||||||
|
|
||||||
sfp->module_t_start_up = T_START_UP;
|
sfp->module_t_start_up = T_START_UP;
|
||||||
+ sfp->module_t_wait = T_WAIT;
|
+ sfp->module_t_wait = T_WAIT;
|
||||||
sfp->phy_t_retry = T_PHY_RETRY;
|
sfp->phy_t_retry = T_PHY_RETRY;
|
||||||
|
|
||||||
sfp->tx_fault_ignore = false;
|
sfp->state_ignore_mask = 0;
|
||||||
@@ -2551,9 +2559,10 @@ static void sfp_sm_main(struct sfp *sfp,
|
@@ -2557,9 +2565,10 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||||
|
|
||||||
/* We need to check the TX_FAULT state, which is not defined
|
/* We need to check the TX_FAULT state, which is not defined
|
||||||
* while TX_DISABLE is asserted. The earliest we want to do
|
* while TX_DISABLE is asserted. The earliest we want to do
|
||||||
@ -72,7 +72,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SFP_S_WAIT:
|
case SFP_S_WAIT:
|
||||||
@@ -2567,8 +2576,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
@@ -2573,8 +2582,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||||
* deasserting.
|
* deasserting.
|
||||||
*/
|
*/
|
||||||
timeout = sfp->module_t_start_up;
|
timeout = sfp->module_t_start_up;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
From d0562705bcd4cb9849156f095b2af0ec1bb53b56 Mon Sep 17 00:00:00 2001
|
From 32596b101f6cd87ab1f6e6a1c2a44c70546dde48 Mon Sep 17 00:00:00 2001
|
||||||
From: Lech Perczak <lech.perczak@gmail.com>
|
From: Lech Perczak <lech.perczak@gmail.com>
|
||||||
Date: Fri, 17 Nov 2023 21:33:04 +0100
|
Date: Sat, 18 Nov 2023 00:23:52 +0100
|
||||||
Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes
|
Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes
|
||||||
|
|
||||||
The PICO-IMX7D SoM has the usual power supply configuration using
|
The PICO-IMX7D SoM has the usual power supply configuration using
|
||||||
@ -18,10 +18,11 @@ Link: https://android.googlesource.com/platform/hardware/bsp/kernel/nxp/imx-v4.1
|
|||||||
Cc: Fabio Estevam <festevam@gmail.com>
|
Cc: Fabio Estevam <festevam@gmail.com>
|
||||||
Cc: Shawn Guo <shawnguo@kernel.org>
|
Cc: Shawn Guo <shawnguo@kernel.org>
|
||||||
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
||||||
|
|
||||||
Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
|
Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
|
||||||
|
Reviewed-by: Fabio Estevam <festevam@gmail.com>
|
||||||
|
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
|
||||||
---
|
---
|
||||||
arch/arm/boot/dts/imx7d-pico.dtsi | 8 ++++++++
|
arch/arm/boot/dts/nxp/imx/imx7d-pico.dtsi | 8 ++++++++
|
||||||
1 file changed, 8 insertions(+)
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
--- a/arch/arm/boot/dts/nxp/imx/imx7d-pico.dtsi
|
--- a/arch/arm/boot/dts/nxp/imx/imx7d-pico.dtsi
|
@ -1,8 +1,7 @@
|
|||||||
From 38eb5b3370c29515d2ce92adac2d6eba96f276f5 Mon Sep 17 00:00:00 2001
|
From 7d36c3573391dcf0da089298a4b5a25c39f7289d Mon Sep 17 00:00:00 2001
|
||||||
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||||
Date: Wed, 20 Mar 2024 15:32:18 +0900
|
Date: Sat, 23 Mar 2024 16:36:09 +0900
|
||||||
Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile
|
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_MOBILE for mobile network
|
||||||
network
|
|
||||||
|
|
||||||
Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network
|
Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network
|
||||||
connection. This is useful to distinguish those LEDs from LEDs that
|
connection. This is useful to distinguish those LEDs from LEDs that
|
||||||
@ -21,6 +20,10 @@ port.
|
|||||||
|
|
||||||
Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
|
Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
|
Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||||
|
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||||
|
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20240323074326.1428-2-musashino.open@gmail.com
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
---
|
---
|
||||||
include/dt-bindings/leds/common.h | 1 +
|
include/dt-bindings/leds/common.h | 1 +
|
||||||
1 file changed, 1 insertion(+)
|
1 file changed, 1 insertion(+)
|
@ -1,8 +1,8 @@
|
|||||||
From e22afe910afcfb51b6ba6a0ae776939959727f54 Mon Sep 17 00:00:00 2001
|
From 77b9f2d6fd9bf34ec810de6bdad42d7d0a47d31b Mon Sep 17 00:00:00 2001
|
||||||
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||||
Date: Wed, 20 Mar 2024 15:59:06 +0900
|
Date: Sat, 23 Mar 2024 16:36:10 +0900
|
||||||
Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link
|
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_SPEED_* for link speed on
|
||||||
speed on LAN/WAN
|
LAN/WAN
|
||||||
|
|
||||||
Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that
|
Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that
|
||||||
indicate link speed of ethernet ports on LAN/WAN. This is useful to
|
indicate link speed of ethernet ports on LAN/WAN. This is useful to
|
||||||
@ -18,8 +18,10 @@ of the ethernet ports in addition to LEDs that indicate link status
|
|||||||
- 100 Mbps: amber:speed-(lan|wan)-N
|
- 100 Mbps: amber:speed-(lan|wan)-N
|
||||||
- 10 Mbps: (none, turned off)
|
- 10 Mbps: (none, turned off)
|
||||||
|
|
||||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
|
||||||
Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
|
Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||||
|
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20240323074326.1428-3-musashino.open@gmail.com
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
---
|
---
|
||||||
include/dt-bindings/leds/common.h | 2 ++
|
include/dt-bindings/leds/common.h | 2 ++
|
||||||
1 file changed, 2 insertions(+)
|
1 file changed, 2 insertions(+)
|
@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -21997,6 +21997,7 @@ U-BOOT ENVIRONMENT VARIABLES
|
@@ -21989,6 +21989,7 @@ U-BOOT ENVIRONMENT VARIABLES
|
||||||
M: Rafał Miłecki <rafal@milecki.pl>
|
M: Rafał Miłecki <rafal@milecki.pl>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
|
F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
|
||||||
|
@ -21,7 +21,7 @@ Link: https://lore.kernel.org/linux-mtd/20231012064134.4068621-1-quic_sridsn@qui
|
|||||||
|
|
||||||
--- a/drivers/mtd/nand/spi/winbond.c
|
--- a/drivers/mtd/nand/spi/winbond.c
|
||||||
+++ b/drivers/mtd/nand/spi/winbond.c
|
+++ b/drivers/mtd/nand/spi/winbond.c
|
||||||
@@ -169,6 +169,51 @@ static const struct spinand_info winbond
|
@@ -195,6 +195,51 @@ static const struct spinand_info winbond
|
||||||
&update_cache_variants),
|
&update_cache_variants),
|
||||||
0,
|
0,
|
||||||
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
|
SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
|
||||||
|
@ -27,7 +27,7 @@ Link: https://lore.kernel.org/linux-mtd/20240107144120.532-1-hujy652@gmail.com
|
|||||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||||
@@ -118,6 +120,7 @@ static int w25n02kv_ecc_get_status(struc
|
@@ -135,6 +137,7 @@ static int w25n02kv_ecc_get_status(struc
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
case STATUS_ECC_HAS_BITFLIPS:
|
case STATUS_ECC_HAS_BITFLIPS:
|
||||||
@ -35,7 +35,7 @@ Link: https://lore.kernel.org/linux-mtd/20240107144120.532-1-hujy652@gmail.com
|
|||||||
/*
|
/*
|
||||||
* Let's try to retrieve the real maximum number of bitflips
|
* Let's try to retrieve the real maximum number of bitflips
|
||||||
* in order to avoid forcing the wear-leveling layer to move
|
* in order to avoid forcing the wear-leveling layer to move
|
||||||
@@ -214,6 +217,15 @@ static const struct spinand_info winbond
|
@@ -240,6 +243,15 @@ static const struct spinand_info winbond
|
||||||
&update_cache_variants),
|
&update_cache_variants),
|
||||||
0,
|
0,
|
||||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
|
SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
From a7a94ca21ac0f347f683d33c72b4aab57ce5eec3 Mon Sep 17 00:00:00 2001
|
From 9da39ef332c417ce52732564c1c682a6e1209302 Mon Sep 17 00:00:00 2001
|
||||||
From: Florian Eckert <fe@dev.tdt.de>
|
From: Florian Eckert <fe@dev.tdt.de>
|
||||||
Date: Mon, 20 Nov 2023 11:13:20 +0100
|
Date: Mon, 4 Dec 2023 15:13:35 +0100
|
||||||
Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format
|
Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format
|
||||||
|
|
||||||
The following warnings are shown during compilation:
|
The following warnings are shown during compilation:
|
||||||
@ -34,6 +34,8 @@ argument 8 has type 'long unsigned int' [-Wformat=]
|
|||||||
To fix this, the correct string format must be used for printing.
|
To fix this, the correct string format must be used for printing.
|
||||||
|
|
||||||
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
|
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
|
||||||
|
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20231204141335.2798194-1-fe@dev.tdt.de
|
||||||
---
|
---
|
||||||
tools/thermal/tmon/tui.c | 2 +-
|
tools/thermal/tmon/tui.c | 2 +-
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
@ -1,123 +0,0 @@
|
|||||||
From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
|
|
||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Date: Sat, 15 Jul 2017 23:42:36 +0200
|
|
||||||
Subject: use -ffunction-sections, -fdata-sections and --gc-sections
|
|
||||||
|
|
||||||
In combination with kernel symbol export stripping this significantly reduces
|
|
||||||
the kernel image size. Used on both ARM and MIPS architectures.
|
|
||||||
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
||||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
|
||||||
---
|
|
||||||
--- a/arch/arm/Kconfig
|
|
||||||
+++ b/arch/arm/Kconfig
|
|
||||||
@@ -128,6 +128,7 @@ config ARM
|
|
||||||
select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
|
|
||||||
select IRQ_FORCED_THREADING
|
|
||||||
select LOCK_MM_AND_FIND_VMA
|
|
||||||
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
|
||||||
select MODULES_USE_ELF_REL
|
|
||||||
select NEED_DMA_MAP_STATE
|
|
||||||
select OF_EARLY_FLATTREE if OF
|
|
||||||
--- a/arch/arm/boot/compressed/Makefile
|
|
||||||
+++ b/arch/arm/boot/compressed/Makefile
|
|
||||||
@@ -92,6 +92,7 @@ endif
|
|
||||||
ifeq ($(CONFIG_USE_OF),y)
|
|
||||||
OBJS += $(libfdt_objs) fdt_check_mem_start.o
|
|
||||||
endif
|
|
||||||
+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
|
|
||||||
|
|
||||||
OBJS += lib1funcs.o ashldi3.o bswapsdi2.o
|
|
||||||
|
|
||||||
--- a/arch/arm/kernel/vmlinux.lds.S
|
|
||||||
+++ b/arch/arm/kernel/vmlinux.lds.S
|
|
||||||
@@ -74,7 +74,7 @@ SECTIONS
|
|
||||||
. = ALIGN(4);
|
|
||||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
|
||||||
__start___ex_table = .;
|
|
||||||
- ARM_MMU_KEEP(*(__ex_table))
|
|
||||||
+ KEEP(*(__ex_table))
|
|
||||||
__stop___ex_table = .;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -99,24 +99,24 @@ SECTIONS
|
|
||||||
}
|
|
||||||
.init.arch.info : {
|
|
||||||
__arch_info_begin = .;
|
|
||||||
- *(.arch.info.init)
|
|
||||||
+ KEEP(*(.arch.info.init))
|
|
||||||
__arch_info_end = .;
|
|
||||||
}
|
|
||||||
.init.tagtable : {
|
|
||||||
__tagtable_begin = .;
|
|
||||||
- *(.taglist.init)
|
|
||||||
+ KEEP(*(.taglist.init))
|
|
||||||
__tagtable_end = .;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_SMP_ON_UP
|
|
||||||
.init.smpalt : {
|
|
||||||
__smpalt_begin = .;
|
|
||||||
- *(.alt.smp.init)
|
|
||||||
+ KEEP(*(.alt.smp.init))
|
|
||||||
__smpalt_end = .;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
.init.pv_table : {
|
|
||||||
__pv_table_begin = .;
|
|
||||||
- *(.pv_table)
|
|
||||||
+ KEEP(*(.pv_table))
|
|
||||||
__pv_table_end = .;
|
|
||||||
}
|
|
||||||
|
|
||||||
--- a/arch/arm/include/asm/vmlinux.lds.h
|
|
||||||
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
|
||||||
@@ -42,13 +42,13 @@
|
|
||||||
#define PROC_INFO \
|
|
||||||
. = ALIGN(4); \
|
|
||||||
__proc_info_begin = .; \
|
|
||||||
- *(.proc.info.init) \
|
|
||||||
+ KEEP(*(.proc.info.init)) \
|
|
||||||
__proc_info_end = .;
|
|
||||||
|
|
||||||
#define IDMAP_TEXT \
|
|
||||||
ALIGN_FUNCTION(); \
|
|
||||||
__idmap_text_start = .; \
|
|
||||||
- *(.idmap.text) \
|
|
||||||
+ KEEP(*(.idmap.text)) \
|
|
||||||
__idmap_text_end = .; \
|
|
||||||
|
|
||||||
#define ARM_DISCARD \
|
|
||||||
@@ -108,12 +108,12 @@
|
|
||||||
. = ALIGN(8); \
|
|
||||||
.ARM.unwind_idx : { \
|
|
||||||
__start_unwind_idx = .; \
|
|
||||||
- *(.ARM.exidx*) \
|
|
||||||
+ KEEP(*(.ARM.exidx*)) \
|
|
||||||
__stop_unwind_idx = .; \
|
|
||||||
} \
|
|
||||||
.ARM.unwind_tab : { \
|
|
||||||
__start_unwind_tab = .; \
|
|
||||||
- *(.ARM.extab*) \
|
|
||||||
+ KEEP(*(.ARM.extab*)) \
|
|
||||||
__stop_unwind_tab = .; \
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@
|
|
||||||
__vectors_lma = .; \
|
|
||||||
OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
|
|
||||||
.vectors { \
|
|
||||||
- *(.vectors) \
|
|
||||||
+ KEEP(*(.vectors)) \
|
|
||||||
} \
|
|
||||||
.vectors.bhb.loop8 { \
|
|
||||||
*(.vectors.bhb.loop8) \
|
|
||||||
@@ -143,7 +143,7 @@
|
|
||||||
\
|
|
||||||
__stubs_lma = .; \
|
|
||||||
.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
|
|
||||||
- *(.stubs) \
|
|
||||||
+ KEEP(*(.stubs)) \
|
|
||||||
} \
|
|
||||||
ARM_LMA(__stubs, .stubs); \
|
|
||||||
. = __stubs_lma + SIZEOF(.stubs); \
|
|
@ -1,63 +0,0 @@
|
|||||||
From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
Date: Tue, 6 Sep 2022 00:31:19 +0100
|
|
||||||
Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
|
|
||||||
To: netdev@vger.kernel.org,
|
|
||||||
linux-kernel@vger.kernel.org,
|
|
||||||
Russell King <linux@armlinux.org.uk>,
|
|
||||||
Andrew Lunn <andrew@lunn.ch>,
|
|
||||||
Heiner Kallweit <hkallweit1@gmail.com>
|
|
||||||
Cc: David S. Miller <davem@davemloft.net>,
|
|
||||||
Eric Dumazet <edumazet@google.com>,
|
|
||||||
Jakub Kicinski <kuba@kernel.org>,
|
|
||||||
Paolo Abeni <pabeni@redhat.com>,
|
|
||||||
Josef Schlehofer <pepe.schlehofer@gmail.com>
|
|
||||||
|
|
||||||
This copper module comes with broken TX_FAULT indicator which must be
|
|
||||||
ignored for it to work. Implement ignoring TX_FAULT state bit also
|
|
||||||
during reset/insertion and mute the warning telling the user that the
|
|
||||||
module indicates TX_FAULT.
|
|
||||||
|
|
||||||
Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
---
|
|
||||||
drivers/net/phy/sfp.c | 14 +++++++++++---
|
|
||||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/phy/sfp.c
|
|
||||||
+++ b/drivers/net/phy/sfp.c
|
|
||||||
@@ -485,6 +485,9 @@ static const struct sfp_quirk sfp_quirks
|
|
||||||
SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
|
|
||||||
sfp_fixup_ignore_tx_fault),
|
|
||||||
|
|
||||||
+ // OEM SFP-GE-T is 1000Base-T module
|
|
||||||
+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
|
|
||||||
+
|
|
||||||
// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
|
|
||||||
// 2500MBd NRZ in their EEPROM
|
|
||||||
SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
|
|
||||||
@@ -2604,7 +2607,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
|
||||||
* or t_start_up, so assume there is a fault.
|
|
||||||
*/
|
|
||||||
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
|
|
||||||
- sfp->sm_fault_retries == N_FAULT_INIT);
|
|
||||||
+ !sfp->tx_fault_ignore &&
|
|
||||||
+ (sfp->sm_fault_retries == N_FAULT_INIT));
|
|
||||||
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
|
|
||||||
init_done:
|
|
||||||
/* Create mdiobus and start trying for PHY */
|
|
||||||
@@ -2862,10 +2866,12 @@ static void sfp_check_state(struct sfp *
|
|
||||||
mutex_lock(&sfp->st_mutex);
|
|
||||||
state = sfp_get_state(sfp);
|
|
||||||
changed = state ^ sfp->state;
|
|
||||||
- if (sfp->tx_fault_ignore)
|
|
||||||
+ if (sfp->tx_fault_ignore) {
|
|
||||||
changed &= SFP_F_PRESENT | SFP_F_LOS;
|
|
||||||
- else
|
|
||||||
+ state &= ~SFP_F_TX_FAULT;
|
|
||||||
+ } else {
|
|
||||||
changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < GPIO_MAX; i++)
|
|
||||||
if (changed & BIT(i))
|
|
@ -1,63 +0,0 @@
|
|||||||
From patchwork Mon Aug 12 01:56:41 2024
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
X-Patchwork-Id: 1971406
|
|
||||||
Return-Path:
|
|
||||||
<linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>
|
|
||||||
X-Original-To: incoming@patchwork.ozlabs.org
|
|
||||||
Delivered-To: patchwork-incoming@legolas.ozlabs.org
|
|
||||||
Date: Mon, 12 Aug 2024 02:56:41 +0100
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
To: Miquel Raynal <miquel.raynal@bootlin.com>,
|
|
||||||
Richard Weinberger <richard@nod.at>,
|
|
||||||
Vignesh Raghavendra <vigneshr@ti.com>,
|
|
||||||
Tudor Ambarus <tudor.ambarus@linaro.org>,
|
|
||||||
Daniel Golle <daniel@makrotopia.org>,
|
|
||||||
Mika Westerberg <mika.westerberg@linux.intel.com>,
|
|
||||||
Chia-Lin Kao <acelan.kao@canonical.com>,
|
|
||||||
Martin Kurbanov <mmkurbanov@salutedevices.com>,
|
|
||||||
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
|
|
||||||
Subject: [PATCH] mtd: spinand: set bitflip_threshold to 75% of ECC strength
|
|
||||||
Message-ID:
|
|
||||||
<2117e387260b0a96f95b8e1652ff79e0e2d71d53.1723427450.git.daniel@makrotopia.org>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Disposition: inline
|
|
||||||
X-BeenThere: linux-mtd@lists.infradead.org
|
|
||||||
X-Mailman-Version: 2.1.34
|
|
||||||
Precedence: list
|
|
||||||
List-Id: Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>
|
|
||||||
List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mtd>,
|
|
||||||
<mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>
|
|
||||||
List-Archive: <http://lists.infradead.org/pipermail/linux-mtd/>
|
|
||||||
List-Post: <mailto:linux-mtd@lists.infradead.org>
|
|
||||||
List-Help: <mailto:linux-mtd-request@lists.infradead.org?subject=help>
|
|
||||||
List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
|
|
||||||
<mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
|
|
||||||
Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
|
|
||||||
Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
|
|
||||||
|
|
||||||
Reporting an unclean read from SPI-NAND only when the maximum number
|
|
||||||
of correctable bitflip errors has been hit seems a bit late.
|
|
||||||
UBI LEB scrubbing, which depends on the lower MTD device reporting
|
|
||||||
correctable bitflips, then only kicks in when it's almost too late.
|
|
||||||
|
|
||||||
Set bitflip_threshold to 75% of the ECC strength, which is also the
|
|
||||||
default for raw NAND.
|
|
||||||
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
---
|
|
||||||
drivers/mtd/nand/spi/core.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
--- a/drivers/mtd/nand/spi/core.c
|
|
||||||
+++ b/drivers/mtd/nand/spi/core.c
|
|
||||||
@@ -1287,6 +1287,7 @@ static int spinand_init(struct spinand_d
|
|
||||||
/* Propagate ECC information to mtd_info */
|
|
||||||
mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
|
|
||||||
mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
|
|
||||||
+ mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
|
|
||||||
|
|
||||||
ret = spinand_create_dirmaps(spinand);
|
|
||||||
if (ret) {
|
|
@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -22024,6 +22024,12 @@ F: Documentation/filesystems/ubifs-authe
|
@@ -22016,6 +22016,12 @@ F: Documentation/filesystems/ubifs-authe
|
||||||
F: Documentation/filesystems/ubifs.rst
|
F: Documentation/filesystems/ubifs.rst
|
||||||
F: fs/ubifs/
|
F: fs/ubifs/
|
||||||
|
|
||||||
|
@ -1,578 +0,0 @@
|
|||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Date: Tue, 23 Apr 2024 11:23:03 +0200
|
|
||||||
Subject: [PATCH] net: add TCP fraglist GRO support
|
|
||||||
|
|
||||||
When forwarding TCP after GRO, software segmentation is very expensive,
|
|
||||||
especially when the checksum needs to be recalculated.
|
|
||||||
One case where that's currently unavoidable is when routing packets over
|
|
||||||
PPPoE. Performance improves significantly when using fraglist GRO
|
|
||||||
implemented in the same way as for UDP.
|
|
||||||
|
|
||||||
Here's a measurement of running 2 TCP streams through a MediaTek MT7622
|
|
||||||
device (2-core Cortex-A53), which runs NAT with flow offload enabled from
|
|
||||||
one ethernet port to PPPoE on another ethernet port + cake qdisc set to
|
|
||||||
1Gbps.
|
|
||||||
|
|
||||||
rx-gro-list off: 630 Mbit/s, CPU 35% idle
|
|
||||||
rx-gro-list on: 770 Mbit/s, CPU 40% idle
|
|
||||||
|
|
||||||
Signe-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
|
|
||||||
--- a/include/net/gro.h
|
|
||||||
+++ b/include/net/gro.h
|
|
||||||
@@ -439,6 +439,7 @@ static inline __wsum ip6_gro_compute_pse
|
|
||||||
}
|
|
||||||
|
|
||||||
int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb);
|
|
||||||
+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb);
|
|
||||||
|
|
||||||
/* Pass the currently batched GRO_NORMAL SKBs up to the stack. */
|
|
||||||
static inline void gro_normal_list(struct napi_struct *napi)
|
|
||||||
--- a/include/net/tcp.h
|
|
||||||
+++ b/include/net/tcp.h
|
|
||||||
@@ -2101,7 +2101,10 @@ void tcp_v4_destroy_sock(struct sock *sk
|
|
||||||
|
|
||||||
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
|
|
||||||
netdev_features_t features);
|
|
||||||
-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb);
|
|
||||||
+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb);
|
|
||||||
+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th);
|
|
||||||
+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
|
|
||||||
+ struct tcphdr *th);
|
|
||||||
INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff));
|
|
||||||
INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb));
|
|
||||||
INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff));
|
|
||||||
--- a/net/core/gro.c
|
|
||||||
+++ b/net/core/gro.c
|
|
||||||
@@ -228,6 +228,33 @@ done:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
|
|
||||||
+{
|
|
||||||
+ if (unlikely(p->len + skb->len >= 65536))
|
|
||||||
+ return -E2BIG;
|
|
||||||
+
|
|
||||||
+ if (NAPI_GRO_CB(p)->last == p)
|
|
||||||
+ skb_shinfo(p)->frag_list = skb;
|
|
||||||
+ else
|
|
||||||
+ NAPI_GRO_CB(p)->last->next = skb;
|
|
||||||
+
|
|
||||||
+ skb_pull(skb, skb_gro_offset(skb));
|
|
||||||
+
|
|
||||||
+ NAPI_GRO_CB(p)->last = skb;
|
|
||||||
+ NAPI_GRO_CB(p)->count++;
|
|
||||||
+ p->data_len += skb->len;
|
|
||||||
+
|
|
||||||
+ /* sk ownership - if any - completely transferred to the aggregated packet */
|
|
||||||
+ skb->destructor = NULL;
|
|
||||||
+ skb->sk = NULL;
|
|
||||||
+ p->truesize += skb->truesize;
|
|
||||||
+ p->len += skb->len;
|
|
||||||
+
|
|
||||||
+ NAPI_GRO_CB(skb)->same_flow = 1;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
|
|
||||||
static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
--- a/net/ipv4/tcp_offload.c
|
|
||||||
+++ b/net/ipv4/tcp_offload.c
|
|
||||||
@@ -31,6 +31,70 @@ static void tcp_gso_tstamp(struct sk_buf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void __tcpv4_gso_segment_csum(struct sk_buff *seg,
|
|
||||||
+ __be32 *oldip, __be32 newip,
|
|
||||||
+ __be16 *oldport, __be16 newport)
|
|
||||||
+{
|
|
||||||
+ struct tcphdr *th;
|
|
||||||
+ struct iphdr *iph;
|
|
||||||
+
|
|
||||||
+ if (*oldip == newip && *oldport == newport)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ th = tcp_hdr(seg);
|
|
||||||
+ iph = ip_hdr(seg);
|
|
||||||
+
|
|
||||||
+ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true);
|
|
||||||
+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
|
|
||||||
+ *oldport = newport;
|
|
||||||
+
|
|
||||||
+ csum_replace4(&iph->check, *oldip, newip);
|
|
||||||
+ *oldip = newip;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs)
|
|
||||||
+{
|
|
||||||
+ const struct tcphdr *th;
|
|
||||||
+ const struct iphdr *iph;
|
|
||||||
+ struct sk_buff *seg;
|
|
||||||
+ struct tcphdr *th2;
|
|
||||||
+ struct iphdr *iph2;
|
|
||||||
+
|
|
||||||
+ seg = segs;
|
|
||||||
+ th = tcp_hdr(seg);
|
|
||||||
+ iph = ip_hdr(seg);
|
|
||||||
+ th2 = tcp_hdr(seg->next);
|
|
||||||
+ iph2 = ip_hdr(seg->next);
|
|
||||||
+
|
|
||||||
+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
|
|
||||||
+ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
|
|
||||||
+ return segs;
|
|
||||||
+
|
|
||||||
+ while ((seg = seg->next)) {
|
|
||||||
+ th2 = tcp_hdr(seg);
|
|
||||||
+ iph2 = ip_hdr(seg);
|
|
||||||
+
|
|
||||||
+ __tcpv4_gso_segment_csum(seg,
|
|
||||||
+ &iph2->saddr, iph->saddr,
|
|
||||||
+ &th2->source, th->source);
|
|
||||||
+ __tcpv4_gso_segment_csum(seg,
|
|
||||||
+ &iph2->daddr, iph->daddr,
|
|
||||||
+ &th2->dest, th->dest);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return segs;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb,
|
|
||||||
+ netdev_features_t features)
|
|
||||||
+{
|
|
||||||
+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
|
|
||||||
+ if (IS_ERR(skb))
|
|
||||||
+ return skb;
|
|
||||||
+
|
|
||||||
+ return __tcpv4_gso_segment_list_csum(skb);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
|
|
||||||
netdev_features_t features)
|
|
||||||
{
|
|
||||||
@@ -40,6 +104,9 @@ static struct sk_buff *tcp4_gso_segment(
|
|
||||||
if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
|
|
||||||
+ return __tcp4_gso_segment_list(skb, features);
|
|
||||||
+
|
|
||||||
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
|
|
||||||
const struct iphdr *iph = ip_hdr(skb);
|
|
||||||
struct tcphdr *th = tcp_hdr(skb);
|
|
||||||
@@ -184,61 +251,76 @@ out:
|
|
||||||
return segs;
|
|
||||||
}
|
|
||||||
|
|
||||||
-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
|
|
||||||
+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th)
|
|
||||||
{
|
|
||||||
- struct sk_buff *pp = NULL;
|
|
||||||
+ struct tcphdr *th2;
|
|
||||||
struct sk_buff *p;
|
|
||||||
+
|
|
||||||
+ list_for_each_entry(p, head, list) {
|
|
||||||
+ if (!NAPI_GRO_CB(p)->same_flow)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ th2 = tcp_hdr(p);
|
|
||||||
+ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
|
|
||||||
+ NAPI_GRO_CB(p)->same_flow = 0;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return p;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb)
|
|
||||||
+{
|
|
||||||
+ unsigned int thlen, hlen, off;
|
|
||||||
struct tcphdr *th;
|
|
||||||
- struct tcphdr *th2;
|
|
||||||
- unsigned int len;
|
|
||||||
- unsigned int thlen;
|
|
||||||
- __be32 flags;
|
|
||||||
- unsigned int mss = 1;
|
|
||||||
- unsigned int hlen;
|
|
||||||
- unsigned int off;
|
|
||||||
- int flush = 1;
|
|
||||||
- int i;
|
|
||||||
|
|
||||||
off = skb_gro_offset(skb);
|
|
||||||
hlen = off + sizeof(*th);
|
|
||||||
th = skb_gro_header(skb, hlen, off);
|
|
||||||
if (unlikely(!th))
|
|
||||||
- goto out;
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
thlen = th->doff * 4;
|
|
||||||
if (thlen < sizeof(*th))
|
|
||||||
- goto out;
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
hlen = off + thlen;
|
|
||||||
if (skb_gro_header_hard(skb, hlen)) {
|
|
||||||
th = skb_gro_header_slow(skb, hlen, off);
|
|
||||||
if (unlikely(!th))
|
|
||||||
- goto out;
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
skb_gro_pull(skb, thlen);
|
|
||||||
|
|
||||||
- len = skb_gro_len(skb);
|
|
||||||
- flags = tcp_flag_word(th);
|
|
||||||
-
|
|
||||||
- list_for_each_entry(p, head, list) {
|
|
||||||
- if (!NAPI_GRO_CB(p)->same_flow)
|
|
||||||
- continue;
|
|
||||||
+ return th;
|
|
||||||
+}
|
|
||||||
|
|
||||||
- th2 = tcp_hdr(p);
|
|
||||||
+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
|
|
||||||
+ struct tcphdr *th)
|
|
||||||
+{
|
|
||||||
+ unsigned int thlen = th->doff * 4;
|
|
||||||
+ struct sk_buff *pp = NULL;
|
|
||||||
+ struct sk_buff *p;
|
|
||||||
+ struct tcphdr *th2;
|
|
||||||
+ unsigned int len;
|
|
||||||
+ __be32 flags;
|
|
||||||
+ unsigned int mss = 1;
|
|
||||||
+ int flush = 1;
|
|
||||||
+ int i;
|
|
||||||
|
|
||||||
- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
|
|
||||||
- NAPI_GRO_CB(p)->same_flow = 0;
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
+ len = skb_gro_len(skb);
|
|
||||||
+ flags = tcp_flag_word(th);
|
|
||||||
|
|
||||||
- goto found;
|
|
||||||
- }
|
|
||||||
- p = NULL;
|
|
||||||
- goto out_check_final;
|
|
||||||
+ p = tcp_gro_lookup(head, th);
|
|
||||||
+ if (!p)
|
|
||||||
+ goto out_check_final;
|
|
||||||
|
|
||||||
-found:
|
|
||||||
/* Include the IP ID check below from the inner most IP hdr */
|
|
||||||
+ th2 = tcp_hdr(p);
|
|
||||||
flush = NAPI_GRO_CB(p)->flush;
|
|
||||||
flush |= (__force int)(flags & TCP_FLAG_CWR);
|
|
||||||
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
|
|
||||||
@@ -275,6 +357,19 @@ found:
|
|
||||||
flush |= p->decrypted ^ skb->decrypted;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ if (unlikely(NAPI_GRO_CB(p)->is_flist)) {
|
|
||||||
+ flush |= (__force int)(flags ^ tcp_flag_word(th2));
|
|
||||||
+ flush |= skb->ip_summed != p->ip_summed;
|
|
||||||
+ flush |= skb->csum_level != p->csum_level;
|
|
||||||
+ flush |= !pskb_may_pull(skb, skb_gro_offset(skb));
|
|
||||||
+ flush |= NAPI_GRO_CB(p)->count >= 64;
|
|
||||||
+
|
|
||||||
+ if (flush || skb_gro_receive_list(p, skb))
|
|
||||||
+ mss = 1;
|
|
||||||
+
|
|
||||||
+ goto out_check_final;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (flush || skb_gro_receive(p, skb)) {
|
|
||||||
mss = 1;
|
|
||||||
goto out_check_final;
|
|
||||||
@@ -296,7 +391,6 @@ out_check_final:
|
|
||||||
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
|
|
||||||
pp = p;
|
|
||||||
|
|
||||||
-out:
|
|
||||||
NAPI_GRO_CB(skb)->flush |= (flush != 0);
|
|
||||||
|
|
||||||
return pp;
|
|
||||||
@@ -320,18 +414,58 @@ void tcp_gro_complete(struct sk_buff *sk
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(tcp_gro_complete);
|
|
||||||
|
|
||||||
+static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
|
|
||||||
+ struct tcphdr *th)
|
|
||||||
+{
|
|
||||||
+ const struct iphdr *iph;
|
|
||||||
+ struct sk_buff *p;
|
|
||||||
+ struct sock *sk;
|
|
||||||
+ struct net *net;
|
|
||||||
+ int iif, sdif;
|
|
||||||
+
|
|
||||||
+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ p = tcp_gro_lookup(head, th);
|
|
||||||
+ if (p) {
|
|
||||||
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ inet_get_iif_sdif(skb, &iif, &sdif);
|
|
||||||
+ iph = skb_gro_network_header(skb);
|
|
||||||
+ net = dev_net(skb->dev);
|
|
||||||
+ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
|
|
||||||
+ iph->saddr, th->source,
|
|
||||||
+ iph->daddr, ntohs(th->dest),
|
|
||||||
+ iif, sdif);
|
|
||||||
+ NAPI_GRO_CB(skb)->is_flist = !sk;
|
|
||||||
+ if (sk)
|
|
||||||
+ sock_put(sk);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
INDIRECT_CALLABLE_SCOPE
|
|
||||||
struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
+ struct tcphdr *th;
|
|
||||||
+
|
|
||||||
/* Don't bother verifying checksum if we're going to flush anyway. */
|
|
||||||
if (!NAPI_GRO_CB(skb)->flush &&
|
|
||||||
skb_gro_checksum_validate(skb, IPPROTO_TCP,
|
|
||||||
- inet_gro_compute_pseudo)) {
|
|
||||||
- NAPI_GRO_CB(skb)->flush = 1;
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ inet_gro_compute_pseudo))
|
|
||||||
+ goto flush;
|
|
||||||
+
|
|
||||||
+ th = tcp_gro_pull_header(skb);
|
|
||||||
+ if (!th)
|
|
||||||
+ goto flush;
|
|
||||||
|
|
||||||
- return tcp_gro_receive(head, skb);
|
|
||||||
+ tcp4_check_fraglist_gro(head, skb, th);
|
|
||||||
+
|
|
||||||
+ return tcp_gro_receive(head, skb, th);
|
|
||||||
+
|
|
||||||
+flush:
|
|
||||||
+ NAPI_GRO_CB(skb)->flush = 1;
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
|
|
||||||
@@ -339,6 +473,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
|
|
||||||
const struct iphdr *iph = ip_hdr(skb);
|
|
||||||
struct tcphdr *th = tcp_hdr(skb);
|
|
||||||
|
|
||||||
+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
|
|
||||||
+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4;
|
|
||||||
+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
|
|
||||||
+
|
|
||||||
+ __skb_incr_checksum_unnecessary(skb);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr,
|
|
||||||
iph->daddr, 0);
|
|
||||||
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
|
|
||||||
--- a/net/ipv4/udp_offload.c
|
|
||||||
+++ b/net/ipv4/udp_offload.c
|
|
||||||
@@ -474,33 +474,6 @@ out:
|
|
||||||
return segs;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
|
|
||||||
-{
|
|
||||||
- if (unlikely(p->len + skb->len >= 65536))
|
|
||||||
- return -E2BIG;
|
|
||||||
-
|
|
||||||
- if (NAPI_GRO_CB(p)->last == p)
|
|
||||||
- skb_shinfo(p)->frag_list = skb;
|
|
||||||
- else
|
|
||||||
- NAPI_GRO_CB(p)->last->next = skb;
|
|
||||||
-
|
|
||||||
- skb_pull(skb, skb_gro_offset(skb));
|
|
||||||
-
|
|
||||||
- NAPI_GRO_CB(p)->last = skb;
|
|
||||||
- NAPI_GRO_CB(p)->count++;
|
|
||||||
- p->data_len += skb->len;
|
|
||||||
-
|
|
||||||
- /* sk ownership - if any - completely transferred to the aggregated packet */
|
|
||||||
- skb->destructor = NULL;
|
|
||||||
- skb->sk = NULL;
|
|
||||||
- p->truesize += skb->truesize;
|
|
||||||
- p->len += skb->len;
|
|
||||||
-
|
|
||||||
- NAPI_GRO_CB(skb)->same_flow = 1;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
|
|
||||||
#define UDP_GRO_CNT_MAX 64
|
|
||||||
static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
|
|
||||||
--- a/net/ipv6/tcpv6_offload.c
|
|
||||||
+++ b/net/ipv6/tcpv6_offload.c
|
|
||||||
@@ -7,24 +7,67 @@
|
|
||||||
*/
|
|
||||||
#include <linux/indirect_call_wrapper.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
+#include <net/inet6_hashtables.h>
|
|
||||||
#include <net/gro.h>
|
|
||||||
#include <net/protocol.h>
|
|
||||||
#include <net/tcp.h>
|
|
||||||
#include <net/ip6_checksum.h>
|
|
||||||
#include "ip6_offload.h"
|
|
||||||
|
|
||||||
+static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
|
|
||||||
+ struct tcphdr *th)
|
|
||||||
+{
|
|
||||||
+#if IS_ENABLED(CONFIG_IPV6)
|
|
||||||
+ const struct ipv6hdr *hdr;
|
|
||||||
+ struct sk_buff *p;
|
|
||||||
+ struct sock *sk;
|
|
||||||
+ struct net *net;
|
|
||||||
+ int iif, sdif;
|
|
||||||
+
|
|
||||||
+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ p = tcp_gro_lookup(head, th);
|
|
||||||
+ if (p) {
|
|
||||||
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ inet6_get_iif_sdif(skb, &iif, &sdif);
|
|
||||||
+ hdr = skb_gro_network_header(skb);
|
|
||||||
+ net = dev_net(skb->dev);
|
|
||||||
+ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
|
|
||||||
+ &hdr->saddr, th->source,
|
|
||||||
+ &hdr->daddr, ntohs(th->dest),
|
|
||||||
+ iif, sdif);
|
|
||||||
+ NAPI_GRO_CB(skb)->is_flist = !sk;
|
|
||||||
+ if (sk)
|
|
||||||
+ sock_put(sk);
|
|
||||||
+#endif /* IS_ENABLED(CONFIG_IPV6) */
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
INDIRECT_CALLABLE_SCOPE
|
|
||||||
struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
+ struct tcphdr *th;
|
|
||||||
+
|
|
||||||
/* Don't bother verifying checksum if we're going to flush anyway. */
|
|
||||||
if (!NAPI_GRO_CB(skb)->flush &&
|
|
||||||
skb_gro_checksum_validate(skb, IPPROTO_TCP,
|
|
||||||
- ip6_gro_compute_pseudo)) {
|
|
||||||
- NAPI_GRO_CB(skb)->flush = 1;
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ ip6_gro_compute_pseudo))
|
|
||||||
+ goto flush;
|
|
||||||
|
|
||||||
- return tcp_gro_receive(head, skb);
|
|
||||||
+ th = tcp_gro_pull_header(skb);
|
|
||||||
+ if (!th)
|
|
||||||
+ goto flush;
|
|
||||||
+
|
|
||||||
+ tcp6_check_fraglist_gro(head, skb, th);
|
|
||||||
+
|
|
||||||
+ return tcp_gro_receive(head, skb, th);
|
|
||||||
+
|
|
||||||
+flush:
|
|
||||||
+ NAPI_GRO_CB(skb)->flush = 1;
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff)
|
|
||||||
@@ -32,6 +75,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
|
|
||||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
|
||||||
struct tcphdr *th = tcp_hdr(skb);
|
|
||||||
|
|
||||||
+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) {
|
|
||||||
+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6;
|
|
||||||
+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
|
|
||||||
+
|
|
||||||
+ __skb_incr_checksum_unnecessary(skb);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,
|
|
||||||
&iph->daddr, 0);
|
|
||||||
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
|
|
||||||
@@ -40,6 +92,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void __tcpv6_gso_segment_csum(struct sk_buff *seg,
|
|
||||||
+ __be16 *oldport, __be16 newport)
|
|
||||||
+{
|
|
||||||
+ struct tcphdr *th;
|
|
||||||
+
|
|
||||||
+ if (*oldport == newport)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ th = tcp_hdr(seg);
|
|
||||||
+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
|
|
||||||
+ *oldport = newport;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs)
|
|
||||||
+{
|
|
||||||
+ const struct tcphdr *th;
|
|
||||||
+ const struct ipv6hdr *iph;
|
|
||||||
+ struct sk_buff *seg;
|
|
||||||
+ struct tcphdr *th2;
|
|
||||||
+ struct ipv6hdr *iph2;
|
|
||||||
+
|
|
||||||
+ seg = segs;
|
|
||||||
+ th = tcp_hdr(seg);
|
|
||||||
+ iph = ipv6_hdr(seg);
|
|
||||||
+ th2 = tcp_hdr(seg->next);
|
|
||||||
+ iph2 = ipv6_hdr(seg->next);
|
|
||||||
+
|
|
||||||
+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
|
|
||||||
+ ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
|
|
||||||
+ ipv6_addr_equal(&iph->daddr, &iph2->daddr))
|
|
||||||
+ return segs;
|
|
||||||
+
|
|
||||||
+ while ((seg = seg->next)) {
|
|
||||||
+ th2 = tcp_hdr(seg);
|
|
||||||
+ iph2 = ipv6_hdr(seg);
|
|
||||||
+
|
|
||||||
+ iph2->saddr = iph->saddr;
|
|
||||||
+ iph2->daddr = iph->daddr;
|
|
||||||
+ __tcpv6_gso_segment_csum(seg, &th2->source, th->source);
|
|
||||||
+ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return segs;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb,
|
|
||||||
+ netdev_features_t features)
|
|
||||||
+{
|
|
||||||
+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb));
|
|
||||||
+ if (IS_ERR(skb))
|
|
||||||
+ return skb;
|
|
||||||
+
|
|
||||||
+ return __tcpv6_gso_segment_list_csum(skb);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
|
|
||||||
netdev_features_t features)
|
|
||||||
{
|
|
||||||
@@ -51,6 +158,9 @@ static struct sk_buff *tcp6_gso_segment(
|
|
||||||
if (!pskb_may_pull(skb, sizeof(*th)))
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
|
|
||||||
+ return __tcp6_gso_segment_list(skb, features);
|
|
||||||
+
|
|
||||||
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
|
|
||||||
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
|
||||||
struct tcphdr *th = tcp_hdr(skb);
|
|
@ -1,54 +0,0 @@
|
|||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Date: Mon, 24 Feb 2025 12:18:23 +0100
|
|
||||||
Subject: [PATCH] net: ipv6: fix TCP GSO segmentation with NAT
|
|
||||||
|
|
||||||
When updating the source/destination address, the TCP/UDP checksum needs to
|
|
||||||
be updated as well.
|
|
||||||
|
|
||||||
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
|
|
||||||
--- a/net/ipv6/tcpv6_offload.c
|
|
||||||
+++ b/net/ipv6/tcpv6_offload.c
|
|
||||||
@@ -112,24 +112,36 @@ static struct sk_buff *__tcpv6_gso_segme
|
|
||||||
struct sk_buff *seg;
|
|
||||||
struct tcphdr *th2;
|
|
||||||
struct ipv6hdr *iph2;
|
|
||||||
+ bool addr_equal;
|
|
||||||
|
|
||||||
seg = segs;
|
|
||||||
th = tcp_hdr(seg);
|
|
||||||
iph = ipv6_hdr(seg);
|
|
||||||
th2 = tcp_hdr(seg->next);
|
|
||||||
iph2 = ipv6_hdr(seg->next);
|
|
||||||
+ addr_equal = ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
|
|
||||||
+ ipv6_addr_equal(&iph->daddr, &iph2->daddr);
|
|
||||||
|
|
||||||
if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
|
|
||||||
- ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
|
|
||||||
- ipv6_addr_equal(&iph->daddr, &iph2->daddr))
|
|
||||||
+ addr_equal)
|
|
||||||
return segs;
|
|
||||||
|
|
||||||
while ((seg = seg->next)) {
|
|
||||||
th2 = tcp_hdr(seg);
|
|
||||||
iph2 = ipv6_hdr(seg);
|
|
||||||
|
|
||||||
- iph2->saddr = iph->saddr;
|
|
||||||
- iph2->daddr = iph->daddr;
|
|
||||||
+ if (!addr_equal) {
|
|
||||||
+ inet_proto_csum_replace16(&th2->check, seg,
|
|
||||||
+ iph2->saddr.s6_addr32,
|
|
||||||
+ iph->saddr.s6_addr32,
|
|
||||||
+ true);
|
|
||||||
+ inet_proto_csum_replace16(&th2->check, seg,
|
|
||||||
+ iph2->daddr.s6_addr32,
|
|
||||||
+ iph->daddr.s6_addr32,
|
|
||||||
+ true);
|
|
||||||
+ iph2->saddr = iph->saddr;
|
|
||||||
+ iph2->daddr = iph->daddr;
|
|
||||||
+ }
|
|
||||||
__tcpv6_gso_segment_csum(seg, &th2->source, th->source);
|
|
||||||
__tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
|
|
||||||
}
|
|
@ -59,7 +59,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|||||||
}
|
}
|
||||||
--- a/net/netfilter/nft_flow_offload.c
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
+++ b/net/netfilter/nft_flow_offload.c
|
+++ b/net/netfilter/nft_flow_offload.c
|
||||||
@@ -486,47 +486,14 @@ static struct nft_expr_type nft_flow_off
|
@@ -487,47 +487,14 @@ static struct nft_expr_type nft_flow_off
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
From patchwork Sat Oct 26 13:52:25 2024
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
X-Patchwork-Id: 13852245
|
|
||||||
X-Patchwork-Delegate: kuba@kernel.org
|
|
||||||
Date: Sat, 26 Oct 2024 14:52:25 +0100
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
To: linux-mediatek@lists.infradead.org,
|
|
||||||
linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
|
|
||||||
netdev@vger.kernel.org, Sujuan Chen <sujuan.chen@mediatek.com>,
|
|
||||||
AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
|
|
||||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
|
||||||
Paolo Abeni <pabeni@redhat.com>, Jakub Kicinski <kuba@kernel.org>,
|
|
||||||
Eric Dumazet <edumazet@google.com>,
|
|
||||||
"David S. Miller" <davem@davemloft.net>,
|
|
||||||
Andrew Lunn <andrew+netdev@lunn.ch>,
|
|
||||||
Lorenzo Bianconi <lorenzo@kernel.org>,
|
|
||||||
Mark Lee <Mark-MC.Lee@mediatek.com>,
|
|
||||||
Sean Wang <sean.wang@mediatek.com>, Felix Fietkau <nbd@nbd.name>,
|
|
||||||
John Crispin <john@phrozen.org>
|
|
||||||
Subject: [PATCH net] net: ethernet: mtk_wed: fix path of MT7988 WO firmware
|
|
||||||
Message-ID: <Zxz0GWTR5X5LdWPe@pidgin.makrotopia.org>
|
|
||||||
Precedence: bulk
|
|
||||||
X-Mailing-List: netdev@vger.kernel.org
|
|
||||||
List-Id: <netdev.vger.kernel.org>
|
|
||||||
List-Subscribe: <mailto:netdev+subscribe@vger.kernel.org>
|
|
||||||
List-Unsubscribe: <mailto:netdev+unsubscribe@vger.kernel.org>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Disposition: inline
|
|
||||||
X-Patchwork-Delegate: kuba@kernel.org
|
|
||||||
|
|
||||||
linux-firmware commit 808cba84 ("mtk_wed: add firmware for mt7988
|
|
||||||
Wireless Ethernet Dispatcher") added mt7988_wo_{0,1}.bin in the
|
|
||||||
'mediatek/mt7988' directory while driver current expects the files in
|
|
||||||
the 'mediatek' directory.
|
|
||||||
|
|
||||||
Change path in the driver header now that the firmware has been added.
|
|
||||||
|
|
||||||
Fixes: e2f64db13aa1 ("net: ethernet: mtk_wed: introduce WED support for MT7988")
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/mediatek/mtk_wed_wo.h | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
|
|
||||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
|
|
||||||
@@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx {
|
|
||||||
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
|
|
||||||
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
|
|
||||||
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
|
|
||||||
-#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
|
|
||||||
-#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
|
|
||||||
+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin"
|
|
||||||
+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin"
|
|
||||||
|
|
||||||
#define MTK_WO_MCU_CFG_LS_BASE 0
|
|
||||||
#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
|
|
@ -1,498 +0,0 @@
|
|||||||
From patchwork Thu Feb 1 21:53:06 2024
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
X-Patchwork-Id: 13541843
|
|
||||||
Date: Thu, 1 Feb 2024 21:53:06 +0000
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
To: Bc-bocun Chen <bc-bocun.chen@mediatek.com>,
|
|
||||||
Chunfeng Yun <chunfeng.yun@mediatek.com>,
|
|
||||||
Vinod Koul <vkoul@kernel.org>,
|
|
||||||
Kishon Vijay Abraham I <kishon@kernel.org>,
|
|
||||||
Rob Herring <robh@kernel.org>,
|
|
||||||
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
|
|
||||||
Conor Dooley <conor+dt@kernel.org>,
|
|
||||||
Daniel Golle <daniel@makrotopia.org>,
|
|
||||||
Qingfang Deng <dqfext@gmail.com>,
|
|
||||||
SkyLake Huang <SkyLake.Huang@mediatek.com>,
|
|
||||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
|
||||||
AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
|
|
||||||
Philipp Zabel <p.zabel@pengutronix.de>,
|
|
||||||
linux-arm-kernel@lists.infradead.org,
|
|
||||||
linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
|
|
||||||
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
|
|
||||||
netdev@vger.kernel.org
|
|
||||||
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
|
|
||||||
Message-ID:
|
|
||||||
<dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
|
|
||||||
References:
|
|
||||||
<702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Disposition: inline
|
|
||||||
In-Reply-To:
|
|
||||||
<702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
|
|
||||||
List-Id: Linux Phy Mailing list <linux-phy.lists.infradead.org>
|
|
||||||
|
|
||||||
Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
|
|
||||||
which can be found in the MT7988 SoC.
|
|
||||||
|
|
||||||
The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
|
|
||||||
PHY_INTERFACE_MODE_* corresponding to the supported modes:
|
|
||||||
|
|
||||||
* USXGMII \
|
|
||||||
* 10GBase-R }- USXGMII PCS - XGDM \
|
|
||||||
* 5GBase-R / \
|
|
||||||
}- Ethernet MAC
|
|
||||||
* 2500Base-X \ /
|
|
||||||
* 1000Base-X }- LynxI PCS - GDM /
|
|
||||||
* Cisco SGMII (MAC side) /
|
|
||||||
|
|
||||||
In order to work-around a performance issue present on the first of
|
|
||||||
two XFI T-PHYs present in MT7988, special tuning is applied which can be
|
|
||||||
selected by adding the 'mediatek,usxgmii-performance-errata' property to
|
|
||||||
the device tree node.
|
|
||||||
|
|
||||||
There is no documentation for most registers used for the
|
|
||||||
analog/tuning part, however, most of the registers have been partially
|
|
||||||
reverse-engineered from MediaTek's SDK implementation (an opaque
|
|
||||||
sequence of 32-bit register writes) and descriptions for all relevant
|
|
||||||
digital registers and bits such as resets and muxes have been supplied
|
|
||||||
by MediaTek.
|
|
||||||
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
---
|
|
||||||
MAINTAINERS | 1 +
|
|
||||||
drivers/phy/mediatek/Kconfig | 12 +
|
|
||||||
drivers/phy/mediatek/Makefile | 1 +
|
|
||||||
drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
|
|
||||||
4 files changed, 406 insertions(+)
|
|
||||||
create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
|
|
||||||
|
|
||||||
--- a/drivers/phy/mediatek/Kconfig
|
|
||||||
+++ b/drivers/phy/mediatek/Kconfig
|
|
||||||
@@ -13,6 +13,18 @@ config PHY_MTK_PCIE
|
|
||||||
callback for PCIe GEN3 port, it supports software efuse
|
|
||||||
initialization.
|
|
||||||
|
|
||||||
+config PHY_MTK_XFI_TPHY
|
|
||||||
+ tristate "MediaTek XFI T-PHY Driver"
|
|
||||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
|
||||||
+ depends on OF && OF_ADDRESS
|
|
||||||
+ depends on HAS_IOMEM
|
|
||||||
+ select GENERIC_PHY
|
|
||||||
+ help
|
|
||||||
+ Say 'Y' here to add support for MediaTek XFI T-PHY driver.
|
|
||||||
+ The driver provides access to the Ethernet SerDes T-PHY supporting
|
|
||||||
+ 1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
|
|
||||||
+ via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
|
|
||||||
+
|
|
||||||
config PHY_MTK_TPHY
|
|
||||||
tristate "MediaTek T-PHY Driver"
|
|
||||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
|
||||||
--- a/drivers/phy/mediatek/Makefile
|
|
||||||
+++ b/drivers/phy/mediatek/Makefile
|
|
||||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-p
|
|
||||||
obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
|
|
||||||
obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
|
|
||||||
obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
|
|
||||||
+obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
|
|
||||||
|
|
||||||
phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
|
|
||||||
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
|
|
||||||
@@ -0,0 +1,393 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
+/* MediaTek 10GE SerDes PHY driver
|
|
||||||
+ *
|
|
||||||
+ * Copyright (c) 2024 Daniel Golle <daniel@makrotopia.org>
|
|
||||||
+ * Bc-bocun Chen <bc-bocun.chen@mediatek.com>
|
|
||||||
+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
|
|
||||||
+ * Copyright (c) 2022 MediaTek Inc.
|
|
||||||
+ * Author: Henry Yen <henry.yen@mediatek.com>
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <linux/module.h>
|
|
||||||
+#include <linux/device.h>
|
|
||||||
+#include <linux/platform_device.h>
|
|
||||||
+#include <linux/of.h>
|
|
||||||
+#include <linux/io.h>
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
+#include <linux/reset.h>
|
|
||||||
+#include <linux/phy.h>
|
|
||||||
+#include <linux/phy/phy.h>
|
|
||||||
+
|
|
||||||
+#define MTK_XFI_TPHY_NUM_CLOCKS 2
|
|
||||||
+
|
|
||||||
+#define REG_DIG_GLB_70 0x0070
|
|
||||||
+#define XTP_PCS_RX_EQ_IN_PROGRESS(x) FIELD_PREP(GENMASK(25, 24), (x))
|
|
||||||
+#define XTP_PCS_MODE_MASK GENMASK(17, 16)
|
|
||||||
+#define XTP_PCS_MODE(x) FIELD_PREP(GENMASK(17, 16), (x))
|
|
||||||
+#define XTP_PCS_RST_B BIT(15)
|
|
||||||
+#define XTP_FRC_PCS_RST_B BIT(14)
|
|
||||||
+#define XTP_PCS_PWD_SYNC_MASK GENMASK(13, 12)
|
|
||||||
+#define XTP_PCS_PWD_SYNC(x) FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
|
|
||||||
+#define XTP_PCS_PWD_ASYNC_MASK GENMASK(11, 10)
|
|
||||||
+#define XTP_PCS_PWD_ASYNC(x) FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
|
|
||||||
+#define XTP_FRC_PCS_PWD_ASYNC BIT(8)
|
|
||||||
+#define XTP_PCS_UPDT BIT(4)
|
|
||||||
+#define XTP_PCS_IN_FR_RG BIT(0)
|
|
||||||
+
|
|
||||||
+#define REG_DIG_GLB_F4 0x00f4
|
|
||||||
+#define XFI_DPHY_PCS_SEL BIT(0)
|
|
||||||
+#define XFI_DPHY_PCS_SEL_SGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
|
|
||||||
+#define XFI_DPHY_PCS_SEL_USXGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
|
|
||||||
+#define XFI_DPHY_AD_SGDT_FRC_EN BIT(5)
|
|
||||||
+
|
|
||||||
+#define REG_DIG_LN_TRX_40 0x3040
|
|
||||||
+#define XTP_LN_FRC_TX_DATA_EN BIT(29)
|
|
||||||
+#define XTP_LN_TX_DATA_EN BIT(28)
|
|
||||||
+
|
|
||||||
+#define REG_DIG_LN_TRX_B0 0x30b0
|
|
||||||
+#define XTP_LN_FRC_TX_MACCK_EN BIT(5)
|
|
||||||
+#define XTP_LN_TX_MACCK_EN BIT(4)
|
|
||||||
+
|
|
||||||
+#define REG_ANA_GLB_D0 0x90d0
|
|
||||||
+#define XTP_GLB_USXGMII_SEL_MASK GENMASK(3, 1)
|
|
||||||
+#define XTP_GLB_USXGMII_SEL(x) FIELD_PREP(GENMASK(3, 1), (x))
|
|
||||||
+#define XTP_GLB_USXGMII_EN BIT(0)
|
|
||||||
+
|
|
||||||
+struct mtk_xfi_tphy {
|
|
||||||
+ void __iomem *base;
|
|
||||||
+ struct device *dev;
|
|
||||||
+ struct reset_control *reset;
|
|
||||||
+ struct clk_bulk_data clocks[MTK_XFI_TPHY_NUM_CLOCKS];
|
|
||||||
+ bool da_war;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
|
|
||||||
+ u32 value)
|
|
||||||
+{
|
|
||||||
+ iowrite32(value, xfi_tphy->base + reg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
|
|
||||||
+ u32 clr, u32 set)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = ioread32(xfi_tphy->base + reg);
|
|
||||||
+ val &= ~clr;
|
|
||||||
+ val |= set;
|
|
||||||
+ iowrite32(val, xfi_tphy->base + reg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
|
|
||||||
+ u32 set)
|
|
||||||
+{
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
|
|
||||||
+ u32 clr)
|
|
||||||
+{
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
|
|
||||||
+ phy_interface_t interface)
|
|
||||||
+{
|
|
||||||
+ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
|
|
||||||
+ bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
|
|
||||||
+ interface == PHY_INTERFACE_MODE_SGMII);
|
|
||||||
+ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
|
|
||||||
+ interface == PHY_INTERFACE_MODE_USXGMII);
|
|
||||||
+ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
|
|
||||||
+ bool is_xgmii = (is_10g || is_5g);
|
|
||||||
+
|
|
||||||
+ dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
|
|
||||||
+
|
|
||||||
+ /* Setup PLL setting */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
|
|
||||||
+ 0x140000);
|
|
||||||
+
|
|
||||||
+ /* Setup RXFE BW setting */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
|
|
||||||
+ is_5g ? 0x800 : 0x400);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
|
|
||||||
+
|
|
||||||
+ /* Setup RX CDR setting */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
|
|
||||||
+ 0x7000400);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
|
|
||||||
+ 0x1000100);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
|
|
||||||
+ is_5g ? 0x1010 : 0x0);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
|
|
||||||
+ is_5g ? 0x30100 :
|
|
||||||
+ 0x100);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
|
|
||||||
+ is_5g ? 0x40000 :
|
|
||||||
+ 0x20000);
|
|
||||||
+
|
|
||||||
+ /* Setting RXFE adaptation range setting */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
|
|
||||||
+ 0x6e0000);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
|
|
||||||
+ if (is_10g)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
|
|
||||||
+ else if (is_5g)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
|
|
||||||
+ else if (is_2p5g)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
|
|
||||||
+ else
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
|
|
||||||
+
|
|
||||||
+ /* Force SGDT_OUT off and select PCS */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
|
|
||||||
+ XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
|
|
||||||
+ XFI_DPHY_AD_SGDT_FRC_EN |
|
|
||||||
+ (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
|
|
||||||
+ XFI_DPHY_PCS_SEL_SGMII));
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ /* Force GLB_CKDET_OUT */
|
|
||||||
+ mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
|
|
||||||
+
|
|
||||||
+ /* Force AEQ on */
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
|
|
||||||
+ XTP_PCS_RX_EQ_IN_PROGRESS(2) |
|
|
||||||
+ XTP_PCS_PWD_SYNC(2) |
|
|
||||||
+ XTP_PCS_PWD_ASYNC(2));
|
|
||||||
+
|
|
||||||
+ usleep_range(1, 5);
|
|
||||||
+ writel(XTP_LN_FRC_TX_DATA_EN, xfi_tphy->base + REG_DIG_LN_TRX_40);
|
|
||||||
+
|
|
||||||
+ /* Setup TX DA default value */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
|
|
||||||
+
|
|
||||||
+ /* Setup RG default value */
|
|
||||||
+ if (is_xgmii) {
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
|
|
||||||
+ if (interface == PHY_INTERFACE_MODE_USXGMII)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
|
|
||||||
+ else
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
|
|
||||||
+ } else {
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (is_1g)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
|
|
||||||
+
|
|
||||||
+ /* Setup RX EQ initial value */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
|
|
||||||
+ (interface != PHY_INTERFACE_MODE_10GBASER) ?
|
|
||||||
+ 0xa8000000 : 0x0);
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
|
|
||||||
+ (interface != PHY_INTERFACE_MODE_10GBASER) ?
|
|
||||||
+ 0xaa : 0x0);
|
|
||||||
+
|
|
||||||
+ if (is_xgmii)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
|
|
||||||
+ else if (is_2p5g)
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
|
|
||||||
+ else
|
|
||||||
+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
|
|
||||||
+
|
|
||||||
+ if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
|
|
||||||
+
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
|
|
||||||
+ 0x50000);
|
|
||||||
+
|
|
||||||
+ /* Setup PHYA speed */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
|
|
||||||
+ XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
|
|
||||||
+ is_10g ? XTP_GLB_USXGMII_SEL(0) :
|
|
||||||
+ is_5g ? XTP_GLB_USXGMII_SEL(1) :
|
|
||||||
+ is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
|
|
||||||
+ XTP_GLB_USXGMII_SEL(3));
|
|
||||||
+ mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
|
|
||||||
+
|
|
||||||
+ /* Release reset */
|
|
||||||
+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
|
|
||||||
+ XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
|
|
||||||
+ usleep_range(150, 500);
|
|
||||||
+
|
|
||||||
+ /* Switch to P0 */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
|
|
||||||
+ XTP_PCS_PWD_SYNC_MASK |
|
|
||||||
+ XTP_PCS_PWD_ASYNC_MASK,
|
|
||||||
+ XTP_FRC_PCS_PWD_ASYNC |
|
|
||||||
+ XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
|
|
||||||
+ usleep_range(1, 5);
|
|
||||||
+
|
|
||||||
+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
|
|
||||||
+ usleep_range(15, 50);
|
|
||||||
+
|
|
||||||
+ if (is_xgmii) {
|
|
||||||
+ /* Switch to Gen3 */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
|
|
||||||
+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
|
|
||||||
+ XTP_PCS_MODE(2) | XTP_PCS_UPDT);
|
|
||||||
+ } else {
|
|
||||||
+ /* Switch to Gen2 */
|
|
||||||
+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
|
|
||||||
+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
|
|
||||||
+ XTP_PCS_MODE(1) | XTP_PCS_UPDT);
|
|
||||||
+ }
|
|
||||||
+ usleep_range(1, 5);
|
|
||||||
+
|
|
||||||
+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
|
|
||||||
+
|
|
||||||
+ usleep_range(100, 500);
|
|
||||||
+
|
|
||||||
+ /* Enable MAC CK */
|
|
||||||
+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
|
|
||||||
+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
|
|
||||||
+
|
|
||||||
+ /* Enable TX data */
|
|
||||||
+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
|
|
||||||
+ XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
|
|
||||||
+ usleep_range(400, 1000);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
|
|
||||||
+ submode)
|
|
||||||
+{
|
|
||||||
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
|
||||||
+
|
|
||||||
+ if (mode != PHY_MODE_ETHERNET)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ switch (submode) {
|
|
||||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
|
||||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ case PHY_INTERFACE_MODE_5GBASER:
|
|
||||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
|
||||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
|
||||||
+ mtk_xfi_tphy_setup(xfi_tphy, submode);
|
|
||||||
+ return 0;
|
|
||||||
+ default:
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int mtk_xfi_tphy_reset(struct phy *phy)
|
|
||||||
+{
|
|
||||||
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
|
||||||
+
|
|
||||||
+ reset_control_assert(xfi_tphy->reset);
|
|
||||||
+ usleep_range(100, 500);
|
|
||||||
+ reset_control_deassert(xfi_tphy->reset);
|
|
||||||
+ usleep_range(1, 10);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int mtk_xfi_tphy_power_on(struct phy *phy)
|
|
||||||
+{
|
|
||||||
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
|
||||||
+
|
|
||||||
+ return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int mtk_xfi_tphy_power_off(struct phy *phy)
|
|
||||||
+{
|
|
||||||
+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
|
|
||||||
+
|
|
||||||
+ clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct phy_ops mtk_xfi_tphy_ops = {
|
|
||||||
+ .power_on = mtk_xfi_tphy_power_on,
|
|
||||||
+ .power_off = mtk_xfi_tphy_power_off,
|
|
||||||
+ .set_mode = mtk_xfi_tphy_set_mode,
|
|
||||||
+ .reset = mtk_xfi_tphy_reset,
|
|
||||||
+ .owner = THIS_MODULE,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct device_node *np = pdev->dev.of_node;
|
|
||||||
+ struct phy_provider *phy_provider;
|
|
||||||
+ struct mtk_xfi_tphy *xfi_tphy;
|
|
||||||
+ struct phy *phy;
|
|
||||||
+
|
|
||||||
+ if (!np)
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
|
|
||||||
+ if (!xfi_tphy)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
|
|
||||||
+ if (!xfi_tphy->base)
|
|
||||||
+ return -EIO;
|
|
||||||
+
|
|
||||||
+ xfi_tphy->dev = &pdev->dev;
|
|
||||||
+
|
|
||||||
+ xfi_tphy->clocks[0].id = "topxtal";
|
|
||||||
+ xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
|
|
||||||
+ if (IS_ERR(xfi_tphy->clocks[0].clk))
|
|
||||||
+ return PTR_ERR(xfi_tphy->clocks[0].clk);
|
|
||||||
+
|
|
||||||
+ xfi_tphy->clocks[1].id = "xfipll";
|
|
||||||
+ xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
|
|
||||||
+ if (IS_ERR(xfi_tphy->clocks[1].clk))
|
|
||||||
+ return PTR_ERR(xfi_tphy->clocks[1].clk);
|
|
||||||
+
|
|
||||||
+ xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
|
||||||
+ if (IS_ERR(xfi_tphy->reset))
|
|
||||||
+ return PTR_ERR(xfi_tphy->reset);
|
|
||||||
+
|
|
||||||
+ xfi_tphy->da_war = of_property_read_bool(np,
|
|
||||||
+ "mediatek,usxgmii-performance-errata");
|
|
||||||
+
|
|
||||||
+ phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
|
|
||||||
+ if (IS_ERR(phy))
|
|
||||||
+ return PTR_ERR(phy);
|
|
||||||
+
|
|
||||||
+ phy_set_drvdata(phy, xfi_tphy);
|
|
||||||
+
|
|
||||||
+ phy_provider = devm_of_phy_provider_register(&pdev->dev,
|
|
||||||
+ of_phy_simple_xlate);
|
|
||||||
+
|
|
||||||
+ return PTR_ERR_OR_ZERO(phy_provider);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct of_device_id mtk_xfi_tphy_match[] = {
|
|
||||||
+ { .compatible = "mediatek,mt7988-xfi-tphy", },
|
|
||||||
+ { }
|
|
||||||
+};
|
|
||||||
+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
|
|
||||||
+
|
|
||||||
+static struct platform_driver mtk_xfi_tphy_driver = {
|
|
||||||
+ .probe = mtk_xfi_tphy_probe,
|
|
||||||
+ .driver = {
|
|
||||||
+ .name = "mtk-xfi-tphy",
|
|
||||||
+ .of_match_table = mtk_xfi_tphy_match,
|
|
||||||
+ },
|
|
||||||
+};
|
|
||||||
+module_platform_driver(mtk_xfi_tphy_driver);
|
|
||||||
+
|
|
||||||
+MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
|
|
||||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
|
||||||
+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen@mediatek.com>");
|
|
||||||
+MODULE_LICENSE("GPL");
|
|
@ -32,7 +32,7 @@ Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -17716,6 +17716,13 @@ L: netdev@vger.kernel.org
|
@@ -17717,6 +17717,13 @@ L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/ethernet/qualcomm/emac/
|
F: drivers/net/ethernet/qualcomm/emac/
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -17722,6 +17722,7 @@ L: netdev@vger.kernel.org
|
@@ -17723,6 +17723,7 @@ L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/net/qcom,ipq4019-ess-edma.yaml
|
F: Documentation/devicetree/bindings/net/qcom,ipq4019-ess-edma.yaml
|
||||||
F: drivers/net/ethernet/qualcomm/ipqess/
|
F: drivers/net/ethernet/qualcomm/ipqess/
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/sfp.c
|
--- a/drivers/net/phy/sfp.c
|
||||||
+++ b/drivers/net/phy/sfp.c
|
+++ b/drivers/net/phy/sfp.c
|
||||||
@@ -1570,6 +1570,10 @@ static void sfp_hwmon_probe(struct work_
|
@@ -1571,6 +1571,10 @@ static void sfp_hwmon_probe(struct work_
|
||||||
struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work);
|
struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
|||||||
/* hwmon interface needs to access 16bit registers in atomic way to
|
/* hwmon interface needs to access 16bit registers in atomic way to
|
||||||
* guarantee coherency of the diagnostic monitoring data. If it is not
|
* guarantee coherency of the diagnostic monitoring data. If it is not
|
||||||
* possible to guarantee coherency because EEPROM is broken in such way
|
* possible to guarantee coherency because EEPROM is broken in such way
|
||||||
@@ -2430,6 +2434,13 @@ static void sfp_sm_module(struct sfp *sf
|
@@ -2433,6 +2437,13 @@ static void sfp_sm_module(struct sfp *sf
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
|||||||
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
|
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
|
||||||
{
|
{
|
||||||
mdiobus_unregister(sfp->i2c_mii);
|
mdiobus_unregister(sfp->i2c_mii);
|
||||||
@@ -1888,9 +1965,15 @@ static void sfp_sm_fault(struct sfp *sfp
|
@@ -1889,9 +1966,15 @@ static void sfp_sm_fault(struct sfp *sfp
|
||||||
|
|
||||||
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
|
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
DRM DRIVERS FOR STI
|
DRM DRIVERS FOR STI
|
||||||
M: Alain Volmat <alain.volmat@foss.st.com>
|
M: Alain Volmat <alain.volmat@foss.st.com>
|
||||||
L: dri-devel@lists.freedesktop.org
|
L: dri-devel@lists.freedesktop.org
|
||||||
@@ -16016,6 +16024,13 @@ F: Documentation/i2c/busses/i2c-ocores.r
|
@@ -16017,6 +16025,13 @@ F: Documentation/i2c/busses/i2c-ocores.r
|
||||||
F: drivers/i2c/busses/i2c-ocores.c
|
F: drivers/i2c/busses/i2c-ocores.c
|
||||||
F: include/linux/platform_data/i2c-ocores.h
|
F: include/linux/platform_data/i2c-ocores.h
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
OPENRISC ARCHITECTURE
|
OPENRISC ARCHITECTURE
|
||||||
M: Jonas Bonn <jonas@southpole.se>
|
M: Jonas Bonn <jonas@southpole.se>
|
||||||
M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
||||||
@@ -16427,6 +16442,14 @@ S: Maintained
|
@@ -16428,6 +16443,14 @@ S: Maintained
|
||||||
F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
|
F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
|
||||||
F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
|
F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
PCI DRIVER FOR RENESAS R-CAR
|
PCI DRIVER FOR RENESAS R-CAR
|
||||||
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||||
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||||
@@ -16658,7 +16681,7 @@ M: Daire McNamara <daire.mcnamara@microc
|
@@ -16659,7 +16682,7 @@ M: Daire McNamara <daire.mcnamara@microc
|
||||||
L: linux-pci@vger.kernel.org
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/devicetree/bindings/pci/microchip*
|
F: Documentation/devicetree/bindings/pci/microchip*
|
||||||
@ -65,7 +65,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
|
|
||||||
PCIE DRIVER FOR QUALCOMM MSM
|
PCIE DRIVER FOR QUALCOMM MSM
|
||||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||||
@@ -16682,6 +16705,13 @@ S: Maintained
|
@@ -16683,6 +16706,13 @@ S: Maintained
|
||||||
F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
|
F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
|
||||||
F: drivers/pci/controller/dwc/pcie-uniphier*
|
F: drivers/pci/controller/dwc/pcie-uniphier*
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
PCIE DRIVER FOR ST SPEAR13XX
|
PCIE DRIVER FOR ST SPEAR13XX
|
||||||
M: Pratyush Anand <pratyush.anand@gmail.com>
|
M: Pratyush Anand <pratyush.anand@gmail.com>
|
||||||
L: linux-pci@vger.kernel.org
|
L: linux-pci@vger.kernel.org
|
||||||
@@ -18454,7 +18484,7 @@ F: drivers/char/hw_random/mpfs-rng.c
|
@@ -18455,7 +18485,7 @@ F: drivers/char/hw_random/mpfs-rng.c
|
||||||
F: drivers/clk/microchip/clk-mpfs*.c
|
F: drivers/clk/microchip/clk-mpfs*.c
|
||||||
F: drivers/i2c/busses/i2c-microchip-corei2c.c
|
F: drivers/i2c/busses/i2c-microchip-corei2c.c
|
||||||
F: drivers/mailbox/mailbox-mpfs.c
|
F: drivers/mailbox/mailbox-mpfs.c
|
||||||
@ -88,7 +88,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
F: drivers/pwm/pwm-microchip-core.c
|
F: drivers/pwm/pwm-microchip-core.c
|
||||||
F: drivers/reset/reset-mpfs.c
|
F: drivers/reset/reset-mpfs.c
|
||||||
F: drivers/rtc/rtc-mpfs.c
|
F: drivers/rtc/rtc-mpfs.c
|
||||||
@@ -20435,6 +20465,15 @@ M: Ion Badulescu <ionut@badula.org>
|
@@ -20436,6 +20466,15 @@ M: Ion Badulescu <ionut@badula.org>
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/net/ethernet/adaptec/starfire*
|
F: drivers/net/ethernet/adaptec/starfire*
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
STARFIVE CRYPTO DRIVER
|
STARFIVE CRYPTO DRIVER
|
||||||
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||||
M: William Qiu <william.qiu@starfivetech.com>
|
M: William Qiu <william.qiu@starfivetech.com>
|
||||||
@@ -20473,6 +20512,13 @@ S: Supported
|
@@ -20474,6 +20513,13 @@ S: Supported
|
||||||
F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||||
F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
STARFIVE JH7110 SYSCON
|
STARFIVE JH7110 SYSCON
|
||||||
M: William Qiu <william.qiu@starfivetech.com>
|
M: William Qiu <william.qiu@starfivetech.com>
|
||||||
M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||||
@@ -20520,9 +20566,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
|
@@ -20521,9 +20567,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
|
||||||
|
|
||||||
STARFIVE JH71XX PMU CONTROLLER DRIVER
|
STARFIVE JH71XX PMU CONTROLLER DRIVER
|
||||||
M: Walker Chen <walker.chen@starfivetech.com>
|
M: Walker Chen <walker.chen@starfivetech.com>
|
||||||
@ -130,7 +130,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
|||||||
F: include/dt-bindings/power/starfive,jh7110-pmu.h
|
F: include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||||
|
|
||||||
STARFIVE SOC DRIVERS
|
STARFIVE SOC DRIVERS
|
||||||
@@ -20530,7 +20577,13 @@ M: Conor Dooley <conor@kernel.org>
|
@@ -20531,7 +20578,13 @@ M: Conor Dooley <conor@kernel.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||||
F: Documentation/devicetree/bindings/soc/starfive/
|
F: Documentation/devicetree/bindings/soc/starfive/
|
||||||
|
@ -20,7 +20,7 @@ Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
|||||||
|
|
||||||
--- a/MAINTAINERS
|
--- a/MAINTAINERS
|
||||||
+++ b/MAINTAINERS
|
+++ b/MAINTAINERS
|
||||||
@@ -20554,7 +20554,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
|
@@ -20555,7 +20555,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
|
||||||
M: Emil Renner Berthing <kernel@esmil.dk>
|
M: Emil Renner Berthing <kernel@esmil.dk>
|
||||||
M: Hal Feng <hal.feng@starfivetech.com>
|
M: Hal Feng <hal.feng@starfivetech.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
Loading…
x
Reference in New Issue
Block a user