Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
7f2aef217e
@ -6,9 +6,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git
|
||||
PKG_SOURCE_DATE:=2025-04-08
|
||||
PKG_SOURCE_VERSION:=9591c9b7578af3548c35bb80cd6c37978669f7c9
|
||||
PKG_MIRROR_HASH:=b5c0024a0c0ebeb61ad6bc037f897685d161f1578aca5a1366dd33603661338b
|
||||
PKG_SOURCE_DATE:=2025-04-15
|
||||
PKG_SOURCE_VERSION:=38a18dc26c9b150f06f56b9c5972d789eb5bc0c4
|
||||
PKG_MIRROR_HASH:=a10a9b524ecd91854265b04819303410ae77e1f5a093f9cc8eb43e25e99c1bae
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
@ -1651,6 +1651,7 @@ endef
|
||||
$(eval $(call KernelPackage,qrtr-mhi))
|
||||
|
||||
define KernelPackage/unix-diag
|
||||
SUBMENU:=$(NETWORK_SUPPORT_MENU)
|
||||
TITLE:=UNIX socket monitoring interface
|
||||
KCONFIG:=CONFIG_UNIX_DIAG
|
||||
FILES:= $(LINUX_DIR)/net/unix/unix_diag.ko
|
||||
@ -1660,6 +1661,7 @@ endef
|
||||
$(eval $(call KernelPackage,unix-diag))
|
||||
|
||||
define KernelPackage/packet-diag
|
||||
SUBMENU:=$(NETWORK_SUPPORT_MENU)
|
||||
TITLE:=Packet sockets monitoring interface
|
||||
KCONFIG:=CONFIG_PACKET_DIAG
|
||||
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
|
||||
+++ 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: drivers/media/i2c/imx415.c
|
||||
|
||||
|
@ -177,7 +177,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
+...
|
||||
--- a/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: drivers/media/i2c/imx477.c
|
||||
|
||||
|
@ -132,7 +132,7 @@ Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
|
||||
+...
|
||||
--- a/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
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
@ -138,7 +138,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
+...
|
||||
--- a/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: drivers/media/i2c/imx519.c
|
||||
|
||||
|
@ -271,7 +271,7 @@ Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
|
||||
+...
|
||||
--- a/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
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
@ -291,7 +291,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
+ };
|
||||
--- a/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
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
@ -67,7 +67,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
+...
|
||||
--- a/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-bu27034.c
|
||||
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -15871,6 +15871,14 @@ S: Maintained
|
||||
@@ -15872,6 +15872,14 @@ S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
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,
|
||||
--- a/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/linux/pwm.h
|
||||
F: include/linux/pwm_backlight.h
|
||||
|
@ -23,7 +23,7 @@ Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
|
||||
--- a/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
|
||||
F: drivers/net/wireless/legacy/ray*
|
||||
|
||||
|
@ -87,7 +87,7 @@ Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
|
||||
+ };
|
||||
--- a/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: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -94,7 +94,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
||||
+
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -18027,6 +18027,11 @@ F: drivers/ras/
|
||||
@@ -18028,6 +18028,11 @@ F: drivers/ras/
|
||||
F: include/linux/ras.h
|
||||
F: include/ras/ras_event.h
|
||||
|
||||
|
@ -25,7 +25,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
||||
|
||||
--- a/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>
|
||||
S: Maintained
|
||||
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
|
||||
+++ 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: drivers/media/i2c/imx477.c
|
||||
|
||||
|
@ -21,7 +21,7 @@ Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
|
||||
|
||||
--- a/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
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
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>
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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 ++++++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
@ -33,7 +35,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -45,7 +47,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
|
||||
.ecc = w25n02kv_ooblayout_ecc,
|
||||
.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),
|
||||
0,
|
||||
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,76 @@
|
||||
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,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;
|
||||
@@ -406,6 +419,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);
|
||||
|
||||
@@ -385,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;
|
||||
@@ -412,15 +417,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
|
||||
@@ -414,6 +414,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)
|
||||
{
|
||||
@@ -429,6 +459,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>
|
||||
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
|
||||
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/
|
||||
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: Willem de Bruijn <willemb@google.com>
|
||||
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
|
||||
+++ 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>
|
||||
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
|
||||
|
||||
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>
|
||||
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: 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
|
||||
+++ 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>
|
||||
Date: Wed, 24 Jan 2024 19:38:01 +0100
|
||||
Subject: [PATCH 3/3] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO
|
||||
node
|
||||
Date: Wed, 31 Jan 2024 03:27:29 +0100
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO node
|
||||
|
||||
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.
|
||||
|
||||
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 ++
|
||||
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))
|
@ -1,5 +1,6 @@
|
||||
From 88806efc034a9830f483963326b99930ad519af1 Mon Sep 17 00:00:00 2001
|
||||
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
|
||||
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")
|
||||
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
|
||||
+++ 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)))
|
||||
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
|
||||
* 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;
|
||||
unsigned int module_power_mW;
|
||||
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)
|
||||
{
|
||||
sfp_fixup_rollball(sfp);
|
||||
@@ -2319,7 +2317,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||
@@ -2320,7 +2318,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||
mask |= SFP_F_RS1;
|
||||
|
||||
sfp->module_t_start_up = T_START_UP;
|
||||
- sfp->module_t_wait = T_WAIT;
|
||||
+ 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,
|
||||
@@ -2556,10 +2554,9 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
|
||||
/* We need to check the TX_FAULT state, which is not defined
|
||||
* 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;
|
||||
|
||||
case SFP_S_WAIT:
|
||||
@@ -2570,8 +2567,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
@@ -2573,8 +2570,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
* deasserting.
|
||||
*/
|
||||
timeout = sfp->module_t_start_up;
|
||||
@ -119,7 +119,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
else
|
||||
timeout = 1;
|
||||
|
||||
@@ -2614,7 +2611,11 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
@@ -2617,7 +2614,11 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
ret = sfp_sm_probe_for_phy(sfp);
|
||||
if (ret == -ENODEV) {
|
||||
if (--sfp->sm_phy_retries) {
|
||||
|
@ -30,7 +30,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/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;
|
||||
unsigned int module_power_mW;
|
||||
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)
|
||||
@@ -2317,6 +2324,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||
@@ -2318,6 +2325,7 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||
mask |= SFP_F_RS1;
|
||||
|
||||
sfp->module_t_start_up = T_START_UP;
|
||||
+ sfp->module_t_wait = T_WAIT;
|
||||
sfp->phy_t_retry = T_PHY_RETRY;
|
||||
|
||||
sfp->tx_fault_ignore = false;
|
||||
@@ -2551,9 +2559,10 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
sfp->state_ignore_mask = 0;
|
||||
@@ -2554,9 +2562,10 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
|
||||
/* We need to check the TX_FAULT state, which is not defined
|
||||
* 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;
|
||||
|
||||
case SFP_S_WAIT:
|
||||
@@ -2567,8 +2576,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
@@ -2570,8 +2579,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
||||
* deasserting.
|
||||
*/
|
||||
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>
|
||||
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
|
||||
|
||||
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: Shawn Guo <shawnguo@kernel.org>
|
||||
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
|
||||
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(+)
|
||||
|
||||
--- 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>
|
||||
Date: Wed, 20 Mar 2024 15:32:18 +0900
|
||||
Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile
|
||||
network
|
||||
Date: Sat, 23 Mar 2024 16:36:09 +0900
|
||||
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_MOBILE for 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
|
||||
@ -21,6 +20,10 @@ port.
|
||||
|
||||
Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
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 +
|
||||
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>
|
||||
Date: Wed, 20 Mar 2024 15:59:06 +0900
|
||||
Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link
|
||||
speed on LAN/WAN
|
||||
Date: Sat, 23 Mar 2024 16:36:10 +0900
|
||||
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_SPEED_* for link speed on
|
||||
LAN/WAN
|
||||
|
||||
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
|
||||
@ -18,8 +18,10 @@ of the ethernet ports in addition to LEDs that indicate link status
|
||||
- 100 Mbps: amber:speed-(lan|wan)-N
|
||||
- 10 Mbps: (none, turned off)
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
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 ++
|
||||
1 file changed, 2 insertions(+)
|
@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/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>
|
||||
S: Maintained
|
||||
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
|
||||
+++ 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),
|
||||
0,
|
||||
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,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, 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;
|
||||
|
||||
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
|
||||
* 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),
|
||||
0,
|
||||
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>
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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 +-
|
||||
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))
|
@ -0,0 +1,79 @@
|
||||
From cf3d39cfd29ab7bcbd6aa79d4a2f132817969e3d Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Tue, 15 Apr 2025 23:16:40 +0200
|
||||
Subject: [PATCH] ARM: 9404/1: arm32: fix boot hang with
|
||||
HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
|
||||
It was reported that some SoC (mvebu based for example) hang on kernel
|
||||
loading. A variant of the feature was present in OpenWrt from long ago
|
||||
and adding the additional entry with KEEP, fix the problem.
|
||||
|
||||
Fixes: ed0f94102251 ("ARM: 9404/1: arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION")
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
arch/arm/include/asm/vmlinux.lds.h | 10 +++++-----
|
||||
arch/arm/kernel/vmlinux.lds.S | 4 ++--
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/arch/arm/include/asm/vmlinux.lds.h
|
||||
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
||||
@@ -48,7 +48,7 @@
|
||||
#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); \
|
||||
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||
@@ -104,13 +104,13 @@ SECTIONS
|
||||
}
|
||||
.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
|
@ -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
|
||||
+++ 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: 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
|
||||
+++ 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,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17716,6 +17716,13 @@ L: netdev@vger.kernel.org
|
||||
@@ -17717,6 +17717,13 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/qualcomm/emac/
|
||||
|
||||
|
@ -64,7 +64,7 @@ Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17722,6 +17722,7 @@ L: netdev@vger.kernel.org
|
||||
@@ -17723,6 +17723,7 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/qcom,ipq4019-ess-edma.yaml
|
||||
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
|
||||
+++ b/drivers/net/phy/sfp.c
|
||||
@@ -1570,6 +1570,10 @@ static void sfp_hwmon_probe(struct work_
|
||||
@@ -1568,6 +1568,10 @@ static void sfp_hwmon_probe(struct work_
|
||||
struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work);
|
||||
int err;
|
||||
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
||||
|
||||
--- a/drivers/net/phy/sfp.c
|
||||
+++ b/drivers/net/phy/sfp.c
|
||||
@@ -676,10 +676,64 @@ static int sfp_i2c_write(struct sfp *sfp
|
||||
@@ -673,10 +673,64 @@ static int sfp_i2c_write(struct sfp *sfp
|
||||
return ret == ARRAY_SIZE(msgs) ? len : 0;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
||||
|
||||
sfp->i2c = i2c;
|
||||
sfp->read = sfp_i2c_read;
|
||||
@@ -711,6 +765,29 @@ static int sfp_i2c_mdiobus_create(struct
|
||||
@@ -708,6 +762,29 @@ static int sfp_i2c_mdiobus_create(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
|
||||
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
|
||||
{
|
||||
mdiobus_unregister(sfp->i2c_mii);
|
||||
@@ -1888,9 +1965,15 @@ static void sfp_sm_fault(struct sfp *sfp
|
||||
@@ -1886,9 +1963,15 @@ static void sfp_sm_fault(struct sfp *sfp
|
||||
|
||||
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
|
||||
{
|
||||
|
33
target/linux/rockchip/armv8/base-files/etc/init.d/phy-leds
Executable file
33
target/linux/rockchip/armv8/base-files/etc/init.d/phy-leds
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=30
|
||||
|
||||
led_set() {
|
||||
local path="/sys/class/leds/$1"
|
||||
local params="$2"
|
||||
local value="$3"
|
||||
|
||||
[ -d "$path" ] || return 1
|
||||
|
||||
for param in $params; do
|
||||
echo "$value" > "$path/$param"
|
||||
done
|
||||
}
|
||||
|
||||
boot() {
|
||||
case "$(board_name)" in
|
||||
friendlyarm,nanopi-r3s|\
|
||||
friendlyarm,nanopi-r4s)
|
||||
led_set "enp1s0-1::lan" "link_10 link_100 link_1000" "1"
|
||||
led_set "enp1s0-1::lan" "rx tx" "0"
|
||||
led_set "enp1s0-2::lan" "link_10 link_100 link_1000" "0"
|
||||
led_set "enp1s0-2::lan" "rx tx" "1"
|
||||
;;
|
||||
huake,guangmiao-g4c)
|
||||
led_set "enp1s0-0::lan" "link_10 link_100 link_1000" "1"
|
||||
led_set "enp1s0-0::lan" "rx tx" "0"
|
||||
led_set "enp1s0-1::lan" "link_10 link_100 link_1000" "0"
|
||||
led_set "enp1s0-1::lan" "rx tx" "1"
|
||||
;;
|
||||
esac
|
||||
}
|
@ -139,7 +139,7 @@ define Device/friendlyarm_nanopi-r3s
|
||||
DEVICE_MODEL := NanoPi R3S
|
||||
SOC := rk3566
|
||||
BOOT_FLOW := pine64-img
|
||||
DEVICE_PACKAGES := kmod-r8168
|
||||
DEVICE_PACKAGES := kmod-r8169
|
||||
endef
|
||||
TARGET_DEVICES += friendlyarm_nanopi-r3s
|
||||
|
||||
@ -212,7 +212,7 @@ define Device/huake_guangmiao-g4c
|
||||
DEVICE_MODEL := GuangMiao G4C
|
||||
SOC := rk3399
|
||||
BOOT_FLOW := pine64-bin
|
||||
DEVICE_PACKAGES := kmod-r8168
|
||||
DEVICE_PACKAGES := kmod-r8169
|
||||
endef
|
||||
TARGET_DEVICES += huake_guangmiao-g4c
|
||||
|
||||
|
@ -27,7 +27,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
DRM DRIVERS FOR STI
|
||||
M: Alain Volmat <alain.volmat@foss.st.com>
|
||||
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: include/linux/platform_data/i2c-ocores.h
|
||||
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
OPENRISC ARCHITECTURE
|
||||
M: Jonas Bonn <jonas@southpole.se>
|
||||
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: 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
|
||||
M: Marek Vasut <marek.vasut+renesas@gmail.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
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/microchip*
|
||||
@ -65,7 +65,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
|
||||
PCIE DRIVER FOR QUALCOMM MSM
|
||||
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: drivers/pci/controller/dwc/pcie-uniphier*
|
||||
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
PCIE DRIVER FOR ST SPEAR13XX
|
||||
M: Pratyush Anand <pratyush.anand@gmail.com>
|
||||
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/i2c/busses/i2c-microchip-corei2c.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/reset/reset-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
|
||||
F: drivers/net/ethernet/adaptec/starfire*
|
||||
|
||||
@ -104,7 +104,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
STARFIVE CRYPTO DRIVER
|
||||
M: Jia Jie Ho <jiajie.ho@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: drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
|
||||
@ -118,7 +118,7 @@ Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
STARFIVE JH7110 SYSCON
|
||||
M: William Qiu <william.qiu@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
|
||||
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
|
||||
|
||||
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
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||
F: Documentation/devicetree/bindings/soc/starfive/
|
||||
|
@ -20,7 +20,7 @@ Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
|
||||
|
||||
--- a/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: Hal Feng <hal.feng@starfivetech.com>
|
||||
S: Maintained
|
||||
|
Loading…
x
Reference in New Issue
Block a user