mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 14:23:38 +00:00
generic: sync kernel 6.6 from upstream
This commit is contained in:
parent
a9dd459fa8
commit
b75357d1a0
@ -0,0 +1,58 @@
|
||||
From 443df175be581618d6ff781dc3af3aa1a9ba789d Mon Sep 17 00:00:00 2001
|
||||
From: Tony Ambardar <Tony.Ambardar@gmail.com>
|
||||
Date: Fri, 31 May 2024 23:55:55 -0700
|
||||
Subject: [PATCH 1/2] compiler_types.h: Define __retain for
|
||||
__attribute__((__retain__))
|
||||
|
||||
Some code includes the __used macro to prevent functions and data from
|
||||
being optimized out. This macro implements __attribute__((__used__)), which
|
||||
operates at the compiler and IR-level, and so still allows a linker to
|
||||
remove objects intended to be kept.
|
||||
|
||||
Compilers supporting __attribute__((__retain__)) can address this gap by
|
||||
setting the flag SHF_GNU_RETAIN on the section of a function/variable,
|
||||
indicating to the linker the object should be retained. This attribute is
|
||||
available since gcc 11, clang 13, and binutils 2.36.
|
||||
|
||||
Provide a __retain macro implementing __attribute__((__retain__)), whose
|
||||
first user will be the '__bpf_kfunc' tag.
|
||||
|
||||
Link: https://lore.kernel.org/bpf/ZlmGoT9KiYLZd91S@krava/T/
|
||||
Cc: stable@vger.kernel.org # v6.6+
|
||||
Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
|
||||
---
|
||||
include/linux/compiler_types.h | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
--- a/include/linux/compiler_types.h
|
||||
+++ b/include/linux/compiler_types.h
|
||||
@@ -145,6 +145,29 @@ static inline void __chk_io_ptr(const vo
|
||||
#define __has_builtin(x) (0)
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * Annotating a function/variable with __retain tells the compiler to place
|
||||
+ * the object in its own section and set the flag SHF_GNU_RETAIN. This flag
|
||||
+ * instructs the linker to retain the object during garbage-cleanup or LTO
|
||||
+ * phases.
|
||||
+ *
|
||||
+ * Note that the __used macro is also used to prevent functions or data
|
||||
+ * being optimized out, but operates at the compiler/IR-level and may still
|
||||
+ * allow unintended removal of objects during linking.
|
||||
+ *
|
||||
+ * Optional: only supported since gcc >= 11, clang >= 13
|
||||
+ *
|
||||
+ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-retain-function-attribute
|
||||
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#retain
|
||||
+ */
|
||||
+#if __has_attribute(__retain__) && \
|
||||
+ (defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || \
|
||||
+ defined(CONFIG_LTO_CLANG))
|
||||
+# define __retain __attribute__((__retain__))
|
||||
+#else
|
||||
+# define __retain
|
||||
+#endif
|
||||
+
|
||||
/* Compiler specific macros. */
|
||||
#ifdef __clang__
|
||||
#include <linux/compiler-clang.h>
|
@ -0,0 +1,65 @@
|
||||
From ac507ed9882fd91a94657d68fe9ceac04b957103 Mon Sep 17 00:00:00 2001
|
||||
From: Tony Ambardar <Tony.Ambardar@gmail.com>
|
||||
Date: Sat, 1 Jun 2024 00:00:21 -0700
|
||||
Subject: [PATCH 2/2] bpf: Harden __bpf_kfunc tag against linker kfunc removal
|
||||
|
||||
BPF kfuncs are often not directly referenced and may be inadvertently
|
||||
removed by optimization steps during kernel builds, thus the __bpf_kfunc
|
||||
tag mitigates against this removal by including the __used macro. However,
|
||||
this macro alone does not prevent removal during linking, and may still
|
||||
yield build warnings (e.g. on mips64el):
|
||||
|
||||
LD vmlinux
|
||||
BTFIDS vmlinux
|
||||
WARN: resolve_btfids: unresolved symbol bpf_verify_pkcs7_signature
|
||||
WARN: resolve_btfids: unresolved symbol bpf_lookup_user_key
|
||||
WARN: resolve_btfids: unresolved symbol bpf_lookup_system_key
|
||||
WARN: resolve_btfids: unresolved symbol bpf_key_put
|
||||
WARN: resolve_btfids: unresolved symbol bpf_iter_task_next
|
||||
WARN: resolve_btfids: unresolved symbol bpf_iter_css_task_new
|
||||
WARN: resolve_btfids: unresolved symbol bpf_get_file_xattr
|
||||
WARN: resolve_btfids: unresolved symbol bpf_ct_insert_entry
|
||||
WARN: resolve_btfids: unresolved symbol bpf_cgroup_release
|
||||
WARN: resolve_btfids: unresolved symbol bpf_cgroup_from_id
|
||||
WARN: resolve_btfids: unresolved symbol bpf_cgroup_acquire
|
||||
WARN: resolve_btfids: unresolved symbol bpf_arena_free_pages
|
||||
NM System.map
|
||||
SORTTAB vmlinux
|
||||
OBJCOPY vmlinux.32
|
||||
|
||||
Update the __bpf_kfunc tag to better guard against linker optimization by
|
||||
including the new __retain compiler macro, which fixes the warnings above.
|
||||
|
||||
Verify the __retain macro with readelf by checking object flags for 'R':
|
||||
|
||||
$ readelf -Wa kernel/trace/bpf_trace.o
|
||||
Section Headers:
|
||||
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
...
|
||||
[178] .text.bpf_key_put PROGBITS 00000000 6420 0050 00 AXR 0 0 8
|
||||
...
|
||||
Key to Flags:
|
||||
...
|
||||
R (retain), D (mbind), p (processor specific)
|
||||
|
||||
Link: https://lore.kernel.org/bpf/ZlmGoT9KiYLZd91S@krava/T/
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/r/202401211357.OCX9yllM-lkp@intel.com/
|
||||
Fixes: 57e7c169cd6a ("bpf: Add __bpf_kfunc tag for marking kernel functions as kfuncs")
|
||||
Cc: stable@vger.kernel.org # v6.6+
|
||||
Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
|
||||
---
|
||||
include/linux/btf.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/include/linux/btf.h
|
||||
+++ b/include/linux/btf.h
|
||||
@@ -81,7 +81,7 @@
|
||||
* as to avoid issues such as the compiler inlining or eliding either a static
|
||||
* kfunc, or a global kfunc in an LTO build.
|
||||
*/
|
||||
-#define __bpf_kfunc __used noinline
|
||||
+#define __bpf_kfunc __used __retain noinline
|
||||
|
||||
/*
|
||||
* Return the name of the passed struct, if exists, or halt the build if for
|
@ -0,0 +1,51 @@
|
||||
From 65033574ade97afccba074d837fd269903a83a9a Mon Sep 17 00:00:00 2001
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Date: Thu, 5 Oct 2023 16:40:30 +0100
|
||||
Subject: [PATCH] arm64: swiotlb: Reduce the default size if no ZONE_DMA
|
||||
bouncing needed
|
||||
|
||||
With CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC enabled, the arm64 kernel still
|
||||
allocates the default SWIOTLB buffer (64MB) even if ZONE_DMA is disabled
|
||||
or all the RAM fits into this zone. However, this potentially wastes a
|
||||
non-negligible amount of memory on platforms with little RAM.
|
||||
|
||||
Reduce the SWIOTLB size to 1MB per 1GB of RAM if only needed for
|
||||
kmalloc() buffer bouncing.
|
||||
|
||||
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Suggested-by: Ross Burton <ross.burton@arm.com>
|
||||
Cc: Ross Burton <ross.burton@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
|
||||
---
|
||||
arch/arm64/mm/init.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/arm64/mm/init.c
|
||||
+++ b/arch/arm64/mm/init.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/gfp.h>
|
||||
+#include <linux/math.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/of.h>
|
||||
@@ -493,8 +494,16 @@ void __init mem_init(void)
|
||||
{
|
||||
bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
|
||||
|
||||
- if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC))
|
||||
+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) {
|
||||
+ /*
|
||||
+ * If no bouncing needed for ZONE_DMA, reduce the swiotlb
|
||||
+ * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
|
||||
+ */
|
||||
+ unsigned long size =
|
||||
+ DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
|
||||
+ swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
|
||||
swiotlb = true;
|
||||
+ }
|
||||
|
||||
swiotlb_init(swiotlb, SWIOTLB_VERBOSE);
|
||||
|
@ -0,0 +1,161 @@
|
||||
From 66a5c40f60f5d88ad8d47ba6a4ba05892853fa1f Mon Sep 17 00:00:00 2001
|
||||
From: Tanzir Hasan <tanzirh@google.com>
|
||||
Date: Tue, 26 Dec 2023 18:00:00 +0000
|
||||
Subject: [PATCH] kernel.h: removed REPEAT_BYTE from kernel.h
|
||||
|
||||
This patch creates wordpart.h and includes it in asm/word-at-a-time.h
|
||||
for all architectures. WORD_AT_A_TIME_CONSTANTS depends on kernel.h
|
||||
because of REPEAT_BYTE. Moving this to another header and including it
|
||||
where necessary allows us to not include the bloated kernel.h. Making
|
||||
this implicit dependency on REPEAT_BYTE explicit allows for later
|
||||
improvements in the lib/string.c inclusion list.
|
||||
|
||||
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
|
||||
Signed-off-by: Tanzir Hasan <tanzirh@google.com>
|
||||
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20231226-libstringheader-v6-1-80aa08c7652c@google.com
|
||||
Signed-off-by: Kees Cook <keescook@chromium.org>
|
||||
---
|
||||
arch/arm/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/arm64/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/powerpc/include/asm/word-at-a-time.h | 4 ++--
|
||||
arch/riscv/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/s390/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/sh/include/asm/word-at-a-time.h | 2 ++
|
||||
arch/x86/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/x86/kvm/mmu/mmu.c | 1 +
|
||||
fs/namei.c | 2 +-
|
||||
include/asm-generic/word-at-a-time.h | 3 ++-
|
||||
include/linux/kernel.h | 8 --------
|
||||
include/linux/wordpart.h | 13 +++++++++++++
|
||||
12 files changed, 31 insertions(+), 17 deletions(-)
|
||||
create mode 100644 include/linux/wordpart.h
|
||||
|
||||
--- a/arch/arm/include/asm/word-at-a-time.h
|
||||
+++ b/arch/arm/include/asm/word-at-a-time.h
|
||||
@@ -8,7 +8,8 @@
|
||||
* Little-endian word-at-a-time zero byte handling.
|
||||
* Heavily based on the x86 algorithm.
|
||||
*/
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
struct word_at_a_time {
|
||||
const unsigned long one_bits, high_bits;
|
||||
--- a/arch/arm64/include/asm/word-at-a-time.h
|
||||
+++ b/arch/arm64/include/asm/word-at-a-time.h
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#ifndef __AARCH64EB__
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
struct word_at_a_time {
|
||||
const unsigned long one_bits, high_bits;
|
||||
--- a/arch/powerpc/include/asm/word-at-a-time.h
|
||||
+++ b/arch/powerpc/include/asm/word-at-a-time.h
|
||||
@@ -4,8 +4,8 @@
|
||||
/*
|
||||
* Word-at-a-time interfaces for PowerPC.
|
||||
*/
|
||||
-
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <asm/asm-compat.h>
|
||||
#include <asm/extable.h>
|
||||
|
||||
--- a/arch/sh/include/asm/word-at-a-time.h
|
||||
+++ b/arch/sh/include/asm/word-at-a-time.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
# include <asm-generic/word-at-a-time.h>
|
||||
#else
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
/*
|
||||
* Little-endian version cribbed from x86.
|
||||
*/
|
||||
--- a/arch/x86/include/asm/word-at-a-time.h
|
||||
+++ b/arch/x86/include/asm/word-at-a-time.h
|
||||
@@ -2,7 +2,8 @@
|
||||
#ifndef _ASM_WORD_AT_A_TIME_H
|
||||
#define _ASM_WORD_AT_A_TIME_H
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
/*
|
||||
* This is largely generic for little-endian machines, but the
|
||||
--- a/arch/x86/kvm/mmu/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu/mmu.c
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <linux/kern_levels.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/kthread.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/memtype.h>
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
-#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/filelock.h>
|
||||
#include <linux/namei.h>
|
||||
--- a/include/asm-generic/word-at-a-time.h
|
||||
+++ b/include/asm-generic/word-at-a-time.h
|
||||
@@ -2,7 +2,8 @@
|
||||
#ifndef _ASM_WORD_AT_A_TIME_H
|
||||
#define _ASM_WORD_AT_A_TIME_H
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
--- a/include/linux/kernel.h
|
||||
+++ b/include/linux/kernel.h
|
||||
@@ -38,14 +38,6 @@
|
||||
|
||||
#define STACK_MAGIC 0xdeadbeef
|
||||
|
||||
-/**
|
||||
- * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
- * @x: value to repeat
|
||||
- *
|
||||
- * NOTE: @x is not checked for > 0xff; larger values produce odd results.
|
||||
- */
|
||||
-#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
|
||||
-
|
||||
/* generic data direction definitions */
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
--- /dev/null
|
||||
+++ b/include/linux/wordpart.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+
|
||||
+#ifndef _LINUX_WORDPART_H
|
||||
+#define _LINUX_WORDPART_H
|
||||
+/**
|
||||
+ * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
+ * @x: value to repeat
|
||||
+ *
|
||||
+ * NOTE: @x is not checked for > 0xff; larger values produce odd results.
|
||||
+ */
|
||||
+#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
|
||||
+
|
||||
+#endif // _LINUX_WORDPART_H
|
@ -0,0 +1,107 @@
|
||||
From adeb04362d74188c1e22ccb824b15a0a7b3de2f4 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Date: Wed, 14 Feb 2024 19:26:32 +0200
|
||||
Subject: [PATCH] kernel.h: Move upper_*_bits() and lower_*_bits() to
|
||||
wordpart.h
|
||||
|
||||
The wordpart.h header is collecting APIs related to the handling
|
||||
parts of the word (usually in byte granularity). The upper_*_bits()
|
||||
and lower_*_bits() are good candidates to be moved to there.
|
||||
|
||||
This helps to clean up header dependency hell with regard to kernel.h
|
||||
as the latter gathers completely unrelated stuff together and slows
|
||||
down compilation (especially when it's included into other header).
|
||||
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Link: https://lore.kernel.org/r/20240214172752.3605073-1-andriy.shevchenko@linux.intel.com
|
||||
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Signed-off-by: Kees Cook <keescook@chromium.org>
|
||||
---
|
||||
include/linux/kernel.h | 30 ++----------------------------
|
||||
include/linux/wordpart.h | 29 +++++++++++++++++++++++++++++
|
||||
2 files changed, 31 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/include/linux/kernel.h
|
||||
+++ b/include/linux/kernel.h
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <linux/sprintf.h>
|
||||
#include <linux/static_call_types.h>
|
||||
#include <linux/instruction_pointer.h>
|
||||
+#include <linux/wordpart.h>
|
||||
+
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include <uapi/linux/kernel.h>
|
||||
@@ -57,34 +59,6 @@
|
||||
} \
|
||||
)
|
||||
|
||||
-/**
|
||||
- * upper_32_bits - return bits 32-63 of a number
|
||||
- * @n: the number we're accessing
|
||||
- *
|
||||
- * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
|
||||
- * the "right shift count >= width of type" warning when that quantity is
|
||||
- * 32-bits.
|
||||
- */
|
||||
-#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
-
|
||||
-/**
|
||||
- * lower_32_bits - return bits 0-31 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
|
||||
-
|
||||
-/**
|
||||
- * upper_16_bits - return bits 16-31 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define upper_16_bits(n) ((u16)((n) >> 16))
|
||||
-
|
||||
-/**
|
||||
- * lower_16_bits - return bits 0-15 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define lower_16_bits(n) ((u16)((n) & 0xffff))
|
||||
-
|
||||
struct completion;
|
||||
struct user;
|
||||
|
||||
--- a/include/linux/wordpart.h
|
||||
+++ b/include/linux/wordpart.h
|
||||
@@ -2,6 +2,35 @@
|
||||
|
||||
#ifndef _LINUX_WORDPART_H
|
||||
#define _LINUX_WORDPART_H
|
||||
+
|
||||
+/**
|
||||
+ * upper_32_bits - return bits 32-63 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ *
|
||||
+ * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
|
||||
+ * the "right shift count >= width of type" warning when that quantity is
|
||||
+ * 32-bits.
|
||||
+ */
|
||||
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
+
|
||||
+/**
|
||||
+ * lower_32_bits - return bits 0-31 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
|
||||
+
|
||||
+/**
|
||||
+ * upper_16_bits - return bits 16-31 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define upper_16_bits(n) ((u16)((n) >> 16))
|
||||
+
|
||||
+/**
|
||||
+ * lower_16_bits - return bits 0-15 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define lower_16_bits(n) ((u16)((n) & 0xffff))
|
||||
+
|
||||
/**
|
||||
* REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
* @x: value to repeat
|
@ -0,0 +1,206 @@
|
||||
From 8cd2accb71f5eb8e92d775fc1978d3779875c2e5 Mon Sep 17 00:00:00 2001
|
||||
From: Baoquan He <bhe@redhat.com>
|
||||
Date: Fri, 8 Dec 2023 15:30:34 +0800
|
||||
Subject: [PATCH] mips, kexec: fix the incorrect ifdeffery and dependency of
|
||||
CONFIG_KEXEC
|
||||
|
||||
The select of KEXEC for CRASH_DUMP in kernel/Kconfig.kexec will be
|
||||
dropped, then compiling errors will be triggered if below config items are
|
||||
set:
|
||||
|
||||
===
|
||||
CONFIG_CRASH_CORE=y
|
||||
CONFIG_KEXEC_CORE=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
===
|
||||
|
||||
--------------------------------------------------------------------
|
||||
mipsel-linux-ld: kernel/kexec_core.o: in function `kimage_free':
|
||||
kernel/kexec_core.c:(.text+0x2200): undefined reference to `machine_kexec_cleanup'
|
||||
mipsel-linux-ld: kernel/kexec_core.o: in function `__crash_kexec':
|
||||
kernel/kexec_core.c:(.text+0x2480): undefined reference to `machine_crash_shutdown'
|
||||
mipsel-linux-ld: kernel/kexec_core.c:(.text+0x2488): undefined reference to `machine_kexec'
|
||||
mipsel-linux-ld: kernel/kexec_core.o: in function `kernel_kexec':
|
||||
kernel/kexec_core.c:(.text+0x29b8): undefined reference to `machine_shutdown'
|
||||
mipsel-linux-ld: kernel/kexec_core.c:(.text+0x29c0): undefined reference to `machine_kexec'
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Here, change the dependency of building kexec_core related object files,
|
||||
and the ifdeffery in mips from CONFIG_KEXEC to CONFIG_KEXEC_CORE.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20231208073036.7884-4-bhe@redhat.com
|
||||
Signed-off-by: Baoquan He <bhe@redhat.com>
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202311302042.sn8cDPIX-lkp@intel.com/
|
||||
Cc: Eric DeVolder <eric_devolder@yahoo.com>
|
||||
Cc: Ignat Korchagin <ignat@cloudflare.com>
|
||||
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
arch/mips/cavium-octeon/smp.c | 4 ++--
|
||||
arch/mips/include/asm/kexec.h | 2 +-
|
||||
arch/mips/include/asm/smp-ops.h | 2 +-
|
||||
arch/mips/include/asm/smp.h | 2 +-
|
||||
arch/mips/kernel/Makefile | 2 +-
|
||||
arch/mips/kernel/smp-bmips.c | 4 ++--
|
||||
arch/mips/kernel/smp-cps.c | 10 +++++-----
|
||||
arch/mips/loongson64/reset.c | 4 ++--
|
||||
arch/mips/loongson64/smp.c | 2 +-
|
||||
9 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/arch/mips/cavium-octeon/smp.c
|
||||
+++ b/arch/mips/cavium-octeon/smp.c
|
||||
@@ -422,7 +422,7 @@ static const struct plat_smp_ops octeon_
|
||||
.cpu_disable = octeon_cpu_disable,
|
||||
.cpu_die = octeon_cpu_die,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||
#endif
|
||||
};
|
||||
@@ -502,7 +502,7 @@ static const struct plat_smp_ops octeon_
|
||||
.cpu_disable = octeon_cpu_disable,
|
||||
.cpu_die = octeon_cpu_die,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||
#endif
|
||||
};
|
||||
--- a/arch/mips/include/asm/kexec.h
|
||||
+++ b/arch/mips/include/asm/kexec.h
|
||||
@@ -31,7 +31,7 @@ static inline void crash_setup_regs(stru
|
||||
prepare_frametrace(newregs);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
struct kimage;
|
||||
extern unsigned long kexec_args[4];
|
||||
extern int (*_machine_kexec_prepare)(struct kimage *);
|
||||
--- a/arch/mips/include/asm/smp-ops.h
|
||||
+++ b/arch/mips/include/asm/smp-ops.h
|
||||
@@ -35,7 +35,7 @@ struct plat_smp_ops {
|
||||
void (*cpu_die)(unsigned int cpu);
|
||||
void (*cleanup_dead_cpu)(unsigned cpu);
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
void (*kexec_nonboot_cpu)(void);
|
||||
#endif
|
||||
};
|
||||
--- a/arch/mips/include/asm/smp.h
|
||||
+++ b/arch/mips/include/asm/smp.h
|
||||
@@ -93,7 +93,7 @@ static inline void __cpu_die(unsigned in
|
||||
extern void __noreturn play_dead(void);
|
||||
#endif
|
||||
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
static inline void kexec_nonboot_cpu(void)
|
||||
{
|
||||
extern const struct plat_smp_ops *mp_ops; /* private */
|
||||
--- a/arch/mips/kernel/Makefile
|
||||
+++ b/arch/mips/kernel/Makefile
|
||||
@@ -90,7 +90,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
|
||||
|
||||
obj-$(CONFIG_RELOCATABLE) += relocate.o
|
||||
|
||||
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
|
||||
+obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o crash.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_EARLY_PRINTK_8250) += early_printk_8250.o
|
||||
--- a/arch/mips/kernel/smp-bmips.c
|
||||
+++ b/arch/mips/kernel/smp-bmips.c
|
||||
@@ -434,7 +434,7 @@ const struct plat_smp_ops bmips43xx_smp_
|
||||
.cpu_disable = bmips_cpu_disable,
|
||||
.cpu_die = bmips_cpu_die,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||
#endif
|
||||
};
|
||||
@@ -451,7 +451,7 @@ const struct plat_smp_ops bmips5000_smp_
|
||||
.cpu_disable = bmips_cpu_disable,
|
||||
.cpu_die = bmips_cpu_die,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||
#endif
|
||||
};
|
||||
--- a/arch/mips/kernel/smp-cps.c
|
||||
+++ b/arch/mips/kernel/smp-cps.c
|
||||
@@ -392,7 +392,7 @@ static void cps_smp_finish(void)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
|
||||
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC_CORE)
|
||||
|
||||
enum cpu_death {
|
||||
CPU_DEATH_HALT,
|
||||
@@ -429,7 +429,7 @@ static void cps_shutdown_this_cpu(enum c
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
|
||||
static void cps_kexec_nonboot_cpu(void)
|
||||
{
|
||||
@@ -439,9 +439,9 @@ static void cps_kexec_nonboot_cpu(void)
|
||||
cps_shutdown_this_cpu(CPU_DEATH_POWER);
|
||||
}
|
||||
|
||||
-#endif /* CONFIG_KEXEC */
|
||||
+#endif /* CONFIG_KEXEC_CORE */
|
||||
|
||||
-#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
|
||||
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC_CORE */
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
||||
@@ -610,7 +610,7 @@ static const struct plat_smp_ops cps_smp
|
||||
.cpu_die = cps_cpu_die,
|
||||
.cleanup_dead_cpu = cps_cleanup_dead_cpu,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = cps_kexec_nonboot_cpu,
|
||||
#endif
|
||||
};
|
||||
--- a/arch/mips/loongson64/reset.c
|
||||
+++ b/arch/mips/loongson64/reset.c
|
||||
@@ -53,7 +53,7 @@ static void loongson_halt(void)
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
|
||||
/* 0X80000000~0X80200000 is safe */
|
||||
#define MAX_ARGS 64
|
||||
@@ -158,7 +158,7 @@ static int __init mips_reboot_setup(void
|
||||
_machine_halt = loongson_halt;
|
||||
pm_power_off = loongson_poweroff;
|
||||
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
|
||||
if (WARN_ON(!kexec_argv))
|
||||
return -ENOMEM;
|
||||
--- a/arch/mips/loongson64/smp.c
|
||||
+++ b/arch/mips/loongson64/smp.c
|
||||
@@ -864,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_
|
||||
.cpu_disable = loongson3_cpu_disable,
|
||||
.cpu_die = loongson3_cpu_die,
|
||||
#endif
|
||||
-#ifdef CONFIG_KEXEC
|
||||
+#ifdef CONFIG_KEXEC_CORE
|
||||
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||
#endif
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001
|
||||
From: William Zhang <william.zhang@broadcom.com>
|
||||
Date: Thu, 22 Feb 2024 19:47:58 -0800
|
||||
Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from
|
||||
dts
|
||||
|
||||
The write protection feature is controlled by the module parameter wp_on
|
||||
with default set to enabled. But not all the board use this feature
|
||||
especially in BCMBCA broadband board. And module parameter is not
|
||||
sufficient as different board can have different option. Add a device
|
||||
tree property and allow this feature to be configured through the board
|
||||
dts on per board basis.
|
||||
|
||||
Signed-off-by: William Zhang <william.zhang@broadcom.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
|
||||
Reviewed-by: David Regan <dregan@broadcom.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com
|
||||
---
|
||||
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
||||
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
||||
@@ -3189,6 +3189,10 @@ int brcmnand_probe(struct platform_devic
|
||||
/* Disable XOR addressing */
|
||||
brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
|
||||
|
||||
+ /* Check if the board connects the WP pin */
|
||||
+ if (of_property_read_bool(dn, "brcm,wp-not-connected"))
|
||||
+ wp_on = 0;
|
||||
+
|
||||
if (ctrl->features & BRCMNAND_HAS_WP) {
|
||||
/* Permanently disable write protection */
|
||||
if (wp_on == 2)
|
@ -1,11 +1,13 @@
|
||||
From ffbbe7d66872ff8957dad2136133e28a1fd5d437 Mon Sep 17 00:00:00 2001
|
||||
From 25d88bfd35bac3196eafa666e3b05033b46ffa21 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 7 Aug 2023 22:51:05 +0100
|
||||
Subject: [PATCH 01/15] dt-bindings: mtd: add basic bindings for UBI
|
||||
Date: Tue, 19 Dec 2023 02:32:00 +0000
|
||||
Subject: [PATCH 1/8] dt-bindings: mtd: add basic bindings for UBI
|
||||
|
||||
Add basic bindings for UBI devices and volumes.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
.../bindings/mtd/partitions/linux,ubi.yaml | 65 +++++++++++++++++++
|
||||
.../bindings/mtd/partitions/ubi-volume.yaml | 35 ++++++++++
|
||||
@ -101,21 +103,21 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+
|
||||
+properties:
|
||||
+ volid:
|
||||
+ $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32
|
||||
+ description:
|
||||
+ Match UBI volume ID
|
||||
+
|
||||
+ volname:
|
||||
+ $ref: "/schemas/types.yaml#/definitions/string"
|
||||
+ $ref: /schemas/types.yaml#/definitions/string
|
||||
+ description:
|
||||
+ Match UBI volume ID
|
||||
+
|
||||
+anyOf:
|
||||
+ - required:
|
||||
+ - volid
|
||||
+ - volid
|
||||
+
|
||||
+ - required:
|
||||
+ - volname
|
||||
+ - volname
|
||||
+
|
||||
+# This is a generic file other binding inherit from and extend
|
||||
+additionalProperties: true
|
@ -1,13 +1,15 @@
|
||||
From e4dad3aa5c3ab9c553555dd23c0b85f725f2eb51 Mon Sep 17 00:00:00 2001
|
||||
From 95b113222b5164ac0887eb5c514ff3970a0136f0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 7 Aug 2023 22:53:01 +0100
|
||||
Subject: [PATCH 02/15] dt-bindings: mtd: ubi-volume: allow UBI volumes to
|
||||
Date: Tue, 19 Dec 2023 02:32:11 +0000
|
||||
Subject: [PATCH 2/8] dt-bindings: mtd: ubi-volume: allow UBI volumes to
|
||||
provide NVMEM
|
||||
|
||||
UBI volumes may be used to contain NVMEM bits, typically device MAC
|
||||
addresses or wireless radio calibration data.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
.../devicetree/bindings/mtd/partitions/linux,ubi.yaml | 10 ++++++++++
|
||||
.../devicetree/bindings/mtd/partitions/ubi-volume.yaml | 5 +++++
|
||||
@ -45,4 +47,4 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+
|
||||
anyOf:
|
||||
- required:
|
||||
- volid
|
||||
- volid
|
@ -1,7 +1,7 @@
|
||||
From e5cf19bd8204925f3bd2067df9e867313eac388b Mon Sep 17 00:00:00 2001
|
||||
From 2bba1cdcfcd2907d0696cc0139f1bd078d36ee81 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 1 May 2023 11:57:51 +0100
|
||||
Subject: [PATCH 03/15] mtd: ubi: block: use notifier to create ubiblock from
|
||||
Date: Tue, 19 Dec 2023 02:32:35 +0000
|
||||
Subject: [PATCH 3/8] mtd: ubi: block: use notifier to create ubiblock from
|
||||
parameter
|
||||
|
||||
Use UBI_VOLUME_ADDED notification to create ubiblock device specified
|
||||
@ -12,21 +12,16 @@ will still be created.
|
||||
|
||||
Suggested-by: Zhihao Cheng <chengzhihao1@huawei.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/block.c | 154 ++++++++++++++++++++++------------------
|
||||
1 file changed, 85 insertions(+), 69 deletions(-)
|
||||
drivers/mtd/ubi/block.c | 136 ++++++++++++++++++++--------------------
|
||||
drivers/mtd/ubi/kapi.c | 54 +++++++++++-----
|
||||
drivers/mtd/ubi/ubi.h | 1 +
|
||||
3 files changed, 106 insertions(+), 85 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/ubi/block.c
|
||||
+++ b/drivers/mtd/ubi/block.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
+#include <linux/namei.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mtd/ubi.h>
|
||||
#include <linux/blkdev.h>
|
||||
@@ -65,10 +66,10 @@ struct ubiblock_pdu {
|
||||
@@ -65,10 +65,10 @@ struct ubiblock_pdu {
|
||||
};
|
||||
|
||||
/* Numbers of elements set in the @ubiblock_param array */
|
||||
@ -39,50 +34,26 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
struct ubiblock {
|
||||
struct ubi_volume_desc *desc;
|
||||
@@ -469,7 +470,7 @@ int ubiblock_remove(struct ubi_volume_in
|
||||
}
|
||||
|
||||
/* Found a device, let's lock it so we can check if it's busy */
|
||||
- mutex_lock(&dev->dev_mutex);
|
||||
+ mutex_lock_nested(&dev->dev_mutex, SINGLE_DEPTH_NESTING);
|
||||
if (dev->refcnt > 0) {
|
||||
ret = -EBUSY;
|
||||
goto out_unlock_dev;
|
||||
@@ -532,6 +533,85 @@ static int ubiblock_resize(struct ubi_vo
|
||||
@@ -532,6 +532,70 @@ static int ubiblock_resize(struct ubi_vo
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
|
||||
+{
|
||||
+ int err, len;
|
||||
+ struct path path;
|
||||
+ struct kstat stat;
|
||||
+ int err, len, cur_ubi_num, cur_vol_id;
|
||||
+
|
||||
+ if (ubi_num == -1) {
|
||||
+ /* No ubi num, name must be a vol device path */
|
||||
+ err = kern_path(name, LOOKUP_FOLLOW, &path);
|
||||
+ if (err)
|
||||
+ return false;
|
||||
+
|
||||
+ err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
|
||||
+ path_put(&path);
|
||||
+ if (err)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!S_ISCHR(stat.mode))
|
||||
+ return false;
|
||||
+
|
||||
+ if (vi->ubi_num != ubi_major2num(MAJOR(stat.rdev)))
|
||||
+ return false;
|
||||
+
|
||||
+ if (vi->vol_id != MINOR(stat.rdev) - 1)
|
||||
+ err = ubi_get_num_by_path(name, &cur_ubi_num, &cur_vol_id);
|
||||
+ if (err || vi->ubi_num != cur_ubi_num || vi->vol_id != cur_vol_id)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (vol_id == -1) {
|
||||
+ /* Got ubi_num, but no vol_id, name must be volume name */
|
||||
+ if (vi->ubi_num != ubi_num)
|
||||
+ return false;
|
||||
+
|
||||
@ -134,7 +105,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int ubiblock_notify(struct notifier_block *nb,
|
||||
unsigned long notification_type, void *ns_ptr)
|
||||
{
|
||||
@@ -539,10 +619,7 @@ static int ubiblock_notify(struct notifi
|
||||
@@ -539,10 +603,7 @@ static int ubiblock_notify(struct notifi
|
||||
|
||||
switch (notification_type) {
|
||||
case UBI_VOLUME_ADDED:
|
||||
@ -146,7 +117,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
break;
|
||||
case UBI_VOLUME_REMOVED:
|
||||
ubiblock_remove(&nt->vi);
|
||||
@@ -568,56 +645,6 @@ static struct notifier_block ubiblock_no
|
||||
@@ -568,56 +629,6 @@ static struct notifier_block ubiblock_no
|
||||
.notifier_call = ubiblock_notify,
|
||||
};
|
||||
|
||||
@ -203,7 +174,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static void ubiblock_remove_all(void)
|
||||
{
|
||||
struct ubiblock *next;
|
||||
@@ -643,18 +670,7 @@ int __init ubiblock_init(void)
|
||||
@@ -643,18 +654,7 @@ int __init ubiblock_init(void)
|
||||
if (ubiblock_major < 0)
|
||||
return ubiblock_major;
|
||||
|
||||
@ -223,3 +194,92 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
goto err_unreg;
|
||||
return 0;
|
||||
--- a/drivers/mtd/ubi/kapi.c
|
||||
+++ b/drivers/mtd/ubi/kapi.c
|
||||
@@ -280,6 +280,41 @@ struct ubi_volume_desc *ubi_open_volume_
|
||||
EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
|
||||
|
||||
/**
|
||||
+ * ubi_get_num_by_path - get UBI device and volume number from device path
|
||||
+ * @pathname: volume character device node path
|
||||
+ * @ubi_num: pointer to UBI device number to be set
|
||||
+ * @vol_id: pointer to UBI volume ID to be set
|
||||
+ *
|
||||
+ * Returns 0 on success and sets ubi_num and vol_id, returns error otherwise.
|
||||
+ */
|
||||
+int ubi_get_num_by_path(const char *pathname, int *ubi_num, int *vol_id)
|
||||
+{
|
||||
+ int error;
|
||||
+ struct path path;
|
||||
+ struct kstat stat;
|
||||
+
|
||||
+ error = kern_path(pathname, LOOKUP_FOLLOW, &path);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
+ error = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
|
||||
+ path_put(&path);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
+ if (!S_ISCHR(stat.mode))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *ubi_num = ubi_major2num(MAJOR(stat.rdev));
|
||||
+ *vol_id = MINOR(stat.rdev) - 1;
|
||||
+
|
||||
+ if (*vol_id < 0 || *ubi_num < 0)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* ubi_open_volume_path - open UBI volume by its character device node path.
|
||||
* @pathname: volume character device node path
|
||||
* @mode: open mode
|
||||
@@ -290,32 +325,17 @@ EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
|
||||
struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
|
||||
{
|
||||
int error, ubi_num, vol_id;
|
||||
- struct path path;
|
||||
- struct kstat stat;
|
||||
|
||||
dbg_gen("open volume %s, mode %d", pathname, mode);
|
||||
|
||||
if (!pathname || !*pathname)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
- error = kern_path(pathname, LOOKUP_FOLLOW, &path);
|
||||
- if (error)
|
||||
- return ERR_PTR(error);
|
||||
-
|
||||
- error = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
|
||||
- path_put(&path);
|
||||
+ error = ubi_get_num_by_path(pathname, &ubi_num, &vol_id);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
|
||||
- if (!S_ISCHR(stat.mode))
|
||||
- return ERR_PTR(-EINVAL);
|
||||
-
|
||||
- ubi_num = ubi_major2num(MAJOR(stat.rdev));
|
||||
- vol_id = MINOR(stat.rdev) - 1;
|
||||
-
|
||||
- if (vol_id >= 0 && ubi_num >= 0)
|
||||
- return ubi_open_volume(ubi_num, vol_id, mode);
|
||||
- return ERR_PTR(-ENODEV);
|
||||
+ return ubi_open_volume(ubi_num, vol_id, mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ubi_open_volume_path);
|
||||
|
||||
--- a/drivers/mtd/ubi/ubi.h
|
||||
+++ b/drivers/mtd/ubi/ubi.h
|
||||
@@ -956,6 +956,7 @@ void ubi_free_internal_volumes(struct ub
|
||||
void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
|
||||
void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
|
||||
struct ubi_volume_info *vi);
|
||||
+int ubi_get_num_by_path(const char *pathname, int *ubi_num, int *vol_id);
|
||||
/* scan.c */
|
||||
int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
|
||||
int pnum, const struct ubi_vid_hdr *vid_hdr);
|
@ -1,7 +1,7 @@
|
||||
From 471a17d8d1b838092d1a76e48cdce8b5b67ff809 Mon Sep 17 00:00:00 2001
|
||||
From 6e331888643887ce85657527bc03f97d46235e71 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 27 Nov 2023 01:54:28 +0000
|
||||
Subject: [PATCH 04/15] mtd: ubi: attach from device tree
|
||||
Date: Tue, 19 Dec 2023 02:33:14 +0000
|
||||
Subject: [PATCH 4/8] mtd: ubi: attach from device tree
|
||||
|
||||
Introduce device tree compatible 'linux,ubi' and attach compatible MTD
|
||||
devices using the MTD add notifier. This is needed for a UBI device to
|
||||
@ -9,11 +9,10 @@ be available early at boot (and not only after late_initcall), so
|
||||
volumes on them can be used eg. as NVMEM providers for other drivers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/build.c | 146 ++++++++++++++++++++++++++++------------
|
||||
drivers/mtd/ubi/cdev.c | 2 +-
|
||||
drivers/mtd/ubi/ubi.h | 2 +-
|
||||
3 files changed, 106 insertions(+), 44 deletions(-)
|
||||
drivers/mtd/ubi/build.c | 135 ++++++++++++++++++++++++++++------------
|
||||
1 file changed, 96 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/ubi/build.c
|
||||
+++ b/drivers/mtd/ubi/build.c
|
||||
@ -25,37 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/major.h>
|
||||
#include "ubi.h"
|
||||
@@ -1072,6 +1073,7 @@ out_free:
|
||||
* ubi_detach_mtd_dev - detach an MTD device.
|
||||
* @ubi_num: UBI device number to detach from
|
||||
* @anyway: detach MTD even if device reference count is not zero
|
||||
+ * @have_lock: called by MTD notifier holding mtd_table_mutex
|
||||
*
|
||||
* This function destroys an UBI device number @ubi_num and detaches the
|
||||
* underlying MTD device. Returns zero in case of success and %-EBUSY if the
|
||||
@@ -1081,7 +1083,7 @@ out_free:
|
||||
* Note, the invocations of this function has to be serialized by the
|
||||
* @ubi_devices_mutex.
|
||||
*/
|
||||
-int ubi_detach_mtd_dev(int ubi_num, int anyway)
|
||||
+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock)
|
||||
{
|
||||
struct ubi_device *ubi;
|
||||
|
||||
@@ -1137,7 +1139,11 @@ int ubi_detach_mtd_dev(int ubi_num, int
|
||||
vfree(ubi->peb_buf);
|
||||
vfree(ubi->fm_buf);
|
||||
ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
|
||||
- put_mtd_device(ubi->mtd);
|
||||
+ if (have_lock)
|
||||
+ __put_mtd_device(ubi->mtd);
|
||||
+ else
|
||||
+ put_mtd_device(ubi->mtd);
|
||||
+
|
||||
put_device(&ubi->dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -1214,43 +1220,43 @@ static struct mtd_info * __init open_mtd
|
||||
@@ -1214,43 +1215,43 @@ static struct mtd_info * __init open_mtd
|
||||
return mtd;
|
||||
}
|
||||
|
||||
@ -111,7 +80,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
- }
|
||||
+static void ubi_notify_remove(struct mtd_info *mtd)
|
||||
+{
|
||||
+ WARN(1, "mtd%d removed despite UBI still being attached", mtd->index);
|
||||
+ /* do nothing for now */
|
||||
+}
|
||||
|
||||
- err = ubi_debugfs_init();
|
||||
@ -128,7 +97,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* Attach MTD devices */
|
||||
for (i = 0; i < mtd_devs; i++) {
|
||||
@@ -1298,25 +1304,79 @@ static int __init ubi_init(void)
|
||||
@@ -1298,25 +1299,79 @@ static int __init ubi_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +107,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ for (k = 0; k < i; k++)
|
||||
+ if (ubi_devices[k]) {
|
||||
+ mutex_lock(&ubi_devices_mutex);
|
||||
+ ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1, false);
|
||||
+ ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
|
||||
+ mutex_unlock(&ubi_devices_mutex);
|
||||
+ }
|
||||
+ return err;
|
||||
@ -217,7 +186,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
out_slab:
|
||||
kmem_cache_destroy(ubi_wl_entry_slab);
|
||||
out_dev_unreg:
|
||||
@@ -1326,18 +1386,20 @@ out:
|
||||
@@ -1326,13 +1381,15 @@ out:
|
||||
pr_err("UBI error: cannot initialize UBI, error %d\n", err);
|
||||
return err;
|
||||
}
|
||||
@ -234,31 +203,3 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
for (i = 0; i < UBI_MAX_DEVICES; i++)
|
||||
if (ubi_devices[i]) {
|
||||
mutex_lock(&ubi_devices_mutex);
|
||||
- ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
|
||||
+ ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1, false);
|
||||
mutex_unlock(&ubi_devices_mutex);
|
||||
}
|
||||
ubi_debugfs_exit();
|
||||
--- a/drivers/mtd/ubi/cdev.c
|
||||
+++ b/drivers/mtd/ubi/cdev.c
|
||||
@@ -1065,7 +1065,7 @@ static long ctrl_cdev_ioctl(struct file
|
||||
}
|
||||
|
||||
mutex_lock(&ubi_devices_mutex);
|
||||
- err = ubi_detach_mtd_dev(ubi_num, 0);
|
||||
+ err = ubi_detach_mtd_dev(ubi_num, 0, false);
|
||||
mutex_unlock(&ubi_devices_mutex);
|
||||
break;
|
||||
}
|
||||
--- a/drivers/mtd/ubi/ubi.h
|
||||
+++ b/drivers/mtd/ubi/ubi.h
|
||||
@@ -939,7 +939,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
|
||||
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
|
||||
int vid_hdr_offset, int max_beb_per1024,
|
||||
bool disable_fm);
|
||||
-int ubi_detach_mtd_dev(int ubi_num, int anyway);
|
||||
+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock);
|
||||
struct ubi_device *ubi_get_device(int ubi_num);
|
||||
void ubi_put_device(struct ubi_device *ubi);
|
||||
struct ubi_device *ubi_get_by_major(int major);
|
@ -1,7 +1,7 @@
|
||||
From 2d664266cfdd114cc7a1fa28dd64275e99222455 Mon Sep 17 00:00:00 2001
|
||||
From 924731fbed3247e3b82b8ab17db587ee28c2e781 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 8 Jun 2023 17:18:09 +0100
|
||||
Subject: [PATCH 05/15] mtd: ubi: introduce pre-removal notification for UBI
|
||||
Date: Tue, 19 Dec 2023 02:33:24 +0000
|
||||
Subject: [PATCH 5/8] mtd: ubi: introduce pre-removal notification for UBI
|
||||
volumes
|
||||
|
||||
Introduce a new notification type UBI_VOLUME_SHUTDOWN to inform users
|
||||
@ -12,57 +12,15 @@ still available (for removal of sysfs nodes, for example, in case of
|
||||
NVMEM which otherwise WARNs on volume removal).
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/block.c | 26 ++++++++++++++++++++++++++
|
||||
drivers/mtd/ubi/build.c | 20 +++++++++++++++-----
|
||||
drivers/mtd/ubi/build.c | 19 ++++++++++++++-----
|
||||
drivers/mtd/ubi/kapi.c | 2 +-
|
||||
drivers/mtd/ubi/ubi.h | 2 ++
|
||||
drivers/mtd/ubi/vmt.c | 17 +++++++++++++++--
|
||||
include/linux/mtd/ubi.h | 2 ++
|
||||
6 files changed, 61 insertions(+), 8 deletions(-)
|
||||
5 files changed, 34 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/ubi/block.c
|
||||
+++ b/drivers/mtd/ubi/block.c
|
||||
@@ -533,6 +533,29 @@ static int ubiblock_resize(struct ubi_vo
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ubiblock_shutdown(struct ubi_volume_info *vi)
|
||||
+{
|
||||
+ struct ubiblock *dev;
|
||||
+ struct gendisk *disk;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mutex_lock(&devices_mutex);
|
||||
+ dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
|
||||
+ if (!dev) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
+ disk = dev->gd;
|
||||
+
|
||||
+out_unlock:
|
||||
+ mutex_unlock(&devices_mutex);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ blk_mark_disk_dead(disk);
|
||||
+
|
||||
+ return ret;
|
||||
+};
|
||||
+
|
||||
static bool
|
||||
match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
|
||||
{
|
||||
@@ -624,6 +647,9 @@ static int ubiblock_notify(struct notifi
|
||||
case UBI_VOLUME_REMOVED:
|
||||
ubiblock_remove(&nt->vi);
|
||||
break;
|
||||
+ case UBI_VOLUME_SHUTDOWN:
|
||||
+ ubiblock_shutdown(&nt->vi);
|
||||
+ break;
|
||||
case UBI_VOLUME_RESIZED:
|
||||
ubiblock_resize(&nt->vi);
|
||||
break;
|
||||
--- a/drivers/mtd/ubi/build.c
|
||||
+++ b/drivers/mtd/ubi/build.c
|
||||
@@ -91,7 +91,7 @@ static struct ubi_device *ubi_devices[UB
|
||||
@ -111,7 +69,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
continue;
|
||||
ubi_eba_replace_table(ubi->volumes[i], NULL);
|
||||
ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
|
||||
@@ -1095,10 +1098,10 @@ int ubi_detach_mtd_dev(int ubi_num, int
|
||||
@@ -1094,7 +1097,6 @@ int ubi_detach_mtd_dev(int ubi_num, int
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&ubi_devices_lock);
|
||||
@ -119,11 +77,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ubi->ref_count -= 1;
|
||||
if (ubi->ref_count) {
|
||||
if (!anyway) {
|
||||
+ ubi->ref_count += 1;
|
||||
spin_unlock(&ubi_devices_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
@@ -1106,6 +1109,13 @@ int ubi_detach_mtd_dev(int ubi_num, int
|
||||
@@ -1105,6 +1107,13 @@ int ubi_detach_mtd_dev(int ubi_num, int
|
||||
ubi_err(ubi, "%s reference count %d, destroy anyway",
|
||||
ubi->ubi_name, ubi->ref_count);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
From 3a041ee543cdf2e707a1dd72946cd6a583509b28 Mon Sep 17 00:00:00 2001
|
||||
From 1c54542170819e36baa43c17ca55bb3d7da89a53 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Fri, 21 Jul 2023 19:26:37 +0100
|
||||
Subject: [PATCH 06/15] mtd: ubi: populate ubi volume fwnode
|
||||
Date: Tue, 19 Dec 2023 02:33:38 +0000
|
||||
Subject: [PATCH 6/8] mtd: ubi: populate ubi volume fwnode
|
||||
|
||||
Look for the 'volumes' subnode of an MTD partition attached to a UBI
|
||||
device and attach matching child nodes to UBI volumes.
|
||||
@ -9,6 +9,7 @@ This allows UBI volumes to be referenced in device tree, e.g. for use
|
||||
as NVMEM providers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/vmt.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
@ -1,7 +1,7 @@
|
||||
From 7eb6666348f3f2d1f7308c712fa5903cbe189401 Mon Sep 17 00:00:00 2001
|
||||
From 15fc7dc926c91c871f6c0305b2938dbdeb14203b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 8 Jun 2023 17:22:04 +0100
|
||||
Subject: [PATCH 07/15] mtd: ubi: provide NVMEM layer over UBI volumes
|
||||
Date: Tue, 19 Dec 2023 02:33:48 +0000
|
||||
Subject: [PATCH 7/8] mtd: ubi: provide NVMEM layer over UBI volumes
|
||||
|
||||
In an ideal world we would like UBI to be used where ever possible on a
|
||||
NAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it
|
||||
@ -17,6 +17,7 @@ read-only, and it is slow, opening and closing the UBI volume for each
|
||||
access due to limitations of the NVMEM provider API.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/Kconfig | 12 +++
|
||||
drivers/mtd/ubi/Makefile | 1 +
|
||||
@ -52,7 +53,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/ubi/nvmem.c
|
||||
@@ -0,0 +1,191 @@
|
||||
@@ -0,0 +1,188 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
|
||||
@ -78,17 +79,14 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+static int ubi_nvmem_reg_read(void *priv, unsigned int from,
|
||||
+ void *val, size_t bytes)
|
||||
+{
|
||||
+ uint32_t offs, to_read, bytes_left;
|
||||
+ int err = 0, lnum = from, offs, bytes_left = bytes, to_read;
|
||||
+ struct ubi_nvmem *unv = priv;
|
||||
+ struct ubi_volume_desc *desc;
|
||||
+ uint64_t lnum = from;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
|
||||
+ if (IS_ERR(desc))
|
||||
+ return PTR_ERR(desc);
|
||||
+
|
||||
+ bytes_left = bytes;
|
||||
+ offs = do_div(lnum, unv->usable_leb_size);
|
||||
+ while (bytes_left) {
|
||||
+ to_read = unv->usable_leb_size - offs;
|
@ -0,0 +1,34 @@
|
||||
From 04231c61dcd51db0f12061e49bb761b197109f2f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 29 Feb 2024 03:47:24 +0000
|
||||
Subject: [PATCH 8/8] mtd: ubi: fix NVMEM over UBI volumes on 32-bit systems
|
||||
|
||||
A compiler warning related to sizeof(int) != 8 when calling do_div()
|
||||
is triggered when building on 32-bit platforms.
|
||||
Address this by using integer types having a well-defined size.
|
||||
|
||||
Fixes: 3ce485803da1 ("mtd: ubi: provide NVMEM layer over UBI volumes")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
|
||||
Tested-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/nvmem.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/ubi/nvmem.c
|
||||
+++ b/drivers/mtd/ubi/nvmem.c
|
||||
@@ -23,9 +23,12 @@ struct ubi_nvmem {
|
||||
static int ubi_nvmem_reg_read(void *priv, unsigned int from,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
- int err = 0, lnum = from, offs, bytes_left = bytes, to_read;
|
||||
+ size_t to_read, bytes_left = bytes;
|
||||
struct ubi_nvmem *unv = priv;
|
||||
struct ubi_volume_desc *desc;
|
||||
+ uint32_t offs;
|
||||
+ uint64_t lnum = from;
|
||||
+ int err = 0;
|
||||
|
||||
desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
|
||||
if (IS_ERR(desc))
|
@ -0,0 +1,75 @@
|
||||
From 56364c910691f6d10ba88c964c9041b9ab777bd6 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Date: Mon, 25 Mar 2024 08:40:28 +0100
|
||||
Subject: [PATCH 1/4] net: Remove conditional threaded-NAPI wakeup based on
|
||||
task state.
|
||||
|
||||
A NAPI thread is scheduled by first setting NAPI_STATE_SCHED bit. If
|
||||
successful (the bit was not yet set) then the NAPI_STATE_SCHED_THREADED
|
||||
is set but only if thread's state is not TASK_INTERRUPTIBLE (is
|
||||
TASK_RUNNING) followed by task wakeup.
|
||||
|
||||
If the task is idle (TASK_INTERRUPTIBLE) then the
|
||||
NAPI_STATE_SCHED_THREADED bit is not set. The thread is no relying on
|
||||
the bit but always leaving the wait-loop after returning from schedule()
|
||||
because there must have been a wakeup.
|
||||
|
||||
The smpboot-threads implementation for per-CPU threads requires an
|
||||
explicit condition and does not support "if we get out of schedule()
|
||||
then there must be something to do".
|
||||
|
||||
Removing this optimisation simplifies the following integration.
|
||||
|
||||
Set NAPI_STATE_SCHED_THREADED unconditionally on wakeup and rely on it
|
||||
in the wait path by removing the `woken' condition.
|
||||
|
||||
Acked-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
net/core/dev.c | 14 ++------------
|
||||
1 file changed, 2 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -4473,13 +4473,7 @@ static inline void ____napi_schedule(str
|
||||
*/
|
||||
thread = READ_ONCE(napi->thread);
|
||||
if (thread) {
|
||||
- /* Avoid doing set_bit() if the thread is in
|
||||
- * INTERRUPTIBLE state, cause napi_thread_wait()
|
||||
- * makes sure to proceed with napi polling
|
||||
- * if the thread is explicitly woken from here.
|
||||
- */
|
||||
- if (READ_ONCE(thread->__state) != TASK_INTERRUPTIBLE)
|
||||
- set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
|
||||
+ set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
|
||||
wake_up_process(thread);
|
||||
return;
|
||||
}
|
||||
@@ -6635,8 +6629,6 @@ static int napi_poll(struct napi_struct
|
||||
|
||||
static int napi_thread_wait(struct napi_struct *napi)
|
||||
{
|
||||
- bool woken = false;
|
||||
-
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
@@ -6645,15 +6637,13 @@ static int napi_thread_wait(struct napi_
|
||||
* Testing SCHED bit is not enough because SCHED bit might be
|
||||
* set by some other busy poll thread or by napi_disable().
|
||||
*/
|
||||
- if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) {
|
||||
+ if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state)) {
|
||||
WARN_ON(!list_empty(&napi->poll_list));
|
||||
__set_current_state(TASK_RUNNING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
schedule();
|
||||
- /* woken being true indicates this thread owns this napi. */
|
||||
- woken = true;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
@ -0,0 +1,330 @@
|
||||
From dad6b97702639fba27a2bd3e986982ad6f0db3a7 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Date: Mon, 25 Mar 2024 08:40:29 +0100
|
||||
Subject: [PATCH 2/4] net: Allow to use SMP threads for backlog NAPI.
|
||||
|
||||
Backlog NAPI is a per-CPU NAPI struct only (with no device behind it)
|
||||
used by drivers which don't do NAPI them self, RPS and parts of the
|
||||
stack which need to avoid recursive deadlocks while processing a packet.
|
||||
|
||||
The non-NAPI driver use the CPU local backlog NAPI. If RPS is enabled
|
||||
then a flow for the skb is computed and based on the flow the skb can be
|
||||
enqueued on a remote CPU. Scheduling/ raising the softirq (for backlog's
|
||||
NAPI) on the remote CPU isn't trivial because the softirq is only
|
||||
scheduled on the local CPU and performed after the hardirq is done.
|
||||
In order to schedule a softirq on the remote CPU, an IPI is sent to the
|
||||
remote CPU which schedules the backlog-NAPI on the then local CPU.
|
||||
|
||||
On PREEMPT_RT interrupts are force-threaded. The soft interrupts are
|
||||
raised within the interrupt thread and processed after the interrupt
|
||||
handler completed still within the context of the interrupt thread. The
|
||||
softirq is handled in the context where it originated.
|
||||
|
||||
With force-threaded interrupts enabled, ksoftirqd is woken up if a
|
||||
softirq is raised from hardirq context. This is the case if it is raised
|
||||
from an IPI. Additionally there is a warning on PREEMPT_RT if the
|
||||
softirq is raised from the idle thread.
|
||||
This was done for two reasons:
|
||||
- With threaded interrupts the processing should happen in thread
|
||||
context (where it originated) and ksoftirqd is the only thread for
|
||||
this context if raised from hardirq. Using the currently running task
|
||||
instead would "punish" a random task.
|
||||
- Once ksoftirqd is active it consumes all further softirqs until it
|
||||
stops running. This changed recently and is no longer the case.
|
||||
|
||||
Instead of keeping the backlog NAPI in ksoftirqd (in force-threaded/
|
||||
PREEMPT_RT setups) I am proposing NAPI-threads for backlog.
|
||||
The "proper" setup with threaded-NAPI is not doable because the threads
|
||||
are not pinned to an individual CPU and can be modified by the user.
|
||||
Additionally a dummy network device would have to be assigned. Also
|
||||
CPU-hotplug has to be considered if additional CPUs show up.
|
||||
All this can be probably done/ solved but the smpboot-threads already
|
||||
provide this infrastructure.
|
||||
|
||||
Sending UDP packets over loopback expects that the packet is processed
|
||||
within the call. Delaying it by handing it over to the thread hurts
|
||||
performance. It is not beneficial to the outcome if the context switch
|
||||
happens immediately after enqueue or after a while to process a few
|
||||
packets in a batch.
|
||||
There is no need to always use the thread if the backlog NAPI is
|
||||
requested on the local CPU. This restores the loopback throuput. The
|
||||
performance drops mostly to the same value after enabling RPS on the
|
||||
loopback comparing the IPI and the tread result.
|
||||
|
||||
Create NAPI-threads for backlog if request during boot. The thread runs
|
||||
the inner loop from napi_threaded_poll(), the wait part is different. It
|
||||
checks for NAPI_STATE_SCHED (the backlog NAPI can not be disabled).
|
||||
|
||||
The NAPI threads for backlog are optional, it has to be enabled via the boot
|
||||
argument "thread_backlog_napi". It is mandatory for PREEMPT_RT to avoid the
|
||||
wakeup of ksoftirqd from the IPI.
|
||||
|
||||
Acked-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
net/core/dev.c | 148 +++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 113 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -78,6 +78,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/mm.h>
|
||||
+#include <linux/smpboot.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/string.h>
|
||||
@@ -217,6 +218,31 @@ static inline struct hlist_head *dev_ind
|
||||
return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)];
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_PREEMPT_RT
|
||||
+
|
||||
+static DEFINE_STATIC_KEY_FALSE(use_backlog_threads_key);
|
||||
+
|
||||
+static int __init setup_backlog_napi_threads(char *arg)
|
||||
+{
|
||||
+ static_branch_enable(&use_backlog_threads_key);
|
||||
+ return 0;
|
||||
+}
|
||||
+early_param("thread_backlog_napi", setup_backlog_napi_threads);
|
||||
+
|
||||
+static bool use_backlog_threads(void)
|
||||
+{
|
||||
+ return static_branch_unlikely(&use_backlog_threads_key);
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+static bool use_backlog_threads(void)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static inline void rps_lock_irqsave(struct softnet_data *sd,
|
||||
unsigned long *flags)
|
||||
{
|
||||
@@ -4441,6 +4467,7 @@ EXPORT_SYMBOL(__dev_direct_xmit);
|
||||
/*************************************************************************
|
||||
* Receiver routines
|
||||
*************************************************************************/
|
||||
+static DEFINE_PER_CPU(struct task_struct *, backlog_napi);
|
||||
|
||||
int netdev_max_backlog __read_mostly = 1000;
|
||||
EXPORT_SYMBOL(netdev_max_backlog);
|
||||
@@ -4473,12 +4500,16 @@ static inline void ____napi_schedule(str
|
||||
*/
|
||||
thread = READ_ONCE(napi->thread);
|
||||
if (thread) {
|
||||
+ if (use_backlog_threads() && thread == raw_cpu_read(backlog_napi))
|
||||
+ goto use_local_napi;
|
||||
+
|
||||
set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
|
||||
wake_up_process(thread);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+use_local_napi:
|
||||
list_add_tail(&napi->poll_list, &sd->poll_list);
|
||||
WRITE_ONCE(napi->list_owner, smp_processor_id());
|
||||
/* If not called from net_rx_action()
|
||||
@@ -4724,6 +4755,11 @@ static void napi_schedule_rps(struct sof
|
||||
|
||||
#ifdef CONFIG_RPS
|
||||
if (sd != mysd) {
|
||||
+ if (use_backlog_threads()) {
|
||||
+ __napi_schedule_irqoff(&sd->backlog);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
sd->rps_ipi_next = mysd->rps_ipi_list;
|
||||
mysd->rps_ipi_list = sd;
|
||||
|
||||
@@ -5947,7 +5983,7 @@ static void net_rps_action_and_irq_enabl
|
||||
#ifdef CONFIG_RPS
|
||||
struct softnet_data *remsd = sd->rps_ipi_list;
|
||||
|
||||
- if (remsd) {
|
||||
+ if (!use_backlog_threads() && remsd) {
|
||||
sd->rps_ipi_list = NULL;
|
||||
|
||||
local_irq_enable();
|
||||
@@ -5962,7 +5998,7 @@ static void net_rps_action_and_irq_enabl
|
||||
static bool sd_has_rps_ipi_waiting(struct softnet_data *sd)
|
||||
{
|
||||
#ifdef CONFIG_RPS
|
||||
- return sd->rps_ipi_list != NULL;
|
||||
+ return !use_backlog_threads() && sd->rps_ipi_list;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -6006,7 +6042,7 @@ static int process_backlog(struct napi_s
|
||||
* We can use a plain write instead of clear_bit(),
|
||||
* and we dont need an smp_mb() memory barrier.
|
||||
*/
|
||||
- napi->state = 0;
|
||||
+ napi->state &= NAPIF_STATE_THREADED;
|
||||
again = false;
|
||||
} else {
|
||||
skb_queue_splice_tail_init(&sd->input_pkt_queue,
|
||||
@@ -6672,43 +6708,48 @@ static void skb_defer_free_flush(struct
|
||||
}
|
||||
}
|
||||
|
||||
-static int napi_threaded_poll(void *data)
|
||||
+static void napi_threaded_poll_loop(struct napi_struct *napi)
|
||||
{
|
||||
- struct napi_struct *napi = data;
|
||||
struct softnet_data *sd;
|
||||
- void *have;
|
||||
+ unsigned long last_qs = jiffies;
|
||||
|
||||
- while (!napi_thread_wait(napi)) {
|
||||
- unsigned long last_qs = jiffies;
|
||||
+ for (;;) {
|
||||
+ bool repoll = false;
|
||||
+ void *have;
|
||||
|
||||
- for (;;) {
|
||||
- bool repoll = false;
|
||||
+ local_bh_disable();
|
||||
+ sd = this_cpu_ptr(&softnet_data);
|
||||
+ sd->in_napi_threaded_poll = true;
|
||||
|
||||
- local_bh_disable();
|
||||
- sd = this_cpu_ptr(&softnet_data);
|
||||
- sd->in_napi_threaded_poll = true;
|
||||
-
|
||||
- have = netpoll_poll_lock(napi);
|
||||
- __napi_poll(napi, &repoll);
|
||||
- netpoll_poll_unlock(have);
|
||||
-
|
||||
- sd->in_napi_threaded_poll = false;
|
||||
- barrier();
|
||||
-
|
||||
- if (sd_has_rps_ipi_waiting(sd)) {
|
||||
- local_irq_disable();
|
||||
- net_rps_action_and_irq_enable(sd);
|
||||
- }
|
||||
- skb_defer_free_flush(sd);
|
||||
- local_bh_enable();
|
||||
+ have = netpoll_poll_lock(napi);
|
||||
+ __napi_poll(napi, &repoll);
|
||||
+ netpoll_poll_unlock(have);
|
||||
+
|
||||
+ sd->in_napi_threaded_poll = false;
|
||||
+ barrier();
|
||||
+
|
||||
+ if (sd_has_rps_ipi_waiting(sd)) {
|
||||
+ local_irq_disable();
|
||||
+ net_rps_action_and_irq_enable(sd);
|
||||
+ }
|
||||
+ skb_defer_free_flush(sd);
|
||||
+ local_bh_enable();
|
||||
|
||||
- if (!repoll)
|
||||
- break;
|
||||
+ if (!repoll)
|
||||
+ break;
|
||||
|
||||
- rcu_softirq_qs_periodic(last_qs);
|
||||
- cond_resched();
|
||||
- }
|
||||
+ rcu_softirq_qs_periodic(last_qs);
|
||||
+ cond_resched();
|
||||
}
|
||||
+}
|
||||
+
|
||||
+static int napi_threaded_poll(void *data)
|
||||
+{
|
||||
+ struct napi_struct *napi = data;
|
||||
+
|
||||
+ while (!napi_thread_wait(napi))
|
||||
+ napi_threaded_poll_loop(napi);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11289,7 +11330,7 @@ static int dev_cpu_dead(unsigned int old
|
||||
|
||||
list_del_init(&napi->poll_list);
|
||||
if (napi->poll == process_backlog)
|
||||
- napi->state = 0;
|
||||
+ napi->state &= NAPIF_STATE_THREADED;
|
||||
else
|
||||
____napi_schedule(sd, napi);
|
||||
}
|
||||
@@ -11297,12 +11338,14 @@ static int dev_cpu_dead(unsigned int old
|
||||
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
||||
local_irq_enable();
|
||||
|
||||
+ if (!use_backlog_threads()) {
|
||||
#ifdef CONFIG_RPS
|
||||
- remsd = oldsd->rps_ipi_list;
|
||||
- oldsd->rps_ipi_list = NULL;
|
||||
+ remsd = oldsd->rps_ipi_list;
|
||||
+ oldsd->rps_ipi_list = NULL;
|
||||
#endif
|
||||
- /* send out pending IPI's on offline CPU */
|
||||
- net_rps_send_ipi(remsd);
|
||||
+ /* send out pending IPI's on offline CPU */
|
||||
+ net_rps_send_ipi(remsd);
|
||||
+ }
|
||||
|
||||
/* Process offline CPU's input_pkt_queue */
|
||||
while ((skb = __skb_dequeue(&oldsd->process_queue))) {
|
||||
@@ -11565,6 +11608,38 @@ static struct pernet_operations __net_in
|
||||
*
|
||||
*/
|
||||
|
||||
+static int backlog_napi_should_run(unsigned int cpu)
|
||||
+{
|
||||
+ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu);
|
||||
+ struct napi_struct *napi = &sd->backlog;
|
||||
+
|
||||
+ return test_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
|
||||
+}
|
||||
+
|
||||
+static void run_backlog_napi(unsigned int cpu)
|
||||
+{
|
||||
+ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu);
|
||||
+
|
||||
+ napi_threaded_poll_loop(&sd->backlog);
|
||||
+}
|
||||
+
|
||||
+static void backlog_napi_setup(unsigned int cpu)
|
||||
+{
|
||||
+ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu);
|
||||
+ struct napi_struct *napi = &sd->backlog;
|
||||
+
|
||||
+ napi->thread = this_cpu_read(backlog_napi);
|
||||
+ set_bit(NAPI_STATE_THREADED, &napi->state);
|
||||
+}
|
||||
+
|
||||
+static struct smp_hotplug_thread backlog_threads = {
|
||||
+ .store = &backlog_napi,
|
||||
+ .thread_should_run = backlog_napi_should_run,
|
||||
+ .thread_fn = run_backlog_napi,
|
||||
+ .thread_comm = "backlog_napi/%u",
|
||||
+ .setup = backlog_napi_setup,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* This is called single threaded during boot, so no need
|
||||
* to take the rtnl semaphore.
|
||||
@@ -11615,7 +11690,10 @@ static int __init net_dev_init(void)
|
||||
init_gro_hash(&sd->backlog);
|
||||
sd->backlog.poll = process_backlog;
|
||||
sd->backlog.weight = weight_p;
|
||||
+ INIT_LIST_HEAD(&sd->backlog.poll_list);
|
||||
}
|
||||
+ if (use_backlog_threads())
|
||||
+ smpboot_register_percpu_thread(&backlog_threads);
|
||||
|
||||
dev_boot_phase = 0;
|
||||
|
@ -0,0 +1,121 @@
|
||||
From 80d2eefcb4c84aa9018b2a997ab3a4c567bc821a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Date: Mon, 25 Mar 2024 08:40:30 +0100
|
||||
Subject: [PATCH 3/4] net: Use backlog-NAPI to clean up the defer_list.
|
||||
|
||||
The defer_list is a per-CPU list which is used to free skbs outside of
|
||||
the socket lock and on the CPU on which they have been allocated.
|
||||
The list is processed during NAPI callbacks so ideally the list is
|
||||
cleaned up.
|
||||
Should the amount of skbs on the list exceed a certain water mark then
|
||||
the softirq is triggered remotely on the target CPU by invoking a remote
|
||||
function call. The raise of the softirqs via a remote function call
|
||||
leads to waking the ksoftirqd on PREEMPT_RT which is undesired.
|
||||
The backlog-NAPI threads already provide the infrastructure which can be
|
||||
utilized to perform the cleanup of the defer_list.
|
||||
|
||||
The NAPI state is updated with the input_pkt_queue.lock acquired. It
|
||||
order not to break the state, it is needed to also wake the backlog-NAPI
|
||||
thread with the lock held. This requires to acquire the use the lock in
|
||||
rps_lock_irq*() if the backlog-NAPI threads are used even with RPS
|
||||
disabled.
|
||||
|
||||
Move the logic of remotely starting softirqs to clean up the defer_list
|
||||
into kick_defer_list_purge(). Make sure a lock is held in
|
||||
rps_lock_irq*() if backlog-NAPI threads are used. Schedule backlog-NAPI
|
||||
for defer_list cleanup if backlog-NAPI is available.
|
||||
|
||||
Acked-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
include/linux/netdevice.h | 1 +
|
||||
net/core/dev.c | 25 +++++++++++++++++++++----
|
||||
net/core/skbuff.c | 4 ++--
|
||||
3 files changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -3300,6 +3300,7 @@ static inline void dev_xmit_recursion_de
|
||||
__this_cpu_dec(softnet_data.xmit.recursion);
|
||||
}
|
||||
|
||||
+void kick_defer_list_purge(struct softnet_data *sd, unsigned int cpu);
|
||||
void __netif_schedule(struct Qdisc *q);
|
||||
void netif_schedule_queue(struct netdev_queue *txq);
|
||||
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -246,7 +246,7 @@ static bool use_backlog_threads(void)
|
||||
static inline void rps_lock_irqsave(struct softnet_data *sd,
|
||||
unsigned long *flags)
|
||||
{
|
||||
- if (IS_ENABLED(CONFIG_RPS))
|
||||
+ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags);
|
||||
else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
local_irq_save(*flags);
|
||||
@@ -254,7 +254,7 @@ static inline void rps_lock_irqsave(stru
|
||||
|
||||
static inline void rps_lock_irq_disable(struct softnet_data *sd)
|
||||
{
|
||||
- if (IS_ENABLED(CONFIG_RPS))
|
||||
+ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_lock_irq(&sd->input_pkt_queue.lock);
|
||||
else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
local_irq_disable();
|
||||
@@ -263,7 +263,7 @@ static inline void rps_lock_irq_disable(
|
||||
static inline void rps_unlock_irq_restore(struct softnet_data *sd,
|
||||
unsigned long *flags)
|
||||
{
|
||||
- if (IS_ENABLED(CONFIG_RPS))
|
||||
+ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_unlock_irqrestore(&sd->input_pkt_queue.lock, *flags);
|
||||
else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
local_irq_restore(*flags);
|
||||
@@ -271,7 +271,7 @@ static inline void rps_unlock_irq_restor
|
||||
|
||||
static inline void rps_unlock_irq_enable(struct softnet_data *sd)
|
||||
{
|
||||
- if (IS_ENABLED(CONFIG_RPS))
|
||||
+ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_unlock_irq(&sd->input_pkt_queue.lock);
|
||||
else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
local_irq_enable();
|
||||
@@ -4774,6 +4774,23 @@ static void napi_schedule_rps(struct sof
|
||||
__napi_schedule_irqoff(&mysd->backlog);
|
||||
}
|
||||
|
||||
+void kick_defer_list_purge(struct softnet_data *sd, unsigned int cpu)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (use_backlog_threads()) {
|
||||
+ rps_lock_irqsave(sd, &flags);
|
||||
+
|
||||
+ if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state))
|
||||
+ __napi_schedule_irqoff(&sd->backlog);
|
||||
+
|
||||
+ rps_unlock_irq_restore(sd, &flags);
|
||||
+
|
||||
+ } else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) {
|
||||
+ smp_call_function_single_async(cpu, &sd->defer_csd);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_NET_FLOW_LIMIT
|
||||
int netdev_flow_limit_table_len __read_mostly = (1 << 12);
|
||||
#endif
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -6863,8 +6863,8 @@ nodefer: __kfree_skb(skb);
|
||||
/* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU
|
||||
* if we are unlucky enough (this seems very unlikely).
|
||||
*/
|
||||
- if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1))
|
||||
- smp_call_function_single_async(cpu, &sd->defer_csd);
|
||||
+ if (unlikely(kick))
|
||||
+ kick_defer_list_purge(sd, cpu);
|
||||
}
|
||||
|
||||
static void skb_splice_csum_page(struct sk_buff *skb, struct page *page,
|
@ -0,0 +1,164 @@
|
||||
From 765b11f8f4e20b7433e4ba4a3e9106a0d59501ed Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Date: Mon, 25 Mar 2024 08:40:31 +0100
|
||||
Subject: [PATCH 4/4] net: Rename rps_lock to backlog_lock.
|
||||
|
||||
The rps_lock.*() functions use the inner lock of a sk_buff_head for
|
||||
locking. This lock is used if RPS is enabled, otherwise the list is
|
||||
accessed lockless and disabling interrupts is enough for the
|
||||
synchronisation because it is only accessed CPU local. Not only the list
|
||||
is protected but also the NAPI state protected.
|
||||
With the addition of backlog threads, the lock is also needed because of
|
||||
the cross CPU access even without RPS. The clean up of the defer_list
|
||||
list is also done via backlog threads (if enabled).
|
||||
|
||||
It has been suggested to rename the locking function since it is no
|
||||
longer just RPS.
|
||||
|
||||
Rename the rps_lock*() functions to backlog_lock*().
|
||||
|
||||
Suggested-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Acked-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
net/core/dev.c | 34 +++++++++++++++++-----------------
|
||||
1 file changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -243,8 +243,8 @@ static bool use_backlog_threads(void)
|
||||
|
||||
#endif
|
||||
|
||||
-static inline void rps_lock_irqsave(struct softnet_data *sd,
|
||||
- unsigned long *flags)
|
||||
+static inline void backlog_lock_irq_save(struct softnet_data *sd,
|
||||
+ unsigned long *flags)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags);
|
||||
@@ -252,7 +252,7 @@ static inline void rps_lock_irqsave(stru
|
||||
local_irq_save(*flags);
|
||||
}
|
||||
|
||||
-static inline void rps_lock_irq_disable(struct softnet_data *sd)
|
||||
+static inline void backlog_lock_irq_disable(struct softnet_data *sd)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_lock_irq(&sd->input_pkt_queue.lock);
|
||||
@@ -260,8 +260,8 @@ static inline void rps_lock_irq_disable(
|
||||
local_irq_disable();
|
||||
}
|
||||
|
||||
-static inline void rps_unlock_irq_restore(struct softnet_data *sd,
|
||||
- unsigned long *flags)
|
||||
+static inline void backlog_unlock_irq_restore(struct softnet_data *sd,
|
||||
+ unsigned long *flags)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_unlock_irqrestore(&sd->input_pkt_queue.lock, *flags);
|
||||
@@ -269,7 +269,7 @@ static inline void rps_unlock_irq_restor
|
||||
local_irq_restore(*flags);
|
||||
}
|
||||
|
||||
-static inline void rps_unlock_irq_enable(struct softnet_data *sd)
|
||||
+static inline void backlog_unlock_irq_enable(struct softnet_data *sd)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads())
|
||||
spin_unlock_irq(&sd->input_pkt_queue.lock);
|
||||
@@ -4779,12 +4779,12 @@ void kick_defer_list_purge(struct softne
|
||||
unsigned long flags;
|
||||
|
||||
if (use_backlog_threads()) {
|
||||
- rps_lock_irqsave(sd, &flags);
|
||||
+ backlog_lock_irq_save(sd, &flags);
|
||||
|
||||
if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state))
|
||||
__napi_schedule_irqoff(&sd->backlog);
|
||||
|
||||
- rps_unlock_irq_restore(sd, &flags);
|
||||
+ backlog_unlock_irq_restore(sd, &flags);
|
||||
|
||||
} else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) {
|
||||
smp_call_function_single_async(cpu, &sd->defer_csd);
|
||||
@@ -4846,7 +4846,7 @@ static int enqueue_to_backlog(struct sk_
|
||||
reason = SKB_DROP_REASON_NOT_SPECIFIED;
|
||||
sd = &per_cpu(softnet_data, cpu);
|
||||
|
||||
- rps_lock_irqsave(sd, &flags);
|
||||
+ backlog_lock_irq_save(sd, &flags);
|
||||
if (!netif_running(skb->dev))
|
||||
goto drop;
|
||||
qlen = skb_queue_len(&sd->input_pkt_queue);
|
||||
@@ -4855,7 +4855,7 @@ static int enqueue_to_backlog(struct sk_
|
||||
enqueue:
|
||||
__skb_queue_tail(&sd->input_pkt_queue, skb);
|
||||
input_queue_tail_incr_save(sd, qtail);
|
||||
- rps_unlock_irq_restore(sd, &flags);
|
||||
+ backlog_unlock_irq_restore(sd, &flags);
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -4870,7 +4870,7 @@ enqueue:
|
||||
|
||||
drop:
|
||||
sd->dropped++;
|
||||
- rps_unlock_irq_restore(sd, &flags);
|
||||
+ backlog_unlock_irq_restore(sd, &flags);
|
||||
|
||||
dev_core_stats_rx_dropped_inc(skb->dev);
|
||||
kfree_skb_reason(skb, reason);
|
||||
@@ -5901,7 +5901,7 @@ static void flush_backlog(struct work_st
|
||||
local_bh_disable();
|
||||
sd = this_cpu_ptr(&softnet_data);
|
||||
|
||||
- rps_lock_irq_disable(sd);
|
||||
+ backlog_lock_irq_disable(sd);
|
||||
skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
|
||||
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
||||
__skb_unlink(skb, &sd->input_pkt_queue);
|
||||
@@ -5909,7 +5909,7 @@ static void flush_backlog(struct work_st
|
||||
input_queue_head_incr(sd);
|
||||
}
|
||||
}
|
||||
- rps_unlock_irq_enable(sd);
|
||||
+ backlog_unlock_irq_enable(sd);
|
||||
|
||||
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
|
||||
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
||||
@@ -5927,14 +5927,14 @@ static bool flush_required(int cpu)
|
||||
struct softnet_data *sd = &per_cpu(softnet_data, cpu);
|
||||
bool do_flush;
|
||||
|
||||
- rps_lock_irq_disable(sd);
|
||||
+ backlog_lock_irq_disable(sd);
|
||||
|
||||
/* as insertion into process_queue happens with the rps lock held,
|
||||
* process_queue access may race only with dequeue
|
||||
*/
|
||||
do_flush = !skb_queue_empty(&sd->input_pkt_queue) ||
|
||||
!skb_queue_empty_lockless(&sd->process_queue);
|
||||
- rps_unlock_irq_enable(sd);
|
||||
+ backlog_unlock_irq_enable(sd);
|
||||
|
||||
return do_flush;
|
||||
#endif
|
||||
@@ -6049,7 +6049,7 @@ static int process_backlog(struct napi_s
|
||||
|
||||
}
|
||||
|
||||
- rps_lock_irq_disable(sd);
|
||||
+ backlog_lock_irq_disable(sd);
|
||||
if (skb_queue_empty(&sd->input_pkt_queue)) {
|
||||
/*
|
||||
* Inline a custom version of __napi_complete().
|
||||
@@ -6065,7 +6065,7 @@ static int process_backlog(struct napi_s
|
||||
skb_queue_splice_tail_init(&sd->input_pkt_queue,
|
||||
&sd->process_queue);
|
||||
}
|
||||
- rps_unlock_irq_enable(sd);
|
||||
+ backlog_unlock_irq_enable(sd);
|
||||
}
|
||||
|
||||
return work;
|
@ -0,0 +1,45 @@
|
||||
From 6a4aee277740d04ac0fd54cfa17cc28261932ddc Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Mon, 25 Mar 2024 20:06:19 +0100
|
||||
Subject: [PATCH] net: phy: qcom: at803x: fix kernel panic with at8031_probe
|
||||
|
||||
On reworking and splitting the at803x driver, in splitting function of
|
||||
at803x PHYs it was added a NULL dereference bug where priv is referenced
|
||||
before it's actually allocated and then is tried to write to for the
|
||||
is_1000basex and is_fiber variables in the case of at8031, writing on
|
||||
the wrong address.
|
||||
|
||||
Fix this by correctly setting priv local variable only after
|
||||
at803x_probe is called and actually allocates priv in the phydev struct.
|
||||
|
||||
Reported-by: William Wortel <wwortel@dorpstraat.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Fixes: 25d2ba94005f ("net: phy: at803x: move specific at8031 probe mode check to dedicated probe")
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20240325190621.2665-1-ansuelsmth@gmail.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/qcom/at803x.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/qcom/at803x.c
|
||||
+++ b/drivers/net/phy/qcom/at803x.c
|
||||
@@ -797,7 +797,7 @@ static int at8031_parse_dt(struct phy_de
|
||||
|
||||
static int at8031_probe(struct phy_device *phydev)
|
||||
{
|
||||
- struct at803x_priv *priv = phydev->priv;
|
||||
+ struct at803x_priv *priv;
|
||||
int mode_cfg;
|
||||
int ccr;
|
||||
int ret;
|
||||
@@ -806,6 +806,8 @@ static int at8031_probe(struct phy_devic
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ priv = phydev->priv;
|
||||
+
|
||||
/* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
|
||||
* options.
|
||||
*/
|
@ -0,0 +1,28 @@
|
||||
From 27c42e925323b975a64429e313b0cf5c0c02a411 Mon Sep 17 00:00:00 2001
|
||||
From: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Date: Mon, 25 Mar 2024 21:19:48 +0530
|
||||
Subject: dt-bindings: arm: qcom,ids: Add SoC ID for IPQ5321
|
||||
|
||||
Add the ID for the Qualcomm IPQ5321 SoC.
|
||||
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Mukesh Ojha <quic_mojha@quicinc.com>
|
||||
Signed-off-by: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240325-ipq5321-sku-support-v2-1-f30ce244732f@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
include/dt-bindings/arm/qcom,ids.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
(limited to 'include/dt-bindings/arm/qcom,ids.h')
|
||||
|
||||
--- a/include/dt-bindings/arm/qcom,ids.h
|
||||
+++ b/include/dt-bindings/arm/qcom,ids.h
|
||||
@@ -260,6 +260,7 @@
|
||||
#define QCOM_ID_IPQ5312 594
|
||||
#define QCOM_ID_IPQ5302 595
|
||||
#define QCOM_ID_IPQ5300 624
|
||||
+#define QCOM_ID_IPQ5321 650
|
||||
|
||||
/*
|
||||
* The board type and revision information, used by Qualcomm bootloaders and
|
@ -0,0 +1,27 @@
|
||||
From 380b50ae3a04222334a3779b3787eba844b1177f Mon Sep 17 00:00:00 2001
|
||||
From: Marco von Rosenberg <marcovr@selfnet.de>
|
||||
Date: Thu, 16 Nov 2023 20:32:31 +0100
|
||||
Subject: net: phy: broadcom: Wire suspend/resume for BCM54612E
|
||||
|
||||
The BCM54612E ethernet PHY supports IDDQ-SR.
|
||||
Therefore wire-up the suspend and resume callbacks
|
||||
to point to bcm54xx_suspend() and bcm54xx_resume().
|
||||
|
||||
Signed-off-by: Marco von Rosenberg <marcovr@selfnet.de>
|
||||
Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/broadcom.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/broadcom.c
|
||||
+++ b/drivers/net/phy/broadcom.c
|
||||
@@ -1001,6 +1001,8 @@ static struct phy_driver broadcom_driver
|
||||
.config_intr = bcm_phy_config_intr,
|
||||
.handle_interrupt = bcm_phy_handle_interrupt,
|
||||
.link_change_notify = bcm54xx_link_change_notify,
|
||||
+ .suspend = bcm54xx_suspend,
|
||||
+ .resume = bcm54xx_resume,
|
||||
}, {
|
||||
.phy_id = PHY_ID_BCM5421,
|
||||
.phy_id_mask = 0xfffffff0,
|
@ -0,0 +1,68 @@
|
||||
From abb45a2477f533cd4aab3085defdff131e2e8c4f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Mon, 6 May 2024 14:32:46 +0200
|
||||
Subject: [PATCH] net: stmmac: dwmac-ipq806x: account for rgmii-txid/rxid/id
|
||||
phy-mode
|
||||
|
||||
Currently the ipq806x dwmac driver is almost always used attached to the
|
||||
CPU port of a switch and phy-mode was always set to "rgmii" or "sgmii".
|
||||
|
||||
Some device came up with a special configuration where the PHY is
|
||||
directly attached to the GMAC port and in those case phy-mode needs to
|
||||
be set to "rgmii-id" to make the PHY correctly work and receive packets.
|
||||
|
||||
Since the driver supports only "rgmii" and "sgmii" mode, when "rgmii-id"
|
||||
(or variants) mode is set, the mode is rejected and probe fails.
|
||||
|
||||
Add support also for these phy-modes to correctly setup PHYs that requires
|
||||
delay applied to tx/rx.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
||||
@@ -171,6 +171,9 @@ static int ipq806x_gmac_set_speed(struct
|
||||
|
||||
switch (gmac->phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
div = get_clk_div_rgmii(gmac, speed);
|
||||
clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
||||
NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
||||
@@ -412,6 +415,9 @@ static int ipq806x_gmac_probe(struct pla
|
||||
val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
|
||||
switch (gmac->phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
@@ -427,6 +433,9 @@ static int ipq806x_gmac_probe(struct pla
|
||||
val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
|
||||
switch (gmac->phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
|
||||
NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
break;
|
||||
@@ -444,6 +453,9 @@ static int ipq806x_gmac_probe(struct pla
|
||||
val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
|
||||
switch (gmac->phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
||||
NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
||||
break;
|
@ -0,0 +1,605 @@
|
||||
From 5d0fad48d2dec175ecb999974b94203c577973ef Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 May 2024 11:43:34 +0100
|
||||
Subject: [PATCH] net: ethernet: mediatek: split tx and rx fields in
|
||||
mtk_soc_data struct
|
||||
|
||||
Split tx and rx fields in mtk_soc_data struct. This is a preliminary
|
||||
patch to roll back to ADMAv1 for MT7986 and MT7981 SoC in order to fix a
|
||||
hw hang if the device receives a corrupted packet when using ADMAv2.0.
|
||||
|
||||
Fixes: 197c9e9b17b1 ("net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Link: https://lore.kernel.org/r/70a799b1f060ec2f57883e88ccb420ac0fb0abb5.1715164770.git.daniel@makrotopia.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 210 ++++++++++++--------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 29 +--
|
||||
2 files changed, 139 insertions(+), 100 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -1138,7 +1138,7 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
eth->scratch_ring = eth->sram_base;
|
||||
else
|
||||
eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
|
||||
- cnt * soc->txrx.txd_size,
|
||||
+ cnt * soc->tx.desc_size,
|
||||
ð->phy_scratch_ring,
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!eth->scratch_ring))
|
||||
@@ -1154,16 +1154,16 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
|
||||
return -ENOMEM;
|
||||
|
||||
- phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
|
||||
+ phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
struct mtk_tx_dma_v2 *txd;
|
||||
|
||||
- txd = eth->scratch_ring + i * soc->txrx.txd_size;
|
||||
+ txd = eth->scratch_ring + i * soc->tx.desc_size;
|
||||
txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
|
||||
if (i < cnt - 1)
|
||||
txd->txd2 = eth->phy_scratch_ring +
|
||||
- (i + 1) * soc->txrx.txd_size;
|
||||
+ (i + 1) * soc->tx.desc_size;
|
||||
|
||||
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
txd->txd4 = 0;
|
||||
@@ -1412,7 +1412,7 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
if (itxd == ring->last_free)
|
||||
return -ENOMEM;
|
||||
|
||||
- itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
|
||||
+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
|
||||
memset(itx_buf, 0, sizeof(*itx_buf));
|
||||
|
||||
txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
|
||||
@@ -1453,7 +1453,7 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
|
||||
memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
|
||||
txd_info.size = min_t(unsigned int, frag_size,
|
||||
- soc->txrx.dma_max_len);
|
||||
+ soc->tx.dma_max_len);
|
||||
txd_info.qid = queue;
|
||||
txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
|
||||
!(frag_size - txd_info.size);
|
||||
@@ -1466,7 +1466,7 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
mtk_tx_set_dma_desc(dev, txd, &txd_info);
|
||||
|
||||
tx_buf = mtk_desc_to_tx_buf(ring, txd,
|
||||
- soc->txrx.txd_size);
|
||||
+ soc->tx.desc_size);
|
||||
if (new_desc)
|
||||
memset(tx_buf, 0, sizeof(*tx_buf));
|
||||
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
|
||||
@@ -1509,7 +1509,7 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
} else {
|
||||
int next_idx;
|
||||
|
||||
- next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size),
|
||||
+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
|
||||
ring->dma_size);
|
||||
mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
|
||||
}
|
||||
@@ -1518,7 +1518,7 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
|
||||
err_dma:
|
||||
do {
|
||||
- tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
|
||||
+ tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
|
||||
|
||||
/* unmap dma */
|
||||
mtk_tx_unmap(eth, tx_buf, NULL, false);
|
||||
@@ -1543,7 +1543,7 @@ static int mtk_cal_txd_req(struct mtk_et
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
nfrags += DIV_ROUND_UP(skb_frag_size(frag),
|
||||
- eth->soc->txrx.dma_max_len);
|
||||
+ eth->soc->tx.dma_max_len);
|
||||
}
|
||||
} else {
|
||||
nfrags += skb_shinfo(skb)->nr_frags;
|
||||
@@ -1650,7 +1650,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
|
||||
|
||||
ring = ð->rx_ring[i];
|
||||
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
|
||||
- rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
|
||||
+ rxd = ring->dma + idx * eth->soc->rx.desc_size;
|
||||
if (rxd->rxd2 & RX_DMA_DONE) {
|
||||
ring->calc_idx_update = true;
|
||||
return ring;
|
||||
@@ -1818,7 +1818,7 @@ static int mtk_xdp_submit_frame(struct m
|
||||
}
|
||||
htxd = txd;
|
||||
|
||||
- tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
|
||||
+ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
|
||||
memset(tx_buf, 0, sizeof(*tx_buf));
|
||||
htx_buf = tx_buf;
|
||||
|
||||
@@ -1837,7 +1837,7 @@ static int mtk_xdp_submit_frame(struct m
|
||||
goto unmap;
|
||||
|
||||
tx_buf = mtk_desc_to_tx_buf(ring, txd,
|
||||
- soc->txrx.txd_size);
|
||||
+ soc->tx.desc_size);
|
||||
memset(tx_buf, 0, sizeof(*tx_buf));
|
||||
n_desc++;
|
||||
}
|
||||
@@ -1875,7 +1875,7 @@ static int mtk_xdp_submit_frame(struct m
|
||||
} else {
|
||||
int idx;
|
||||
|
||||
- idx = txd_to_idx(ring, txd, soc->txrx.txd_size);
|
||||
+ idx = txd_to_idx(ring, txd, soc->tx.desc_size);
|
||||
mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
|
||||
MT7628_TX_CTX_IDX0);
|
||||
}
|
||||
@@ -1886,7 +1886,7 @@ static int mtk_xdp_submit_frame(struct m
|
||||
|
||||
unmap:
|
||||
while (htxd != txd) {
|
||||
- tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size);
|
||||
+ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
|
||||
mtk_tx_unmap(eth, tx_buf, NULL, false);
|
||||
|
||||
htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
|
||||
@@ -2017,7 +2017,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
goto rx_done;
|
||||
|
||||
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
|
||||
- rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
|
||||
+ rxd = ring->dma + idx * eth->soc->rx.desc_size;
|
||||
data = ring->data[idx];
|
||||
|
||||
if (!mtk_rx_get_desc(eth, &trxd, rxd))
|
||||
@@ -2152,7 +2152,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
rxdcsum = &trxd.rxd4;
|
||||
}
|
||||
|
||||
- if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
|
||||
+ if (*rxdcsum & eth->soc->rx.dma_l4_valid)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
else
|
||||
skb_checksum_none_assert(skb);
|
||||
@@ -2276,7 +2276,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
|
||||
break;
|
||||
|
||||
tx_buf = mtk_desc_to_tx_buf(ring, desc,
|
||||
- eth->soc->txrx.txd_size);
|
||||
+ eth->soc->tx.desc_size);
|
||||
if (!tx_buf->data)
|
||||
break;
|
||||
|
||||
@@ -2327,7 +2327,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
|
||||
}
|
||||
mtk_tx_unmap(eth, tx_buf, &bq, true);
|
||||
|
||||
- desc = ring->dma + cpu * eth->soc->txrx.txd_size;
|
||||
+ desc = ring->dma + cpu * eth->soc->tx.desc_size;
|
||||
ring->last_free = desc;
|
||||
atomic_inc(&ring->free_count);
|
||||
|
||||
@@ -2417,7 +2417,7 @@ static int mtk_napi_rx(struct napi_struc
|
||||
do {
|
||||
int rx_done;
|
||||
|
||||
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask,
|
||||
+ mtk_w32(eth, eth->soc->rx.irq_done_mask,
|
||||
reg_map->pdma.irq_status);
|
||||
rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
|
||||
rx_done_total += rx_done;
|
||||
@@ -2433,10 +2433,10 @@ static int mtk_napi_rx(struct napi_struc
|
||||
return budget;
|
||||
|
||||
} while (mtk_r32(eth, reg_map->pdma.irq_status) &
|
||||
- eth->soc->txrx.rx_irq_done_mask);
|
||||
+ eth->soc->rx.irq_done_mask);
|
||||
|
||||
if (napi_complete_done(napi, rx_done_total))
|
||||
- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
|
||||
|
||||
return rx_done_total;
|
||||
}
|
||||
@@ -2445,7 +2445,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
{
|
||||
const struct mtk_soc_data *soc = eth->soc;
|
||||
struct mtk_tx_ring *ring = ð->tx_ring;
|
||||
- int i, sz = soc->txrx.txd_size;
|
||||
+ int i, sz = soc->tx.desc_size;
|
||||
struct mtk_tx_dma_v2 *txd;
|
||||
int ring_size;
|
||||
u32 ofs, val;
|
||||
@@ -2568,14 +2568,14 @@ static void mtk_tx_clean(struct mtk_eth
|
||||
}
|
||||
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
|
||||
dma_free_coherent(eth->dma_dev,
|
||||
- ring->dma_size * soc->txrx.txd_size,
|
||||
+ ring->dma_size * soc->tx.desc_size,
|
||||
ring->dma, ring->phys);
|
||||
ring->dma = NULL;
|
||||
}
|
||||
|
||||
if (ring->dma_pdma) {
|
||||
dma_free_coherent(eth->dma_dev,
|
||||
- ring->dma_size * soc->txrx.txd_size,
|
||||
+ ring->dma_size * soc->tx.desc_size,
|
||||
ring->dma_pdma, ring->phys_pdma);
|
||||
ring->dma_pdma = NULL;
|
||||
}
|
||||
@@ -2630,15 +2630,15 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
|
||||
rx_flag != MTK_RX_FLAGS_NORMAL) {
|
||||
ring->dma = dma_alloc_coherent(eth->dma_dev,
|
||||
- rx_dma_size * eth->soc->txrx.rxd_size,
|
||||
- &ring->phys, GFP_KERNEL);
|
||||
+ rx_dma_size * eth->soc->rx.desc_size,
|
||||
+ &ring->phys, GFP_KERNEL);
|
||||
} else {
|
||||
struct mtk_tx_ring *tx_ring = ð->tx_ring;
|
||||
|
||||
ring->dma = tx_ring->dma + tx_ring_size *
|
||||
- eth->soc->txrx.txd_size * (ring_no + 1);
|
||||
+ eth->soc->tx.desc_size * (ring_no + 1);
|
||||
ring->phys = tx_ring->phys + tx_ring_size *
|
||||
- eth->soc->txrx.txd_size * (ring_no + 1);
|
||||
+ eth->soc->tx.desc_size * (ring_no + 1);
|
||||
}
|
||||
|
||||
if (!ring->dma)
|
||||
@@ -2649,7 +2649,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
dma_addr_t dma_addr;
|
||||
void *data;
|
||||
|
||||
- rxd = ring->dma + i * eth->soc->txrx.rxd_size;
|
||||
+ rxd = ring->dma + i * eth->soc->rx.desc_size;
|
||||
if (ring->page_pool) {
|
||||
data = mtk_page_pool_get_buff(ring->page_pool,
|
||||
&dma_addr, GFP_KERNEL);
|
||||
@@ -2740,7 +2740,7 @@ static void mtk_rx_clean(struct mtk_eth
|
||||
if (!ring->data[i])
|
||||
continue;
|
||||
|
||||
- rxd = ring->dma + i * eth->soc->txrx.rxd_size;
|
||||
+ rxd = ring->dma + i * eth->soc->rx.desc_size;
|
||||
if (!rxd->rxd1)
|
||||
continue;
|
||||
|
||||
@@ -2757,7 +2757,7 @@ static void mtk_rx_clean(struct mtk_eth
|
||||
|
||||
if (!in_sram && ring->dma) {
|
||||
dma_free_coherent(eth->dma_dev,
|
||||
- ring->dma_size * eth->soc->txrx.rxd_size,
|
||||
+ ring->dma_size * eth->soc->rx.desc_size,
|
||||
ring->dma, ring->phys);
|
||||
ring->dma = NULL;
|
||||
}
|
||||
@@ -3120,7 +3120,7 @@ static void mtk_dma_free(struct mtk_eth
|
||||
netdev_reset_queue(eth->netdev[i]);
|
||||
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
|
||||
dma_free_coherent(eth->dma_dev,
|
||||
- MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
|
||||
+ MTK_QDMA_RING_SIZE * soc->tx.desc_size,
|
||||
eth->scratch_ring, eth->phy_scratch_ring);
|
||||
eth->scratch_ring = NULL;
|
||||
eth->phy_scratch_ring = 0;
|
||||
@@ -3170,7 +3170,7 @@ static irqreturn_t mtk_handle_irq_rx(int
|
||||
|
||||
eth->rx_events++;
|
||||
if (likely(napi_schedule_prep(ð->rx_napi))) {
|
||||
- mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
|
||||
__napi_schedule(ð->rx_napi);
|
||||
}
|
||||
|
||||
@@ -3196,9 +3196,9 @@ static irqreturn_t mtk_handle_irq(int ir
|
||||
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
|
||||
|
||||
if (mtk_r32(eth, reg_map->pdma.irq_mask) &
|
||||
- eth->soc->txrx.rx_irq_done_mask) {
|
||||
+ eth->soc->rx.irq_done_mask) {
|
||||
if (mtk_r32(eth, reg_map->pdma.irq_status) &
|
||||
- eth->soc->txrx.rx_irq_done_mask)
|
||||
+ eth->soc->rx.irq_done_mask)
|
||||
mtk_handle_irq_rx(irq, _eth);
|
||||
}
|
||||
if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
|
||||
@@ -3216,10 +3216,10 @@ static void mtk_poll_controller(struct n
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
|
||||
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
|
||||
- mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
|
||||
mtk_handle_irq_rx(eth->irq[2], dev);
|
||||
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
|
||||
- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3383,7 +3383,7 @@ static int mtk_open(struct net_device *d
|
||||
napi_enable(ð->tx_napi);
|
||||
napi_enable(ð->rx_napi);
|
||||
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
|
||||
- mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_enable(eth, soc->rx.irq_done_mask);
|
||||
refcount_set(ð->dma_refcnt, 1);
|
||||
}
|
||||
else
|
||||
@@ -3467,7 +3467,7 @@ static int mtk_stop(struct net_device *d
|
||||
mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
|
||||
|
||||
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
|
||||
- mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
+ mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
|
||||
napi_disable(ð->tx_napi);
|
||||
napi_disable(ð->rx_napi);
|
||||
|
||||
@@ -3943,9 +3943,9 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
|
||||
/* FE int grouping */
|
||||
mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
|
||||
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4);
|
||||
+ mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4);
|
||||
mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
|
||||
- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
|
||||
+ mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4);
|
||||
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
|
||||
|
||||
if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
@@ -5037,11 +5037,15 @@ static const struct mtk_soc_data mt2701_
|
||||
.required_clks = MT7623_CLKS_BITMAP,
|
||||
.required_pctl = true,
|
||||
.version = 1,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5057,11 +5061,15 @@ static const struct mtk_soc_data mt7621_
|
||||
.offload_version = 1,
|
||||
.hash_offset = 2,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5079,11 +5087,15 @@ static const struct mtk_soc_data mt7622_
|
||||
.hash_offset = 2,
|
||||
.has_accounting = true,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5100,11 +5112,15 @@ static const struct mtk_soc_data mt7623_
|
||||
.hash_offset = 2,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
|
||||
.disable_pll_modes = true,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5119,11 +5135,15 @@ static const struct mtk_soc_data mt7629_
|
||||
.required_pctl = false,
|
||||
.has_accounting = true,
|
||||
.version = 1,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5141,11 +5161,15 @@ static const struct mtk_soc_data mt7981_
|
||||
.hash_offset = 4,
|
||||
.has_accounting = true,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
},
|
||||
@@ -5163,11 +5187,15 @@ static const struct mtk_soc_data mt7986_
|
||||
.hash_offset = 4,
|
||||
.has_accounting = true,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
},
|
||||
@@ -5185,11 +5213,15 @@ static const struct mtk_soc_data mt7988_
|
||||
.hash_offset = 4,
|
||||
.has_accounting = true,
|
||||
.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
},
|
||||
@@ -5202,11 +5234,15 @@ static const struct mtk_soc_data rt5350_
|
||||
.required_clks = MT7628_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
.version = 1,
|
||||
- .txrx = {
|
||||
- .txd_size = sizeof(struct mtk_tx_dma),
|
||||
- .rxd_size = sizeof(struct mtk_rx_dma),
|
||||
- .rx_irq_done_mask = MTK_RX_DONE_INT,
|
||||
- .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
|
||||
+ .tx = {
|
||||
+ .desc_size = sizeof(struct mtk_tx_dma),
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
+ .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -327,8 +327,8 @@
|
||||
/* QDMA descriptor txd3 */
|
||||
#define TX_DMA_OWNER_CPU BIT(31)
|
||||
#define TX_DMA_LS0 BIT(30)
|
||||
-#define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
|
||||
-#define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
|
||||
+#define TX_DMA_PLEN0(x) (((x) & eth->soc->tx.dma_max_len) << eth->soc->tx.dma_len_offset)
|
||||
+#define TX_DMA_PLEN1(x) ((x) & eth->soc->tx.dma_max_len)
|
||||
#define TX_DMA_SWC BIT(14)
|
||||
#define TX_DMA_PQID GENMASK(3, 0)
|
||||
#define TX_DMA_ADDR64_MASK GENMASK(3, 0)
|
||||
@@ -348,8 +348,8 @@
|
||||
/* QDMA descriptor rxd2 */
|
||||
#define RX_DMA_DONE BIT(31)
|
||||
#define RX_DMA_LSO BIT(30)
|
||||
-#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
|
||||
-#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
|
||||
+#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->rx.dma_max_len) << eth->soc->rx.dma_len_offset)
|
||||
+#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->rx.dma_len_offset) & eth->soc->rx.dma_max_len)
|
||||
#define RX_DMA_VTAG BIT(15)
|
||||
#define RX_DMA_ADDR64_MASK GENMASK(3, 0)
|
||||
#if IS_ENABLED(CONFIG_64BIT)
|
||||
@@ -1153,10 +1153,9 @@ struct mtk_reg_map {
|
||||
* @foe_entry_size Foe table entry size.
|
||||
* @has_accounting Bool indicating support for accounting of
|
||||
* offloaded flows.
|
||||
- * @txd_size Tx DMA descriptor size.
|
||||
- * @rxd_size Rx DMA descriptor size.
|
||||
- * @rx_irq_done_mask Rx irq done register mask.
|
||||
- * @rx_dma_l4_valid Rx DMA valid register mask.
|
||||
+ * @desc_size Tx/Rx DMA descriptor size.
|
||||
+ * @irq_done_mask Rx irq done register mask.
|
||||
+ * @dma_l4_valid Rx DMA valid register mask.
|
||||
* @dma_max_len Max DMA tx/rx buffer length.
|
||||
* @dma_len_offset Tx/Rx DMA length field offset.
|
||||
*/
|
||||
@@ -1174,13 +1173,17 @@ struct mtk_soc_data {
|
||||
bool has_accounting;
|
||||
bool disable_pll_modes;
|
||||
struct {
|
||||
- u32 txd_size;
|
||||
- u32 rxd_size;
|
||||
- u32 rx_irq_done_mask;
|
||||
- u32 rx_dma_l4_valid;
|
||||
+ u32 desc_size;
|
||||
u32 dma_max_len;
|
||||
u32 dma_len_offset;
|
||||
- } txrx;
|
||||
+ } tx;
|
||||
+ struct {
|
||||
+ u32 desc_size;
|
||||
+ u32 irq_done_mask;
|
||||
+ u32 dma_l4_valid;
|
||||
+ u32 dma_max_len;
|
||||
+ u32 dma_len_offset;
|
||||
+ } rx;
|
||||
};
|
||||
|
||||
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
|
@ -0,0 +1,128 @@
|
||||
From 4d572e867bdb372bb4add39a0fa495c6a9c9a8da Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 8 May 2024 11:43:56 +0100
|
||||
Subject: [PATCH] net: ethernet: mediatek: use ADMAv1 instead of ADMAv2.0 on
|
||||
MT7981 and MT7986
|
||||
|
||||
ADMAv2.0 is plagued by RX hangs which can't easily detected and happen upon
|
||||
receival of a corrupted Ethernet frame.
|
||||
|
||||
Use ADMAv1 instead which is also still present and usable, and doesn't
|
||||
suffer from that problem.
|
||||
|
||||
Fixes: 197c9e9b17b1 ("net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset")
|
||||
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/57cef74bbd0c243366ad1ff4221e3f72f437ec80.1715164770.git.daniel@makrotopia.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 46 ++++++++++-----------
|
||||
1 file changed, 23 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -110,16 +110,16 @@ static const struct mtk_reg_map mt7986_r
|
||||
.tx_irq_mask = 0x461c,
|
||||
.tx_irq_status = 0x4618,
|
||||
.pdma = {
|
||||
- .rx_ptr = 0x6100,
|
||||
- .rx_cnt_cfg = 0x6104,
|
||||
- .pcrx_ptr = 0x6108,
|
||||
- .glo_cfg = 0x6204,
|
||||
- .rst_idx = 0x6208,
|
||||
- .delay_irq = 0x620c,
|
||||
- .irq_status = 0x6220,
|
||||
- .irq_mask = 0x6228,
|
||||
- .adma_rx_dbg0 = 0x6238,
|
||||
- .int_grp = 0x6250,
|
||||
+ .rx_ptr = 0x4100,
|
||||
+ .rx_cnt_cfg = 0x4104,
|
||||
+ .pcrx_ptr = 0x4108,
|
||||
+ .glo_cfg = 0x4204,
|
||||
+ .rst_idx = 0x4208,
|
||||
+ .delay_irq = 0x420c,
|
||||
+ .irq_status = 0x4220,
|
||||
+ .irq_mask = 0x4228,
|
||||
+ .adma_rx_dbg0 = 0x4238,
|
||||
+ .int_grp = 0x4250,
|
||||
},
|
||||
.qdma = {
|
||||
.qtx_cfg = 0x4400,
|
||||
@@ -1106,7 +1106,7 @@ static bool mtk_rx_get_desc(struct mtk_e
|
||||
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
|
||||
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
|
||||
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
|
||||
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
|
||||
}
|
||||
@@ -2024,7 +2024,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
break;
|
||||
|
||||
/* find out which mac the packet come from. values start at 1 */
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
|
||||
|
||||
switch (val) {
|
||||
@@ -2136,7 +2136,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
skb->dev = netdev;
|
||||
bytes += skb->len;
|
||||
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
|
||||
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
|
||||
if (hash != MTK_RXD5_FOE_ENTRY)
|
||||
@@ -2686,7 +2686,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
|
||||
rxd->rxd3 = 0;
|
||||
rxd->rxd4 = 0;
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
rxd->rxd5 = 0;
|
||||
rxd->rxd6 = 0;
|
||||
rxd->rxd7 = 0;
|
||||
@@ -3889,7 +3889,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
else
|
||||
mtk_hw_reset(eth);
|
||||
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
/* Set FE to PDMAv2 if necessary */
|
||||
val = mtk_r32(eth, MTK_FE_GLO_MISC);
|
||||
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
|
||||
@@ -5167,11 +5167,11 @@ static const struct mtk_soc_data mt7981_
|
||||
.dma_len_offset = 8,
|
||||
},
|
||||
.rx = {
|
||||
- .desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
- .irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
- .dma_len_offset = 8,
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5193,11 +5193,11 @@ static const struct mtk_soc_data mt7986_
|
||||
.dma_len_offset = 8,
|
||||
},
|
||||
.rx = {
|
||||
- .desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
- .irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .desc_size = sizeof(struct mtk_rx_dma),
|
||||
+ .irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
- .dma_len_offset = 8,
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
+ .dma_len_offset = 16,
|
||||
},
|
||||
};
|
||||
|
@ -0,0 +1,113 @@
|
||||
From 52ea72ad0daa0f29535b4cef39257616c5a211d3 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 24 Oct 2023 00:00:19 +0200
|
||||
Subject: [PATCH 1/5] net: ethernet: mtk_wed: fix firmware loading for MT7986
|
||||
SoC
|
||||
|
||||
The WED mcu firmware does not contain all the memory regions defined in
|
||||
the dts reserved_memory node (e.g. MT7986 WED firmware does not contain
|
||||
cpu-boot region).
|
||||
Reverse the mtk_wed_mcu_run_firmware() logic to check all the fw
|
||||
sections are defined in the dts reserved_memory node.
|
||||
|
||||
Fixes: c6d961aeaa77 ("net: ethernet: mtk_wed: move mem_region array out of mtk_wed_mcu_load_firmware")
|
||||
Tested-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/d983cbfe8ea562fef9264de8f0c501f7d5705bd5.1698098381.git.lorenzo@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 48 +++++++++++----------
|
||||
1 file changed, 25 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
|
||||
@@ -258,16 +258,12 @@ mtk_wed_get_memory_region(struct mtk_wed
|
||||
}
|
||||
|
||||
static int
|
||||
-mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw,
|
||||
- struct mtk_wed_wo_memory_region *region)
|
||||
+mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw)
|
||||
{
|
||||
const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data;
|
||||
const struct mtk_wed_fw_trailer *trailer;
|
||||
const struct mtk_wed_fw_region *fw_region;
|
||||
|
||||
- if (!region->phy_addr || !region->size)
|
||||
- return 0;
|
||||
-
|
||||
trailer_ptr = fw->data + fw->size - sizeof(*trailer);
|
||||
trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
|
||||
region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
|
||||
@@ -275,33 +271,41 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_
|
||||
|
||||
while (region_ptr < trailer_ptr) {
|
||||
u32 length;
|
||||
+ int i;
|
||||
|
||||
fw_region = (const struct mtk_wed_fw_region *)region_ptr;
|
||||
length = le32_to_cpu(fw_region->len);
|
||||
-
|
||||
- if (region->phy_addr != le32_to_cpu(fw_region->addr))
|
||||
- goto next;
|
||||
-
|
||||
- if (region->size < length)
|
||||
- goto next;
|
||||
-
|
||||
if (first_region_ptr < ptr + length)
|
||||
goto next;
|
||||
|
||||
- if (region->shared && region->consumed)
|
||||
- return 0;
|
||||
+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
|
||||
+ struct mtk_wed_wo_memory_region *region;
|
||||
|
||||
- if (!region->shared || !region->consumed) {
|
||||
- memcpy_toio(region->addr, ptr, length);
|
||||
- region->consumed = true;
|
||||
- return 0;
|
||||
+ region = &mem_region[i];
|
||||
+ if (region->phy_addr != le32_to_cpu(fw_region->addr))
|
||||
+ continue;
|
||||
+
|
||||
+ if (region->size < length)
|
||||
+ continue;
|
||||
+
|
||||
+ if (region->shared && region->consumed)
|
||||
+ break;
|
||||
+
|
||||
+ if (!region->shared || !region->consumed) {
|
||||
+ memcpy_toio(region->addr, ptr, length);
|
||||
+ region->consumed = true;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (i == ARRAY_SIZE(mem_region))
|
||||
+ return -EINVAL;
|
||||
next:
|
||||
region_ptr += sizeof(*fw_region);
|
||||
ptr += length;
|
||||
}
|
||||
|
||||
- return -EINVAL;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -360,11 +364,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
|
||||
dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n",
|
||||
trailer->chip_id, trailer->num_region);
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
|
||||
- ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
- }
|
||||
+ ret = mtk_wed_mcu_run_firmware(wo, fw);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
|
||||
/* set the start address */
|
||||
if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
|
@ -0,0 +1,51 @@
|
||||
From 7aa8defd3495208289abcc629946af26a2af3391 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 24 Oct 2023 00:01:30 +0200
|
||||
Subject: [PATCH 2/5] net: ethernet: mtk_wed: remove wo pointer in
|
||||
wo_r32/wo_w32 signature
|
||||
|
||||
wo pointer is no longer used in wo_r32 and wo_w32 routines so get rid of
|
||||
it.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/530537db0872f7523deff21f0a5dfdd9b75fdc9d.1698098459.git.lorenzo@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
|
||||
@@ -32,12 +32,12 @@ static struct mtk_wed_wo_memory_region m
|
||||
},
|
||||
};
|
||||
|
||||
-static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
|
||||
+static u32 wo_r32(u32 reg)
|
||||
{
|
||||
return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
|
||||
}
|
||||
|
||||
-static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
|
||||
+static void wo_w32(u32 reg, u32 val)
|
||||
{
|
||||
writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
|
||||
}
|
||||
@@ -373,13 +373,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
|
||||
boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
|
||||
else
|
||||
boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
|
||||
- wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
|
||||
+ wo_w32(boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
|
||||
/* wo firmware reset */
|
||||
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
|
||||
+ wo_w32(MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
|
||||
|
||||
- val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
|
||||
+ val = wo_r32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
|
||||
MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
|
||||
- wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
|
||||
+ wo_w32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 65aacd457eaf5d0c958ed8030ec46f99ea808dd9 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 17 Nov 2023 17:39:22 +0100
|
||||
Subject: [PATCH 3/5] net: ethernet: mtk_wed: rely on __dev_alloc_page in
|
||||
mtk_wed_tx_buffer_alloc
|
||||
|
||||
Simplify the code and use __dev_alloc_page() instead of __dev_alloc_pages()
|
||||
with order 0 in mtk_wed_tx_buffer_alloc routine
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_wed.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
|
||||
@@ -670,7 +670,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
|
||||
void *buf;
|
||||
int s;
|
||||
|
||||
- page = __dev_alloc_pages(GFP_KERNEL, 0);
|
||||
+ page = __dev_alloc_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
@ -0,0 +1,91 @@
|
||||
From 5f5997322584b6257543d4d103f81484b8006d84 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 17 Nov 2023 17:42:59 +0100
|
||||
Subject: [PATCH 4/5] net: ethernet: mtk_wed: add support for devices with more
|
||||
than 4GB of dram
|
||||
|
||||
Introduce WED offloading support for boards with more than 4GB of
|
||||
memory.
|
||||
|
||||
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
|
||||
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/1c7efdf5d384ea7af3c0209723e40b2ee0f956bf.1700239272.git.lorenzo@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 ++++-
|
||||
drivers/net/ethernet/mediatek/mtk_wed.c | 8 +++++---
|
||||
drivers/net/ethernet/mediatek/mtk_wed_wo.c | 3 ++-
|
||||
3 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -1158,15 +1158,18 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
+ dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
|
||||
struct mtk_tx_dma_v2 *txd;
|
||||
|
||||
txd = eth->scratch_ring + i * soc->tx.desc_size;
|
||||
- txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
|
||||
+ txd->txd1 = addr;
|
||||
if (i < cnt - 1)
|
||||
txd->txd2 = eth->phy_scratch_ring +
|
||||
(i + 1) * soc->tx.desc_size;
|
||||
|
||||
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
+ if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
|
||||
+ txd->txd3 |= TX_DMA_PREP_ADDR64(addr);
|
||||
txd->txd4 = 0;
|
||||
if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
txd->txd5 = 0;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
|
||||
@@ -691,10 +691,11 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
|
||||
|
||||
for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
|
||||
struct mtk_wdma_desc *desc = desc_ptr;
|
||||
+ u32 ctrl;
|
||||
|
||||
desc->buf0 = cpu_to_le32(buf_phys);
|
||||
if (!mtk_wed_is_v3_or_greater(dev->hw)) {
|
||||
- u32 txd_size, ctrl;
|
||||
+ u32 txd_size;
|
||||
|
||||
txd_size = dev->wlan.init_buf(buf, buf_phys,
|
||||
token++);
|
||||
@@ -708,11 +709,11 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
|
||||
ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 |
|
||||
FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
|
||||
MTK_WED_BUF_SIZE - txd_size);
|
||||
- desc->ctrl = cpu_to_le32(ctrl);
|
||||
desc->info = 0;
|
||||
} else {
|
||||
- desc->ctrl = cpu_to_le32(token << 16);
|
||||
+ ctrl = token << 16 | TX_DMA_PREP_ADDR64(buf_phys);
|
||||
}
|
||||
+ desc->ctrl = cpu_to_le32(ctrl);
|
||||
|
||||
desc_ptr += desc_size;
|
||||
buf += MTK_WED_BUF_SIZE;
|
||||
@@ -811,6 +812,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_we
|
||||
buf_phys = page_phys;
|
||||
for (s = 0; s < MTK_WED_RX_BUF_PER_PAGE; s++) {
|
||||
desc->buf0 = cpu_to_le32(buf_phys);
|
||||
+ desc->token = cpu_to_le32(RX_DMA_PREP_ADDR64(buf_phys));
|
||||
buf_phys += MTK_WED_PAGE_BUF_SIZE;
|
||||
desc++;
|
||||
}
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
|
||||
@@ -142,7 +142,8 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
|
||||
dma_addr_t addr;
|
||||
void *buf;
|
||||
|
||||
- buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC);
|
||||
+ buf = page_frag_alloc(&q->cache, q->buf_size,
|
||||
+ GFP_ATOMIC | GFP_DMA32);
|
||||
if (!buf)
|
||||
break;
|
||||
|
@ -0,0 +1,364 @@
|
||||
From c57e558194430d10d5e5f4acd8a8655b68dade13 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Wunderlich <frank-w@public-files.de>
|
||||
Date: Mon, 3 Jun 2024 21:25:05 +0200
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: handle dma buffer size soc
|
||||
specific
|
||||
|
||||
The mainline MTK ethernet driver suffers long time from rarly but
|
||||
annoying tx queue timeouts. We think that this is caused by fixed
|
||||
dma sizes hardcoded for all SoCs.
|
||||
|
||||
We suspect this problem arises from a low level of free TX DMADs,
|
||||
the TX Ring alomost full.
|
||||
|
||||
The transmit timeout is caused by the Tx queue not waking up. The
|
||||
Tx queue stops when the free counter is less than ring->thres, and
|
||||
it will wake up once the free counter is greater than ring->thres.
|
||||
If the CPU is too late to wake up the Tx queues, it may cause a
|
||||
transmit timeout.
|
||||
Therefore, we increased the TX and RX DMADs to improve this error
|
||||
situation.
|
||||
|
||||
Use the dma-size implementation from SDK in a per SoC manner. In
|
||||
difference to SDK we have no RSS feature yet, so all RX/TX sizes
|
||||
should be raised from 512 to 2048 byte except fqdma on mt7988 to
|
||||
avoid the tx timeout issue.
|
||||
|
||||
Fixes: 656e705243fd ("net-next: mediatek: add support for MT7623 ethernet")
|
||||
Suggested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 104 +++++++++++++-------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 9 +-
|
||||
2 files changed, 77 insertions(+), 36 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -1131,9 +1131,9 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
{
|
||||
const struct mtk_soc_data *soc = eth->soc;
|
||||
dma_addr_t phy_ring_tail;
|
||||
- int cnt = MTK_QDMA_RING_SIZE;
|
||||
+ int cnt = soc->tx.fq_dma_size;
|
||||
dma_addr_t dma_addr;
|
||||
- int i;
|
||||
+ int i, j, len;
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
|
||||
eth->scratch_ring = eth->sram_base;
|
||||
@@ -1142,40 +1142,46 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
cnt * soc->tx.desc_size,
|
||||
ð->phy_scratch_ring,
|
||||
GFP_KERNEL);
|
||||
+
|
||||
if (unlikely(!eth->scratch_ring))
|
||||
return -ENOMEM;
|
||||
|
||||
- eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
|
||||
- if (unlikely(!eth->scratch_head))
|
||||
- return -ENOMEM;
|
||||
+ phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
|
||||
|
||||
- dma_addr = dma_map_single(eth->dma_dev,
|
||||
- eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
|
||||
- DMA_FROM_DEVICE);
|
||||
- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
|
||||
- return -ENOMEM;
|
||||
+ for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
|
||||
+ len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
|
||||
+ eth->scratch_head[j] = kcalloc(len, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
|
||||
|
||||
- phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
|
||||
+ if (unlikely(!eth->scratch_head[j]))
|
||||
+ return -ENOMEM;
|
||||
|
||||
- for (i = 0; i < cnt; i++) {
|
||||
- dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
|
||||
- struct mtk_tx_dma_v2 *txd;
|
||||
-
|
||||
- txd = eth->scratch_ring + i * soc->tx.desc_size;
|
||||
- txd->txd1 = addr;
|
||||
- if (i < cnt - 1)
|
||||
- txd->txd2 = eth->phy_scratch_ring +
|
||||
- (i + 1) * soc->tx.desc_size;
|
||||
-
|
||||
- txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
- if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
|
||||
- txd->txd3 |= TX_DMA_PREP_ADDR64(addr);
|
||||
- txd->txd4 = 0;
|
||||
- if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
- txd->txd5 = 0;
|
||||
- txd->txd6 = 0;
|
||||
- txd->txd7 = 0;
|
||||
- txd->txd8 = 0;
|
||||
+ dma_addr = dma_map_single(eth->dma_dev,
|
||||
+ eth->scratch_head[j], len * MTK_QDMA_PAGE_SIZE,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+
|
||||
+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < cnt; i++) {
|
||||
+ struct mtk_tx_dma_v2 *txd;
|
||||
+
|
||||
+ txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
|
||||
+ txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
|
||||
+ if (j * MTK_FQ_DMA_LENGTH + i < cnt)
|
||||
+ txd->txd2 = eth->phy_scratch_ring +
|
||||
+ (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
|
||||
+
|
||||
+ txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
+ if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
|
||||
+ txd->txd3 |= TX_DMA_PREP_ADDR64(dma_addr + i * MTK_QDMA_PAGE_SIZE);
|
||||
+
|
||||
+ txd->txd4 = 0;
|
||||
+ if (mtk_is_netsys_v2_or_greater(eth)) {
|
||||
+ txd->txd5 = 0;
|
||||
+ txd->txd6 = 0;
|
||||
+ txd->txd7 = 0;
|
||||
+ txd->txd8 = 0;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2457,7 +2463,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
|
||||
ring_size = MTK_QDMA_RING_SIZE;
|
||||
else
|
||||
- ring_size = MTK_DMA_SIZE;
|
||||
+ ring_size = soc->tx.dma_size;
|
||||
|
||||
ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
|
||||
GFP_KERNEL);
|
||||
@@ -2465,8 +2471,8 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
goto no_tx_mem;
|
||||
|
||||
if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
|
||||
- ring->dma = eth->sram_base + ring_size * sz;
|
||||
- ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
|
||||
+ ring->dma = eth->sram_base + soc->tx.fq_dma_size * sz;
|
||||
+ ring->phys = eth->phy_scratch_ring + soc->tx.fq_dma_size * (dma_addr_t)sz;
|
||||
} else {
|
||||
ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
|
||||
&ring->phys, GFP_KERNEL);
|
||||
@@ -2588,6 +2594,7 @@ static void mtk_tx_clean(struct mtk_eth
|
||||
static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
|
||||
{
|
||||
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
|
||||
+ const struct mtk_soc_data *soc = eth->soc;
|
||||
struct mtk_rx_ring *ring;
|
||||
int rx_data_len, rx_dma_size, tx_ring_size;
|
||||
int i;
|
||||
@@ -2595,7 +2602,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
|
||||
tx_ring_size = MTK_QDMA_RING_SIZE;
|
||||
else
|
||||
- tx_ring_size = MTK_DMA_SIZE;
|
||||
+ tx_ring_size = soc->tx.dma_size;
|
||||
|
||||
if (rx_flag == MTK_RX_FLAGS_QDMA) {
|
||||
if (ring_no)
|
||||
@@ -2610,7 +2617,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
rx_dma_size = MTK_HW_LRO_DMA_SIZE;
|
||||
} else {
|
||||
rx_data_len = ETH_DATA_LEN;
|
||||
- rx_dma_size = MTK_DMA_SIZE;
|
||||
+ rx_dma_size = soc->rx.dma_size;
|
||||
}
|
||||
|
||||
ring->frag_size = mtk_max_frag_size(rx_data_len);
|
||||
@@ -3139,7 +3146,10 @@ static void mtk_dma_free(struct mtk_eth
|
||||
mtk_rx_clean(eth, ð->rx_ring[i], false);
|
||||
}
|
||||
|
||||
- kfree(eth->scratch_head);
|
||||
+ for (i = 0; i < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); i++) {
|
||||
+ kfree(eth->scratch_head[i]);
|
||||
+ eth->scratch_head[i] = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static bool mtk_hw_reset_check(struct mtk_eth *eth)
|
||||
@@ -5045,11 +5055,14 @@ static const struct mtk_soc_data mt2701_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
.irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5069,11 +5082,14 @@ static const struct mtk_soc_data mt7621_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
.irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5095,11 +5111,14 @@ static const struct mtk_soc_data mt7622_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
.irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5120,11 +5139,14 @@ static const struct mtk_soc_data mt7623_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
.irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5143,11 +5165,14 @@ static const struct mtk_soc_data mt7629_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
.irq_done_mask = MTK_RX_DONE_INT,
|
||||
.dma_l4_valid = RX_DMA_L4_VALID,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
},
|
||||
@@ -5169,6 +5194,8 @@ static const struct mtk_soc_data mt7981_
|
||||
.desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -5176,6 +5203,7 @@ static const struct mtk_soc_data mt7981_
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5195,6 +5223,8 @@ static const struct mtk_soc_data mt7986_
|
||||
.desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -5202,6 +5232,7 @@ static const struct mtk_soc_data mt7986_
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5221,6 +5252,8 @@ static const struct mtk_soc_data mt7988_
|
||||
.desc_size = sizeof(struct mtk_tx_dma_v2),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
+ .fq_dma_size = MTK_DMA_SIZE(4K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma_v2),
|
||||
@@ -5228,6 +5261,7 @@ static const struct mtk_soc_data mt7988_
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
.dma_len_offset = 8,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5242,6 +5276,7 @@ static const struct mtk_soc_data rt5350_
|
||||
.desc_size = sizeof(struct mtk_tx_dma),
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
.rx = {
|
||||
.desc_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -5249,6 +5284,7 @@ static const struct mtk_soc_data rt5350_
|
||||
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
|
||||
.dma_max_len = MTK_TX_DMA_BUF_LEN,
|
||||
.dma_len_offset = 16,
|
||||
+ .dma_size = MTK_DMA_SIZE(2K),
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -32,7 +32,9 @@
|
||||
#define MTK_TX_DMA_BUF_LEN 0x3fff
|
||||
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
|
||||
#define MTK_QDMA_RING_SIZE 2048
|
||||
-#define MTK_DMA_SIZE 512
|
||||
+#define MTK_DMA_SIZE(x) (SZ_##x)
|
||||
+#define MTK_FQ_DMA_HEAD 32
|
||||
+#define MTK_FQ_DMA_LENGTH 2048
|
||||
#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
|
||||
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
|
||||
#define MTK_DMA_DUMMY_DESC 0xffffffff
|
||||
@@ -1176,6 +1178,8 @@ struct mtk_soc_data {
|
||||
u32 desc_size;
|
||||
u32 dma_max_len;
|
||||
u32 dma_len_offset;
|
||||
+ u32 dma_size;
|
||||
+ u32 fq_dma_size;
|
||||
} tx;
|
||||
struct {
|
||||
u32 desc_size;
|
||||
@@ -1183,6 +1187,7 @@ struct mtk_soc_data {
|
||||
u32 dma_l4_valid;
|
||||
u32 dma_max_len;
|
||||
u32 dma_len_offset;
|
||||
+ u32 dma_size;
|
||||
} rx;
|
||||
};
|
||||
|
||||
@@ -1264,7 +1269,7 @@ struct mtk_eth {
|
||||
struct napi_struct rx_napi;
|
||||
void *scratch_ring;
|
||||
dma_addr_t phy_scratch_ring;
|
||||
- void *scratch_head;
|
||||
+ void *scratch_head[MTK_FQ_DMA_HEAD];
|
||||
struct clk *clks[MTK_CLK_MAX];
|
||||
|
||||
struct mii_bus *mii_bus;
|
@ -0,0 +1,90 @@
|
||||
From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:38 +0100
|
||||
Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
|
||||
|
||||
We convert from a phylink_config struct to a dsa_port struct in many
|
||||
places, let's provide a helper for this.
|
||||
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 6 ++++++
|
||||
net/dsa/port.c | 12 ++++++------
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -327,6 +327,12 @@ struct dsa_port {
|
||||
};
|
||||
};
|
||||
|
||||
+static inline struct dsa_port *
|
||||
+dsa_phylink_to_port(struct phylink_config *config)
|
||||
+{
|
||||
+ return container_of(config, struct dsa_port, pl_config);
|
||||
+}
|
||||
+
|
||||
/* TODO: ideally DSA ports would have a single dp->link_dp member,
|
||||
* and no dst->rtable nor this struct dsa_link would be needed,
|
||||
* but this would require some more complex tree walking,
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1572,7 +1572,7 @@ static struct phylink_pcs *
|
||||
dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1586,7 +1586,7 @@ static int dsa_port_phylink_mac_prepare(
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int err = 0;
|
||||
|
||||
@@ -1601,7 +1601,7 @@ static void dsa_port_phylink_mac_config(
|
||||
unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_config)
|
||||
@@ -1614,7 +1614,7 @@ static int dsa_port_phylink_mac_finish(s
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int err = 0;
|
||||
|
||||
@@ -1629,7 +1629,7 @@ static void dsa_port_phylink_mac_link_do
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phy_device *phydev = NULL;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1652,7 +1652,7 @@ static void dsa_port_phylink_mac_link_up
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_link_up) {
|
@ -0,0 +1,119 @@
|
||||
From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:43 +0100
|
||||
Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
|
||||
phylink mac ops
|
||||
|
||||
Rather than having a shim for each and every phylink MAC operation,
|
||||
allow DSA switch drivers to provide their own ops structure. When a
|
||||
DSA driver provides the phylink MAC operations, the shimmed ops must
|
||||
not be provided, so fail an attempt to register a switch with both
|
||||
the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
|
||||
operations populated in dsa_switch_ops populated.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 5 +++++
|
||||
net/dsa/dsa.c | 11 +++++++++++
|
||||
net/dsa/port.c | 26 ++++++++++++++++++++------
|
||||
3 files changed, 36 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -458,6 +458,11 @@ struct dsa_switch {
|
||||
const struct dsa_switch_ops *ops;
|
||||
|
||||
/*
|
||||
+ * Allow a DSA switch driver to override the phylink MAC ops
|
||||
+ */
|
||||
+ const struct phylink_mac_ops *phylink_mac_ops;
|
||||
+
|
||||
+ /*
|
||||
* Slave mii_bus and devices for the individual ports.
|
||||
*/
|
||||
u32 phys_mii_mask;
|
||||
--- a/net/dsa/dsa.c
|
||||
+++ b/net/dsa/dsa.c
|
||||
@@ -1510,6 +1510,17 @@ static int dsa_switch_probe(struct dsa_s
|
||||
if (!ds->num_ports)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (ds->phylink_mac_ops) {
|
||||
+ if (ds->ops->phylink_mac_select_pcs ||
|
||||
+ ds->ops->phylink_mac_prepare ||
|
||||
+ ds->ops->phylink_mac_config ||
|
||||
+ ds->ops->phylink_mac_finish ||
|
||||
+ ds->ops->phylink_mac_link_down ||
|
||||
+ ds->ops->phylink_mac_link_up ||
|
||||
+ ds->ops->adjust_link)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
if (np) {
|
||||
err = dsa_switch_parse_of(ds, np);
|
||||
if (err)
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1677,6 +1677,7 @@ static const struct phylink_mac_ops dsa_
|
||||
|
||||
int dsa_port_phylink_create(struct dsa_port *dp)
|
||||
{
|
||||
+ const struct phylink_mac_ops *mac_ops;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
phy_interface_t mode;
|
||||
struct phylink *pl;
|
||||
@@ -1700,8 +1701,12 @@ int dsa_port_phylink_create(struct dsa_p
|
||||
}
|
||||
}
|
||||
|
||||
- pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
- mode, &dsa_port_phylink_mac_ops);
|
||||
+ mac_ops = &dsa_port_phylink_mac_ops;
|
||||
+ if (ds->phylink_mac_ops)
|
||||
+ mac_ops = ds->phylink_mac_ops;
|
||||
+
|
||||
+ pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
|
||||
+ mac_ops);
|
||||
if (IS_ERR(pl)) {
|
||||
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
|
||||
return PTR_ERR(pl);
|
||||
@@ -1967,12 +1972,23 @@ static void dsa_shared_port_validate_of(
|
||||
dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
}
|
||||
|
||||
+static void dsa_shared_port_link_down(struct dsa_port *dp)
|
||||
+{
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+
|
||||
+ if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
|
||||
+ ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+ else if (ds->ops->phylink_mac_link_down)
|
||||
+ ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+}
|
||||
+
|
||||
int dsa_shared_port_link_register_of(struct dsa_port *dp)
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
bool missing_link_description;
|
||||
bool missing_phy_mode;
|
||||
- int port = dp->index;
|
||||
|
||||
dsa_shared_port_validate_of(dp, &missing_phy_mode,
|
||||
&missing_link_description);
|
||||
@@ -1988,9 +2004,7 @@ int dsa_shared_port_link_register_of(str
|
||||
"Skipping phylink registration for %s port %d\n",
|
||||
dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
} else {
|
||||
- if (ds->ops->phylink_mac_link_down)
|
||||
- ds->ops->phylink_mac_link_down(ds, port,
|
||||
- MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
|
||||
+ dsa_shared_port_link_down(dp);
|
||||
|
||||
return dsa_shared_port_phylink_register(dp);
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
From c278ec644377249aba5b1e1ca2b5705fd1c0132c Mon Sep 17 00:00:00 2001
|
||||
From: Paweł Owoc <frut3k7@gmail.com>
|
||||
Date: Mon, 1 Apr 2024 16:51:06 +0200
|
||||
Subject: [PATCH net-next v2] net: phy: aquantia: add support for AQR114C PHY ID
|
||||
|
||||
Add support for AQR114C PHY ID. This PHY advertise 10G speed:
|
||||
SPEED(0x04): 0x6031
|
||||
capabilities: -400g +5g +2.5g -200g -25g -10g-xr -100g -40g -10g/1g -10
|
||||
+100 +1000 -10-ts -2-tl +10g
|
||||
EXTABLE(0x0B): 0x40fc
|
||||
capabilities: -10g-cx4 -10g-lrm +10g-t +10g-kx4 +10g-kr +1000-t +1000-kx
|
||||
+100-tx -10-t -p2mp -40g/100g -1000/100-t1 -25g -200g/400g
|
||||
+2.5g/5g -1000-h
|
||||
|
||||
but supports only up to 5G speed (as with AQR111/111B0).
|
||||
AQR111 init config is used to set max speed 5G.
|
||||
|
||||
Signed-off-by: Paweł Owoc <frut3k7@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20240401145114.1699451-1-frut3k7@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/aquantia/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_main.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#define PHY_ID_AQR412 0x03a1b712
|
||||
#define PHY_ID_AQR113 0x31c31c40
|
||||
#define PHY_ID_AQR113C 0x31c31c12
|
||||
+#define PHY_ID_AQR114C 0x31c31c22
|
||||
#define PHY_ID_AQR813 0x31c31cb2
|
||||
|
||||
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
|
||||
@@ -880,6 +881,25 @@ static struct phy_driver aqr_driver[] =
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
},
|
||||
{
|
||||
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
|
||||
+ .name = "Aquantia AQR114C",
|
||||
+ .probe = aqr107_probe,
|
||||
+ .get_rate_matching = aqr107_get_rate_matching,
|
||||
+ .config_init = aqr111_config_init,
|
||||
+ .config_aneg = aqr_config_aneg,
|
||||
+ .config_intr = aqr_config_intr,
|
||||
+ .handle_interrupt = aqr_handle_interrupt,
|
||||
+ .read_status = aqr107_read_status,
|
||||
+ .get_tunable = aqr107_get_tunable,
|
||||
+ .set_tunable = aqr107_set_tunable,
|
||||
+ .suspend = aqr107_suspend,
|
||||
+ .resume = aqr107_resume,
|
||||
+ .get_sset_count = aqr107_get_sset_count,
|
||||
+ .get_strings = aqr107_get_strings,
|
||||
+ .get_stats = aqr107_get_stats,
|
||||
+ .link_change_notify = aqr107_link_change_notify,
|
||||
+},
|
||||
+{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
|
||||
.name = "Aquantia AQR813",
|
||||
.probe = aqr107_probe,
|
||||
@@ -916,6 +936,7 @@ static struct mdio_device_id __maybe_unu
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
|
||||
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
|
||||
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
|
||||
{ }
|
||||
};
|
@ -85,7 +85,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
/**
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -6555,7 +6555,7 @@ static int __napi_poll(struct napi_struc
|
||||
@@ -6602,7 +6602,7 @@ static int __napi_poll(struct napi_struc
|
||||
* accidentally calling ->poll() when NAPI is not scheduled.
|
||||
*/
|
||||
work = 0;
|
||||
|
@ -0,0 +1,319 @@
|
||||
From 18764b883e157e28126b54e7d4ba9dd487d5bf54 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Sat, 16 Dec 2023 20:58:10 +0100
|
||||
Subject: [PATCH] r8169: add support for LED's on RTL8168/RTL8101
|
||||
|
||||
This adds support for the LED's on most chip versions. Excluded are
|
||||
the old non-PCIe versions and RTL8125. RTL8125 has a different LED
|
||||
register layout, support for it will follow later.
|
||||
|
||||
LED's can be controlled from userspace using the netdev LED trigger.
|
||||
|
||||
Tested on RTL8168h.
|
||||
|
||||
Note: The driver can't know which LED's are actually physically
|
||||
wired. Therefore not every LED device may represent a physically
|
||||
available LED.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/Makefile | 3 +
|
||||
drivers/net/ethernet/realtek/r8169.h | 7 +
|
||||
drivers/net/ethernet/realtek/r8169_leds.c | 157 ++++++++++++++++++++++
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 65 +++++++++
|
||||
4 files changed, 232 insertions(+)
|
||||
create mode 100644 drivers/net/ethernet/realtek/r8169_leds.c
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/Makefile
|
||||
+++ b/drivers/net/ethernet/realtek/Makefile
|
||||
@@ -7,4 +7,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
|
||||
obj-$(CONFIG_8139TOO) += 8139too.o
|
||||
obj-$(CONFIG_ATP) += atp.o
|
||||
r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
|
||||
+ifdef CONFIG_LEDS_TRIGGER_NETDEV
|
||||
+r8169-objs += r8169_leds.o
|
||||
+endif
|
||||
obj-$(CONFIG_R8169) += r8169.o
|
||||
--- a/drivers/net/ethernet/realtek/r8169.h
|
||||
+++ b/drivers/net/ethernet/realtek/r8169.h
|
||||
@@ -8,6 +8,7 @@
|
||||
* See MAINTAINERS file for support contact information.
|
||||
*/
|
||||
|
||||
+#include <linux/netdevice.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
@@ -77,3 +78,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
|
||||
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
|
||||
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
|
||||
enum mac_version ver);
|
||||
+
|
||||
+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
|
||||
+ char *buf, int buf_len);
|
||||
+int rtl8168_get_led_mode(struct rtl8169_private *tp);
|
||||
+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
|
||||
+void rtl8168_init_leds(struct net_device *ndev);
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
@@ -0,0 +1,157 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
|
||||
+ *
|
||||
+ * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
|
||||
+ *
|
||||
+ * See MAINTAINERS file for support contact information.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <uapi/linux/uleds.h>
|
||||
+
|
||||
+#include "r8169.h"
|
||||
+
|
||||
+#define RTL8168_LED_CTRL_OPTION2 BIT(15)
|
||||
+#define RTL8168_LED_CTRL_ACT BIT(3)
|
||||
+#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
|
||||
+#define RTL8168_LED_CTRL_LINK_100 BIT(1)
|
||||
+#define RTL8168_LED_CTRL_LINK_10 BIT(0)
|
||||
+
|
||||
+#define RTL8168_NUM_LEDS 3
|
||||
+
|
||||
+#define RTL8168_SUPPORTED_MODES \
|
||||
+ (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
|
||||
+ BIT(TRIGGER_NETDEV_TX))
|
||||
+
|
||||
+struct r8169_led_classdev {
|
||||
+ struct led_classdev led;
|
||||
+ struct net_device *ndev;
|
||||
+ int index;
|
||||
+};
|
||||
+
|
||||
+#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
|
||||
+
|
||||
+static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+ int shift = ldev->index * 4;
|
||||
+ bool rx, tx;
|
||||
+
|
||||
+ if (flags & ~RTL8168_SUPPORTED_MODES)
|
||||
+ goto nosupp;
|
||||
+
|
||||
+ rx = flags & BIT(TRIGGER_NETDEV_RX);
|
||||
+ tx = flags & BIT(TRIGGER_NETDEV_TX);
|
||||
+ if (rx != tx)
|
||||
+ goto nosupp;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+nosupp:
|
||||
+ /* Switch LED off to indicate that mode isn't supported */
|
||||
+ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+ int shift = ldev->index * 4;
|
||||
+ u16 mode = 0;
|
||||
+
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
|
||||
+ mode |= RTL8168_LED_CTRL_LINK_10;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
|
||||
+ mode |= RTL8168_LED_CTRL_LINK_100;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
|
||||
+ mode |= RTL8168_LED_CTRL_LINK_1000;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_TX))
|
||||
+ mode |= RTL8168_LED_CTRL_ACT;
|
||||
+
|
||||
+ return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
|
||||
+}
|
||||
+
|
||||
+static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+ int shift = ldev->index * 4;
|
||||
+ int mode;
|
||||
+
|
||||
+ mode = rtl8168_get_led_mode(tp);
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ if (mode & RTL8168_LED_CTRL_OPTION2) {
|
||||
+ rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
|
||||
+ netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
|
||||
+ }
|
||||
+
|
||||
+ mode = (mode >> shift) & 0x000f;
|
||||
+
|
||||
+ if (mode & RTL8168_LED_CTRL_ACT)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
|
||||
+
|
||||
+ if (mode & RTL8168_LED_CTRL_LINK_10)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
|
||||
+ if (mode & RTL8168_LED_CTRL_LINK_100)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
|
||||
+ if (mode & RTL8168_LED_CTRL_LINK_1000)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct device *
|
||||
+ r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+
|
||||
+ return &ldev->ndev->dev;
|
||||
+}
|
||||
+
|
||||
+static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
|
||||
+ struct net_device *ndev, int index)
|
||||
+{
|
||||
+ struct rtl8169_private *tp = netdev_priv(ndev);
|
||||
+ struct led_classdev *led_cdev = &ldev->led;
|
||||
+ char led_name[LED_MAX_NAME_SIZE];
|
||||
+
|
||||
+ ldev->ndev = ndev;
|
||||
+ ldev->index = index;
|
||||
+
|
||||
+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
|
||||
+ led_cdev->name = led_name;
|
||||
+ led_cdev->default_trigger = "netdev";
|
||||
+ led_cdev->hw_control_trigger = "netdev";
|
||||
+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
|
||||
+ led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
|
||||
+ led_cdev->hw_control_set = rtl8168_led_hw_control_set;
|
||||
+ led_cdev->hw_control_get = rtl8168_led_hw_control_get;
|
||||
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
|
||||
+
|
||||
+ /* ignore errors */
|
||||
+ devm_led_classdev_register(&ndev->dev, led_cdev);
|
||||
+}
|
||||
+
|
||||
+void rtl8168_init_leds(struct net_device *ndev)
|
||||
+{
|
||||
+ /* bind resource mgmt to netdev */
|
||||
+ struct device *dev = &ndev->dev;
|
||||
+ struct r8169_led_classdev *leds;
|
||||
+ int i;
|
||||
+
|
||||
+ leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
|
||||
+ if (!leds)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
|
||||
+ rtl8168_setup_ldev(leds + i, ndev, i);
|
||||
+}
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -289,6 +289,7 @@ enum rtl8168_8101_registers {
|
||||
};
|
||||
|
||||
enum rtl8168_registers {
|
||||
+ LED_CTRL = 0x18,
|
||||
LED_FREQ = 0x1a,
|
||||
EEE_LED = 0x1b,
|
||||
ERIDR = 0x70,
|
||||
@@ -620,6 +621,7 @@ struct rtl8169_private {
|
||||
|
||||
raw_spinlock_t config25_lock;
|
||||
raw_spinlock_t mac_ocp_lock;
|
||||
+ struct mutex led_lock; /* serialize LED ctrl RMW access */
|
||||
|
||||
raw_spinlock_t cfg9346_usage_lock;
|
||||
int cfg9346_usage_count;
|
||||
@@ -792,6 +794,62 @@ static const struct rtl_cond name = {
|
||||
\
|
||||
static bool name ## _check(struct rtl8169_private *tp)
|
||||
|
||||
+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
|
||||
+{
|
||||
+ struct device *dev = tp_to_dev(tp);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ mutex_lock(&tp->led_lock);
|
||||
+ RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
|
||||
+ mutex_unlock(&tp->led_lock);
|
||||
+
|
||||
+ pm_runtime_put_sync(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int rtl8168_get_led_mode(struct rtl8169_private *tp)
|
||||
+{
|
||||
+ struct device *dev = tp_to_dev(tp);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = RTL_R16(tp, LED_CTRL);
|
||||
+
|
||||
+ pm_runtime_put_sync(dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
|
||||
+ char *buf, int buf_len)
|
||||
+{
|
||||
+ struct pci_dev *pdev = tp->pci_dev;
|
||||
+ char pdom[8], pfun[8];
|
||||
+ int domain;
|
||||
+
|
||||
+ domain = pci_domain_nr(pdev->bus);
|
||||
+ if (domain)
|
||||
+ snprintf(pdom, sizeof(pdom), "P%d", domain);
|
||||
+ else
|
||||
+ pdom[0] = '\0';
|
||||
+
|
||||
+ if (pdev->multifunction)
|
||||
+ snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
|
||||
+ else
|
||||
+ pfun[0] = '\0';
|
||||
+
|
||||
+ snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
|
||||
+ PCI_SLOT(pdev->devfn), pfun, idx);
|
||||
+}
|
||||
+
|
||||
static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
|
||||
{
|
||||
/* based on RTL8168FP_OOBMAC_BASE in vendor driver */
|
||||
@@ -5258,6 +5316,7 @@ static int rtl_init_one(struct pci_dev *
|
||||
raw_spin_lock_init(&tp->cfg9346_usage_lock);
|
||||
raw_spin_lock_init(&tp->config25_lock);
|
||||
raw_spin_lock_init(&tp->mac_ocp_lock);
|
||||
+ mutex_init(&tp->led_lock);
|
||||
|
||||
dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
|
||||
struct pcpu_sw_netstats);
|
||||
@@ -5414,6 +5473,12 @@ static int rtl_init_one(struct pci_dev *
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
+#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
|
||||
+ if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
|
||||
+ tp->mac_version < RTL_GIGA_MAC_VER_61)
|
||||
+ rtl8168_init_leds(dev);
|
||||
+#endif
|
||||
+
|
||||
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
||||
rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
|
||||
|
@ -0,0 +1,75 @@
|
||||
From a2634a5ffcafc31c343c6153ae487eb184c433a6 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Wed, 3 Jan 2024 16:52:04 +0100
|
||||
Subject: [PATCH] r8169: fix building with CONFIG_LEDS_CLASS=m
|
||||
|
||||
When r8169 is built-in but LED support is a loadable module, the new
|
||||
code to drive the LED causes a link failure:
|
||||
|
||||
ld: drivers/net/ethernet/realtek/r8169_leds.o: in function `rtl8168_init_leds':
|
||||
r8169_leds.c:(.text+0x36c): undefined reference to `devm_led_classdev_register_ext'
|
||||
|
||||
LED support is an optional feature, so fix this issue by adding a Kconfig
|
||||
symbol R8169_LEDS that is guaranteed to be false if r8169 is built-in
|
||||
and LED core support is a module. As a positive side effect of this change
|
||||
r8169_leds.o no longer is built under this configuration.
|
||||
|
||||
Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202312281159.9TPeXbNd-lkp@intel.com/
|
||||
Suggested-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Simon Horman <horms@kernel.org> # build-tested
|
||||
Tested-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Link: https://lore.kernel.org/r/d055aeb5-fe5c-4ccf-987f-5af93a17537b@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/realtek/Kconfig | 7 +++++++
|
||||
drivers/net/ethernet/realtek/Makefile | 6 ++----
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 5 ++---
|
||||
3 files changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/Kconfig
|
||||
+++ b/drivers/net/ethernet/realtek/Kconfig
|
||||
@@ -113,4 +113,11 @@ config R8169
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called r8169. This is recommended.
|
||||
|
||||
+config R8169_LEDS
|
||||
+ def_bool R8169 && LEDS_TRIGGER_NETDEV
|
||||
+ depends on !(R8169=y && LEDS_CLASS=m)
|
||||
+ help
|
||||
+ Optional support for controlling the NIC LED's with the netdev
|
||||
+ LED trigger.
|
||||
+
|
||||
endif # NET_VENDOR_REALTEK
|
||||
--- a/drivers/net/ethernet/realtek/Makefile
|
||||
+++ b/drivers/net/ethernet/realtek/Makefile
|
||||
@@ -6,8 +6,6 @@
|
||||
obj-$(CONFIG_8139CP) += 8139cp.o
|
||||
obj-$(CONFIG_8139TOO) += 8139too.o
|
||||
obj-$(CONFIG_ATP) += atp.o
|
||||
-r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
|
||||
-ifdef CONFIG_LEDS_TRIGGER_NETDEV
|
||||
-r8169-objs += r8169_leds.o
|
||||
-endif
|
||||
+r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
|
||||
+r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
|
||||
obj-$(CONFIG_R8169) += r8169.o
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -5473,11 +5473,10 @@ static int rtl_init_one(struct pci_dev *
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
-#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
|
||||
- if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
|
||||
+ if (IS_ENABLED(CONFIG_R8169_LEDS) &&
|
||||
+ tp->mac_version > RTL_GIGA_MAC_VER_06 &&
|
||||
tp->mac_version < RTL_GIGA_MAC_VER_61)
|
||||
rtl8168_init_leds(dev);
|
||||
-#endif
|
||||
|
||||
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
||||
rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
|
@ -0,0 +1,355 @@
|
||||
From 3907f1ffc0ecf466d5c04aadc44c4b9203f3ec9a Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Thu, 1 Feb 2024 22:38:01 +0100
|
||||
Subject: [PATCH] r8169: add support for RTL8126A
|
||||
|
||||
This adds support for the RTL8126A found on Asus z790 Maximus Formula.
|
||||
It was successfully tested w/o the firmware at 1000Mbps. Firmware file
|
||||
has been provided by Realtek and submitted to linux-firmware.
|
||||
2.5G and 5G modes are untested.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169.h | 1 +
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 105 ++++++++++++++----
|
||||
.../net/ethernet/realtek/r8169_phy_config.c | 7 ++
|
||||
3 files changed, 89 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169.h
|
||||
+++ b/drivers/net/ethernet/realtek/r8169.h
|
||||
@@ -68,6 +68,7 @@ enum mac_version {
|
||||
/* support for RTL_GIGA_MAC_VER_60 has been removed */
|
||||
RTL_GIGA_MAC_VER_61,
|
||||
RTL_GIGA_MAC_VER_63,
|
||||
+ RTL_GIGA_MAC_VER_65,
|
||||
RTL_GIGA_MAC_NONE
|
||||
};
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -55,6 +55,7 @@
|
||||
#define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
|
||||
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
|
||||
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
|
||||
+#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
|
||||
|
||||
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
|
||||
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
|
||||
@@ -140,6 +141,7 @@ static const struct {
|
||||
[RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
|
||||
/* reserve 62 for CFG_METHOD_4 in the vendor driver */
|
||||
[RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
|
||||
+ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
|
||||
};
|
||||
|
||||
static const struct pci_device_id rtl8169_pci_tbl[] = {
|
||||
@@ -162,6 +164,7 @@ static const struct pci_device_id rtl816
|
||||
{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
|
||||
{ 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
|
||||
{ PCI_VDEVICE(REALTEK, 0x8125) },
|
||||
+ { PCI_VDEVICE(REALTEK, 0x8126) },
|
||||
{ PCI_VDEVICE(REALTEK, 0x3000) },
|
||||
{}
|
||||
};
|
||||
@@ -331,8 +334,12 @@ enum rtl8168_registers {
|
||||
};
|
||||
|
||||
enum rtl8125_registers {
|
||||
+ INT_CFG0_8125 = 0x34,
|
||||
+#define INT_CFG0_ENABLE_8125 BIT(0)
|
||||
+#define INT_CFG0_CLKREQEN BIT(3)
|
||||
IntrMask_8125 = 0x38,
|
||||
IntrStatus_8125 = 0x3c,
|
||||
+ INT_CFG1_8125 = 0x7a,
|
||||
TxPoll_8125 = 0x90,
|
||||
MAC0_BKP = 0x19e0,
|
||||
EEE_TXIDLE_TIMER_8125 = 0x6048,
|
||||
@@ -1144,7 +1151,7 @@ static void rtl_writephy(struct rtl8169_
|
||||
case RTL_GIGA_MAC_VER_31:
|
||||
r8168dp_2_mdio_write(tp, location, val);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
|
||||
r8168g_mdio_write(tp, location, val);
|
||||
break;
|
||||
default:
|
||||
@@ -1159,7 +1166,7 @@ static int rtl_readphy(struct rtl8169_pr
|
||||
case RTL_GIGA_MAC_VER_28:
|
||||
case RTL_GIGA_MAC_VER_31:
|
||||
return r8168dp_2_mdio_read(tp, location);
|
||||
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
|
||||
return r8168g_mdio_read(tp, location);
|
||||
default:
|
||||
return r8169_mdio_read(tp, location);
|
||||
@@ -1368,7 +1375,7 @@ static void rtl_set_d3_pll_down(struct r
|
||||
case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
|
||||
case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
|
||||
case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
|
||||
- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
|
||||
if (enable)
|
||||
RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
|
||||
else
|
||||
@@ -1535,7 +1542,7 @@ static void __rtl8169_set_wol(struct rtl
|
||||
break;
|
||||
case RTL_GIGA_MAC_VER_34:
|
||||
case RTL_GIGA_MAC_VER_37:
|
||||
- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
|
||||
if (wolopts)
|
||||
rtl_mod_config2(tp, 0, PME_SIGNAL);
|
||||
else
|
||||
@@ -2122,6 +2129,9 @@ static enum mac_version rtl8169_get_mac_
|
||||
u16 val;
|
||||
enum mac_version ver;
|
||||
} mac_info[] = {
|
||||
+ /* 8126A family. */
|
||||
+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
|
||||
+
|
||||
/* 8125B family. */
|
||||
{ 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
|
||||
|
||||
@@ -2392,6 +2402,7 @@ static void rtl_init_rxcfg(struct rtl816
|
||||
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
|
||||
break;
|
||||
case RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_65:
|
||||
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
|
||||
RX_PAUSE_SLOT_ON);
|
||||
break;
|
||||
@@ -2578,7 +2589,7 @@ static void rtl_wait_txrx_fifo_empty(str
|
||||
case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
|
||||
rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
|
||||
RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
|
||||
rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
|
||||
rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
|
||||
@@ -2822,7 +2833,7 @@ static void rtl_enable_exit_l1(struct rt
|
||||
case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
|
||||
rtl_eri_set_bits(tp, 0xd4, 0x0c00);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
|
||||
r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
|
||||
break;
|
||||
default:
|
||||
@@ -2836,7 +2847,7 @@ static void rtl_disable_exit_l1(struct r
|
||||
case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
|
||||
rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
|
||||
r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
|
||||
break;
|
||||
default:
|
||||
@@ -2846,6 +2857,8 @@ static void rtl_disable_exit_l1(struct r
|
||||
|
||||
static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
|
||||
{
|
||||
+ u8 val8;
|
||||
+
|
||||
if (tp->mac_version < RTL_GIGA_MAC_VER_32)
|
||||
return;
|
||||
|
||||
@@ -2859,11 +2872,19 @@ static void rtl_hw_aspm_clkreq_enable(st
|
||||
return;
|
||||
|
||||
rtl_mod_config5(tp, 0, ASPM_en);
|
||||
- rtl_mod_config2(tp, 0, ClkReqEn);
|
||||
+ switch (tp->mac_version) {
|
||||
+ case RTL_GIGA_MAC_VER_65:
|
||||
+ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
|
||||
+ RTL_W8(tp, INT_CFG0_8125, val8);
|
||||
+ break;
|
||||
+ default:
|
||||
+ rtl_mod_config2(tp, 0, ClkReqEn);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
|
||||
- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
|
||||
/* reset ephy tx/rx disable timer */
|
||||
r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
|
||||
/* chip can trigger L1.2 */
|
||||
@@ -2875,14 +2896,22 @@ static void rtl_hw_aspm_clkreq_enable(st
|
||||
} else {
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
|
||||
- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
|
||||
r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
- rtl_mod_config2(tp, ClkReqEn, 0);
|
||||
+ switch (tp->mac_version) {
|
||||
+ case RTL_GIGA_MAC_VER_65:
|
||||
+ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
|
||||
+ RTL_W8(tp, INT_CFG0_8125, val8);
|
||||
+ break;
|
||||
+ default:
|
||||
+ rtl_mod_config2(tp, ClkReqEn, 0);
|
||||
+ break;
|
||||
+ }
|
||||
rtl_mod_config5(tp, ASPM_en, 0);
|
||||
}
|
||||
}
|
||||
@@ -3678,10 +3707,15 @@ static void rtl_hw_start_8125_common(str
|
||||
/* disable new tx descriptor format */
|
||||
r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
|
||||
|
||||
- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
|
||||
+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
|
||||
+ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
|
||||
+
|
||||
+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
|
||||
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
|
||||
+ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
|
||||
r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
|
||||
else
|
||||
- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
|
||||
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0300);
|
||||
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_63)
|
||||
r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
|
||||
@@ -3694,6 +3728,10 @@ static void rtl_hw_start_8125_common(str
|
||||
r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
|
||||
r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
|
||||
r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
|
||||
+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
|
||||
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
|
||||
+ else
|
||||
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
|
||||
r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
|
||||
r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
|
||||
r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
|
||||
@@ -3708,10 +3746,10 @@ static void rtl_hw_start_8125_common(str
|
||||
|
||||
rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
|
||||
|
||||
- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
|
||||
- rtl8125b_config_eee_mac(tp);
|
||||
- else
|
||||
+ if (tp->mac_version == RTL_GIGA_MAC_VER_61)
|
||||
rtl8125a_config_eee_mac(tp);
|
||||
+ else
|
||||
+ rtl8125b_config_eee_mac(tp);
|
||||
|
||||
rtl_disable_rxdvgate(tp);
|
||||
}
|
||||
@@ -3755,6 +3793,12 @@ static void rtl_hw_start_8125b(struct rt
|
||||
rtl_hw_start_8125_common(tp);
|
||||
}
|
||||
|
||||
+static void rtl_hw_start_8126a(struct rtl8169_private *tp)
|
||||
+{
|
||||
+ rtl_set_def_aspm_entry_latency(tp);
|
||||
+ rtl_hw_start_8125_common(tp);
|
||||
+}
|
||||
+
|
||||
static void rtl_hw_config(struct rtl8169_private *tp)
|
||||
{
|
||||
static const rtl_generic_fct hw_configs[] = {
|
||||
@@ -3797,6 +3841,7 @@ static void rtl_hw_config(struct rtl8169
|
||||
[RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
|
||||
[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
|
||||
[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
|
||||
+ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
|
||||
};
|
||||
|
||||
if (hw_configs[tp->mac_version])
|
||||
@@ -3807,9 +3852,23 @@ static void rtl_hw_start_8125(struct rtl
|
||||
{
|
||||
int i;
|
||||
|
||||
+ RTL_W8(tp, INT_CFG0_8125, 0x00);
|
||||
+
|
||||
/* disable interrupt coalescing */
|
||||
- for (i = 0xa00; i < 0xb00; i += 4)
|
||||
- RTL_W32(tp, i, 0);
|
||||
+ switch (tp->mac_version) {
|
||||
+ case RTL_GIGA_MAC_VER_61:
|
||||
+ for (i = 0xa00; i < 0xb00; i += 4)
|
||||
+ RTL_W32(tp, i, 0);
|
||||
+ break;
|
||||
+ case RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_65:
|
||||
+ for (i = 0xa00; i < 0xa80; i += 4)
|
||||
+ RTL_W32(tp, i, 0);
|
||||
+ RTL_W16(tp, INT_CFG1_8125, 0x0000);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
rtl_hw_config(tp);
|
||||
}
|
||||
@@ -3887,8 +3946,7 @@ static int rtl8169_change_mtu(struct net
|
||||
rtl_jumbo_config(tp);
|
||||
|
||||
switch (tp->mac_version) {
|
||||
- case RTL_GIGA_MAC_VER_61:
|
||||
- case RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
|
||||
rtl8125_set_eee_txidle_timer(tp);
|
||||
break;
|
||||
default:
|
||||
@@ -4037,7 +4095,7 @@ static void rtl8169_cleanup(struct rtl81
|
||||
RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
|
||||
rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
|
||||
rtl_enable_rxdvgate(tp);
|
||||
fsleep(2000);
|
||||
break;
|
||||
@@ -4188,8 +4246,7 @@ static unsigned int rtl_quirk_packet_pad
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_34:
|
||||
- case RTL_GIGA_MAC_VER_61:
|
||||
- case RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
|
||||
padto = max_t(unsigned int, padto, ETH_ZLEN);
|
||||
break;
|
||||
default:
|
||||
@@ -5225,7 +5282,7 @@ static void rtl_hw_initialize(struct rtl
|
||||
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
|
||||
rtl_hw_init_8168g(tp);
|
||||
break;
|
||||
- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
|
||||
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
|
||||
rtl_hw_init_8125(tp);
|
||||
break;
|
||||
default:
|
||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
|
||||
@@ -1102,6 +1102,12 @@ static void rtl8125b_hw_phy_config(struc
|
||||
rtl8125b_config_eee_phy(phydev);
|
||||
}
|
||||
|
||||
+static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
|
||||
+ struct phy_device *phydev)
|
||||
+{
|
||||
+ r8169_apply_firmware(tp);
|
||||
+}
|
||||
+
|
||||
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
|
||||
enum mac_version ver)
|
||||
{
|
||||
@@ -1152,6 +1158,7 @@ void r8169_hw_phy_config(struct rtl8169_
|
||||
[RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
|
||||
[RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
|
||||
[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
|
||||
+ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
|
||||
};
|
||||
|
||||
if (phy_configs[ver])
|
@ -0,0 +1,81 @@
|
||||
From 4c49b6824a607af4760fac4f5c0b9954ab902cef Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Wed, 7 Feb 2024 08:16:40 +0100
|
||||
Subject: [PATCH] r8169: improve checking for valid LED modes
|
||||
|
||||
After 3a2746320403 ("leds: trigger: netdev: Display only supported link
|
||||
speed attribute") the check for valid link modes can be simplified.
|
||||
In addition factor it out, so that it can be re-used by the upcoming
|
||||
LED support for RTL8125.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://lore.kernel.org/r/8876a9f4-7a2d-48c3-8eae-0d834f5c27c5@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169_leds.c | 38 ++++++++++++-----------
|
||||
1 file changed, 20 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
@@ -20,11 +20,6 @@
|
||||
|
||||
#define RTL8168_NUM_LEDS 3
|
||||
|
||||
-#define RTL8168_SUPPORTED_MODES \
|
||||
- (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
|
||||
- BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
|
||||
- BIT(TRIGGER_NETDEV_TX))
|
||||
-
|
||||
struct r8169_led_classdev {
|
||||
struct led_classdev led;
|
||||
struct net_device *ndev;
|
||||
@@ -33,28 +28,35 @@ struct r8169_led_classdev {
|
||||
|
||||
#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
|
||||
|
||||
+static bool r8169_trigger_mode_is_valid(unsigned long flags)
|
||||
+{
|
||||
+ bool rx, tx;
|
||||
+
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
|
||||
+ return false;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
|
||||
+ return false;
|
||||
+
|
||||
+ rx = flags & BIT(TRIGGER_NETDEV_RX);
|
||||
+ tx = flags & BIT(TRIGGER_NETDEV_TX);
|
||||
+
|
||||
+ return rx == tx;
|
||||
+}
|
||||
+
|
||||
static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
int shift = ldev->index * 4;
|
||||
- bool rx, tx;
|
||||
|
||||
- if (flags & ~RTL8168_SUPPORTED_MODES)
|
||||
- goto nosupp;
|
||||
-
|
||||
- rx = flags & BIT(TRIGGER_NETDEV_RX);
|
||||
- tx = flags & BIT(TRIGGER_NETDEV_TX);
|
||||
- if (rx != tx)
|
||||
- goto nosupp;
|
||||
+ if (!r8169_trigger_mode_is_valid(flags)) {
|
||||
+ /* Switch LED off to indicate that mode isn't supported */
|
||||
+ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
-
|
||||
-nosupp:
|
||||
- /* Switch LED off to indicate that mode isn't supported */
|
||||
- rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
|
||||
- return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
|
@ -0,0 +1,244 @@
|
||||
From be51ed104ba9929c741afb718ef7198dbcecef94 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Mon, 12 Feb 2024 19:44:11 +0100
|
||||
Subject: [PATCH] r8169: add LED support for RTL8125/RTL8126
|
||||
|
||||
This adds LED support for RTL8125/RTL8126.
|
||||
|
||||
Note: Due to missing datasheets changing the 5Gbps link mode isn't
|
||||
supported for RTL8126.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/f982602c-9de3-4ca6-85a3-2c1d118dcb15@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169.h | 3 +
|
||||
drivers/net/ethernet/realtek/r8169_leds.c | 106 ++++++++++++++++++++++
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 61 ++++++++++++-
|
||||
3 files changed, 166 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169.h
|
||||
+++ b/drivers/net/ethernet/realtek/r8169.h
|
||||
@@ -85,3 +85,6 @@ void r8169_get_led_name(struct rtl8169_p
|
||||
int rtl8168_get_led_mode(struct rtl8169_private *tp);
|
||||
int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
|
||||
void rtl8168_init_leds(struct net_device *ndev);
|
||||
+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
|
||||
+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
|
||||
+void rtl8125_init_leds(struct net_device *ndev);
|
||||
--- a/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
@@ -18,7 +18,14 @@
|
||||
#define RTL8168_LED_CTRL_LINK_100 BIT(1)
|
||||
#define RTL8168_LED_CTRL_LINK_10 BIT(0)
|
||||
|
||||
+#define RTL8125_LED_CTRL_ACT BIT(9)
|
||||
+#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
|
||||
+#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
|
||||
+#define RTL8125_LED_CTRL_LINK_100 BIT(1)
|
||||
+#define RTL8125_LED_CTRL_LINK_10 BIT(0)
|
||||
+
|
||||
#define RTL8168_NUM_LEDS 3
|
||||
+#define RTL8125_NUM_LEDS 4
|
||||
|
||||
struct r8169_led_classdev {
|
||||
struct led_classdev led;
|
||||
@@ -157,3 +164,102 @@ void rtl8168_init_leds(struct net_device
|
||||
for (i = 0; i < RTL8168_NUM_LEDS; i++)
|
||||
rtl8168_setup_ldev(leds + i, ndev, i);
|
||||
}
|
||||
+
|
||||
+static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+
|
||||
+ if (!r8169_trigger_mode_is_valid(flags)) {
|
||||
+ /* Switch LED off to indicate that mode isn't supported */
|
||||
+ rtl8125_set_led_mode(tp, ldev->index, 0);
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+ u16 mode = 0;
|
||||
+
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
|
||||
+ mode |= RTL8125_LED_CTRL_LINK_10;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
|
||||
+ mode |= RTL8125_LED_CTRL_LINK_100;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
|
||||
+ mode |= RTL8125_LED_CTRL_LINK_1000;
|
||||
+ if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
|
||||
+ mode |= RTL8125_LED_CTRL_LINK_2500;
|
||||
+ if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
|
||||
+ mode |= RTL8125_LED_CTRL_ACT;
|
||||
+
|
||||
+ return rtl8125_set_led_mode(tp, ldev->index, mode);
|
||||
+}
|
||||
+
|
||||
+static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||
+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||
+ int mode;
|
||||
+
|
||||
+ mode = rtl8125_get_led_mode(tp, ldev->index);
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ if (mode & RTL8125_LED_CTRL_LINK_10)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
|
||||
+ if (mode & RTL8125_LED_CTRL_LINK_100)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
|
||||
+ if (mode & RTL8125_LED_CTRL_LINK_1000)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
|
||||
+ if (mode & RTL8125_LED_CTRL_LINK_2500)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_LINK_2500);
|
||||
+ if (mode & RTL8125_LED_CTRL_ACT)
|
||||
+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
|
||||
+ struct net_device *ndev, int index)
|
||||
+{
|
||||
+ struct rtl8169_private *tp = netdev_priv(ndev);
|
||||
+ struct led_classdev *led_cdev = &ldev->led;
|
||||
+ char led_name[LED_MAX_NAME_SIZE];
|
||||
+
|
||||
+ ldev->ndev = ndev;
|
||||
+ ldev->index = index;
|
||||
+
|
||||
+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
|
||||
+ led_cdev->name = led_name;
|
||||
+ led_cdev->hw_control_trigger = "netdev";
|
||||
+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
|
||||
+ led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
|
||||
+ led_cdev->hw_control_set = rtl8125_led_hw_control_set;
|
||||
+ led_cdev->hw_control_get = rtl8125_led_hw_control_get;
|
||||
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
|
||||
+
|
||||
+ /* ignore errors */
|
||||
+ devm_led_classdev_register(&ndev->dev, led_cdev);
|
||||
+}
|
||||
+
|
||||
+void rtl8125_init_leds(struct net_device *ndev)
|
||||
+{
|
||||
+ /* bind resource mgmt to netdev */
|
||||
+ struct device *dev = &ndev->dev;
|
||||
+ struct r8169_led_classdev *leds;
|
||||
+ int i;
|
||||
+
|
||||
+ leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
|
||||
+ if (!leds)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < RTL8125_NUM_LEDS; i++)
|
||||
+ rtl8125_setup_led_ldev(leds + i, ndev, i);
|
||||
+}
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -334,17 +334,23 @@ enum rtl8168_registers {
|
||||
};
|
||||
|
||||
enum rtl8125_registers {
|
||||
+ LEDSEL0 = 0x18,
|
||||
INT_CFG0_8125 = 0x34,
|
||||
#define INT_CFG0_ENABLE_8125 BIT(0)
|
||||
#define INT_CFG0_CLKREQEN BIT(3)
|
||||
IntrMask_8125 = 0x38,
|
||||
IntrStatus_8125 = 0x3c,
|
||||
INT_CFG1_8125 = 0x7a,
|
||||
+ LEDSEL2 = 0x84,
|
||||
+ LEDSEL1 = 0x86,
|
||||
TxPoll_8125 = 0x90,
|
||||
+ LEDSEL3 = 0x96,
|
||||
MAC0_BKP = 0x19e0,
|
||||
EEE_TXIDLE_TIMER_8125 = 0x6048,
|
||||
};
|
||||
|
||||
+#define LEDSEL_MASK_8125 0x23f
|
||||
+
|
||||
#define RX_VLAN_INNER_8125 BIT(22)
|
||||
#define RX_VLAN_OUTER_8125 BIT(23)
|
||||
#define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
|
||||
@@ -835,6 +841,51 @@ int rtl8168_get_led_mode(struct rtl8169_
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int rtl8125_get_led_reg(int index)
|
||||
+{
|
||||
+ static const int led_regs[] = { LEDSEL0, LEDSEL1, LEDSEL2, LEDSEL3 };
|
||||
+
|
||||
+ return led_regs[index];
|
||||
+}
|
||||
+
|
||||
+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode)
|
||||
+{
|
||||
+ int reg = rtl8125_get_led_reg(index);
|
||||
+ struct device *dev = tp_to_dev(tp);
|
||||
+ int ret;
|
||||
+ u16 val;
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ mutex_lock(&tp->led_lock);
|
||||
+ val = RTL_R16(tp, reg) & ~LEDSEL_MASK_8125;
|
||||
+ RTL_W16(tp, reg, val | mode);
|
||||
+ mutex_unlock(&tp->led_lock);
|
||||
+
|
||||
+ pm_runtime_put_sync(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index)
|
||||
+{
|
||||
+ int reg = rtl8125_get_led_reg(index);
|
||||
+ struct device *dev = tp_to_dev(tp);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = RTL_R16(tp, reg);
|
||||
+
|
||||
+ pm_runtime_put_sync(dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void r8169_get_led_name(struct rtl8169_private *tp, int idx,
|
||||
char *buf, int buf_len)
|
||||
{
|
||||
@@ -5530,10 +5581,12 @@ static int rtl_init_one(struct pci_dev *
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
- if (IS_ENABLED(CONFIG_R8169_LEDS) &&
|
||||
- tp->mac_version > RTL_GIGA_MAC_VER_06 &&
|
||||
- tp->mac_version < RTL_GIGA_MAC_VER_61)
|
||||
- rtl8168_init_leds(dev);
|
||||
+ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
|
||||
+ if (rtl_is_8125(tp))
|
||||
+ rtl8125_init_leds(dev);
|
||||
+ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
|
||||
+ rtl8168_init_leds(dev);
|
||||
+ }
|
||||
|
||||
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
||||
rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
|
@ -0,0 +1,25 @@
|
||||
From f4d3e595c0000ce39dec7e4799ea42ce42ab6867 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Sat, 17 Feb 2024 15:48:23 +0100
|
||||
Subject: [PATCH] r8169: add MODULE_FIRMWARE entry for RTL8126A
|
||||
|
||||
Add the missing MODULE_FIRMWARE entry for RTL8126A.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://lore.kernel.org/r/47ef79d2-59c4-4d44-9595-366c70c4ad87@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -680,6 +680,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
|
||||
MODULE_FIRMWARE(FIRMWARE_8107E_2);
|
||||
MODULE_FIRMWARE(FIRMWARE_8125A_3);
|
||||
MODULE_FIRMWARE(FIRMWARE_8125B_2);
|
||||
+MODULE_FIRMWARE(FIRMWARE_8126A_2);
|
||||
|
||||
static inline struct device *tp_to_dev(struct rtl8169_private *tp)
|
||||
{
|
@ -0,0 +1,30 @@
|
||||
From 39f59c72ad3a1eaab9a60f0671bc94d2bc826d21 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Sun, 7 Apr 2024 23:19:25 +0200
|
||||
Subject: [PATCH] r8169: add support for RTL8168M
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A user reported an unknown chip version. According to the r8168 vendor
|
||||
driver it's called RTL8168M, but handling is identical to RTL8168H.
|
||||
So let's simply treat it as RTL8168H.
|
||||
|
||||
Tested-by: Евгений <octobergun@gmail.com>
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -2212,6 +2212,8 @@ static enum mac_version rtl8169_get_mac_
|
||||
* the wild. Let's disable detection.
|
||||
* { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
|
||||
*/
|
||||
+ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
|
||||
+ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
|
||||
|
||||
/* 8168G family. */
|
||||
{ 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
|
@ -0,0 +1,147 @@
|
||||
From 19fa4f2a85d777a8052e869c1b892a2f7556569d Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Mon, 8 Apr 2024 20:47:40 +0200
|
||||
Subject: [PATCH] r8169: fix LED-related deadlock on module removal
|
||||
|
||||
Binding devm_led_classdev_register() to the netdev is problematic
|
||||
because on module removal we get a RTNL-related deadlock. Fix this
|
||||
by avoiding the device-managed LED functions.
|
||||
|
||||
Note: We can safely call led_classdev_unregister() for a LED even
|
||||
if registering it failed, because led_classdev_unregister() detects
|
||||
this and is a no-op in this case.
|
||||
|
||||
Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Lukas Wunner <lukas@wunner.de>
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169.h | 6 ++--
|
||||
drivers/net/ethernet/realtek/r8169_leds.c | 35 +++++++++++++++--------
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 8 ++++--
|
||||
3 files changed, 33 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169.h
|
||||
+++ b/drivers/net/ethernet/realtek/r8169.h
|
||||
@@ -73,6 +73,7 @@ enum mac_version {
|
||||
};
|
||||
|
||||
struct rtl8169_private;
|
||||
+struct r8169_led_classdev;
|
||||
|
||||
void r8169_apply_firmware(struct rtl8169_private *tp);
|
||||
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
|
||||
@@ -84,7 +85,8 @@ void r8169_get_led_name(struct rtl8169_p
|
||||
char *buf, int buf_len);
|
||||
int rtl8168_get_led_mode(struct rtl8169_private *tp);
|
||||
int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
|
||||
-void rtl8168_init_leds(struct net_device *ndev);
|
||||
+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
|
||||
int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
|
||||
int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
|
||||
-void rtl8125_init_leds(struct net_device *ndev);
|
||||
+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
|
||||
+void r8169_remove_leds(struct r8169_led_classdev *leds);
|
||||
--- a/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_leds.c
|
||||
@@ -147,22 +147,22 @@ static void rtl8168_setup_ldev(struct r8
|
||||
led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
|
||||
|
||||
/* ignore errors */
|
||||
- devm_led_classdev_register(&ndev->dev, led_cdev);
|
||||
+ led_classdev_register(&ndev->dev, led_cdev);
|
||||
}
|
||||
|
||||
-void rtl8168_init_leds(struct net_device *ndev)
|
||||
+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
|
||||
{
|
||||
- /* bind resource mgmt to netdev */
|
||||
- struct device *dev = &ndev->dev;
|
||||
struct r8169_led_classdev *leds;
|
||||
int i;
|
||||
|
||||
- leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
|
||||
+ leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
|
||||
if (!leds)
|
||||
- return;
|
||||
+ return NULL;
|
||||
|
||||
for (i = 0; i < RTL8168_NUM_LEDS; i++)
|
||||
rtl8168_setup_ldev(leds + i, ndev, i);
|
||||
+
|
||||
+ return leds;
|
||||
}
|
||||
|
||||
static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
|
||||
@@ -246,20 +246,31 @@ static void rtl8125_setup_led_ldev(struc
|
||||
led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
|
||||
|
||||
/* ignore errors */
|
||||
- devm_led_classdev_register(&ndev->dev, led_cdev);
|
||||
+ led_classdev_register(&ndev->dev, led_cdev);
|
||||
}
|
||||
|
||||
-void rtl8125_init_leds(struct net_device *ndev)
|
||||
+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev)
|
||||
{
|
||||
- /* bind resource mgmt to netdev */
|
||||
- struct device *dev = &ndev->dev;
|
||||
struct r8169_led_classdev *leds;
|
||||
int i;
|
||||
|
||||
- leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
|
||||
+ leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
|
||||
if (!leds)
|
||||
- return;
|
||||
+ return NULL;
|
||||
|
||||
for (i = 0; i < RTL8125_NUM_LEDS; i++)
|
||||
rtl8125_setup_led_ldev(leds + i, ndev, i);
|
||||
+
|
||||
+ return leds;
|
||||
+}
|
||||
+
|
||||
+void r8169_remove_leds(struct r8169_led_classdev *leds)
|
||||
+{
|
||||
+ if (!leds)
|
||||
+ return;
|
||||
+
|
||||
+ for (struct r8169_led_classdev *l = leds; l->ndev; l++)
|
||||
+ led_classdev_unregister(&l->led);
|
||||
+
|
||||
+ kfree(leds);
|
||||
}
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -651,6 +651,8 @@ struct rtl8169_private {
|
||||
const char *fw_name;
|
||||
struct rtl_fw *rtl_fw;
|
||||
|
||||
+ struct r8169_led_classdev *leds;
|
||||
+
|
||||
u32 ocp_base;
|
||||
};
|
||||
|
||||
@@ -5126,6 +5128,8 @@ static void rtl_remove_one(struct pci_de
|
||||
|
||||
cancel_work_sync(&tp->wk.work);
|
||||
|
||||
+ r8169_remove_leds(tp->leds);
|
||||
+
|
||||
unregister_netdev(tp->dev);
|
||||
|
||||
if (tp->dash_type != RTL_DASH_NONE)
|
||||
@@ -5586,9 +5590,9 @@ static int rtl_init_one(struct pci_dev *
|
||||
|
||||
if (IS_ENABLED(CONFIG_R8169_LEDS)) {
|
||||
if (rtl_is_8125(tp))
|
||||
- rtl8125_init_leds(dev);
|
||||
+ tp->leds = rtl8125_init_leds(dev);
|
||||
else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
|
||||
- rtl8168_init_leds(dev);
|
||||
+ tp->leds = rtl8168_init_leds(dev);
|
||||
}
|
||||
|
||||
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
@ -0,0 +1,31 @@
|
||||
From 97e176fcbbf3c0f2bd410c9b241177c051f57176 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Wed, 10 Apr 2024 15:11:28 +0200
|
||||
Subject: [PATCH] r8169: add missing conditional compiling for call to
|
||||
r8169_remove_leds
|
||||
|
||||
Add missing dependency on CONFIG_R8169_LEDS. As-is a link error occurs
|
||||
if config option CONFIG_R8169_LEDS isn't enabled.
|
||||
|
||||
Fixes: 19fa4f2a85d7 ("r8169: fix LED-related deadlock on module removal")
|
||||
Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Tested-By: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
|
||||
Link: https://lore.kernel.org/r/d080038c-eb6b-45ac-9237-b8c1cdd7870f@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -5128,7 +5128,8 @@ static void rtl_remove_one(struct pci_de
|
||||
|
||||
cancel_work_sync(&tp->wk.work);
|
||||
|
||||
- r8169_remove_leds(tp->leds);
|
||||
+ if (IS_ENABLED(CONFIG_R8169_LEDS))
|
||||
+ r8169_remove_leds(tp->leds);
|
||||
|
||||
unregister_netdev(tp->dev);
|
||||
|
@ -0,0 +1,58 @@
|
||||
From b91ef50f70e7c092c50c1b92e63ef3fb0041cdd4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
|
||||
Date: Mon, 18 Sep 2023 21:19:12 +0200
|
||||
Subject: [PATCH 01/30] net: dsa: mt7530: Convert to platform remove callback
|
||||
returning void
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The .remove() callback for a platform driver returns an int which makes
|
||||
many driver authors wrongly assume it's possible to do error handling by
|
||||
returning an error code. However the value returned is ignored (apart
|
||||
from emitting a warning) and this typically results in resource leaks.
|
||||
To improve here there is a quest to make the remove callback return
|
||||
void. In the first step of this quest all drivers are converted to
|
||||
.remove_new() which already returns void. Eventually after all drivers
|
||||
are converted, .remove_new() is renamed to .remove().
|
||||
|
||||
Trivially convert this driver from always returning zero in the remove
|
||||
callback to the void returning variant.
|
||||
|
||||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mmio.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mmio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mmio.c
|
||||
@@ -63,15 +63,12 @@ mt7988_probe(struct platform_device *pde
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7988_remove(struct platform_device *pdev)
|
||||
+static void mt7988_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mt7530_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
if (priv)
|
||||
mt7530_remove_common(priv);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static void mt7988_shutdown(struct platform_device *pdev)
|
||||
@@ -88,7 +85,7 @@ static void mt7988_shutdown(struct platf
|
||||
|
||||
static struct platform_driver mt7988_platform_driver = {
|
||||
.probe = mt7988_probe,
|
||||
- .remove = mt7988_remove,
|
||||
+ .remove_new = mt7988_remove,
|
||||
.shutdown = mt7988_shutdown,
|
||||
.driver = {
|
||||
.name = "mt7530-mmio",
|
@ -0,0 +1,51 @@
|
||||
From d22c85764665af931c5c61bbe282b4116a88e792 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 27 Sep 2023 13:13:56 +0100
|
||||
Subject: [PATCH 02/30] net: dsa: mt753x: remove mt753x_phylink_pcs_link_up()
|
||||
|
||||
Remove the mt753x_phylink_pcs_link_up() function for two reasons:
|
||||
|
||||
1) priv->pcs[i].pcs.neg_mode is set true, meaning it doesn't take a
|
||||
MLO_AN_FIXED anymore, but one of PHYLINK_PCS_NEG_*. However, this
|
||||
is inconsequential due to...
|
||||
2) priv->pcs[port].pcs.ops is always initialised to point at
|
||||
mt7530_pcs_ops, which does not have a pcs_link_up() member.
|
||||
|
||||
So, let's remove mt753x_phylink_pcs_link_up() entirely.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Link: https://lore.kernel.org/r/E1qlTQS-008BWe-Va@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 11 -----------
|
||||
1 file changed, 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3037,15 +3037,6 @@ static void mt753x_phylink_mac_link_down
|
||||
mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
|
||||
- unsigned int mode,
|
||||
- phy_interface_t interface,
|
||||
- int speed, int duplex)
|
||||
-{
|
||||
- if (pcs->ops->pcs_link_up)
|
||||
- pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
|
||||
-}
|
||||
-
|
||||
static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
@@ -3133,8 +3124,6 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
return ret;
|
||||
mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
PMCR_CPU_PORT_SETTING(priv->id));
|
||||
- mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
|
||||
- interface, speed, DUPLEX_FULL);
|
||||
mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
|
||||
speed, DUPLEX_FULL, true, true);
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 9b4f1f5a0801652056670a38503b4049eb413caf Mon Sep 17 00:00:00 2001
|
||||
From: Justin Stitt <justinstitt@google.com>
|
||||
Date: Mon, 9 Oct 2023 18:29:19 +0000
|
||||
Subject: [PATCH 03/30] net: dsa: mt7530: replace deprecated strncpy with
|
||||
ethtool_sprintf
|
||||
|
||||
`strncpy` is deprecated for use on NUL-terminated destination strings
|
||||
[1] and as such we should prefer more robust and less ambiguous string
|
||||
interfaces.
|
||||
|
||||
ethtool_sprintf() is designed specifically for get_strings() usage.
|
||||
Let's replace strncpy in favor of this more robust and easier to
|
||||
understand interface.
|
||||
|
||||
Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
|
||||
Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
|
||||
Link: https://github.com/KSPP/linux/issues/90
|
||||
Signed-off-by: Justin Stitt <justinstitt@google.com>
|
||||
Reviewed-by: Kees Cook <keescook@chromium.org>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Link: https://lore.kernel.org/r/20231009-strncpy-drivers-net-dsa-mt7530-c-v1-1-ec6677a6436a@google.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -836,8 +836,7 @@ mt7530_get_strings(struct dsa_switch *ds
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
|
||||
- strncpy(data + i * ETH_GSTRING_LEN, mt7530_mib[i].name,
|
||||
- ETH_GSTRING_LEN);
|
||||
+ ethtool_sprintf(&data, "%s", mt7530_mib[i].name);
|
||||
}
|
||||
|
||||
static void
|
@ -0,0 +1,116 @@
|
||||
From af26b0d1bf934bbaa7cafb871a51e95087a088a0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:34:31 +0300
|
||||
Subject: [PATCH 04/30] net: dsa: mt7530: support OF-based registration of
|
||||
switch MDIO bus
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Currently the MDIO bus of the switches the MT7530 DSA subdriver controls
|
||||
can only be registered as non-OF-based. Bring support for registering the
|
||||
bus OF-based.
|
||||
|
||||
The subdrivers that control switches [with MDIO bus] probed on OF must
|
||||
follow this logic to support all cases properly:
|
||||
|
||||
No switch MDIO bus defined: Populate ds->user_mii_bus, register the MDIO
|
||||
bus, set the interrupts for PHYs if "interrupt-controller" is defined at
|
||||
the switch node. This case should only be covered for the switches which
|
||||
their dt-bindings documentation didn't document the MDIO bus from the
|
||||
start. This is to keep supporting the device trees that do not describe the
|
||||
MDIO bus on the device tree but the MDIO bus is being used nonetheless.
|
||||
|
||||
Switch MDIO bus defined: Don't populate ds->user_mii_bus, register the MDIO
|
||||
bus, set the interrupts for PHYs if ["interrupt-controller" is defined at
|
||||
the switch node and "interrupts" is defined at the PHY nodes under the
|
||||
switch MDIO bus node].
|
||||
|
||||
Switch MDIO bus defined but explicitly disabled: If the device tree says
|
||||
status = "disabled" for the MDIO bus, we shouldn't need an MDIO bus at all.
|
||||
Instead, just exit as early as possible and do not call any MDIO API.
|
||||
|
||||
The use of ds->user_mii_bus is inappropriate when the MDIO bus of the
|
||||
switch is described on the device tree [1], which is why we don't populate
|
||||
ds->user_mii_bus in that case.
|
||||
|
||||
Link: https://lore.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/ [1]
|
||||
Suggested-by: David Bauer <mail@david-bauer.net>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122053431.7751-1-arinc.unal@arinc9.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 34 ++++++++++++++++++++++++++--------
|
||||
1 file changed, 26 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2345,24 +2345,40 @@ mt7530_free_irq_common(struct mt7530_pri
|
||||
static void
|
||||
mt7530_free_irq(struct mt7530_priv *priv)
|
||||
{
|
||||
- mt7530_free_mdio_irq(priv);
|
||||
+ struct device_node *mnp, *np = priv->dev->of_node;
|
||||
+
|
||||
+ mnp = of_get_child_by_name(np, "mdio");
|
||||
+ if (!mnp)
|
||||
+ mt7530_free_mdio_irq(priv);
|
||||
+ of_node_put(mnp);
|
||||
+
|
||||
mt7530_free_irq_common(priv);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_setup_mdio(struct mt7530_priv *priv)
|
||||
{
|
||||
+ struct device_node *mnp, *np = priv->dev->of_node;
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
struct device *dev = priv->dev;
|
||||
struct mii_bus *bus;
|
||||
static int idx;
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mnp = of_get_child_by_name(np, "mdio");
|
||||
+
|
||||
+ if (mnp && !of_device_is_available(mnp))
|
||||
+ goto out;
|
||||
|
||||
bus = devm_mdiobus_alloc(dev);
|
||||
- if (!bus)
|
||||
- return -ENOMEM;
|
||||
+ if (!bus) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!mnp)
|
||||
+ ds->slave_mii_bus = bus;
|
||||
|
||||
- ds->slave_mii_bus = bus;
|
||||
bus->priv = priv;
|
||||
bus->name = KBUILD_MODNAME "-mii";
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", idx++);
|
||||
@@ -2373,16 +2389,18 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
bus->parent = dev;
|
||||
bus->phy_mask = ~ds->phys_mii_mask;
|
||||
|
||||
- if (priv->irq)
|
||||
+ if (priv->irq && !mnp)
|
||||
mt7530_setup_mdio_irq(priv);
|
||||
|
||||
- ret = devm_mdiobus_register(dev, bus);
|
||||
+ ret = devm_of_mdiobus_register(dev, bus, mnp);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register MDIO bus: %d\n", ret);
|
||||
- if (priv->irq)
|
||||
+ if (priv->irq && !mnp)
|
||||
mt7530_free_mdio_irq(priv);
|
||||
}
|
||||
|
||||
+out:
|
||||
+ of_node_put(mnp);
|
||||
return ret;
|
||||
}
|
||||
|
@ -0,0 +1,125 @@
|
||||
From 617b07e08bcb1f69a72a085a7d847d1ca2999830 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:52 +0300
|
||||
Subject: [PATCH 05/30] net: dsa: mt7530: always trap frames to active CPU port
|
||||
on MT7530
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On the MT7530 switch, the CPU_PORT field indicates which CPU port to trap
|
||||
frames to, regardless of the affinity of the inbound user port.
|
||||
|
||||
When multiple CPU ports are in use, if the DSA conduit interface is down,
|
||||
trapped frames won't be passed to the conduit interface.
|
||||
|
||||
To make trapping frames work including this case, implement
|
||||
ds->ops->conduit_state_change() on this subdriver and set the CPU_PORT
|
||||
field to the numerically smallest CPU port whose conduit interface is up.
|
||||
Introduce the active_cpu_ports field to store the information of the active
|
||||
CPU ports. Correct the macros, CPU_PORT is bits 4 through 6 of the
|
||||
register.
|
||||
|
||||
Add a comment to explain frame trapping for this switch.
|
||||
|
||||
Currently, the driver doesn't support the use of multiple CPU ports so this
|
||||
is not necessarily a bug fix.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-1-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 35 +++++++++++++++++++++++++++++++----
|
||||
drivers/net/dsa/mt7530.h | 6 ++++--
|
||||
2 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1232,10 +1232,6 @@ mt753x_cpu_port_enable(struct dsa_switch
|
||||
mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
|
||||
UNU_FFP(BIT(port)));
|
||||
|
||||
- /* Set CPU port number */
|
||||
- if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
|
||||
- mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
|
||||
-
|
||||
/* Add the CPU port to the CPU port bitmap for MT7531 and the switch on
|
||||
* the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
|
||||
* is affine to the inbound user port.
|
||||
@@ -3305,6 +3301,36 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void
|
||||
+mt753x_conduit_state_change(struct dsa_switch *ds,
|
||||
+ const struct net_device *conduit,
|
||||
+ bool operational)
|
||||
+{
|
||||
+ struct dsa_port *cpu_dp = conduit->dsa_ptr;
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+ int val = 0;
|
||||
+ u8 mask;
|
||||
+
|
||||
+ /* Set the CPU port to trap frames to for MT7530. Trapped frames will be
|
||||
+ * forwarded to the numerically smallest CPU port whose conduit
|
||||
+ * interface is up.
|
||||
+ */
|
||||
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
|
||||
+ return;
|
||||
+
|
||||
+ mask = BIT(cpu_dp->index);
|
||||
+
|
||||
+ if (operational)
|
||||
+ priv->active_cpu_ports |= mask;
|
||||
+ else
|
||||
+ priv->active_cpu_ports &= ~mask;
|
||||
+
|
||||
+ if (priv->active_cpu_ports)
|
||||
+ val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports));
|
||||
+
|
||||
+ mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
|
||||
+}
|
||||
+
|
||||
static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
return 0;
|
||||
@@ -3360,6 +3386,7 @@ const struct dsa_switch_ops mt7530_switc
|
||||
.phylink_mac_link_up = mt753x_phylink_mac_link_up,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
+ .master_state_change = mt753x_conduit_state_change,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -45,8 +45,8 @@ enum mt753x_id {
|
||||
#define UNU_FFP(x) (((x) & 0xff) << 8)
|
||||
#define UNU_FFP_MASK UNU_FFP(~0)
|
||||
#define CPU_EN BIT(7)
|
||||
-#define CPU_PORT(x) ((x) << 4)
|
||||
-#define CPU_MASK (0xf << 4)
|
||||
+#define CPU_PORT_MASK GENMASK(6, 4)
|
||||
+#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x)
|
||||
#define MIRROR_EN BIT(3)
|
||||
#define MIRROR_PORT(x) ((x) & 0x7)
|
||||
#define MIRROR_MASK 0x7
|
||||
@@ -790,6 +790,7 @@ struct mt753x_info {
|
||||
* @irq_domain: IRQ domain of the switch irq_chip
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
+ * @active_cpu_ports: Holding the active CPU ports
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -816,6 +817,7 @@ struct mt7530_priv {
|
||||
struct irq_domain *irq_domain;
|
||||
u32 irq_enable;
|
||||
int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
|
||||
+ u8 active_cpu_ports;
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
@ -0,0 +1,45 @@
|
||||
From 07f411e26f82d75723df1c0c072e5602d06f4e30 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:53 +0300
|
||||
Subject: [PATCH 06/30] net: dsa: mt7530: use p5_interface_select as data type
|
||||
for p5_intf_sel
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use the p5_interface_select enumeration as the data type for the
|
||||
p5_intf_sel field. This ensures p5_intf_sel can only take the values
|
||||
defined in the p5_interface_select enumeration.
|
||||
|
||||
Remove the explicit assignment of 0 to P5_DISABLED as the first enum item
|
||||
is automatically assigned 0.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-2-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -713,7 +713,7 @@ struct mt7530_port {
|
||||
|
||||
/* Port 5 interface select definitions */
|
||||
enum p5_interface_select {
|
||||
- P5_DISABLED = 0,
|
||||
+ P5_DISABLED,
|
||||
P5_INTF_SEL_PHY_P0,
|
||||
P5_INTF_SEL_PHY_P4,
|
||||
P5_INTF_SEL_GMAC5,
|
||||
@@ -806,7 +806,7 @@ struct mt7530_priv {
|
||||
bool mcm;
|
||||
phy_interface_t p6_interface;
|
||||
phy_interface_t p5_interface;
|
||||
- unsigned int p5_intf_sel;
|
||||
+ enum p5_interface_select p5_intf_sel;
|
||||
u8 mirror_rx;
|
||||
u8 mirror_tx;
|
||||
struct mt7530_port ports[MT7530_NUM_PORTS];
|
@ -0,0 +1,227 @@
|
||||
From 8f7db12efc189eedd196ed8d053236ce27add484 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:54 +0300
|
||||
Subject: [PATCH 07/30] net: dsa: mt7530: store port 5 SGMII capability of
|
||||
MT7531
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Introduce the p5_sgmii field to store the information for whether port 5
|
||||
has got SGMII or not. Instead of reading the MT7531_TOP_SIG_SR register
|
||||
multiple times, the register will be read once and the value will be
|
||||
stored on the p5_sgmii field. This saves unnecessary reads of the
|
||||
register.
|
||||
|
||||
Move the comment about MT7531AE and MT7531BE to mt7531_setup(), where the
|
||||
switch is identified.
|
||||
|
||||
Get rid of mt7531_dual_sgmii_supported() now that priv->p5_sgmii stores the
|
||||
information. Address the code where mt7531_dual_sgmii_supported() is used.
|
||||
|
||||
Get rid of mt7531_is_rgmii_port() which just prints the opposite of
|
||||
priv->p5_sgmii.
|
||||
|
||||
Instead of calling mt7531_pll_setup() then returning, do not call it if
|
||||
port 5 is SGMII.
|
||||
|
||||
Remove P5_INTF_SEL_GMAC5_SGMII. The p5_interface_select enum is supposed to
|
||||
represent the mode that port 5 is being used in, not the hardware
|
||||
information of port 5. Set p5_intf_sel to P5_INTF_SEL_GMAC5 instead, if
|
||||
port 5 is not dsa_is_unused_port().
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-3-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 7 ++---
|
||||
drivers/net/dsa/mt7530.c | 48 ++++++++++++-----------------------
|
||||
drivers/net/dsa/mt7530.h | 6 +++--
|
||||
3 files changed, 22 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -81,17 +81,14 @@ static const struct regmap_bus mt7530_re
|
||||
};
|
||||
|
||||
static int
|
||||
-mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
{
|
||||
struct regmap_config *mt7531_pcs_config[2] = {};
|
||||
struct phylink_pcs *pcs;
|
||||
struct regmap *regmap;
|
||||
int i, ret = 0;
|
||||
|
||||
- /* MT7531AE has two SGMII units for port 5 and port 6
|
||||
- * MT7531BE has only one SGMII unit for port 6
|
||||
- */
|
||||
- for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
|
||||
+ for (i = priv->p5_sgmii ? 0 : 1; i < 2; i++) {
|
||||
mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
sizeof(struct regmap_config),
|
||||
GFP_KERNEL);
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -487,15 +487,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||||
-
|
||||
- return (val & PAD_DUAL_SGMII_EN) != 0;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
@@ -510,9 +501,6 @@ mt7531_pll_setup(struct mt7530_priv *pri
|
||||
u32 xtal;
|
||||
u32 val;
|
||||
|
||||
- if (mt7531_dual_sgmii_supported(priv))
|
||||
- return;
|
||||
-
|
||||
val = mt7530_read(priv, MT7531_CREV);
|
||||
top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||||
hwstrap = mt7530_read(priv, MT7531_HWTRAP);
|
||||
@@ -920,8 +908,6 @@ static const char *p5_intf_modes(unsigne
|
||||
return "PHY P4";
|
||||
case P5_INTF_SEL_GMAC5:
|
||||
return "GMAC5";
|
||||
- case P5_INTF_SEL_GMAC5_SGMII:
|
||||
- return "GMAC5_SGMII";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
@@ -2694,6 +2680,12 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+ /* MT7531AE has got two SGMII units. One for port 5, one for port 6.
|
||||
+ * MT7531BE has got only one SGMII unit which is for port 6.
|
||||
+ */
|
||||
+ val = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||||
+ priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
|
||||
+
|
||||
/* all MACs must be forced link-down before sw reset */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
|
||||
@@ -2703,21 +2695,18 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
|
||||
SYS_CTRL_REG_RST);
|
||||
|
||||
- mt7531_pll_setup(priv);
|
||||
-
|
||||
- if (mt7531_dual_sgmii_supported(priv)) {
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII;
|
||||
-
|
||||
+ if (!priv->p5_sgmii) {
|
||||
+ mt7531_pll_setup(priv);
|
||||
+ } else {
|
||||
/* Let ds->slave_mii_bus be able to access external phy. */
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
|
||||
MT7531_EXT_P_MDC_11);
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
|
||||
MT7531_EXT_P_MDIO_12);
|
||||
- } else {
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||||
}
|
||||
- dev_dbg(ds->dev, "P5 support %s interface\n",
|
||||
- p5_intf_modes(priv->p5_intf_sel));
|
||||
+
|
||||
+ if (!dsa_is_unused_port(ds, 5))
|
||||
+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||||
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
|
||||
MT7531_GPIO0_INTERRUPT);
|
||||
@@ -2784,11 +2773,6 @@ static void mt7530_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
-static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
|
||||
-{
|
||||
- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
|
||||
-}
|
||||
-
|
||||
static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
@@ -2801,7 +2785,7 @@ static void mt7531_mac_port_get_caps(str
|
||||
break;
|
||||
|
||||
case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
|
||||
- if (mt7531_is_rgmii_port(priv, port)) {
|
||||
+ if (!priv->p5_sgmii) {
|
||||
phy_interface_set_rgmii(config->supported_interfaces);
|
||||
break;
|
||||
}
|
||||
@@ -2868,7 +2852,7 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
{
|
||||
u32 val;
|
||||
|
||||
- if (!mt7531_is_rgmii_port(priv, port)) {
|
||||
+ if (priv->p5_sgmii) {
|
||||
dev_err(priv->dev, "RGMII mode is not available for port %d\n",
|
||||
port);
|
||||
return -EINVAL;
|
||||
@@ -3111,7 +3095,7 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
|
||||
switch (port) {
|
||||
case 5:
|
||||
- if (mt7531_is_rgmii_port(priv, port))
|
||||
+ if (!priv->p5_sgmii)
|
||||
interface = PHY_INTERFACE_MODE_RGMII;
|
||||
else
|
||||
interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
@@ -3263,7 +3247,7 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
if (priv->create_sgmii) {
|
||||
- ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
|
||||
+ ret = priv->create_sgmii(priv);
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq(priv);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -717,7 +717,6 @@ enum p5_interface_select {
|
||||
P5_INTF_SEL_PHY_P0,
|
||||
P5_INTF_SEL_PHY_P4,
|
||||
P5_INTF_SEL_GMAC5,
|
||||
- P5_INTF_SEL_GMAC5_SGMII,
|
||||
};
|
||||
|
||||
struct mt7530_priv;
|
||||
@@ -786,6 +785,8 @@ struct mt753x_info {
|
||||
* registers
|
||||
* @p6_interface Holding the current port 6 interface
|
||||
* @p5_intf_sel: Holding the current port 5 interface select
|
||||
+ * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
|
||||
+ * has got SGMII
|
||||
* @irq: IRQ number of the switch
|
||||
* @irq_domain: IRQ domain of the switch irq_chip
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
@@ -807,6 +808,7 @@ struct mt7530_priv {
|
||||
phy_interface_t p6_interface;
|
||||
phy_interface_t p5_interface;
|
||||
enum p5_interface_select p5_intf_sel;
|
||||
+ bool p5_sgmii;
|
||||
u8 mirror_rx;
|
||||
u8 mirror_tx;
|
||||
struct mt7530_port ports[MT7530_NUM_PORTS];
|
||||
@@ -816,7 +818,7 @@ struct mt7530_priv {
|
||||
int irq;
|
||||
struct irq_domain *irq_domain;
|
||||
u32 irq_enable;
|
||||
- int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
|
||||
+ int (*create_sgmii)(struct mt7530_priv *priv);
|
||||
u8 active_cpu_ports;
|
||||
};
|
||||
|
@ -0,0 +1,133 @@
|
||||
From c91b7fb8fbb2e18ebb497e67f4252cec78e3a29b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:55 +0300
|
||||
Subject: [PATCH 08/30] net: dsa: mt7530: improve comments regarding switch
|
||||
ports
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There's no logic to numerically order the CPU ports. Just state the port
|
||||
number instead.
|
||||
|
||||
Remove the irrelevant PHY muxing information from
|
||||
mt7530_mac_port_get_caps(). Explain the supported MII modes instead.
|
||||
|
||||
Remove the out of place PHY muxing information from
|
||||
mt753x_phylink_mac_config(). The function is for MT7530, MT7531, and the
|
||||
switch on the MT7988 SoC but there's no PHY muxing on MT7531 or the switch
|
||||
on the MT7988 SoC.
|
||||
|
||||
These comments were gradually introduced with the commits below.
|
||||
commit ca366d6c889b ("net: dsa: mt7530: Convert to PHYLINK API")
|
||||
commit 38f790a80560 ("net: dsa: mt7530: Add support for port 5")
|
||||
commit 88bdef8be9f6 ("net: dsa: mt7530: Extend device data ready for adding
|
||||
a new hardware")
|
||||
commit c288575f7810 ("net: dsa: mt7530: Add the support of MT7531 switch")
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-4-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 30 ++++++++++++++++++++----------
|
||||
1 file changed, 20 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2751,12 +2751,14 @@ static void mt7530_mac_port_get_caps(str
|
||||
struct phylink_config *config)
|
||||
{
|
||||
switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
+ case 0 ... 4:
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
break;
|
||||
|
||||
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
+ /* Port 5 supports rgmii with delays, mii, and gmii. */
|
||||
+ case 5:
|
||||
phy_interface_set_rgmii(config->supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_MII,
|
||||
config->supported_interfaces);
|
||||
@@ -2764,7 +2766,8 @@ static void mt7530_mac_port_get_caps(str
|
||||
config->supported_interfaces);
|
||||
break;
|
||||
|
||||
- case 6: /* 1st cpu port */
|
||||
+ /* Port 6 supports rgmii and trgmii. */
|
||||
+ case 6:
|
||||
__set_bit(PHY_INTERFACE_MODE_RGMII,
|
||||
config->supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_TRGMII,
|
||||
@@ -2779,19 +2782,24 @@ static void mt7531_mac_port_get_caps(str
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
+ case 0 ... 4:
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
break;
|
||||
|
||||
- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
|
||||
+ /* Port 5 supports rgmii with delays on MT7531BE, sgmii/802.3z on
|
||||
+ * MT7531AE.
|
||||
+ */
|
||||
+ case 5:
|
||||
if (!priv->p5_sgmii) {
|
||||
phy_interface_set_rgmii(config->supported_interfaces);
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
|
||||
- case 6: /* 1st cpu port supports sgmii/8023z only */
|
||||
+ /* Port 6 supports sgmii/802.3z. */
|
||||
+ case 6:
|
||||
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
config->supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
@@ -2810,11 +2818,13 @@ static void mt7988_mac_port_get_caps(str
|
||||
phy_interface_zero(config->supported_interfaces);
|
||||
|
||||
switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
+ case 0 ... 4:
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
break;
|
||||
|
||||
+ /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */
|
||||
case 6:
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
@@ -2978,12 +2988,12 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
+ case 0 ... 4:
|
||||
if (state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
+ case 5:
|
||||
if (priv->p5_interface == state->interface)
|
||||
break;
|
||||
|
||||
@@ -2993,7 +3003,7 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
if (priv->p5_intf_sel != P5_DISABLED)
|
||||
priv->p5_interface = state->interface;
|
||||
break;
|
||||
- case 6: /* 1st cpu port */
|
||||
+ case 6:
|
||||
if (priv->p6_interface == state->interface)
|
||||
break;
|
||||
|
@ -0,0 +1,95 @@
|
||||
From c1b2294a9b4b9b6c0cbe58666cb86e0a9cb0abfd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:56 +0300
|
||||
Subject: [PATCH 09/30] net: dsa: mt7530: improve code path for setting up port
|
||||
5
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There're two code paths for setting up port 5:
|
||||
|
||||
mt7530_setup()
|
||||
-> mt7530_setup_port5()
|
||||
|
||||
mt753x_phylink_mac_config()
|
||||
-> mt753x_mac_config()
|
||||
-> mt7530_mac_config()
|
||||
-> mt7530_setup_port5()
|
||||
|
||||
Currently mt7530_setup_port5() from mt7530_setup() always runs. If port 5
|
||||
is used as a CPU, DSA, or user port, mt7530_setup_port5() from
|
||||
mt753x_phylink_mac_config() won't run. That is because priv->p5_interface
|
||||
set on mt7530_setup_port5() will match state->interface on
|
||||
mt753x_phylink_mac_config() which will stop running mt7530_setup_port5()
|
||||
again.
|
||||
|
||||
Therefore, mt7530_setup_port5() will never run from
|
||||
mt753x_phylink_mac_config().
|
||||
|
||||
Address this by not running mt7530_setup_port5() from mt7530_setup() if
|
||||
port 5 is used as a CPU, DSA, or user port. This driver isn't in the
|
||||
dsa_switches_apply_workarounds[] array so phylink will always be present.
|
||||
|
||||
To keep the cases where port 5 isn't controlled by phylink working as
|
||||
before, preserve the mt7530_setup_port5() call from mt7530_setup().
|
||||
|
||||
Do not set priv->p5_intf_sel to P5_DISABLED. It is already set to that when
|
||||
"priv" is allocated.
|
||||
|
||||
Move setting the interface to a more specific location. It's supposed to be
|
||||
overwritten if PHY muxing is detected.
|
||||
|
||||
Improve the comment which explains the process.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-5-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 17 ++++++++---------
|
||||
1 file changed, 8 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2529,16 +2529,15 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
return ret;
|
||||
|
||||
/* Setup port 5 */
|
||||
- priv->p5_intf_sel = P5_DISABLED;
|
||||
- interface = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
if (!dsa_is_unused_port(ds, 5)) {
|
||||
priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||||
- ret = of_get_phy_mode(dsa_to_port(ds, 5)->dn, &interface);
|
||||
- if (ret && ret != -ENODEV)
|
||||
- return ret;
|
||||
} else {
|
||||
- /* Scan the ethernet nodes. look for GMAC1, lookup used phy */
|
||||
+ /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.
|
||||
+ * Set priv->p5_intf_sel to the appropriate value if PHY muxing
|
||||
+ * is detected.
|
||||
+ */
|
||||
+ interface = PHY_INTERFACE_MODE_NA;
|
||||
+
|
||||
for_each_child_of_node(dn, mac_np) {
|
||||
if (!of_device_is_compatible(mac_np,
|
||||
"mediatek,eth-mac"))
|
||||
@@ -2569,6 +2568,8 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
of_node_put(phy_node);
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ mt7530_setup_port5(ds, interface);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
@@ -2579,8 +2580,6 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
#endif /* CONFIG_GPIOLIB */
|
||||
|
||||
- mt7530_setup_port5(ds, interface);
|
||||
-
|
||||
/* Flush the FDB table */
|
||||
ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
|
||||
if (ret < 0)
|
@ -0,0 +1,42 @@
|
||||
From cd1cee68e57eedb460a68d1f42abf9f740b17e94 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:57 +0300
|
||||
Subject: [PATCH 10/30] net: dsa: mt7530: do not set priv->p5_interface on
|
||||
mt7530_setup_port5()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Running mt7530_setup_port5() from mt7530_setup() used to handle all cases
|
||||
of configuring port 5, including phylink.
|
||||
|
||||
Setting priv->p5_interface under mt7530_setup_port5() makes sure that
|
||||
mt7530_setup_port5() from mt753x_phylink_mac_config() won't run.
|
||||
|
||||
The commit ("net: dsa: mt7530: improve code path for setting up port 5")
|
||||
makes so that mt7530_setup_port5() from mt7530_setup() runs only on
|
||||
non-phylink cases.
|
||||
|
||||
Get rid of unnecessarily setting priv->p5_interface under
|
||||
mt7530_setup_port5() as port 5 phylink configuration will be done by
|
||||
running mt7530_setup_port5() from mt753x_phylink_mac_config() now.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-6-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -978,8 +978,6 @@ static void mt7530_setup_port5(struct ds
|
||||
dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
|
||||
val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
|
||||
|
||||
- priv->p5_interface = interface;
|
||||
-
|
||||
unlock_exit:
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
From e55a68aeb0f8b9c74b582b7a5e92b82988832bf8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Jan 2024 08:35:58 +0300
|
||||
Subject: [PATCH 11/30] net: dsa: mt7530: do not run mt7530_setup_port5() if
|
||||
port 5 is disabled
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There's no need to run all the code on mt7530_setup_port5() if port 5 is
|
||||
disabled. The only case for calling mt7530_setup_port5() from
|
||||
mt7530_setup() is when PHY muxing is enabled. That is because port 5 is not
|
||||
defined as a port on the devicetree, therefore, it cannot be controlled by
|
||||
phylink.
|
||||
|
||||
Because of this, run mt7530_setup_port5() if priv->p5_intf_sel is
|
||||
P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4. Remove the P5_DISABLED case from
|
||||
mt7530_setup_port5().
|
||||
|
||||
Stop initialising the interface variable as the remaining cases will always
|
||||
call mt7530_setup_port5() with it initialised.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-7-042401f2b279@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -942,9 +942,6 @@ static void mt7530_setup_port5(struct ds
|
||||
/* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
|
||||
val &= ~MHWTRAP_P5_DIS;
|
||||
break;
|
||||
- case P5_DISABLED:
|
||||
- interface = PHY_INTERFACE_MODE_NA;
|
||||
- break;
|
||||
default:
|
||||
dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
|
||||
priv->p5_intf_sel);
|
||||
@@ -2534,8 +2531,6 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
* Set priv->p5_intf_sel to the appropriate value if PHY muxing
|
||||
* is detected.
|
||||
*/
|
||||
- interface = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
for_each_child_of_node(dn, mac_np) {
|
||||
if (!of_device_is_compatible(mac_np,
|
||||
"mediatek,eth-mac"))
|
||||
@@ -2567,7 +2562,9 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
break;
|
||||
}
|
||||
|
||||
- mt7530_setup_port5(ds, interface);
|
||||
+ if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 ||
|
||||
+ priv->p5_intf_sel == P5_INTF_SEL_PHY_P4)
|
||||
+ mt7530_setup_port5(ds, interface);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
@ -0,0 +1,58 @@
|
||||
From 1f538cda24bcb69919da2fcac0211b66281d3d4e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:02 +0300
|
||||
Subject: [PATCH 12/30] net: dsa: mt7530: empty default case on
|
||||
mt7530_setup_port5()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There're two code paths for setting up port 5:
|
||||
|
||||
mt7530_setup()
|
||||
-> mt7530_setup_port5()
|
||||
|
||||
mt753x_phylink_mac_config()
|
||||
-> mt753x_mac_config()
|
||||
-> mt7530_mac_config()
|
||||
-> mt7530_setup_port5()
|
||||
|
||||
On the first code path, priv->p5_intf_sel is either set to
|
||||
P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.
|
||||
|
||||
On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
|
||||
mt7530_setup_port5() is run.
|
||||
|
||||
Empty the default case which will never run but is needed nonetheless to
|
||||
handle all the remaining enumeration values.
|
||||
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-1-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -943,9 +943,7 @@ static void mt7530_setup_port5(struct ds
|
||||
val &= ~MHWTRAP_P5_DIS;
|
||||
break;
|
||||
default:
|
||||
- dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
|
||||
- priv->p5_intf_sel);
|
||||
- goto unlock_exit;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* Setup RGMII settings */
|
||||
@@ -975,7 +973,6 @@ static void mt7530_setup_port5(struct ds
|
||||
dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
|
||||
val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
|
||||
|
||||
-unlock_exit:
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 12c511cd31c2dc6bd96e4a89f7709d515aa8a76b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:03 +0300
|
||||
Subject: [PATCH 13/30] net: dsa: mt7530: move XTAL check to mt7530_setup()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The crystal frequency concerns the switch core. The frequency should be
|
||||
checked when the switch is being set up so the driver can reject the
|
||||
unsupported hardware earlier and without requiring port 6 to be used.
|
||||
|
||||
Move it to mt7530_setup(). Drop the unnecessary function printing.
|
||||
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-2-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 13 ++++++-------
|
||||
1 file changed, 6 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
|
||||
|
||||
xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
|
||||
|
||||
- if (xtal == HWTRAP_XTAL_20MHZ) {
|
||||
- dev_err(priv->dev,
|
||||
- "%s: MT7530 with a 20MHz XTAL is not supported!\n",
|
||||
- __func__);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
trgint = 0;
|
||||
@@ -2458,6 +2451,12 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+ if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
|
||||
+ dev_err(priv->dev,
|
||||
+ "MT7530 with a 20MHz XTAL is not supported!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
/* Reset the switch through internal reset */
|
||||
mt7530_write(priv, MT7530_SYS_CTRL,
|
||||
SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
|
@ -0,0 +1,146 @@
|
||||
From c33899a6a8c1a5723afbfc075600aba2e2bdbea7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:04 +0300
|
||||
Subject: [PATCH 14/30] net: dsa: mt7530: simplify mt7530_pad_clk_setup()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This code is from before this driver was converted to phylink API. Phylink
|
||||
deals with the unsupported interface cases before mt7530_pad_clk_setup() is
|
||||
run. Therefore, the default case would never run. However, it must be
|
||||
defined nonetheless to handle all the remaining enumeration values, the
|
||||
phy-modes.
|
||||
|
||||
Switch to if statement for RGMII and return which simplifies the code and
|
||||
saves an indent.
|
||||
|
||||
Set P6_INTF_MODE, which is the three least significant bits of the
|
||||
MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
|
||||
after reset. This is to keep supporting dynamic reconfiguration of the port
|
||||
in the case the interface changes from TRGMII to RGMII.
|
||||
|
||||
Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
|
||||
being used.
|
||||
|
||||
Read XTAL after checking for RGMII as it's only needed for the TRGMII
|
||||
interface mode.
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 91 ++++++++++++++++++----------------------
|
||||
1 file changed, 40 insertions(+), 51 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -418,65 +418,54 @@ static int
|
||||
mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- u32 ncpo1, ssc_delta, trgint, xtal;
|
||||
+ u32 ncpo1, ssc_delta, xtal;
|
||||
|
||||
- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
|
||||
+ /* Disable the MT7530 TRGMII clocks */
|
||||
+ core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
|
||||
- switch (interface) {
|
||||
- case PHY_INTERFACE_MODE_RGMII:
|
||||
- trgint = 0;
|
||||
- break;
|
||||
- case PHY_INTERFACE_MODE_TRGMII:
|
||||
- trgint = 1;
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
- ssc_delta = 0x57;
|
||||
- else
|
||||
- ssc_delta = 0x87;
|
||||
- if (priv->id == ID_MT7621) {
|
||||
- /* PLL frequency: 125MHz: 1.0GBit */
|
||||
- if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
- ncpo1 = 0x0640;
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
- ncpo1 = 0x0a00;
|
||||
- } else { /* PLL frequency: 250MHz: 2.0Gbit */
|
||||
- if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
- ncpo1 = 0x0c80;
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
- ncpo1 = 0x1400;
|
||||
- }
|
||||
- break;
|
||||
- default:
|
||||
- dev_err(priv->dev, "xMII interface %d not supported\n",
|
||||
- interface);
|
||||
- return -EINVAL;
|
||||
+ if (interface == PHY_INTERFACE_MODE_RGMII) {
|
||||
+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
|
||||
+ P6_INTF_MODE(0));
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
|
||||
- P6_INTF_MODE(trgint));
|
||||
+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
|
||||
|
||||
- if (trgint) {
|
||||
- /* Disable the MT7530 TRGMII clocks */
|
||||
- core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
-
|
||||
- /* Setup the MT7530 TRGMII Tx Clock */
|
||||
- core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
|
||||
- core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
|
||||
- core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
|
||||
- core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
|
||||
- core_write(priv, CORE_PLL_GROUP4,
|
||||
- RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
|
||||
- RG_SYSPLL_BIAS_LPF_EN);
|
||||
- core_write(priv, CORE_PLL_GROUP2,
|
||||
- RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
|
||||
- RG_SYSPLL_POSDIV(1));
|
||||
- core_write(priv, CORE_PLL_GROUP7,
|
||||
- RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
|
||||
- RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
|
||||
+ xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
|
||||
|
||||
- /* Enable the MT7530 TRGMII clocks */
|
||||
- core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
+ if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ ssc_delta = 0x57;
|
||||
+ else
|
||||
+ ssc_delta = 0x87;
|
||||
+
|
||||
+ if (priv->id == ID_MT7621) {
|
||||
+ /* PLL frequency: 125MHz: 1.0GBit */
|
||||
+ if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
+ ncpo1 = 0x0640;
|
||||
+ if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ ncpo1 = 0x0a00;
|
||||
+ } else { /* PLL frequency: 250MHz: 2.0Gbit */
|
||||
+ if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
+ ncpo1 = 0x0c80;
|
||||
+ if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ ncpo1 = 0x1400;
|
||||
}
|
||||
|
||||
+ /* Setup the MT7530 TRGMII Tx Clock */
|
||||
+ core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
|
||||
+ core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
|
||||
+ core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
|
||||
+ core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
|
||||
+ core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
|
||||
+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
|
||||
+ core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL |
|
||||
+ RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1));
|
||||
+ core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG |
|
||||
+ RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
|
||||
+
|
||||
+ /* Enable the MT7530 TRGMII clocks */
|
||||
+ core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
From e612922de7070a28802216650ee88128a57290de Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:05 +0300
|
||||
Subject: [PATCH 15/30] net: dsa: mt7530: call port 6 setup from
|
||||
mt7530_mac_config()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
|
||||
things than setting up port 6. That part was moved to more appropriate
|
||||
locations, mt7530_setup() and mt7530_pll_setup().
|
||||
|
||||
Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
|
||||
and move it to a more appropriate location, under mt7530_mac_config().
|
||||
|
||||
Change mt7530_setup_port6() to void as there're no error cases.
|
||||
|
||||
Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
|
||||
pointer.
|
||||
|
||||
This is the code path for setting up the ports before:
|
||||
|
||||
dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
|
||||
-> mt753x_mac_config()
|
||||
-> mt753x_info :: mac_port_config() -> mt7530_mac_config()
|
||||
-> mt7530_setup_port5()
|
||||
-> mt753x_pad_setup()
|
||||
-> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
|
||||
|
||||
This is after:
|
||||
|
||||
dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
|
||||
-> mt753x_mac_config()
|
||||
-> mt753x_info :: mac_port_config() -> mt7530_mac_config()
|
||||
-> mt7530_setup_port5()
|
||||
-> mt7530_setup_port6()
|
||||
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-4-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 19 +++++++++++--------
|
||||
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(
|
||||
}
|
||||
|
||||
/* Setup port 6 interface mode and TRGMII TX circuit */
|
||||
-static int
|
||||
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
+static void
|
||||
+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 ncpo1, ssc_delta, xtal;
|
||||
@@ -426,7 +426,7 @@ mt7530_pad_clk_setup(struct dsa_switch *
|
||||
if (interface == PHY_INTERFACE_MODE_RGMII) {
|
||||
mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
|
||||
P6_INTF_MODE(0));
|
||||
- return 0;
|
||||
+ return;
|
||||
}
|
||||
|
||||
mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
|
||||
@@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch *
|
||||
|
||||
/* Enable the MT7530 TRGMII clocks */
|
||||
core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
+}
|
||||
|
||||
+static int
|
||||
+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
+{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2826,11 +2830,10 @@ mt7530_mac_config(struct dsa_switch *ds,
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
- /* Only need to setup port5. */
|
||||
- if (port != 5)
|
||||
- return 0;
|
||||
-
|
||||
- mt7530_setup_port5(priv->ds, interface);
|
||||
+ if (port == 5)
|
||||
+ mt7530_setup_port5(priv->ds, interface);
|
||||
+ else if (port == 6)
|
||||
+ mt7530_setup_port6(priv->ds, interface);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
From af83e0c7d766078fcd5580c0c81b9e5b55ff5906 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:06 +0300
|
||||
Subject: [PATCH 16/30] net: dsa: mt7530: remove pad_setup function pointer
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
|
||||
mt7530: Extend device data ready for adding a new hardware"). It was being
|
||||
used to set up the core clock and port 6 of the MT7530 switch, and pll of
|
||||
the MT7531 switch.
|
||||
|
||||
All of these were moved to more appropriate locations, and it was never
|
||||
used for the switch on the MT7988 SoC. Therefore, this function pointer
|
||||
hasn't got a use anymore. Remove it.
|
||||
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-5-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 36 ++----------------------------------
|
||||
drivers/net/dsa/mt7530.h | 3 ---
|
||||
2 files changed, 2 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds
|
||||
core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static void
|
||||
mt7531_pll_setup(struct mt7530_priv *priv)
|
||||
{
|
||||
@@ -2817,14 +2805,6 @@ static void mt7988_mac_port_get_caps(str
|
||||
}
|
||||
|
||||
static int
|
||||
-mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- return priv->info->pad_setup(ds, state->interface);
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2989,8 +2969,6 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
if (priv->p6_interface == state->interface)
|
||||
break;
|
||||
|
||||
- mt753x_pad_setup(ds, state);
|
||||
-
|
||||
if (mt753x_mac_config(ds, port, mode, state) < 0)
|
||||
goto unsupported;
|
||||
|
||||
@@ -3307,11 +3285,6 @@ mt753x_conduit_state_change(struct dsa_s
|
||||
mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
|
||||
}
|
||||
|
||||
-static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int mt7988_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
@@ -3375,7 +3348,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7530_phy_write_c22,
|
||||
.phy_read_c45 = mt7530_phy_read_c45,
|
||||
.phy_write_c45 = mt7530_phy_write_c45,
|
||||
- .pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
@@ -3387,7 +3359,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7530_phy_write_c22,
|
||||
.phy_read_c45 = mt7530_phy_read_c45,
|
||||
.phy_write_c45 = mt7530_phy_write_c45,
|
||||
- .pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
@@ -3399,7 +3370,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7531_ind_c22_phy_write,
|
||||
.phy_read_c45 = mt7531_ind_c45_phy_read,
|
||||
.phy_write_c45 = mt7531_ind_c45_phy_write,
|
||||
- .pad_setup = mt7531_pad_setup,
|
||||
.cpu_port_config = mt7531_cpu_port_config,
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
@@ -3412,7 +3382,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7531_ind_c22_phy_write,
|
||||
.phy_read_c45 = mt7531_ind_c45_phy_read,
|
||||
.phy_write_c45 = mt7531_ind_c45_phy_write,
|
||||
- .pad_setup = mt7988_pad_setup,
|
||||
.cpu_port_config = mt7988_cpu_port_config,
|
||||
.mac_port_get_caps = mt7988_mac_port_get_caps,
|
||||
.mac_port_config = mt7988_mac_config,
|
||||
@@ -3442,9 +3411,8 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
/* Sanity check if these required device operations are filled
|
||||
* properly.
|
||||
*/
|
||||
- if (!priv->info->sw_setup || !priv->info->pad_setup ||
|
||||
- !priv->info->phy_read_c22 || !priv->info->phy_write_c22 ||
|
||||
- !priv->info->mac_port_get_caps ||
|
||||
+ if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
|
||||
+ !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
|
||||
!priv->info->mac_port_config)
|
||||
return -EINVAL;
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -734,8 +734,6 @@ struct mt753x_pcs {
|
||||
* @phy_write_c22: Holding the way writing PHY port using C22
|
||||
* @phy_read_c45: Holding the way reading PHY port using C45
|
||||
* @phy_write_c45: Holding the way writing PHY port using C45
|
||||
- * @pad_setup: Holding the way setting up the bus pad for a certain
|
||||
- * MAC port
|
||||
* @phy_mode_supported: Check if the PHY type is being supported on a certain
|
||||
* port
|
||||
* @mac_port_validate: Holding the way to set addition validate type for a
|
||||
@@ -756,7 +754,6 @@ struct mt753x_info {
|
||||
int regnum);
|
||||
int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum, u16 val);
|
||||
- int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
|
||||
int (*cpu_port_config)(struct dsa_switch *ds, int port);
|
||||
void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
@ -0,0 +1,36 @@
|
||||
From 9716e3e2c21547c97a9d79119da8fdce5659c2cc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:07 +0300
|
||||
Subject: [PATCH 17/30] net: dsa: mt7530: correct port capabilities of MT7988
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
|
||||
125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
|
||||
Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
|
||||
ports which connect to switch PHYs to '0 ... 3'.
|
||||
|
||||
Port 4 and 5 are not used at all in this design.
|
||||
|
||||
Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-6-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2790,7 +2790,7 @@ static void mt7988_mac_port_get_caps(str
|
||||
|
||||
switch (port) {
|
||||
/* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
- case 0 ... 4:
|
||||
+ case 0 ... 3:
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
break;
|
@ -0,0 +1,38 @@
|
||||
From 4d7b17712513710778c0f2f83ea5d9b55ed58c36 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 6 Feb 2024 01:08:08 +0300
|
||||
Subject: [PATCH 18/30] net: dsa: mt7530: do not clear
|
||||
config->supported_interfaces
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There's no need to clear the config->supported_interfaces bitmap before
|
||||
reporting the supported interfaces as all bits in the bitmap will already
|
||||
be initialized to zero when the phylink_config structure is allocated. The
|
||||
"config" pointer points to &dp->phylink_config, and "dp" is allocated by
|
||||
dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.
|
||||
|
||||
There's no code that would change the bitmap beforehand. Remove it.
|
||||
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-7-d7d92a185cb1@arinc9.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2786,8 +2786,6 @@ static void mt7531_mac_port_get_caps(str
|
||||
static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
- phy_interface_zero(config->supported_interfaces);
|
||||
-
|
||||
switch (port) {
|
||||
/* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
case 0 ... 3:
|
@ -0,0 +1,81 @@
|
||||
From 69e689e28191f9a242de6821a85f2c5ae4dbd5ae Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:42:57 +0200
|
||||
Subject: [PATCH 19/30] net: dsa: mt7530: remove .mac_port_config for MT7988
|
||||
and make it optional
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
For the switch on the MT7988 SoC, the mac_port_config member for ID_MT7988
|
||||
in mt753x_table is not needed as the interfaces of all MACs are already
|
||||
handled on mt7988_mac_port_get_caps().
|
||||
|
||||
Therefore, remove the mac_port_config member from ID_MT7988 in
|
||||
mt753x_table. Before calling priv->info->mac_port_config(), if there's no
|
||||
mac_port_config member in mt753x_table, exit mt753x_mac_config()
|
||||
successfully.
|
||||
|
||||
Remove calling priv->info->mac_port_config() from the sanity check as the
|
||||
sanity check requires a pointer to a mac_port_config function to be
|
||||
non-NULL. This will fail for MT7988 as mac_port_config won't be a member of
|
||||
its info table.
|
||||
|
||||
Co-developed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++--------------
|
||||
1 file changed, 4 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2869,17 +2869,6 @@ static bool mt753x_is_mac_port(u32 port)
|
||||
}
|
||||
|
||||
static int
|
||||
-mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
- phy_interface_t interface)
|
||||
-{
|
||||
- if (dsa_is_cpu_port(ds, port) &&
|
||||
- interface == PHY_INTERFACE_MODE_INTERNAL)
|
||||
- return 0;
|
||||
-
|
||||
- return -EINVAL;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2919,6 +2908,9 @@ mt753x_mac_config(struct dsa_switch *ds,
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
+ if (!priv->info->mac_port_config)
|
||||
+ return 0;
|
||||
+
|
||||
return priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
}
|
||||
|
||||
@@ -3382,7 +3374,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c45 = mt7531_ind_c45_phy_write,
|
||||
.cpu_port_config = mt7988_cpu_port_config,
|
||||
.mac_port_get_caps = mt7988_mac_port_get_caps,
|
||||
- .mac_port_config = mt7988_mac_config,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt753x_table);
|
||||
@@ -3410,8 +3401,7 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
* properly.
|
||||
*/
|
||||
if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
|
||||
- !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
|
||||
- !priv->info->mac_port_config)
|
||||
+ !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps)
|
||||
return -EINVAL;
|
||||
|
||||
priv->id = priv->info->id;
|
@ -0,0 +1,31 @@
|
||||
From f8faa3a04ca860b31f22d7d526c5e3f3de511a8f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:42:58 +0200
|
||||
Subject: [PATCH 20/30] net: dsa: mt7530: set interrupt register only for
|
||||
MT7530
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Setting this register related to interrupts is only needed for the MT7530
|
||||
switch. Make an exclusive check to ensure this.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2254,7 +2254,7 @@ mt7530_setup_irq(struct mt7530_priv *pri
|
||||
}
|
||||
|
||||
/* This register must be set for MT7530 to properly fire interrupts */
|
||||
- if (priv->id != ID_MT7531)
|
||||
+ if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
|
||||
mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
|
||||
|
||||
ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn,
|
@ -0,0 +1,41 @@
|
||||
From 80f4f866d7dad41b12cf37476c38766a89b8b5c4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:42:59 +0200
|
||||
Subject: [PATCH 21/30] net: dsa: mt7530: do not use SW_PHY_RST to reset MT7531
|
||||
switch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
According to the document MT7531 Reference Manual for Development Board
|
||||
v1.0, the SW_PHY_RST bit on the SYS_CTRL register doesn't exist for
|
||||
MT7531. This is likely why forcing link down on all ports is necessary for
|
||||
MT7531.
|
||||
|
||||
Therefore, do not set SW_PHY_RST on mt7531_setup().
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2657,14 +2657,12 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
val = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||||
priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
|
||||
|
||||
- /* all MACs must be forced link-down before sw reset */
|
||||
+ /* Force link down on all ports before internal reset */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
|
||||
|
||||
/* Reset the switch through internal reset */
|
||||
- mt7530_write(priv, MT7530_SYS_CTRL,
|
||||
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
|
||||
- SYS_CTRL_REG_RST);
|
||||
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
|
||||
|
||||
if (!priv->p5_sgmii) {
|
||||
mt7531_pll_setup(priv);
|
@ -0,0 +1,217 @@
|
||||
From 58670652cacb7c5752e01f29979d0ca4cdbfcc0a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:00 +0200
|
||||
Subject: [PATCH 22/30] net: dsa: mt7530: get rid of useless error returns on
|
||||
phylink code path
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Remove error returns on the cases where they are already handled with the
|
||||
function the mac_port_get_caps member in mt753x_table points to.
|
||||
|
||||
mt7531_mac_config() is also called from mt7531_cpu_port_config() outside of
|
||||
phylink but the port and interface modes are already handled there.
|
||||
|
||||
Change the functions and the mac_port_config function pointer to void now
|
||||
that there're no error returns anymore.
|
||||
|
||||
Remove mt753x_is_mac_port() that used to help the said error returns.
|
||||
|
||||
On mt7531_mac_config(), switch to if statements to simplify the code.
|
||||
|
||||
Remove internal phy cases from mt753x_phylink_mac_config(), there is no
|
||||
need to check the interface mode as that's already handled with the
|
||||
function the mac_port_get_caps member in mt753x_table points to.
|
||||
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 81 ++++++++--------------------------------
|
||||
drivers/net/dsa/mt7530.h | 6 +--
|
||||
2 files changed, 19 insertions(+), 68 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2800,7 +2800,7 @@ static void mt7988_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
-static int
|
||||
+static void
|
||||
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2810,22 +2810,14 @@ mt7530_mac_config(struct dsa_switch *ds,
|
||||
mt7530_setup_port5(priv->ds, interface);
|
||||
else if (port == 6)
|
||||
mt7530_setup_port6(priv->ds, interface);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
-static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
|
||||
- phy_interface_t interface,
|
||||
- struct phy_device *phydev)
|
||||
+static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
|
||||
+ phy_interface_t interface,
|
||||
+ struct phy_device *phydev)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
- if (priv->p5_sgmii) {
|
||||
- dev_err(priv->dev, "RGMII mode is not available for port %d\n",
|
||||
- port);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
|
||||
val |= GP_CLK_EN;
|
||||
val &= ~GP_MODE_MASK;
|
||||
@@ -2853,20 +2845,14 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
break;
|
||||
default:
|
||||
- return -EINVAL;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
- mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
|
||||
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static bool mt753x_is_mac_port(u32 port)
|
||||
-{
|
||||
- return (port == 5 || port == 6);
|
||||
+ mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
|
||||
}
|
||||
|
||||
-static int
|
||||
+static void
|
||||
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2874,42 +2860,21 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
struct phy_device *phydev;
|
||||
struct dsa_port *dp;
|
||||
|
||||
- if (!mt753x_is_mac_port(port)) {
|
||||
- dev_err(priv->dev, "port %d is not a MAC port\n", port);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- switch (interface) {
|
||||
- case PHY_INTERFACE_MODE_RGMII:
|
||||
- case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
- case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
- case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
+ if (phy_interface_mode_is_rgmii(interface)) {
|
||||
dp = dsa_to_port(ds, port);
|
||||
phydev = dp->slave->phydev;
|
||||
- return mt7531_rgmii_setup(priv, port, interface, phydev);
|
||||
- case PHY_INTERFACE_MODE_SGMII:
|
||||
- case PHY_INTERFACE_MODE_NA:
|
||||
- case PHY_INTERFACE_MODE_1000BASEX:
|
||||
- case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- /* handled in SGMII PCS driver */
|
||||
- return 0;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
+ mt7531_rgmii_setup(priv, port, interface, phydev);
|
||||
}
|
||||
-
|
||||
- return -EINVAL;
|
||||
}
|
||||
|
||||
-static int
|
||||
+static void
|
||||
mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
- if (!priv->info->mac_port_config)
|
||||
- return 0;
|
||||
-
|
||||
- return priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
+ if (priv->info->mac_port_config)
|
||||
+ priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
}
|
||||
|
||||
static struct phylink_pcs *
|
||||
@@ -2938,17 +2903,11 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
switch (port) {
|
||||
- case 0 ... 4:
|
||||
- if (state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
- state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
- goto unsupported;
|
||||
- break;
|
||||
case 5:
|
||||
if (priv->p5_interface == state->interface)
|
||||
break;
|
||||
|
||||
- if (mt753x_mac_config(ds, port, mode, state) < 0)
|
||||
- goto unsupported;
|
||||
+ mt753x_mac_config(ds, port, mode, state);
|
||||
|
||||
if (priv->p5_intf_sel != P5_DISABLED)
|
||||
priv->p5_interface = state->interface;
|
||||
@@ -2957,16 +2916,10 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
if (priv->p6_interface == state->interface)
|
||||
break;
|
||||
|
||||
- if (mt753x_mac_config(ds, port, mode, state) < 0)
|
||||
- goto unsupported;
|
||||
+ mt753x_mac_config(ds, port, mode, state);
|
||||
|
||||
priv->p6_interface = state->interface;
|
||||
break;
|
||||
- default:
|
||||
-unsupported:
|
||||
- dev_err(ds->dev, "%s: unsupported %s port: %i\n",
|
||||
- __func__, phy_modes(state->interface), port);
|
||||
- return;
|
||||
}
|
||||
|
||||
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
|
||||
@@ -3049,7 +3002,6 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
phy_interface_t interface;
|
||||
int speed;
|
||||
- int ret;
|
||||
|
||||
switch (port) {
|
||||
case 5:
|
||||
@@ -3074,9 +3026,8 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
else
|
||||
speed = SPEED_1000;
|
||||
|
||||
- ret = mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
|
||||
+
|
||||
mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
PMCR_CPU_PORT_SETTING(priv->id));
|
||||
mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -760,9 +760,9 @@ struct mt753x_info {
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
phy_interface_t interface,
|
||||
unsigned long *supported);
|
||||
- int (*mac_port_config)(struct dsa_switch *ds, int port,
|
||||
- unsigned int mode,
|
||||
- phy_interface_t interface);
|
||||
+ void (*mac_port_config)(struct dsa_switch *ds, int port,
|
||||
+ unsigned int mode,
|
||||
+ phy_interface_t interface);
|
||||
};
|
||||
|
||||
/* struct mt7530_priv - This is the main data structure for holding the state
|
@ -0,0 +1,305 @@
|
||||
From 859df5cf6ff07a9c930be4681284346aa73dd1fb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:01 +0200
|
||||
Subject: [PATCH 23/30] net: dsa: mt7530: get rid of
|
||||
priv->info->cpu_port_config()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
priv->info->cpu_port_config() is used for MT7531 and the switch on the
|
||||
MT7988 SoC. It sets up the ports described as a CPU port earlier than the
|
||||
phylink code path would do.
|
||||
|
||||
This function is useless as:
|
||||
- Configuring the MACs can be done from the phylink_mac_config code path
|
||||
instead.
|
||||
- All the link configuration it does on the CPU ports are later undone with
|
||||
the port_enable, phylink_mac_config, and then phylink_mac_link_up code
|
||||
path [1].
|
||||
|
||||
priv->p5_interface and priv->p6_interface were being used to prevent
|
||||
configuring the MACs from the phylink_mac_config code path. Remove them now
|
||||
that they hold no purpose.
|
||||
|
||||
Remove priv->info->cpu_port_config(). On mt753x_phylink_mac_config, switch
|
||||
to if statements to simplify the code.
|
||||
|
||||
Remove the overwriting of the speed and duplex interfaces for certain
|
||||
interface modes. Phylink already provides the speed and duplex variables
|
||||
with proper values. Phylink already sets the max speed of TRGMII to
|
||||
SPEED_1000. Add SPEED_2500 for PHY_INTERFACE_MODE_2500BASEX to where the
|
||||
speed and EEE bits are set instead.
|
||||
|
||||
On the switch on the MT7988 SoC, PHY_INTERFACE_MODE_INTERNAL is being used
|
||||
to describe the interface mode of the 10G MAC, which is of port 6. On
|
||||
mt7988_cpu_port_config() PMCR_FORCE_SPEED_1000 was set via the
|
||||
PMCR_CPU_PORT_SETTING() mask. Add SPEED_10000 case to where the speed bits
|
||||
are set to cover this. No need to add it to where the EEE bits are set as
|
||||
the "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
|
||||
v0.1" document shows that these bits don't exist on the MT7530_PMCR_P(6)
|
||||
register.
|
||||
|
||||
Remove the definition of PMCR_CPU_PORT_SETTING() now that it holds no
|
||||
purpose.
|
||||
|
||||
Change mt753x_cpu_port_enable() to void now that there're no error cases
|
||||
left.
|
||||
|
||||
Link: https://lore.kernel.org/netdev/ZHy2jQLesdYFMQtO@shell.armlinux.org.uk/ [1]
|
||||
Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 114 +++------------------------------------
|
||||
drivers/net/dsa/mt7530.h | 11 ----
|
||||
2 files changed, 7 insertions(+), 118 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1163,18 +1163,10 @@ mt753x_trap_frames(struct mt7530_priv *p
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
}
|
||||
|
||||
-static int
|
||||
+static void
|
||||
mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- int ret;
|
||||
-
|
||||
- /* Setup max capability of CPU port at first */
|
||||
- if (priv->info->cpu_port_config) {
|
||||
- ret = priv->info->cpu_port_config(ds, port);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
/* Enable Mediatek header mode on the cpu port */
|
||||
mt7530_write(priv, MT7530_PVC_P(port),
|
||||
@@ -1200,8 +1192,6 @@ mt753x_cpu_port_enable(struct dsa_switch
|
||||
/* Set to fallback mode for independent VLAN learning */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_FALLBACK_MODE);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2458,8 +2448,6 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
val |= MHWTRAP_MANUAL;
|
||||
mt7530_write(priv, MT7530_MHWTRAP, val);
|
||||
|
||||
- priv->p6_interface = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
|
||||
mt7530_pll_setup(priv);
|
||||
|
||||
@@ -2477,9 +2465,7 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
|
||||
if (dsa_is_cpu_port(ds, i)) {
|
||||
- ret = mt753x_cpu_port_enable(ds, i);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ mt753x_cpu_port_enable(ds, i);
|
||||
} else {
|
||||
mt7530_port_disable(ds, i);
|
||||
|
||||
@@ -2586,9 +2572,7 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
|
||||
|
||||
if (dsa_is_cpu_port(ds, i)) {
|
||||
- ret = mt753x_cpu_port_enable(ds, i);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ mt753x_cpu_port_enable(ds, i);
|
||||
} else {
|
||||
mt7530_port_disable(ds, i);
|
||||
|
||||
@@ -2680,10 +2664,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
|
||||
MT7531_GPIO0_INTERRUPT);
|
||||
|
||||
- /* Let phylink decide the interface later. */
|
||||
- priv->p5_interface = PHY_INTERFACE_MODE_NA;
|
||||
- priv->p6_interface = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
/* Enable Energy-Efficient Ethernet (EEE) and PHY core PLL, since
|
||||
* phy_device has not yet been created provided for
|
||||
* phy_[read,write]_mmd_indirect is called, we provide our own
|
||||
@@ -2902,26 +2882,9 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
- switch (port) {
|
||||
- case 5:
|
||||
- if (priv->p5_interface == state->interface)
|
||||
- break;
|
||||
-
|
||||
+ if (port == 5 || port == 6)
|
||||
mt753x_mac_config(ds, port, mode, state);
|
||||
|
||||
- if (priv->p5_intf_sel != P5_DISABLED)
|
||||
- priv->p5_interface = state->interface;
|
||||
- break;
|
||||
- case 6:
|
||||
- if (priv->p6_interface == state->interface)
|
||||
- break;
|
||||
-
|
||||
- mt753x_mac_config(ds, port, mode, state);
|
||||
-
|
||||
- priv->p6_interface = state->interface;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
|
||||
mcr_new = mcr_cur;
|
||||
mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
|
||||
@@ -2957,17 +2920,10 @@ static void mt753x_phylink_mac_link_up(s
|
||||
|
||||
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
|
||||
- /* MT753x MAC works in 1G full duplex mode for all up-clocked
|
||||
- * variants.
|
||||
- */
|
||||
- if (interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
- (phy_interface_mode_is_8023z(interface))) {
|
||||
- speed = SPEED_1000;
|
||||
- duplex = DUPLEX_FULL;
|
||||
- }
|
||||
-
|
||||
switch (speed) {
|
||||
case SPEED_1000:
|
||||
+ case SPEED_2500:
|
||||
+ case SPEED_10000:
|
||||
mcr |= PMCR_FORCE_SPEED_1000;
|
||||
break;
|
||||
case SPEED_100:
|
||||
@@ -2985,6 +2941,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
|
||||
switch (speed) {
|
||||
case SPEED_1000:
|
||||
+ case SPEED_2500:
|
||||
mcr |= PMCR_FORCE_EEE1G;
|
||||
break;
|
||||
case SPEED_100:
|
||||
@@ -2996,61 +2953,6 @@ static void mt753x_phylink_mac_link_up(s
|
||||
mt7530_set(priv, MT7530_PMCR_P(port), mcr);
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7531_cpu_port_config(struct dsa_switch *ds, int port)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
- phy_interface_t interface;
|
||||
- int speed;
|
||||
-
|
||||
- switch (port) {
|
||||
- case 5:
|
||||
- if (!priv->p5_sgmii)
|
||||
- interface = PHY_INTERFACE_MODE_RGMII;
|
||||
- else
|
||||
- interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
-
|
||||
- priv->p5_interface = interface;
|
||||
- break;
|
||||
- case 6:
|
||||
- interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
-
|
||||
- priv->p6_interface = interface;
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- speed = SPEED_2500;
|
||||
- else
|
||||
- speed = SPEED_1000;
|
||||
-
|
||||
- mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
|
||||
-
|
||||
- mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
- PMCR_CPU_PORT_SETTING(priv->id));
|
||||
- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
|
||||
- speed, DUPLEX_FULL, true, true);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-mt7988_cpu_port_config(struct dsa_switch *ds, int port)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
- PMCR_CPU_PORT_SETTING(priv->id));
|
||||
-
|
||||
- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
|
||||
- PHY_INTERFACE_MODE_INTERNAL, NULL,
|
||||
- SPEED_10000, DUPLEX_FULL, true, true);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
@@ -3309,7 +3211,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7531_ind_c22_phy_write,
|
||||
.phy_read_c45 = mt7531_ind_c45_phy_read,
|
||||
.phy_write_c45 = mt7531_ind_c45_phy_write,
|
||||
- .cpu_port_config = mt7531_cpu_port_config,
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
},
|
||||
@@ -3321,7 +3222,6 @@ const struct mt753x_info mt753x_table[]
|
||||
.phy_write_c22 = mt7531_ind_c22_phy_write,
|
||||
.phy_read_c45 = mt7531_ind_c45_phy_read,
|
||||
.phy_write_c45 = mt7531_ind_c45_phy_write,
|
||||
- .cpu_port_config = mt7988_cpu_port_config,
|
||||
.mac_port_get_caps = mt7988_mac_port_get_caps,
|
||||
},
|
||||
};
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -340,13 +340,6 @@ enum mt7530_vlan_port_acc_frm {
|
||||
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
||||
PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
|
||||
PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
|
||||
-#define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \
|
||||
- PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
|
||||
- PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
|
||||
- PMCR_TX_EN | PMCR_RX_EN | \
|
||||
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
||||
- PMCR_FORCE_SPEED_1000 | \
|
||||
- PMCR_FORCE_FDX | PMCR_FORCE_LNK)
|
||||
|
||||
#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
|
||||
#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
|
||||
@@ -754,7 +747,6 @@ struct mt753x_info {
|
||||
int regnum);
|
||||
int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum, u16 val);
|
||||
- int (*cpu_port_config)(struct dsa_switch *ds, int port);
|
||||
void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
@@ -780,7 +772,6 @@ struct mt753x_info {
|
||||
* @ports: Holding the state among ports
|
||||
* @reg_mutex: The lock for protecting among process accessing
|
||||
* registers
|
||||
- * @p6_interface Holding the current port 6 interface
|
||||
* @p5_intf_sel: Holding the current port 5 interface select
|
||||
* @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
|
||||
* has got SGMII
|
||||
@@ -802,8 +793,6 @@ struct mt7530_priv {
|
||||
const struct mt753x_info *info;
|
||||
unsigned int id;
|
||||
bool mcm;
|
||||
- phy_interface_t p6_interface;
|
||||
- phy_interface_t p5_interface;
|
||||
enum p5_interface_select p5_intf_sel;
|
||||
bool p5_sgmii;
|
||||
u8 mirror_rx;
|
@ -0,0 +1,48 @@
|
||||
From c74a98baa8d098157975b3f94e496dd3a73e0864 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:02 +0200
|
||||
Subject: [PATCH 24/30] net: dsa: mt7530: get rid of mt753x_mac_config()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There is no need for a separate function to call
|
||||
priv->info->mac_port_config(). Call it from mt753x_phylink_mac_config()
|
||||
instead and remove mt753x_mac_config().
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 14 ++------------
|
||||
1 file changed, 2 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2847,16 +2847,6 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
}
|
||||
}
|
||||
|
||||
-static void
|
||||
-mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
- const struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- if (priv->info->mac_port_config)
|
||||
- priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
-}
|
||||
-
|
||||
static struct phylink_pcs *
|
||||
mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
|
||||
phy_interface_t interface)
|
||||
@@ -2882,8 +2872,8 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
- if (port == 5 || port == 6)
|
||||
- mt753x_mac_config(ds, port, mode, state);
|
||||
+ if ((port == 5 || port == 6) && priv->info->mac_port_config)
|
||||
+ priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
|
||||
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
|
||||
mcr_new = mcr_cur;
|
@ -0,0 +1,57 @@
|
||||
From ab1ddb241bc1cb3d80aa51207810edd5cb0bbdc5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:03 +0200
|
||||
Subject: [PATCH 25/30] net: dsa: mt7530: put initialising PCS devices code
|
||||
back to original order
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The commit fae463084032 ("net: dsa: mt753x: fix pcs conversion regression")
|
||||
fixes regression caused by cpu_port_config manually calling phylink
|
||||
operations. cpu_port_config was deemed useless and was removed. Therefore,
|
||||
put initialising PCS devices code back to its original order.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3025,17 +3025,9 @@ static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- int i, ret;
|
||||
+ int ret = priv->info->sw_setup(ds);
|
||||
+ int i;
|
||||
|
||||
- /* Initialise the PCS devices */
|
||||
- for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
- priv->pcs[i].pcs.neg_mode = true;
|
||||
- priv->pcs[i].priv = priv;
|
||||
- priv->pcs[i].port = i;
|
||||
- }
|
||||
-
|
||||
- ret = priv->info->sw_setup(ds);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -3047,6 +3039,14 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
+ /* Initialise the PCS devices */
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
+ priv->pcs[i].pcs.neg_mode = true;
|
||||
+ priv->pcs[i].priv = priv;
|
||||
+ priv->pcs[i].port = i;
|
||||
+ }
|
||||
+
|
||||
if (priv->create_sgmii) {
|
||||
ret = priv->create_sgmii(priv);
|
||||
if (ret && priv->irq)
|
@ -0,0 +1,68 @@
|
||||
From aa474698f75f4790a4de2052dd487736d2361b2e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:04 +0200
|
||||
Subject: [PATCH 26/30] net: dsa: mt7530: sort link settings ops and force link
|
||||
down on all ports
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
port_enable and port_disable clears the link settings. Move that to
|
||||
mt7530_setup() and mt7531_setup_common() which set up the switches. This
|
||||
way, the link settings are cleared on all ports at setup, and then only
|
||||
once with phylink_mac_link_down() when a link goes down.
|
||||
|
||||
Enable force mode at setup to apply the force part of the link settings.
|
||||
This ensures that disabled ports will have their link down.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1215,7 +1215,6 @@ mt7530_port_enable(struct dsa_switch *ds
|
||||
priv->ports[port].enable = true;
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
|
||||
priv->ports[port].pm);
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
|
||||
@@ -1235,7 +1234,6 @@ mt7530_port_disable(struct dsa_switch *d
|
||||
priv->ports[port].enable = false;
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
|
||||
PCR_MATRIX_CLR);
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
@@ -2457,6 +2455,12 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
mt7530_mib_reset(ds);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ /* Clear link settings and enable force mode to force link down
|
||||
+ * on all ports until they're enabled later.
|
||||
+ */
|
||||
+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
+ PMCR_FORCE_MODE, PMCR_FORCE_MODE);
|
||||
+
|
||||
/* Disable forwarding by default on all ports */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
PCR_MATRIX_CLR);
|
||||
@@ -2562,6 +2566,12 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
UNU_FFP_MASK);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ /* Clear link settings and enable force mode to force link down
|
||||
+ * on all ports until they're enabled later.
|
||||
+ */
|
||||
+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
+ MT7531_FORCE_MODE, MT7531_FORCE_MODE);
|
||||
+
|
||||
/* Disable forwarding by default on all ports */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
PCR_MATRIX_CLR);
|
@ -0,0 +1,83 @@
|
||||
From 1ca89c2e349d7c5e045911d741dacf4c83d029e7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Fri, 1 Mar 2024 12:43:05 +0200
|
||||
Subject: [PATCH 27/30] net: dsa: mt7530: simplify link operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
|
||||
for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
|
||||
Platform: Datasheet (Open Version) v0.1" documents show that these bits are
|
||||
enabled at reset:
|
||||
|
||||
PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
|
||||
PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
|
||||
PMCR_TX_EN
|
||||
PMCR_RX_EN
|
||||
PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
|
||||
PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
|
||||
PMCR_TX_FC_EN
|
||||
PMCR_RX_FC_EN
|
||||
|
||||
These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
|
||||
on the MT7988 SoC:
|
||||
|
||||
PMCR_IFG_XMIT()
|
||||
PMCR_MAC_MODE
|
||||
PMCR_BACKOFF_EN
|
||||
PMCR_BACKPR_EN
|
||||
|
||||
Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
|
||||
phylink_mac_config as they're already set.
|
||||
|
||||
The bit for setting the port on force mode is already done on
|
||||
mt7530_setup() and mt7531_setup_common(). So get rid of
|
||||
PMCR_FORCE_MODE_ID() which helped determine which bit to use for the switch
|
||||
model.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 12 +-----------
|
||||
drivers/net/dsa/mt7530.h | 2 --
|
||||
2 files changed, 1 insertion(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2880,23 +2880,13 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- u32 mcr_cur, mcr_new;
|
||||
|
||||
if ((port == 5 || port == 6) && priv->info->mac_port_config)
|
||||
priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
|
||||
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
|
||||
- mcr_new = mcr_cur;
|
||||
- mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
|
||||
- mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
|
||||
- PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
|
||||
-
|
||||
/* Are we connected to external phy */
|
||||
if (port == 5 && dsa_is_user_port(ds, 5))
|
||||
- mcr_new |= PMCR_EXT_PHY;
|
||||
-
|
||||
- if (mcr_new != mcr_cur)
|
||||
- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
|
||||
+ mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -333,8 +333,6 @@ enum mt7530_vlan_port_acc_frm {
|
||||
MT7531_FORCE_DPX | \
|
||||
MT7531_FORCE_RX_FC | \
|
||||
MT7531_FORCE_TX_FC)
|
||||
-#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
- MT7531_FORCE_MODE : PMCR_FORCE_MODE)
|
||||
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
|
||||
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
|
||||
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
@ -0,0 +1,94 @@
|
||||
From de16cf680331cd0bd7db97c3f8d376f5eac39cae Mon Sep 17 00:00:00 2001
|
||||
From: Justin Swartz <justin.swartz@risingedge.co.za>
|
||||
Date: Tue, 5 Mar 2024 06:39:51 +0200
|
||||
Subject: [PATCH 28/30] net: dsa: mt7530: disable LEDs before reset
|
||||
|
||||
Disable LEDs just before resetting the MT7530 to avoid
|
||||
situations where the ESW_P4_LED_0 and ESW_P3_LED_0 pin
|
||||
states may cause an unintended external crystal frequency
|
||||
to be selected.
|
||||
|
||||
The HT_XTAL_FSEL (External Crystal Frequency Selection)
|
||||
field of HWTRAP (the Hardware Trap register) stores a
|
||||
2-bit value that represents the state of the ESW_P4_LED_0
|
||||
and ESW_P4_LED_0 pins (seemingly) sampled just after the
|
||||
MT7530 has been reset, as:
|
||||
|
||||
ESW_P4_LED_0 ESW_P3_LED_0 Frequency
|
||||
-----------------------------------------
|
||||
0 1 20MHz
|
||||
1 0 40MHz
|
||||
1 1 25MHz
|
||||
|
||||
The value of HT_XTAL_FSEL is bootstrapped by pulling
|
||||
ESW_P4_LED_0 and ESW_P3_LED_0 up or down accordingly,
|
||||
but:
|
||||
|
||||
if a 40MHz crystal has been selected and
|
||||
the ESW_P3_LED_0 pin is high during reset,
|
||||
|
||||
or a 20MHz crystal has been selected and
|
||||
the ESW_P4_LED_0 pin is high during reset,
|
||||
|
||||
then the value of HT_XTAL_FSEL will indicate
|
||||
that a 25MHz crystal is present.
|
||||
|
||||
By default, the state of the LED pins is PHY controlled
|
||||
to reflect the link state.
|
||||
|
||||
To illustrate, if a board has:
|
||||
|
||||
5 ports with active low LED control,
|
||||
and HT_XTAL_FSEL bootstrapped for 40MHz.
|
||||
|
||||
When the MT7530 is powered up without any external
|
||||
connection, only the LED associated with Port 3 is
|
||||
illuminated as ESW_P3_LED_0 is low.
|
||||
|
||||
In this state, directly after mt7530_setup()'s reset
|
||||
is performed, the HWTRAP register (0x7800) reflects
|
||||
the intended HT_XTAL_FSEL (HWTRAP bits 10:9) of 40MHz:
|
||||
|
||||
mt7530-mdio mdio-bus:1f: mt7530_read: 00007800 == 00007dcf
|
||||
|
||||
>>> bin(0x7dcf >> 9 & 0b11)
|
||||
'0b10'
|
||||
|
||||
But if a cable is connected to Port 3 and the link
|
||||
is active before mt7530_setup()'s reset takes place,
|
||||
then HT_XTAL_FSEL seems to be set for 25MHz:
|
||||
|
||||
mt7530-mdio mdio-bus:1f: mt7530_read: 00007800 == 00007fcf
|
||||
|
||||
>>> bin(0x7fcf >> 9 & 0b11)
|
||||
'0b11'
|
||||
|
||||
Once HT_XTAL_FSEL reflects 25MHz, none of the ports
|
||||
are functional until the MT7621 (or MT7530 itself)
|
||||
is reset.
|
||||
|
||||
By disabling the LED pins just before reset, the chance
|
||||
of an unintended HT_XTAL_FSEL value is reduced.
|
||||
|
||||
Signed-off-by: Justin Swartz <justin.swartz@risingedge.co.za>
|
||||
Link: https://lore.kernel.org/r/20240305043952.21590-1-justin.swartz@risingedge.co.za
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2391,6 +2391,12 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Disable LEDs before reset to prevent the MT7530 sampling a
|
||||
+ * potentially incorrect HT_XTAL_FSEL value.
|
||||
+ */
|
||||
+ mt7530_write(priv, MT7530_LED_EN, 0);
|
||||
+ usleep_range(1000, 1100);
|
||||
+
|
||||
/* Reset whole chip through gpio pin or memory-mapped registers for
|
||||
* different type of hardware
|
||||
*/
|
@ -0,0 +1,154 @@
|
||||
From b9547109205c5e0a27e5bed568b0fc183fff906b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 14 Mar 2024 12:28:35 +0300
|
||||
Subject: [PATCH 30/30] net: dsa: mt7530: prevent possible incorrect XTAL
|
||||
frequency selection
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On MT7530, the HT_XTAL_FSEL field of the HWTRAP register stores a 2-bit
|
||||
value that represents the frequency of the crystal oscillator connected to
|
||||
the switch IC. The field is populated by the state of the ESW_P4_LED_0 and
|
||||
ESW_P4_LED_0 pins, which is done right after reset is deasserted.
|
||||
|
||||
ESW_P4_LED_0 ESW_P3_LED_0 Frequency
|
||||
-----------------------------------------
|
||||
0 0 Reserved
|
||||
0 1 20MHz
|
||||
1 0 40MHz
|
||||
1 1 25MHz
|
||||
|
||||
On MT7531, the XTAL25 bit of the STRAP register stores this. The LAN0LED0
|
||||
pin is used to populate the bit. 25MHz when the pin is high, 40MHz when
|
||||
it's low.
|
||||
|
||||
These pins are also used with LEDs, therefore, their state can be set to
|
||||
something other than the bootstrapping configuration. For example, a link
|
||||
may be established on port 3 before the DSA subdriver takes control of the
|
||||
switch which would set ESW_P3_LED_0 to high.
|
||||
|
||||
Currently on mt7530_setup() and mt7531_setup(), 1000 - 1100 usec delay is
|
||||
described between reset assertion and deassertion. Some switch ICs in real
|
||||
life conditions cannot always have these pins set back to the bootstrapping
|
||||
configuration before reset deassertion in this amount of delay. This causes
|
||||
wrong crystal frequency to be selected which puts the switch in a
|
||||
nonfunctional state after reset deassertion.
|
||||
|
||||
The tests below are conducted on an MT7530 with a 40MHz crystal oscillator
|
||||
by Justin Swartz.
|
||||
|
||||
With a cable from an active peer connected to port 3 before reset, an
|
||||
incorrect crystal frequency (0b11 = 25MHz) is selected:
|
||||
|
||||
[1] [3] [5]
|
||||
: : :
|
||||
_____________________________ __________________
|
||||
ESW_P4_LED_0 |_______|
|
||||
_____________________________
|
||||
ESW_P3_LED_0 |__________________________
|
||||
|
||||
: : : :
|
||||
: : [4]...:
|
||||
: :
|
||||
[2]................:
|
||||
|
||||
[1] Reset is asserted.
|
||||
[2] Period of 1000 - 1100 usec.
|
||||
[3] Reset is deasserted.
|
||||
[4] Period of 315 usec. HWTRAP register is populated with incorrect
|
||||
XTAL frequency.
|
||||
[5] Signals reflect the bootstrapped configuration.
|
||||
|
||||
Increase the delay between reset_control_assert() and
|
||||
reset_control_deassert(), and gpiod_set_value_cansleep(priv->reset, 0) and
|
||||
gpiod_set_value_cansleep(priv->reset, 1) to 5000 - 5100 usec. This amount
|
||||
ensures a higher possibility that the switch IC will have these pins back
|
||||
to the bootstrapping configuration before reset deassertion.
|
||||
|
||||
With a cable from an active peer connected to port 3 before reset, the
|
||||
correct crystal frequency (0b10 = 40MHz) is selected:
|
||||
|
||||
[1] [2-1] [3] [5]
|
||||
: : : :
|
||||
_____________________________ __________________
|
||||
ESW_P4_LED_0 |_______|
|
||||
___________________ _______
|
||||
ESW_P3_LED_0 |_________| |__________________
|
||||
|
||||
: : : : :
|
||||
: [2-2]...: [4]...:
|
||||
[2]................:
|
||||
|
||||
[1] Reset is asserted.
|
||||
[2] Period of 5000 - 5100 usec.
|
||||
[2-1] ESW_P3_LED_0 goes low.
|
||||
[2-2] Remaining period of 5000 - 5100 usec.
|
||||
[3] Reset is deasserted.
|
||||
[4] Period of 310 usec. HWTRAP register is populated with bootstrapped
|
||||
XTAL frequency.
|
||||
[5] Signals reflect the bootstrapped configuration.
|
||||
|
||||
ESW_P3_LED_0 low period before reset deassertion:
|
||||
|
||||
5000 usec
|
||||
- 5100 usec
|
||||
TEST RESET HOLD
|
||||
# (usec)
|
||||
---------------------
|
||||
1 5410
|
||||
2 5440
|
||||
3 4375
|
||||
4 5490
|
||||
5 5475
|
||||
6 4335
|
||||
7 4370
|
||||
8 5435
|
||||
9 4205
|
||||
10 4335
|
||||
11 3750
|
||||
12 3170
|
||||
13 4395
|
||||
14 4375
|
||||
15 3515
|
||||
16 4335
|
||||
17 4220
|
||||
18 4175
|
||||
19 4175
|
||||
20 4350
|
||||
|
||||
Min 3170
|
||||
Max 5490
|
||||
|
||||
Median 4342.500
|
||||
Avg 4466.500
|
||||
|
||||
Revert commit 2920dd92b980 ("net: dsa: mt7530: disable LEDs before reset").
|
||||
Changing the state of pins via reset assertion is simpler and more
|
||||
efficient than doing so by setting the LED controller off.
|
||||
|
||||
Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
|
||||
Fixes: c288575f7810 ("net: dsa: mt7530: Add the support of MT7531 switch")
|
||||
Co-developed-by: Justin Swartz <justin.swartz@risingedge.co.za>
|
||||
Signed-off-by: Justin Swartz <justin.swartz@risingedge.co.za>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2391,12 +2391,6 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
}
|
||||
|
||||
- /* Disable LEDs before reset to prevent the MT7530 sampling a
|
||||
- * potentially incorrect HT_XTAL_FSEL value.
|
||||
- */
|
||||
- mt7530_write(priv, MT7530_LED_EN, 0);
|
||||
- usleep_range(1000, 1100);
|
||||
-
|
||||
/* Reset whole chip through gpio pin or memory-mapped registers for
|
||||
* different type of hardware
|
||||
*/
|
@ -0,0 +1,135 @@
|
||||
From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Fri, 12 Apr 2024 16:15:34 +0100
|
||||
Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Convert mt753x to provide its own phylink MAC operations, thus avoiding
|
||||
the shim layer in DSA's port.c
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
|
||||
1 file changed, 29 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2858,28 +2858,34 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
}
|
||||
|
||||
static struct phylink_pcs *
|
||||
-mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
|
||||
+mt753x_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
- return &priv->pcs[port].pcs;
|
||||
+ return &priv->pcs[dp->index].pcs;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- return priv->ports[port].sgmii_pcs;
|
||||
+ return priv->ports[dp->index].sgmii_pcs;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
-mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
+mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ int port = dp->index;
|
||||
+
|
||||
+ priv = ds->priv;
|
||||
|
||||
if ((port == 5 || port == 6) && priv->info->mac_port_config)
|
||||
priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
@@ -2889,23 +2895,25 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_down(struct phylink_config *config,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
+ mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_up(struct phylink_config *config,
|
||||
+ struct phy_device *phydev,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
- struct phy_device *phydev,
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
u32 mcr;
|
||||
|
||||
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
@@ -2940,7 +2948,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
}
|
||||
}
|
||||
|
||||
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
|
||||
+ mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
@@ -3160,16 +3168,19 @@ const struct dsa_switch_ops mt7530_switc
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
- .phylink_mac_config = mt753x_phylink_mac_config,
|
||||
- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
|
||||
- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
.master_state_change = mt753x_conduit_state_change,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
+static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
|
||||
+ .mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
+ .mac_config = mt753x_phylink_mac_config,
|
||||
+ .mac_link_down = mt753x_phylink_mac_link_down,
|
||||
+ .mac_link_up = mt753x_phylink_mac_link_up,
|
||||
+};
|
||||
+
|
||||
const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
@@ -3247,6 +3258,7 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
priv->dev = dev;
|
||||
priv->ds->priv = priv;
|
||||
priv->ds->ops = &mt7530_switch_ops;
|
||||
+ priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
|
||||
mutex_init(&priv->reg_mutex);
|
||||
dev_set_drvdata(dev, priv);
|
||||
|
@ -0,0 +1,238 @@
|
||||
From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:30 +0300
|
||||
Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
|
||||
device tree
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Read the PHY address the switch listens on from the reg property of the
|
||||
switch node on the device tree. This change brings support for MT7530
|
||||
switches on boards with such bootstrapping configuration where the switch
|
||||
listens on a different PHY address than the hardcoded PHY address on the
|
||||
driver, 31.
|
||||
|
||||
As described on the "MT7621 Programming Guide v0.4" document, the MT7530
|
||||
switch and its PHYs can be configured to listen on the range of 7-12,
|
||||
15-20, 23-28, and 31 and 0-4 PHY addresses.
|
||||
|
||||
There are operations where the switch PHY registers are used. For the PHY
|
||||
address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
|
||||
into a macro and use it. The PHY address for the control PHY is 0 when the
|
||||
switch listens on 31. In any other case, it is one greater than the PHY
|
||||
address the switch listens on.
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
|
||||
drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++------------
|
||||
drivers/net/dsa/mt7530.h | 4 +++-
|
||||
3 files changed, 41 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -18,7 +18,8 @@
|
||||
static int
|
||||
mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
|
||||
lo = val & 0xffff;
|
||||
hi = val >> 16;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, r, lo);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, r, lo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
page = (reg >> 6) & 0x3ff;
|
||||
r = (reg >> 2) & 0xf;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
+ lo = bus->read(bus, priv->mdiodev->addr, r);
|
||||
+ hi = bus->read(bus, priv->mdiodev->addr, 0x10);
|
||||
|
||||
*val = (hi << 16) | (lo & 0xffff);
|
||||
|
||||
@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
- regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7530_regmap_bus, priv->bus,
|
||||
+ regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
mt7531_pcs_config[i]);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
|
||||
priv->bus = mdiodev->bus;
|
||||
priv->dev = &mdiodev->dev;
|
||||
+ priv->mdiodev = mdiodev;
|
||||
|
||||
ret = mt7530_probe_common(priv);
|
||||
if (ret)
|
||||
@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
regmap_config->reg_stride = 4;
|
||||
regmap_config->max_register = MT7530_CREV;
|
||||
regmap_config->disable_locking = true;
|
||||
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
- priv->bus, regmap_config);
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
+ regmap_config);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
|
||||
int value, ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, 0, MII_MMD_DATA);
|
||||
+ value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
|
||||
return value;
|
||||
err:
|
||||
@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
|
||||
int ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the data into MMD's selected register */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, data);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, data);
|
||||
err:
|
||||
if (ret < 0)
|
||||
dev_err(&bus->dev,
|
||||
@@ -2679,16 +2687,19 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
* phy_[read,write]_mmd_indirect is called, we provide our own
|
||||
* mt7531_ind_mmd_phy_[read,write] to complete this function.
|
||||
*/
|
||||
- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
|
||||
+ val = mt7531_ind_c45_phy_read(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4);
|
||||
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
|
||||
val &= ~MT7531_PHY_PLL_OFF;
|
||||
- mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
|
||||
- CORE_PLL_GROUP4, val);
|
||||
+ mt7531_ind_c45_phy_write(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
|
||||
|
||||
/* Disable EEE advertisement on the switch PHYs. */
|
||||
- for (i = MT753X_CTRL_PHY_ADDR;
|
||||
- i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
|
||||
+ for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
|
||||
+ i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
|
||||
+ i++) {
|
||||
mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
|
||||
0);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
|
||||
#define MT7531_PHY_PLL_OFF BIT(5)
|
||||
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
|
||||
|
||||
-#define MT753X_CTRL_PHY_ADDR 0
|
||||
+#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
|
||||
|
||||
#define CORE_PLL_GROUP5 0x404
|
||||
#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
|
||||
@@ -778,6 +778,7 @@ struct mt753x_info {
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
* @active_cpu_ports: Holding the active CPU ports
|
||||
+ * @mdiodev: The pointer to the MDIO device structure
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -804,6 +805,7 @@ struct mt7530_priv {
|
||||
u32 irq_enable;
|
||||
int (*create_sgmii)(struct mt7530_priv *priv);
|
||||
u8 active_cpu_ports;
|
||||
+ struct mdio_device *mdiodev;
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
@ -0,0 +1,186 @@
|
||||
From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:31 +0300
|
||||
Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The core_rmw() function calls core_read_mmd_indirect() to read the
|
||||
requested register, and then calls core_write_mmd_indirect() to write the
|
||||
requested value to the register. Because Clause 22 is used to access Clause
|
||||
45 registers, some operations on core_write_mmd_indirect() are
|
||||
unnecessarily run. Get rid of core_read_mmd_indirect() and
|
||||
core_write_mmd_indirect(), and run only the necessary operations on
|
||||
core_write() and core_rmw().
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
|
||||
1 file changed, 43 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
|
||||
MIB_DESC(1, 0xb8, "RxArlDrop"),
|
||||
};
|
||||
|
||||
-/* Since phy_device has not yet been created and
|
||||
- * phy_{read,write}_mmd_indirect is not available, we provide our own
|
||||
- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
|
||||
- * to complete this function.
|
||||
- */
|
||||
-static int
|
||||
-core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
|
||||
+static void
|
||||
+mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
- int value, ret;
|
||||
+ int ret;
|
||||
+
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
- /* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA);
|
||||
-
|
||||
- return value;
|
||||
+ /* Write the data into MMD's selected register */
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
- dev_err(&bus->dev, "failed to read mmd register\n");
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
- return ret;
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
-static int
|
||||
-core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
|
||||
- int devad, u32 data)
|
||||
+static void
|
||||
+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
+ u32 val;
|
||||
int ret;
|
||||
|
||||
+ mt7530_mutex_lock(priv);
|
||||
+
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
+ /* Read the content of the MMD's selected register */
|
||||
+ val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
/* Write the data into MMD's selected register */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, data);
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
if (ret < 0)
|
||||
- dev_err(&bus->dev,
|
||||
- "failed to write mmd register\n");
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
-{
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
-
|
||||
- mt7530_mutex_unlock(priv);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
mt7530_mutex_unlock(priv);
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
From 856e8954a0a88d1a4d2b43e9002b9249131a156f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:08 +0300
|
||||
Subject: [PATCH 01/15] net: dsa: mt7530: disable EEE abilities on failure on
|
||||
MT7531 and MT7988
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 bits let the
|
||||
PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits determine the 1G/100 EEE
|
||||
abilities of the MAC. If MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 are
|
||||
unset, the abilities are left to be determined by PHY auto polling.
|
||||
|
||||
The commit 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features")
|
||||
made it so that the PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits are set on
|
||||
mt753x_phylink_mac_link_up(). But it did not set the MT7531_FORCE_EEE1G and
|
||||
MT7531_FORCE_EEE100 bits. Because of this, the EEE abilities will be
|
||||
determined by PHY auto polling, regardless of the result of phy_init_eee().
|
||||
|
||||
Define these bits and add them to the MT7531_FORCE_MODE mask which is set
|
||||
in mt7531_setup_common(). With this, there won't be any EEE abilities set
|
||||
when phy_init_eee() returns a negative value.
|
||||
|
||||
Thanks to Russell for explaining when phy_init_eee() could return a
|
||||
negative value below.
|
||||
|
||||
Looking at phy_init_eee(), it could return a negative value when:
|
||||
|
||||
1. phydev->drv is NULL
|
||||
2. if genphy_c45_eee_is_active() returns negative
|
||||
3. if genphy_c45_eee_is_active() returns zero, it returns -EPROTONOSUPPORT
|
||||
4. if phy_set_bits_mmd() fails (e.g. communication error with the PHY)
|
||||
|
||||
If we then look at genphy_c45_eee_is_active(), then:
|
||||
|
||||
genphy_c45_read_eee_adv() and genphy_c45_read_eee_lpa() propagate their
|
||||
non-zero return values, otherwise this function returns zero or positive
|
||||
integer.
|
||||
|
||||
If we then look at genphy_c45_read_eee_adv(), then a failure of
|
||||
phy_read_mmd() would cause a negative value to be returned.
|
||||
|
||||
Looking at genphy_c45_read_eee_lpa(), the same is true.
|
||||
|
||||
So, it can be summarised as:
|
||||
|
||||
- phydev->drv is NULL
|
||||
- there is a communication error accessing the PHY
|
||||
- EEE is not active
|
||||
|
||||
otherwise, it returns zero on success.
|
||||
|
||||
If one wishes to determine whether an error occurred vs EEE not being
|
||||
supported through negotiation for the negotiated speed, if it returns
|
||||
-EPROTONOSUPPORT in the latter case. Other error codes mean either the
|
||||
driver has been unloaded or communication error.
|
||||
|
||||
In conclusion, determining the EEE abilities by PHY auto polling shouldn't
|
||||
result in having any EEE abilities enabled, when one of the last two
|
||||
situations in the summary happens. And it seems that if phydev->drv is
|
||||
NULL, there would be bigger problems with the device than a broken link. So
|
||||
this is not a bugfix.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.h | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -328,11 +328,15 @@ enum mt7530_vlan_port_acc_frm {
|
||||
#define MT7531_FORCE_DPX BIT(29)
|
||||
#define MT7531_FORCE_RX_FC BIT(28)
|
||||
#define MT7531_FORCE_TX_FC BIT(27)
|
||||
+#define MT7531_FORCE_EEE100 BIT(26)
|
||||
+#define MT7531_FORCE_EEE1G BIT(25)
|
||||
#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \
|
||||
MT7531_FORCE_SPD | \
|
||||
MT7531_FORCE_DPX | \
|
||||
MT7531_FORCE_RX_FC | \
|
||||
- MT7531_FORCE_TX_FC)
|
||||
+ MT7531_FORCE_TX_FC | \
|
||||
+ MT7531_FORCE_EEE100 | \
|
||||
+ MT7531_FORCE_EEE1G)
|
||||
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
|
||||
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
|
||||
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
@ -0,0 +1,200 @@
|
||||
From 712ad00d2f43814c81a7abfcbc339690a05fb6a0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:09 +0300
|
||||
Subject: [PATCH 02/15] net: dsa: mt7530: refactor MT7530_PMCR_P()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT7530_PMCR_P() registers are on MT7530, MT7531, and the switch on the
|
||||
MT7988 SoC. Rename the definition for them to MT753X_PMCR_P(). Bit 15 is
|
||||
for MT7530 only. Add MT7530 prefix to the definition for bit 15.
|
||||
|
||||
Use GENMASK and FIELD_PREP for PMCR_IFG_XMIT().
|
||||
|
||||
Rename PMCR_TX_EN and PMCR_RX_EN to PMCR_MAC_TX_EN and PMCR_MAC_TX_EN to
|
||||
follow the naming on the "MT7621 Giga Switch Programming Guide v0.3",
|
||||
"MT7531 Reference Manual for Development Board v1.0", and "MT7988A Wi-Fi 7
|
||||
Generation Router Platform: Datasheet (Open Version) v0.1" documents.
|
||||
|
||||
These documents show that PMCR_RX_FC_EN is at bit 5. Correct this along
|
||||
with renaming it to PMCR_FORCE_RX_FC_EN, and the same for PMCR_TX_FC_EN.
|
||||
|
||||
Remove PMCR_SPEED_MASK which doesn't have a use.
|
||||
|
||||
Rename the force mode definitions for MT7531 to FORCE_MODE. Add MASK at the
|
||||
end for the mask that includes all force mode definitions.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 24 ++++++++---------
|
||||
drivers/net/dsa/mt7530.h | 58 +++++++++++++++++++++-------------------
|
||||
2 files changed, 42 insertions(+), 40 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -896,7 +896,7 @@ static void mt7530_setup_port5(struct ds
|
||||
val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
|
||||
|
||||
/* Setup the MAC by default for the cpu port */
|
||||
- mt7530_write(priv, MT7530_PMCR_P(5), 0x56300);
|
||||
+ mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
|
||||
break;
|
||||
case P5_INTF_SEL_GMAC5:
|
||||
/* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
|
||||
@@ -2444,8 +2444,8 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
/* Clear link settings and enable force mode to force link down
|
||||
* on all ports until they're enabled later.
|
||||
*/
|
||||
- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
- PMCR_FORCE_MODE, PMCR_FORCE_MODE);
|
||||
+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
+ MT7530_FORCE_MODE, MT7530_FORCE_MODE);
|
||||
|
||||
/* Disable forwarding by default on all ports */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
@@ -2555,8 +2555,8 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
/* Clear link settings and enable force mode to force link down
|
||||
* on all ports until they're enabled later.
|
||||
*/
|
||||
- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
- MT7531_FORCE_MODE, MT7531_FORCE_MODE);
|
||||
+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
|
||||
+ MT7531_FORCE_MODE_MASK, MT7531_FORCE_MODE_MASK);
|
||||
|
||||
/* Disable forwarding by default on all ports */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
@@ -2639,7 +2639,7 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
|
||||
/* Force link down on all ports before internal reset */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
|
||||
+ mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK);
|
||||
|
||||
/* Reset the switch through internal reset */
|
||||
mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
|
||||
@@ -2881,7 +2881,7 @@ mt753x_phylink_mac_config(struct phylink
|
||||
|
||||
/* Are we connected to external phy */
|
||||
if (port == 5 && dsa_is_user_port(ds, 5))
|
||||
- mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
|
||||
+ mt7530_set(priv, MT753X_PMCR_P(port), PMCR_EXT_PHY);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_mac_link_down(struct phylink_config *config,
|
||||
@@ -2891,7 +2891,7 @@ static void mt753x_phylink_mac_link_down
|
||||
struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
|
||||
+ mt7530_clear(priv, MT753X_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_mac_link_up(struct phylink_config *config,
|
||||
@@ -2905,7 +2905,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
struct mt7530_priv *priv = dp->ds->priv;
|
||||
u32 mcr;
|
||||
|
||||
- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
+ mcr = PMCR_MAC_RX_EN | PMCR_MAC_TX_EN | PMCR_FORCE_LNK;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_1000:
|
||||
@@ -2920,9 +2920,9 @@ static void mt753x_phylink_mac_link_up(s
|
||||
if (duplex == DUPLEX_FULL) {
|
||||
mcr |= PMCR_FORCE_FDX;
|
||||
if (tx_pause)
|
||||
- mcr |= PMCR_TX_FC_EN;
|
||||
+ mcr |= PMCR_FORCE_TX_FC_EN;
|
||||
if (rx_pause)
|
||||
- mcr |= PMCR_RX_FC_EN;
|
||||
+ mcr |= PMCR_FORCE_RX_FC_EN;
|
||||
}
|
||||
|
||||
if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
|
||||
@@ -2937,7 +2937,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
}
|
||||
}
|
||||
|
||||
- mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
|
||||
+ mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -304,44 +304,46 @@ enum mt7530_vlan_port_acc_frm {
|
||||
#define G0_PORT_VID_DEF G0_PORT_VID(0)
|
||||
|
||||
/* Register for port MAC control register */
|
||||
-#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))
|
||||
-#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18)
|
||||
+#define MT753X_PMCR_P(x) (0x3000 + ((x) * 0x100))
|
||||
+#define PMCR_IFG_XMIT_MASK GENMASK(19, 18)
|
||||
+#define PMCR_IFG_XMIT(x) FIELD_PREP(PMCR_IFG_XMIT_MASK, x)
|
||||
#define PMCR_EXT_PHY BIT(17)
|
||||
#define PMCR_MAC_MODE BIT(16)
|
||||
-#define PMCR_FORCE_MODE BIT(15)
|
||||
-#define PMCR_TX_EN BIT(14)
|
||||
-#define PMCR_RX_EN BIT(13)
|
||||
+#define MT7530_FORCE_MODE BIT(15)
|
||||
+#define PMCR_MAC_TX_EN BIT(14)
|
||||
+#define PMCR_MAC_RX_EN BIT(13)
|
||||
#define PMCR_BACKOFF_EN BIT(9)
|
||||
#define PMCR_BACKPR_EN BIT(8)
|
||||
#define PMCR_FORCE_EEE1G BIT(7)
|
||||
#define PMCR_FORCE_EEE100 BIT(6)
|
||||
-#define PMCR_TX_FC_EN BIT(5)
|
||||
-#define PMCR_RX_FC_EN BIT(4)
|
||||
+#define PMCR_FORCE_RX_FC_EN BIT(5)
|
||||
+#define PMCR_FORCE_TX_FC_EN BIT(4)
|
||||
#define PMCR_FORCE_SPEED_1000 BIT(3)
|
||||
#define PMCR_FORCE_SPEED_100 BIT(2)
|
||||
#define PMCR_FORCE_FDX BIT(1)
|
||||
#define PMCR_FORCE_LNK BIT(0)
|
||||
-#define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \
|
||||
- PMCR_FORCE_SPEED_1000)
|
||||
-#define MT7531_FORCE_LNK BIT(31)
|
||||
-#define MT7531_FORCE_SPD BIT(30)
|
||||
-#define MT7531_FORCE_DPX BIT(29)
|
||||
-#define MT7531_FORCE_RX_FC BIT(28)
|
||||
-#define MT7531_FORCE_TX_FC BIT(27)
|
||||
-#define MT7531_FORCE_EEE100 BIT(26)
|
||||
-#define MT7531_FORCE_EEE1G BIT(25)
|
||||
-#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \
|
||||
- MT7531_FORCE_SPD | \
|
||||
- MT7531_FORCE_DPX | \
|
||||
- MT7531_FORCE_RX_FC | \
|
||||
- MT7531_FORCE_TX_FC | \
|
||||
- MT7531_FORCE_EEE100 | \
|
||||
- MT7531_FORCE_EEE1G)
|
||||
-#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
|
||||
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
|
||||
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
||||
- PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
|
||||
- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
|
||||
+#define MT7531_FORCE_MODE_LNK BIT(31)
|
||||
+#define MT7531_FORCE_MODE_SPD BIT(30)
|
||||
+#define MT7531_FORCE_MODE_DPX BIT(29)
|
||||
+#define MT7531_FORCE_MODE_RX_FC BIT(28)
|
||||
+#define MT7531_FORCE_MODE_TX_FC BIT(27)
|
||||
+#define MT7531_FORCE_MODE_EEE100 BIT(26)
|
||||
+#define MT7531_FORCE_MODE_EEE1G BIT(25)
|
||||
+#define MT7531_FORCE_MODE_MASK (MT7531_FORCE_MODE_LNK | \
|
||||
+ MT7531_FORCE_MODE_SPD | \
|
||||
+ MT7531_FORCE_MODE_DPX | \
|
||||
+ MT7531_FORCE_MODE_RX_FC | \
|
||||
+ MT7531_FORCE_MODE_TX_FC | \
|
||||
+ MT7531_FORCE_MODE_EEE100 | \
|
||||
+ MT7531_FORCE_MODE_EEE1G)
|
||||
+#define PMCR_LINK_SETTINGS_MASK (PMCR_MAC_TX_EN | PMCR_MAC_RX_EN | \
|
||||
+ PMCR_FORCE_EEE1G | \
|
||||
+ PMCR_FORCE_EEE100 | \
|
||||
+ PMCR_FORCE_RX_FC_EN | \
|
||||
+ PMCR_FORCE_TX_FC_EN | \
|
||||
+ PMCR_FORCE_SPEED_1000 | \
|
||||
+ PMCR_FORCE_SPEED_100 | \
|
||||
+ PMCR_FORCE_FDX | PMCR_FORCE_LNK)
|
||||
|
||||
#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
|
||||
#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
|
@ -0,0 +1,185 @@
|
||||
From 875ec5b67ab88e969b171e6e9ea803e3ed759614 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:10 +0300
|
||||
Subject: [PATCH 03/15] net: dsa: mt7530: rename p5_intf_sel and use only for
|
||||
MT7530 switch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The p5_intf_sel pointer is used to store the information of whether PHY
|
||||
muxing is used or not. PHY muxing is a feature specific to port 5 of the
|
||||
MT7530 switch. Do not use it for other switch models.
|
||||
|
||||
Rename the pointer to p5_mode to store the mode the port is being used in.
|
||||
Rename the p5_interface_select enum to mt7530_p5_mode, the string
|
||||
representation to mt7530_p5_mode_str, and the enum elements.
|
||||
|
||||
If PHY muxing is not detected, the default mode, GMAC5, will be used.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 62 +++++++++++++++++-----------------------
|
||||
drivers/net/dsa/mt7530.h | 15 +++++-----
|
||||
2 files changed, 33 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -857,19 +857,15 @@ mt7530_set_ageing_time(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const char *p5_intf_modes(unsigned int p5_interface)
|
||||
+static const char *mt7530_p5_mode_str(unsigned int mode)
|
||||
{
|
||||
- switch (p5_interface) {
|
||||
- case P5_DISABLED:
|
||||
- return "DISABLED";
|
||||
- case P5_INTF_SEL_PHY_P0:
|
||||
- return "PHY P0";
|
||||
- case P5_INTF_SEL_PHY_P4:
|
||||
- return "PHY P4";
|
||||
- case P5_INTF_SEL_GMAC5:
|
||||
- return "GMAC5";
|
||||
+ switch (mode) {
|
||||
+ case MUX_PHY_P0:
|
||||
+ return "MUX PHY P0";
|
||||
+ case MUX_PHY_P4:
|
||||
+ return "MUX PHY P4";
|
||||
default:
|
||||
- return "unknown";
|
||||
+ return "GMAC5";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -886,23 +882,23 @@ static void mt7530_setup_port5(struct ds
|
||||
val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
|
||||
val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
|
||||
|
||||
- switch (priv->p5_intf_sel) {
|
||||
- case P5_INTF_SEL_PHY_P0:
|
||||
- /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */
|
||||
+ switch (priv->p5_mode) {
|
||||
+ /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
|
||||
+ case MUX_PHY_P0:
|
||||
val |= MHWTRAP_PHY0_SEL;
|
||||
fallthrough;
|
||||
- case P5_INTF_SEL_PHY_P4:
|
||||
- /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */
|
||||
+
|
||||
+ /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
|
||||
+ case MUX_PHY_P4:
|
||||
val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
|
||||
|
||||
/* Setup the MAC by default for the cpu port */
|
||||
mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
|
||||
break;
|
||||
- case P5_INTF_SEL_GMAC5:
|
||||
- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
|
||||
- val &= ~MHWTRAP_P5_DIS;
|
||||
- break;
|
||||
+
|
||||
+ /* GMAC5: P5 -> SoC MAC or external PHY */
|
||||
default:
|
||||
+ val &= ~MHWTRAP_P5_DIS;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -930,8 +926,8 @@ static void mt7530_setup_port5(struct ds
|
||||
|
||||
mt7530_write(priv, MT7530_MHWTRAP, val);
|
||||
|
||||
- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
|
||||
- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
|
||||
+ dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
|
||||
+ mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
@@ -2476,13 +2472,11 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Setup port 5 */
|
||||
- if (!dsa_is_unused_port(ds, 5)) {
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||||
- } else {
|
||||
+ /* Check for PHY muxing on port 5 */
|
||||
+ if (dsa_is_unused_port(ds, 5)) {
|
||||
/* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.
|
||||
- * Set priv->p5_intf_sel to the appropriate value if PHY muxing
|
||||
- * is detected.
|
||||
+ * Set priv->p5_mode to the appropriate value if PHY muxing is
|
||||
+ * detected.
|
||||
*/
|
||||
for_each_child_of_node(dn, mac_np) {
|
||||
if (!of_device_is_compatible(mac_np,
|
||||
@@ -2506,17 +2500,16 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
id = of_mdio_parse_addr(ds->dev, phy_node);
|
||||
if (id == 0)
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_PHY_P0;
|
||||
+ priv->p5_mode = MUX_PHY_P0;
|
||||
if (id == 4)
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_PHY_P4;
|
||||
+ priv->p5_mode = MUX_PHY_P4;
|
||||
}
|
||||
of_node_put(mac_np);
|
||||
of_node_put(phy_node);
|
||||
break;
|
||||
}
|
||||
|
||||
- if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 ||
|
||||
- priv->p5_intf_sel == P5_INTF_SEL_PHY_P4)
|
||||
+ if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4)
|
||||
mt7530_setup_port5(ds, interface);
|
||||
}
|
||||
|
||||
@@ -2654,9 +2647,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
MT7531_EXT_P_MDIO_12);
|
||||
}
|
||||
|
||||
- if (!dsa_is_unused_port(ds, 5))
|
||||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||||
-
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
|
||||
MT7531_GPIO0_INTERRUPT);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -708,12 +708,11 @@ struct mt7530_port {
|
||||
struct phylink_pcs *sgmii_pcs;
|
||||
};
|
||||
|
||||
-/* Port 5 interface select definitions */
|
||||
-enum p5_interface_select {
|
||||
- P5_DISABLED,
|
||||
- P5_INTF_SEL_PHY_P0,
|
||||
- P5_INTF_SEL_PHY_P4,
|
||||
- P5_INTF_SEL_GMAC5,
|
||||
+/* Port 5 mode definitions of the MT7530 switch */
|
||||
+enum mt7530_p5_mode {
|
||||
+ GMAC5,
|
||||
+ MUX_PHY_P0,
|
||||
+ MUX_PHY_P4,
|
||||
};
|
||||
|
||||
struct mt7530_priv;
|
||||
@@ -776,7 +775,7 @@ struct mt753x_info {
|
||||
* @ports: Holding the state among ports
|
||||
* @reg_mutex: The lock for protecting among process accessing
|
||||
* registers
|
||||
- * @p5_intf_sel: Holding the current port 5 interface select
|
||||
+ * @p5_mode: Holding the current mode of port 5 of the MT7530 switch
|
||||
* @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
|
||||
* has got SGMII
|
||||
* @irq: IRQ number of the switch
|
||||
@@ -798,7 +797,7 @@ struct mt7530_priv {
|
||||
const struct mt753x_info *info;
|
||||
unsigned int id;
|
||||
bool mcm;
|
||||
- enum p5_interface_select p5_intf_sel;
|
||||
+ enum mt7530_p5_mode p5_mode;
|
||||
bool p5_sgmii;
|
||||
u8 mirror_rx;
|
||||
u8 mirror_tx;
|
@ -0,0 +1,169 @@
|
||||
From 83fe3df057e641cd0e88425e579d7a5a370ca430 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:11 +0300
|
||||
Subject: [PATCH 04/15] net: dsa: mt7530: rename mt753x_bpdu_port_fw enum to
|
||||
mt753x_to_cpu_fw
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The mt753x_bpdu_port_fw enum is globally used for manipulating the process
|
||||
of deciding the forwardable ports, specifically concerning the CPU port(s).
|
||||
Therefore, rename it and the values in it to mt753x_to_cpu_fw.
|
||||
|
||||
Change FOLLOW_MFC to SYSTEM_DEFAULT to be on par with the switch documents.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 44 ++++++++++-------------
|
||||
drivers/net/dsa/mt7530.h | 76 ++++++++++++++++++++--------------------
|
||||
2 files changed, 56 insertions(+), 64 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1107,42 +1107,34 @@ mt753x_trap_frames(struct mt7530_priv *p
|
||||
* VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_BPC,
|
||||
- MT753X_PAE_BPDU_FR | MT753X_PAE_EG_TAG_MASK |
|
||||
- MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
|
||||
- MT753X_BPDU_PORT_FW_MASK,
|
||||
- MT753X_PAE_BPDU_FR |
|
||||
- MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
- MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_BPDU_CPU_ONLY);
|
||||
+ PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK |
|
||||
+ BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK,
|
||||
+ PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) |
|
||||
+ BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ TO_CPU_FW_CPU_ONLY);
|
||||
|
||||
/* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
|
||||
* them VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_RGAC1,
|
||||
- MT753X_R02_BPDU_FR | MT753X_R02_EG_TAG_MASK |
|
||||
- MT753X_R02_PORT_FW_MASK | MT753X_R01_BPDU_FR |
|
||||
- MT753X_R01_EG_TAG_MASK | MT753X_R01_PORT_FW_MASK,
|
||||
- MT753X_R02_BPDU_FR |
|
||||
- MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
- MT753X_R01_BPDU_FR |
|
||||
- MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_BPDU_CPU_ONLY);
|
||||
+ R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK |
|
||||
+ R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK,
|
||||
+ R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR |
|
||||
+ R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ TO_CPU_FW_CPU_ONLY);
|
||||
|
||||
/* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
|
||||
* them VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_RGAC2,
|
||||
- MT753X_R0E_BPDU_FR | MT753X_R0E_EG_TAG_MASK |
|
||||
- MT753X_R0E_PORT_FW_MASK | MT753X_R03_BPDU_FR |
|
||||
- MT753X_R03_EG_TAG_MASK | MT753X_R03_PORT_FW_MASK,
|
||||
- MT753X_R0E_BPDU_FR |
|
||||
- MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
- MT753X_R03_BPDU_FR |
|
||||
- MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
- MT753X_BPDU_CPU_ONLY);
|
||||
+ R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK |
|
||||
+ R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK,
|
||||
+ R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR |
|
||||
+ R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
+ TO_CPU_FW_CPU_ONLY);
|
||||
}
|
||||
|
||||
static void
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -67,47 +67,47 @@ enum mt753x_id {
|
||||
#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_MIRROR_MASK : MIRROR_MASK)
|
||||
|
||||
-/* Registers for BPDU and PAE frame control*/
|
||||
+/* Register for BPDU and PAE frame control */
|
||||
#define MT753X_BPC 0x24
|
||||
-#define MT753X_PAE_BPDU_FR BIT(25)
|
||||
-#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22)
|
||||
-#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
|
||||
-#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16)
|
||||
-#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
|
||||
-#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6)
|
||||
-#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
|
||||
-#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
|
||||
+#define PAE_BPDU_FR BIT(25)
|
||||
+#define PAE_EG_TAG_MASK GENMASK(24, 22)
|
||||
+#define PAE_EG_TAG(x) FIELD_PREP(PAE_EG_TAG_MASK, x)
|
||||
+#define PAE_PORT_FW_MASK GENMASK(18, 16)
|
||||
+#define PAE_PORT_FW(x) FIELD_PREP(PAE_PORT_FW_MASK, x)
|
||||
+#define BPDU_EG_TAG_MASK GENMASK(8, 6)
|
||||
+#define BPDU_EG_TAG(x) FIELD_PREP(BPDU_EG_TAG_MASK, x)
|
||||
+#define BPDU_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
-/* Register for :01 and :02 MAC DA frame control */
|
||||
+/* Register for 01-80-C2-00-00-[01,02] MAC DA frame control */
|
||||
#define MT753X_RGAC1 0x28
|
||||
-#define MT753X_R02_BPDU_FR BIT(25)
|
||||
-#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22)
|
||||
-#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
|
||||
-#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16)
|
||||
-#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
|
||||
-#define MT753X_R01_BPDU_FR BIT(9)
|
||||
-#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6)
|
||||
-#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
|
||||
-#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0)
|
||||
+#define R02_BPDU_FR BIT(25)
|
||||
+#define R02_EG_TAG_MASK GENMASK(24, 22)
|
||||
+#define R02_EG_TAG(x) FIELD_PREP(R02_EG_TAG_MASK, x)
|
||||
+#define R02_PORT_FW_MASK GENMASK(18, 16)
|
||||
+#define R02_PORT_FW(x) FIELD_PREP(R02_PORT_FW_MASK, x)
|
||||
+#define R01_BPDU_FR BIT(9)
|
||||
+#define R01_EG_TAG_MASK GENMASK(8, 6)
|
||||
+#define R01_EG_TAG(x) FIELD_PREP(R01_EG_TAG_MASK, x)
|
||||
+#define R01_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
-/* Register for :03 and :0E MAC DA frame control */
|
||||
+/* Register for 01-80-C2-00-00-[03,0E] MAC DA frame control */
|
||||
#define MT753X_RGAC2 0x2c
|
||||
-#define MT753X_R0E_BPDU_FR BIT(25)
|
||||
-#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22)
|
||||
-#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
|
||||
-#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16)
|
||||
-#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
|
||||
-#define MT753X_R03_BPDU_FR BIT(9)
|
||||
-#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6)
|
||||
-#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
|
||||
-#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0)
|
||||
+#define R0E_BPDU_FR BIT(25)
|
||||
+#define R0E_EG_TAG_MASK GENMASK(24, 22)
|
||||
+#define R0E_EG_TAG(x) FIELD_PREP(R0E_EG_TAG_MASK, x)
|
||||
+#define R0E_PORT_FW_MASK GENMASK(18, 16)
|
||||
+#define R0E_PORT_FW(x) FIELD_PREP(R0E_PORT_FW_MASK, x)
|
||||
+#define R03_BPDU_FR BIT(9)
|
||||
+#define R03_EG_TAG_MASK GENMASK(8, 6)
|
||||
+#define R03_EG_TAG(x) FIELD_PREP(R03_EG_TAG_MASK, x)
|
||||
+#define R03_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
-enum mt753x_bpdu_port_fw {
|
||||
- MT753X_BPDU_FOLLOW_MFC,
|
||||
- MT753X_BPDU_CPU_EXCLUDE = 4,
|
||||
- MT753X_BPDU_CPU_INCLUDE = 5,
|
||||
- MT753X_BPDU_CPU_ONLY = 6,
|
||||
- MT753X_BPDU_DROP = 7,
|
||||
+enum mt753x_to_cpu_fw {
|
||||
+ TO_CPU_FW_SYSTEM_DEFAULT,
|
||||
+ TO_CPU_FW_CPU_EXCLUDE = 4,
|
||||
+ TO_CPU_FW_CPU_INCLUDE = 5,
|
||||
+ TO_CPU_FW_CPU_ONLY = 6,
|
||||
+ TO_CPU_FW_DROP = 7,
|
||||
};
|
||||
|
||||
/* Registers for address table access */
|
@ -0,0 +1,201 @@
|
||||
From 1dbc1bdc2869e6d2929235c70d64e393aa5a5fa2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:12 +0300
|
||||
Subject: [PATCH 05/15] net: dsa: mt7530: refactor MT7530_MFC and MT7531_CFC,
|
||||
add MT7531_QRY_FFP
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT7530_MFC register is on MT7530, MT7531, and the switch on the MT7988
|
||||
SoC. Rename it to MT753X_MFC. Bit 7 to 0 differs between MT7530 and
|
||||
MT7531/MT7988. Add MT7530 prefix to these definitions, and define the
|
||||
IGMP/MLD Query Frame Flooding Ports mask for MT7531.
|
||||
|
||||
Rename the cases of MIRROR_MASK to MIRROR_PORT_MASK.
|
||||
|
||||
Move mt753x_mirror_port_get() and mt753x_port_mirror_set() to mt7530.h as
|
||||
macros.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 38 ++++++++--------------
|
||||
drivers/net/dsa/mt7530.h | 69 +++++++++++++++++++++++++---------------
|
||||
2 files changed, 57 insertions(+), 50 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1147,7 +1147,7 @@ mt753x_cpu_port_enable(struct dsa_switch
|
||||
PORT_SPEC_TAG);
|
||||
|
||||
/* Enable flooding on the CPU port */
|
||||
- mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
|
||||
+ mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
|
||||
UNU_FFP(BIT(port)));
|
||||
|
||||
/* Add the CPU port to the CPU port bitmap for MT7531 and the switch on
|
||||
@@ -1311,15 +1311,15 @@ mt7530_port_bridge_flags(struct dsa_swit
|
||||
flags.val & BR_LEARNING ? 0 : SA_DIS);
|
||||
|
||||
if (flags.mask & BR_FLOOD)
|
||||
- mt7530_rmw(priv, MT7530_MFC, UNU_FFP(BIT(port)),
|
||||
+ mt7530_rmw(priv, MT753X_MFC, UNU_FFP(BIT(port)),
|
||||
flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0);
|
||||
|
||||
if (flags.mask & BR_MCAST_FLOOD)
|
||||
- mt7530_rmw(priv, MT7530_MFC, UNM_FFP(BIT(port)),
|
||||
+ mt7530_rmw(priv, MT753X_MFC, UNM_FFP(BIT(port)),
|
||||
flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0);
|
||||
|
||||
if (flags.mask & BR_BCAST_FLOOD)
|
||||
- mt7530_rmw(priv, MT7530_MFC, BC_FFP(BIT(port)),
|
||||
+ mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)),
|
||||
flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
|
||||
|
||||
return 0;
|
||||
@@ -1855,20 +1855,6 @@ mt7530_port_vlan_del(struct dsa_switch *
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mt753x_mirror_port_get(unsigned int id, u32 val)
|
||||
-{
|
||||
- return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
- MT7531_MIRROR_PORT_GET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
-}
|
||||
-
|
||||
-static int mt753x_mirror_port_set(unsigned int id, u32 val)
|
||||
-{
|
||||
- return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
- MT7531_MIRROR_PORT_SET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
-}
|
||||
-
|
||||
static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
|
||||
struct dsa_mall_mirror_tc_entry *mirror,
|
||||
bool ingress, struct netlink_ext_ack *extack)
|
||||
@@ -1884,14 +1870,14 @@ static int mt753x_port_mirror_add(struct
|
||||
val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
|
||||
|
||||
/* MT7530 only supports one monitor port */
|
||||
- monitor_port = mt753x_mirror_port_get(priv->id, val);
|
||||
+ monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val);
|
||||
if (val & MT753X_MIRROR_EN(priv->id) &&
|
||||
monitor_port != mirror->to_local_port)
|
||||
return -EEXIST;
|
||||
|
||||
val |= MT753X_MIRROR_EN(priv->id);
|
||||
- val &= ~MT753X_MIRROR_MASK(priv->id);
|
||||
- val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port);
|
||||
+ val &= ~MT753X_MIRROR_PORT_MASK(priv->id);
|
||||
+ val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port);
|
||||
mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
|
||||
|
||||
val = mt7530_read(priv, MT7530_PCR_P(port));
|
||||
@@ -2533,7 +2519,7 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
mt7530_mib_reset(ds);
|
||||
|
||||
/* Disable flooding on all ports */
|
||||
- mt7530_clear(priv, MT7530_MFC, BC_FFP_MASK | UNM_FFP_MASK |
|
||||
+ mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK |
|
||||
UNU_FFP_MASK);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
@@ -3089,10 +3075,12 @@ mt753x_conduit_state_change(struct dsa_s
|
||||
else
|
||||
priv->active_cpu_ports &= ~mask;
|
||||
|
||||
- if (priv->active_cpu_ports)
|
||||
- val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports));
|
||||
+ if (priv->active_cpu_ports) {
|
||||
+ val = MT7530_CPU_EN |
|
||||
+ MT7530_CPU_PORT(__ffs(priv->active_cpu_ports));
|
||||
+ }
|
||||
|
||||
- mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
|
||||
+ mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
|
||||
}
|
||||
|
||||
static int mt7988_setup(struct dsa_switch *ds)
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -36,36 +36,55 @@ enum mt753x_id {
|
||||
#define MT753X_AGC 0xc
|
||||
#define LOCAL_EN BIT(7)
|
||||
|
||||
-/* Registers to mac forward control for unknown frames */
|
||||
-#define MT7530_MFC 0x10
|
||||
-#define BC_FFP(x) (((x) & 0xff) << 24)
|
||||
-#define BC_FFP_MASK BC_FFP(~0)
|
||||
-#define UNM_FFP(x) (((x) & 0xff) << 16)
|
||||
-#define UNM_FFP_MASK UNM_FFP(~0)
|
||||
-#define UNU_FFP(x) (((x) & 0xff) << 8)
|
||||
-#define UNU_FFP_MASK UNU_FFP(~0)
|
||||
-#define CPU_EN BIT(7)
|
||||
-#define CPU_PORT_MASK GENMASK(6, 4)
|
||||
-#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x)
|
||||
-#define MIRROR_EN BIT(3)
|
||||
-#define MIRROR_PORT(x) ((x) & 0x7)
|
||||
-#define MIRROR_MASK 0x7
|
||||
+/* Register for MAC forward control */
|
||||
+#define MT753X_MFC 0x10
|
||||
+#define BC_FFP_MASK GENMASK(31, 24)
|
||||
+#define BC_FFP(x) FIELD_PREP(BC_FFP_MASK, x)
|
||||
+#define UNM_FFP_MASK GENMASK(23, 16)
|
||||
+#define UNM_FFP(x) FIELD_PREP(UNM_FFP_MASK, x)
|
||||
+#define UNU_FFP_MASK GENMASK(15, 8)
|
||||
+#define UNU_FFP(x) FIELD_PREP(UNU_FFP_MASK, x)
|
||||
+#define MT7530_CPU_EN BIT(7)
|
||||
+#define MT7530_CPU_PORT_MASK GENMASK(6, 4)
|
||||
+#define MT7530_CPU_PORT(x) FIELD_PREP(MT7530_CPU_PORT_MASK, x)
|
||||
+#define MT7530_MIRROR_EN BIT(3)
|
||||
+#define MT7530_MIRROR_PORT_MASK GENMASK(2, 0)
|
||||
+#define MT7530_MIRROR_PORT_GET(x) FIELD_GET(MT7530_MIRROR_PORT_MASK, x)
|
||||
+#define MT7530_MIRROR_PORT_SET(x) FIELD_PREP(MT7530_MIRROR_PORT_MASK, x)
|
||||
+#define MT7531_QRY_FFP_MASK GENMASK(7, 0)
|
||||
+#define MT7531_QRY_FFP(x) FIELD_PREP(MT7531_QRY_FFP_MASK, x)
|
||||
|
||||
-/* Registers for CPU forward control */
|
||||
+/* Register for CPU forward control */
|
||||
#define MT7531_CFC 0x4
|
||||
#define MT7531_MIRROR_EN BIT(19)
|
||||
-#define MT7531_MIRROR_MASK (MIRROR_MASK << 16)
|
||||
-#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK)
|
||||
-#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
|
||||
+#define MT7531_MIRROR_PORT_MASK GENMASK(18, 16)
|
||||
+#define MT7531_MIRROR_PORT_GET(x) FIELD_GET(MT7531_MIRROR_PORT_MASK, x)
|
||||
+#define MT7531_MIRROR_PORT_SET(x) FIELD_PREP(MT7531_MIRROR_PORT_MASK, x)
|
||||
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
|
||||
#define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x)
|
||||
|
||||
-#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
- MT7531_CFC : MT7530_MFC)
|
||||
-#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
- MT7531_MIRROR_EN : MIRROR_EN)
|
||||
-#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
- MT7531_MIRROR_MASK : MIRROR_MASK)
|
||||
+#define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \
|
||||
+ id == ID_MT7988) ? \
|
||||
+ MT7531_CFC : MT753X_MFC)
|
||||
+
|
||||
+#define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \
|
||||
+ id == ID_MT7988) ? \
|
||||
+ MT7531_MIRROR_EN : MT7530_MIRROR_EN)
|
||||
+
|
||||
+#define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \
|
||||
+ id == ID_MT7988) ? \
|
||||
+ MT7531_MIRROR_PORT_MASK : \
|
||||
+ MT7530_MIRROR_PORT_MASK)
|
||||
+
|
||||
+#define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \
|
||||
+ id == ID_MT7988) ? \
|
||||
+ MT7531_MIRROR_PORT_GET(val) : \
|
||||
+ MT7530_MIRROR_PORT_GET(val))
|
||||
+
|
||||
+#define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \
|
||||
+ id == ID_MT7988) ? \
|
||||
+ MT7531_MIRROR_PORT_SET(val) : \
|
||||
+ MT7530_MIRROR_PORT_SET(val))
|
||||
|
||||
/* Register for BPDU and PAE frame control */
|
||||
#define MT753X_BPC 0x24
|
@ -0,0 +1,257 @@
|
||||
From 3ccf67597d35c06a7319e407b1c42f78a7966779 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:13 +0300
|
||||
Subject: [PATCH 06/15] net: dsa: mt7530: refactor MT7530_HWTRAP and
|
||||
MT7530_MHWTRAP
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT7530_HWTRAP and MT7530_MHWTRAP registers are on MT7530 and MT7531.
|
||||
It's called hardware trap on MT7530, software trap on MT7531. That's
|
||||
because some bits of the trap on MT7530 cannot be modified by software
|
||||
whilst all bits of the trap on MT7531 can. Rename the definitions for them
|
||||
to MT753X_TRAP and MT753X_MTRAP. Add MT7530 and MT7531 prefixes to the
|
||||
definitions specific to the switch model.
|
||||
|
||||
Remove the extra parentheses from MT7530_XTAL_40MHZ and MT7530_XTAL_20MHZ.
|
||||
|
||||
Rename MHWTRAP_PHY0_SEL, MHWTRAP_MANUAL, and MHWTRAP_PHY_ACCESS to be on
|
||||
par with the "MT7621 Giga Switch Programming Guide v0.3" document.
|
||||
|
||||
Make an enumaration for the XTAL frequency. Set the data type of the xtal
|
||||
variable on mt7531_pll_setup() to it.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 59 ++++++++++++++++++++--------------------
|
||||
drivers/net/dsa/mt7530.h | 50 ++++++++++++++++------------------
|
||||
2 files changed, 54 insertions(+), 55 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -417,23 +417,23 @@ mt7530_setup_port6(struct dsa_switch *ds
|
||||
|
||||
mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
|
||||
|
||||
- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
|
||||
+ xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK;
|
||||
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ if (xtal == MT7530_XTAL_25MHZ)
|
||||
ssc_delta = 0x57;
|
||||
else
|
||||
ssc_delta = 0x87;
|
||||
|
||||
if (priv->id == ID_MT7621) {
|
||||
/* PLL frequency: 125MHz: 1.0GBit */
|
||||
- if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
+ if (xtal == MT7530_XTAL_40MHZ)
|
||||
ncpo1 = 0x0640;
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ if (xtal == MT7530_XTAL_25MHZ)
|
||||
ncpo1 = 0x0a00;
|
||||
} else { /* PLL frequency: 250MHz: 2.0Gbit */
|
||||
- if (xtal == HWTRAP_XTAL_40MHZ)
|
||||
+ if (xtal == MT7530_XTAL_40MHZ)
|
||||
ncpo1 = 0x0c80;
|
||||
- if (xtal == HWTRAP_XTAL_25MHZ)
|
||||
+ if (xtal == MT7530_XTAL_25MHZ)
|
||||
ncpo1 = 0x1400;
|
||||
}
|
||||
|
||||
@@ -456,19 +456,20 @@ mt7530_setup_port6(struct dsa_switch *ds
|
||||
static void
|
||||
mt7531_pll_setup(struct mt7530_priv *priv)
|
||||
{
|
||||
+ enum mt7531_xtal_fsel xtal;
|
||||
u32 top_sig;
|
||||
u32 hwstrap;
|
||||
- u32 xtal;
|
||||
u32 val;
|
||||
|
||||
val = mt7530_read(priv, MT7531_CREV);
|
||||
top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||||
- hwstrap = mt7530_read(priv, MT7531_HWTRAP);
|
||||
+ hwstrap = mt7530_read(priv, MT753X_TRAP);
|
||||
if ((val & CHIP_REV_M) > 0)
|
||||
- xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ :
|
||||
- HWTRAP_XTAL_FSEL_25MHZ;
|
||||
+ xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ :
|
||||
+ MT7531_XTAL_FSEL_25MHZ;
|
||||
else
|
||||
- xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK;
|
||||
+ xtal = (hwstrap & MT7531_XTAL25) ? MT7531_XTAL_FSEL_25MHZ :
|
||||
+ MT7531_XTAL_FSEL_40MHZ;
|
||||
|
||||
/* Step 1 : Disable MT7531 COREPLL */
|
||||
val = mt7530_read(priv, MT7531_PLLGP_EN);
|
||||
@@ -497,13 +498,13 @@ mt7531_pll_setup(struct mt7530_priv *pri
|
||||
usleep_range(25, 35);
|
||||
|
||||
switch (xtal) {
|
||||
- case HWTRAP_XTAL_FSEL_25MHZ:
|
||||
+ case MT7531_XTAL_FSEL_25MHZ:
|
||||
val = mt7530_read(priv, MT7531_PLLGP_CR0);
|
||||
val &= ~RG_COREPLL_SDM_PCW_M;
|
||||
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
|
||||
mt7530_write(priv, MT7531_PLLGP_CR0, val);
|
||||
break;
|
||||
- case HWTRAP_XTAL_FSEL_40MHZ:
|
||||
+ case MT7531_XTAL_FSEL_40MHZ:
|
||||
val = mt7530_read(priv, MT7531_PLLGP_CR0);
|
||||
val &= ~RG_COREPLL_SDM_PCW_M;
|
||||
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
|
||||
@@ -877,20 +878,20 @@ static void mt7530_setup_port5(struct ds
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
- val = mt7530_read(priv, MT7530_MHWTRAP);
|
||||
+ val = mt7530_read(priv, MT753X_MTRAP);
|
||||
|
||||
- val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
|
||||
- val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
|
||||
+ val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS;
|
||||
+ val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL;
|
||||
|
||||
switch (priv->p5_mode) {
|
||||
/* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
|
||||
case MUX_PHY_P0:
|
||||
- val |= MHWTRAP_PHY0_SEL;
|
||||
+ val |= MT7530_P5_PHY0_SEL;
|
||||
fallthrough;
|
||||
|
||||
/* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
|
||||
case MUX_PHY_P4:
|
||||
- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
|
||||
+ val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS;
|
||||
|
||||
/* Setup the MAC by default for the cpu port */
|
||||
mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
|
||||
@@ -898,13 +899,13 @@ static void mt7530_setup_port5(struct ds
|
||||
|
||||
/* GMAC5: P5 -> SoC MAC or external PHY */
|
||||
default:
|
||||
- val &= ~MHWTRAP_P5_DIS;
|
||||
+ val &= ~MT7530_P5_DIS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Setup RGMII settings */
|
||||
if (phy_interface_mode_is_rgmii(interface)) {
|
||||
- val |= MHWTRAP_P5_RGMII_MODE;
|
||||
+ val |= MT7530_P5_RGMII_MODE;
|
||||
|
||||
/* P5 RGMII RX Clock Control: delay setting for 1000M */
|
||||
mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
|
||||
@@ -924,7 +925,7 @@ static void mt7530_setup_port5(struct ds
|
||||
P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
|
||||
}
|
||||
|
||||
- mt7530_write(priv, MT7530_MHWTRAP, val);
|
||||
+ mt7530_write(priv, MT753X_MTRAP, val);
|
||||
|
||||
dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
|
||||
mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));
|
||||
@@ -2365,7 +2366,7 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
/* Waiting for MT7530 got to stable */
|
||||
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
|
||||
+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
|
||||
ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
|
||||
20, 1000000);
|
||||
if (ret < 0) {
|
||||
@@ -2380,7 +2381,7 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
|
||||
+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_20MHZ) {
|
||||
dev_err(priv->dev,
|
||||
"MT7530 with a 20MHz XTAL is not supported!\n");
|
||||
return -EINVAL;
|
||||
@@ -2401,12 +2402,12 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
RD_TAP_MASK, RD_TAP(16));
|
||||
|
||||
/* Enable port 6 */
|
||||
- val = mt7530_read(priv, MT7530_MHWTRAP);
|
||||
- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
|
||||
- val |= MHWTRAP_MANUAL;
|
||||
- mt7530_write(priv, MT7530_MHWTRAP, val);
|
||||
+ val = mt7530_read(priv, MT753X_MTRAP);
|
||||
+ val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS;
|
||||
+ val |= MT7530_CHG_TRAP;
|
||||
+ mt7530_write(priv, MT753X_MTRAP, val);
|
||||
|
||||
- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
|
||||
+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
|
||||
mt7530_pll_setup(priv);
|
||||
|
||||
mt753x_trap_frames(priv);
|
||||
@@ -2586,7 +2587,7 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
/* Waiting for MT7530 got to stable */
|
||||
- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
|
||||
+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
|
||||
ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
|
||||
20, 1000000);
|
||||
if (ret < 0) {
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -495,32 +495,30 @@ enum mt7531_clk_skew {
|
||||
MT7531_CLK_SKEW_REVERSE = 3,
|
||||
};
|
||||
|
||||
-/* Register for hw trap status */
|
||||
-#define MT7530_HWTRAP 0x7800
|
||||
-#define HWTRAP_XTAL_MASK (BIT(10) | BIT(9))
|
||||
-#define HWTRAP_XTAL_25MHZ (BIT(10) | BIT(9))
|
||||
-#define HWTRAP_XTAL_40MHZ (BIT(10))
|
||||
-#define HWTRAP_XTAL_20MHZ (BIT(9))
|
||||
+/* Register for trap status */
|
||||
+#define MT753X_TRAP 0x7800
|
||||
+#define MT7530_XTAL_MASK (BIT(10) | BIT(9))
|
||||
+#define MT7530_XTAL_25MHZ (BIT(10) | BIT(9))
|
||||
+#define MT7530_XTAL_40MHZ BIT(10)
|
||||
+#define MT7530_XTAL_20MHZ BIT(9)
|
||||
+#define MT7531_XTAL25 BIT(7)
|
||||
|
||||
-#define MT7531_HWTRAP 0x7800
|
||||
-#define HWTRAP_XTAL_FSEL_MASK BIT(7)
|
||||
-#define HWTRAP_XTAL_FSEL_25MHZ BIT(7)
|
||||
-#define HWTRAP_XTAL_FSEL_40MHZ 0
|
||||
-/* Unique fields of (M)HWSTRAP for MT7531 */
|
||||
-#define XTAL_FSEL_S 7
|
||||
-#define XTAL_FSEL_M BIT(7)
|
||||
-#define PHY_EN BIT(6)
|
||||
-#define CHG_STRAP BIT(8)
|
||||
+/* Register for trap modification */
|
||||
+#define MT753X_MTRAP 0x7804
|
||||
+#define MT7530_P5_PHY0_SEL BIT(20)
|
||||
+#define MT7530_CHG_TRAP BIT(16)
|
||||
+#define MT7530_P5_MAC_SEL BIT(13)
|
||||
+#define MT7530_P6_DIS BIT(8)
|
||||
+#define MT7530_P5_RGMII_MODE BIT(7)
|
||||
+#define MT7530_P5_DIS BIT(6)
|
||||
+#define MT7530_PHY_INDIRECT_ACCESS BIT(5)
|
||||
+#define MT7531_CHG_STRAP BIT(8)
|
||||
+#define MT7531_PHY_EN BIT(6)
|
||||
|
||||
-/* Register for hw trap modification */
|
||||
-#define MT7530_MHWTRAP 0x7804
|
||||
-#define MHWTRAP_PHY0_SEL BIT(20)
|
||||
-#define MHWTRAP_MANUAL BIT(16)
|
||||
-#define MHWTRAP_P5_MAC_SEL BIT(13)
|
||||
-#define MHWTRAP_P6_DIS BIT(8)
|
||||
-#define MHWTRAP_P5_RGMII_MODE BIT(7)
|
||||
-#define MHWTRAP_P5_DIS BIT(6)
|
||||
-#define MHWTRAP_PHY_ACCESS BIT(5)
|
||||
+enum mt7531_xtal_fsel {
|
||||
+ MT7531_XTAL_FSEL_25MHZ,
|
||||
+ MT7531_XTAL_FSEL_40MHZ,
|
||||
+};
|
||||
|
||||
/* Register for TOP signal control */
|
||||
#define MT7530_TOP_SIG_CTRL 0x7808
|
@ -0,0 +1,117 @@
|
||||
From 2982f395c9a513b168f1e685588f70013cba2f5f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:14 +0300
|
||||
Subject: [PATCH 07/15] net: dsa: mt7530: move MT753X_MTRAP operations for
|
||||
MT7530
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On MT7530, the media-independent interfaces of port 5 and 6 are controlled
|
||||
by the MT7530_P5_DIS and MT7530_P6_DIS bits of the hardware trap. Deal with
|
||||
these bits only when the relevant port is being enabled or disabled. This
|
||||
ensures that these ports will be disabled when they are not in use.
|
||||
|
||||
Do not set MT7530_CHG_TRAP on mt7530_setup_port5() as that's already being
|
||||
done on mt7530_setup().
|
||||
|
||||
Instead of globally setting MT7530_P5_MAC_SEL, clear it, then set it only
|
||||
on the appropriate case.
|
||||
|
||||
If PHY muxing is detected, clear MT7530_P5_DIS before calling
|
||||
mt7530_setup_port5().
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 38 +++++++++++++++++++++++++++-----------
|
||||
1 file changed, 27 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -880,8 +880,7 @@ static void mt7530_setup_port5(struct ds
|
||||
|
||||
val = mt7530_read(priv, MT753X_MTRAP);
|
||||
|
||||
- val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS;
|
||||
- val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL;
|
||||
+ val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE;
|
||||
|
||||
switch (priv->p5_mode) {
|
||||
/* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
|
||||
@@ -891,15 +890,13 @@ static void mt7530_setup_port5(struct ds
|
||||
|
||||
/* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
|
||||
case MUX_PHY_P4:
|
||||
- val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS;
|
||||
-
|
||||
/* Setup the MAC by default for the cpu port */
|
||||
mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
|
||||
break;
|
||||
|
||||
/* GMAC5: P5 -> SoC MAC or external PHY */
|
||||
default:
|
||||
- val &= ~MT7530_P5_DIS;
|
||||
+ val |= MT7530_P5_MAC_SEL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1193,6 +1190,14 @@ mt7530_port_enable(struct dsa_switch *ds
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
|
||||
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (port == 5)
|
||||
+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
|
||||
+ else if (port == 6)
|
||||
+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P6_DIS);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1211,6 +1216,14 @@ mt7530_port_disable(struct dsa_switch *d
|
||||
PCR_MATRIX_CLR);
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
+
|
||||
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
|
||||
+ return;
|
||||
+
|
||||
+ if (port == 5)
|
||||
+ mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS);
|
||||
+ else if (port == 6)
|
||||
+ mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2401,11 +2414,11 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
mt7530_rmw(priv, MT7530_TRGMII_RD(i),
|
||||
RD_TAP_MASK, RD_TAP(16));
|
||||
|
||||
- /* Enable port 6 */
|
||||
- val = mt7530_read(priv, MT753X_MTRAP);
|
||||
- val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS;
|
||||
- val |= MT7530_CHG_TRAP;
|
||||
- mt7530_write(priv, MT753X_MTRAP, val);
|
||||
+ /* Allow modifying the trap and directly access PHY registers via the
|
||||
+ * MDIO bus the switch is on.
|
||||
+ */
|
||||
+ mt7530_rmw(priv, MT753X_MTRAP, MT7530_CHG_TRAP |
|
||||
+ MT7530_PHY_INDIRECT_ACCESS, MT7530_CHG_TRAP);
|
||||
|
||||
if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
|
||||
mt7530_pll_setup(priv);
|
||||
@@ -2488,8 +2501,11 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4)
|
||||
+ if (priv->p5_mode == MUX_PHY_P0 ||
|
||||
+ priv->p5_mode == MUX_PHY_P4) {
|
||||
+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
|
||||
mt7530_setup_port5(ds, interface);
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
@ -0,0 +1,39 @@
|
||||
From 1f5669efca65564c7533704917f79003c6b36c9c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:15 +0300
|
||||
Subject: [PATCH 08/15] net: dsa: mt7530: return mt7530_setup_mdio &
|
||||
mt7531_setup_common on error
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The mt7530_setup_mdio() and mt7531_setup_common() functions should be
|
||||
checked for errors. Return if the functions return a non-zero value.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2667,7 +2667,9 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
0);
|
||||
}
|
||||
|
||||
- mt7531_setup_common(ds);
|
||||
+ ret = mt7531_setup_common(ds);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
ret = mt7530_setup_vlan0(priv);
|
||||
@@ -3020,6 +3022,8 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
ret = mt7530_setup_mdio(priv);
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
/* Initialise the PCS devices */
|
||||
for (i = 0; i < priv->ds->num_ports; i++) {
|
@ -0,0 +1,75 @@
|
||||
From 6cc2d4ccd77509df74b7b8ef46bbc6ba0a571318 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:16 +0300
|
||||
Subject: [PATCH 09/15] net: dsa: mt7530: define MAC speed capabilities per
|
||||
switch model
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
With the support of the MT7988 SoC switch, the MAC speed capabilities
|
||||
defined on mt753x_phylink_get_caps() won't apply to all switch models
|
||||
anymore. Move them to more appropriate locations instead of overwriting
|
||||
config->mac_capabilities.
|
||||
|
||||
Remove the comment on mt753x_phylink_get_caps() as it's become invalid with
|
||||
the support of MT7531 and MT7988 SoC switch.
|
||||
|
||||
Add break to case 6 of mt7988_mac_port_get_caps() to be explicit.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2685,6 +2685,8 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
|
||||
+
|
||||
switch (port) {
|
||||
/* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
case 0 ... 4:
|
||||
@@ -2716,6 +2718,8 @@ static void mt7531_mac_port_get_caps(str
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
|
||||
+
|
||||
switch (port) {
|
||||
/* Ports which are connected to switch PHYs. There is no MII pinout. */
|
||||
case 0 ... 4:
|
||||
@@ -2755,14 +2759,17 @@ static void mt7988_mac_port_get_caps(str
|
||||
case 0 ... 3:
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
+
|
||||
+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
|
||||
break;
|
||||
|
||||
/* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */
|
||||
case 6:
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
- MAC_10000FD;
|
||||
+
|
||||
+ config->mac_capabilities |= MAC_10000FD;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2932,9 +2939,7 @@ static void mt753x_phylink_get_caps(stru
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
- /* This switch only supports full-duplex at 1Gbps */
|
||||
- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
- MAC_10 | MAC_100 | MAC_1000FD;
|
||||
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
|
||||
|
||||
priv->info->mac_port_get_caps(ds, port, config);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
From dd0f15fc877c10567699190bce0f55e96f4ad6b5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:17 +0300
|
||||
Subject: [PATCH 10/15] net: dsa: mt7530: get rid of function sanity check
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Get rid of checking whether functions are filled properly. priv->info which
|
||||
is an mt753x_info structure is filled and checked for before this check.
|
||||
It's unnecessary checking whether it's filled properly.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3232,13 +3232,6 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
if (!priv->info)
|
||||
return -EINVAL;
|
||||
|
||||
- /* Sanity check if these required device operations are filled
|
||||
- * properly.
|
||||
- */
|
||||
- if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
|
||||
- !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps)
|
||||
- return -EINVAL;
|
||||
-
|
||||
priv->id = priv->info->id;
|
||||
priv->dev = dev;
|
||||
priv->ds->priv = priv;
|
@ -0,0 +1,71 @@
|
||||
From 2dff9759602b069f97ccc939e15a47ca051b2983 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:18 +0300
|
||||
Subject: [PATCH 11/15] net: dsa: mt7530: refactor MT7530_PMEEECR_P()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT7530_PMEEECR_P() register is on MT7530, MT7531, and the switch on the
|
||||
MT7988 SoC. Rename the definition for them to MT753X_PMEEECR_P(). Use the
|
||||
FIELD_PREP and FIELD_GET macros. Rename GET_LPI_THRESH() and
|
||||
SET_LPI_THRESH() to LPI_THRESH_GET() and LPI_THRESH_SET().
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 8 ++++----
|
||||
drivers/net/dsa/mt7530.h | 13 +++++++------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3051,10 +3051,10 @@ static int mt753x_get_mac_eee(struct dsa
|
||||
struct ethtool_eee *e)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
|
||||
+ u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
|
||||
|
||||
e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
|
||||
- e->tx_lpi_timer = GET_LPI_THRESH(eeecr);
|
||||
+ e->tx_lpi_timer = LPI_THRESH_GET(eeecr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3068,11 +3068,11 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
if (e->tx_lpi_timer > 0xFFF)
|
||||
return -EINVAL;
|
||||
|
||||
- set = SET_LPI_THRESH(e->tx_lpi_timer);
|
||||
+ set = LPI_THRESH_SET(e->tx_lpi_timer);
|
||||
if (!e->tx_lpi_enabled)
|
||||
/* Force LPI Mode without a delay */
|
||||
set |= LPI_MODE_EN;
|
||||
- mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set);
|
||||
+ mt7530_rmw(priv, MT753X_PMEEECR_P(port), mask, set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -364,13 +364,14 @@ enum mt7530_vlan_port_acc_frm {
|
||||
PMCR_FORCE_SPEED_100 | \
|
||||
PMCR_FORCE_FDX | PMCR_FORCE_LNK)
|
||||
|
||||
-#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
|
||||
-#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
|
||||
-#define WAKEUP_TIME_100(x) (((x) & 0xFF) << 16)
|
||||
+#define MT753X_PMEEECR_P(x) (0x3004 + (x) * 0x100)
|
||||
+#define WAKEUP_TIME_1000_MASK GENMASK(31, 24)
|
||||
+#define WAKEUP_TIME_1000(x) FIELD_PREP(WAKEUP_TIME_1000_MASK, x)
|
||||
+#define WAKEUP_TIME_100_MASK GENMASK(23, 16)
|
||||
+#define WAKEUP_TIME_100(x) FIELD_PREP(WAKEUP_TIME_100_MASK, x)
|
||||
#define LPI_THRESH_MASK GENMASK(15, 4)
|
||||
-#define LPI_THRESH_SHT 4
|
||||
-#define SET_LPI_THRESH(x) (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK)
|
||||
-#define GET_LPI_THRESH(x) (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT)
|
||||
+#define LPI_THRESH_GET(x) FIELD_GET(LPI_THRESH_MASK, x)
|
||||
+#define LPI_THRESH_SET(x) FIELD_PREP(LPI_THRESH_MASK, x)
|
||||
#define LPI_MODE_EN BIT(0)
|
||||
|
||||
#define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
|
@ -0,0 +1,48 @@
|
||||
From 21d67c2fabfe40baf33202d3287b67b6c16f8382 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:19 +0300
|
||||
Subject: [PATCH 12/15] net: dsa: mt7530: get rid of mac_port_validate member
|
||||
of mt753x_info
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The mac_port_validate member of the mt753x_info structure is not being
|
||||
used, remove it. Improve the member description section in the process.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.h | 10 +++-------
|
||||
1 file changed, 3 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -743,15 +743,14 @@ struct mt753x_pcs {
|
||||
|
||||
/* struct mt753x_info - This is the main data structure for holding the specific
|
||||
* part for each supported device
|
||||
+ * @id: Holding the identifier to a switch model
|
||||
+ * @pcs_ops: Holding the pointer to the MAC PCS operations structure
|
||||
* @sw_setup: Holding the handler to a device initialization
|
||||
* @phy_read_c22: Holding the way reading PHY port using C22
|
||||
* @phy_write_c22: Holding the way writing PHY port using C22
|
||||
* @phy_read_c45: Holding the way reading PHY port using C45
|
||||
* @phy_write_c45: Holding the way writing PHY port using C45
|
||||
- * @phy_mode_supported: Check if the PHY type is being supported on a certain
|
||||
- * port
|
||||
- * @mac_port_validate: Holding the way to set addition validate type for a
|
||||
- * certan MAC port
|
||||
+ * @mac_port_get_caps: Holding the handler that provides MAC capabilities
|
||||
* @mac_port_config: Holding the way setting up the PHY attribute to a
|
||||
* certain MAC port
|
||||
*/
|
||||
@@ -770,9 +769,6 @@ struct mt753x_info {
|
||||
int regnum, u16 val);
|
||||
void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
||||
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
- phy_interface_t interface,
|
||||
- unsigned long *supported);
|
||||
void (*mac_port_config)(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface);
|
@ -0,0 +1,57 @@
|
||||
From 6efc8ae3eb0363328f479191a0cf0dc12a16e090 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:20 +0300
|
||||
Subject: [PATCH 13/15] net: dsa: mt7530: use priv->ds->num_ports instead of
|
||||
MT7530_NUM_PORTS
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use priv->ds->num_ports on all for loops which configure the switch
|
||||
registers. In the future, the value of MT7530_NUM_PORTS will depend on
|
||||
priv->id. Therefore, this change prepares the subdriver for a simpler
|
||||
implementation.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1411,7 +1411,7 @@ mt7530_port_set_vlan_unaware(struct dsa_
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID_DEF);
|
||||
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
if (dsa_is_user_port(ds, i) &&
|
||||
dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
|
||||
all_user_ports_removed = false;
|
||||
@@ -2428,7 +2428,7 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
/* Enable and reset MIB counters */
|
||||
mt7530_mib_reset(ds);
|
||||
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
/* Clear link settings and enable force mode to force link down
|
||||
* on all ports until they're enabled later.
|
||||
*/
|
||||
@@ -2539,7 +2539,7 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK |
|
||||
UNU_FFP_MASK);
|
||||
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
/* Clear link settings and enable force mode to force link down
|
||||
* on all ports until they're enabled later.
|
||||
*/
|
||||
@@ -2626,7 +2626,7 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
|
||||
|
||||
/* Force link down on all ports before internal reset */
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++)
|
||||
mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK);
|
||||
|
||||
/* Reset the switch through internal reset */
|
@ -0,0 +1,37 @@
|
||||
From c078ebbf5f6f6d8390035a9f92eeab766b78884d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:21 +0300
|
||||
Subject: [PATCH 14/15] net: dsa: mt7530: do not pass port variable to
|
||||
mt7531_rgmii_setup()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The mt7531_rgmii_setup() function does not use the port variable, do not
|
||||
pass the variable to it.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2785,7 +2785,7 @@ mt7530_mac_config(struct dsa_switch *ds,
|
||||
mt7530_setup_port6(priv->ds, interface);
|
||||
}
|
||||
|
||||
-static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
|
||||
+static void mt7531_rgmii_setup(struct mt7530_priv *priv,
|
||||
phy_interface_t interface,
|
||||
struct phy_device *phydev)
|
||||
{
|
||||
@@ -2836,7 +2836,7 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
if (phy_interface_mode_is_rgmii(interface)) {
|
||||
dp = dsa_to_port(ds, port);
|
||||
phydev = dp->slave->phydev;
|
||||
- mt7531_rgmii_setup(priv, port, interface, phydev);
|
||||
+ mt7531_rgmii_setup(priv, interface, phydev);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
From e7a9cc3cc00b40e0bc2bae40bd2ece0e48fa51d5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Mon, 22 Apr 2024 10:15:22 +0300
|
||||
Subject: [PATCH 15/15] net: dsa: mt7530: explain exposing MDIO bus of MT7531AE
|
||||
better
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on MT7531AE.
|
||||
Therefore, the GPIO 11-12 pins are set to function as MDC and MDIO to
|
||||
expose the MDIO bus of the switch. Replace the comment with a better
|
||||
explanation.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2635,7 +2635,10 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
if (!priv->p5_sgmii) {
|
||||
mt7531_pll_setup(priv);
|
||||
} else {
|
||||
- /* Let ds->slave_mii_bus be able to access external phy. */
|
||||
+ /* Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on
|
||||
+ * MT7531AE. Set the GPIO 11-12 pins to function as MDC and MDIO
|
||||
+ * to expose the MDIO bus of the switch.
|
||||
+ */
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
|
||||
MT7531_EXT_P_MDC_11);
|
||||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
|
@ -0,0 +1,45 @@
|
||||
From 16e6592cd5c5bd74d8890973489f60176c692614 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Sun, 28 Apr 2024 12:19:58 +0300
|
||||
Subject: [PATCH] net: dsa: mt7530: do not set MT7530_P5_DIS when PHY muxing is
|
||||
being used
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
DSA initalises the ds->num_ports amount of ports in
|
||||
dsa_switch_touch_ports(). When the PHY muxing feature is in use, port 5
|
||||
won't be defined in the device tree. Because of this, the type member of
|
||||
the dsa_port structure for this port will be assigned DSA_PORT_TYPE_UNUSED.
|
||||
The dsa_port_setup() function calls ds->ops->port_disable() when the port
|
||||
type is DSA_PORT_TYPE_UNUSED.
|
||||
|
||||
The MT7530_P5_DIS bit is unset in mt7530_setup() when PHY muxing is being
|
||||
used. mt7530_port_disable() which is assigned to ds->ops->port_disable() is
|
||||
called afterwards. Currently, mt7530_port_disable() sets MT7530_P5_DIS
|
||||
which breaks network connectivity when PHY muxing is being used.
|
||||
|
||||
Therefore, do not set MT7530_P5_DIS when PHY muxing is being used.
|
||||
|
||||
Fixes: 377174c5760c ("net: dsa: mt7530: move MT753X_MTRAP operations for MT7530")
|
||||
Reported-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20240428-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-v2-1-bb7c37d293f8@arinc9.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1220,7 +1220,8 @@ mt7530_port_disable(struct dsa_switch *d
|
||||
if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
|
||||
return;
|
||||
|
||||
- if (port == 5)
|
||||
+ /* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */
|
||||
+ if (port == 5 && priv->p5_mode == GMAC5)
|
||||
mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS);
|
||||
else if (port == 6)
|
||||
mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS);
|
@ -0,0 +1,45 @@
|
||||
From d8dcf5bd6d0eace9f7c1daa14b63b3925b09d033 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Tue, 30 Apr 2024 08:01:33 +0300
|
||||
Subject: [PATCH] net: dsa: mt7530: detect PHY muxing when PHY is defined on
|
||||
switch MDIO bus
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Currently, the MT7530 DSA subdriver configures the MT7530 switch to provide
|
||||
direct access to switch PHYs, meaning, the switch PHYs listen on the MDIO
|
||||
bus the switch listens on. The PHY muxing feature makes use of this.
|
||||
|
||||
This is problematic as the PHY may be attached before the switch is
|
||||
initialised, in which case, the PHY will fail to be attached.
|
||||
|
||||
Since commit 91374ba537bd ("net: dsa: mt7530: support OF-based registration
|
||||
of switch MDIO bus"), we can describe the switch PHYs on the MDIO bus of
|
||||
the switch on the device tree. Extend the check to detect PHY muxing when
|
||||
the PHY is defined on the MDIO bus of the switch on the device tree.
|
||||
|
||||
When the PHY is described this way, the switch will be initialised first,
|
||||
then the switch MDIO bus will be registered. Only after these steps, the
|
||||
PHY will be attached.
|
||||
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20240430-b4-for-netnext-mt7530-use-switch-mdio-bus-for-phy-muxing-v2-1-9104d886d0db@arinc9.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2484,7 +2484,8 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
if (!phy_node)
|
||||
continue;
|
||||
|
||||
- if (phy_node->parent == priv->dev->of_node->parent) {
|
||||
+ if (phy_node->parent == priv->dev->of_node->parent ||
|
||||
+ phy_node->parent->parent == priv->dev->of_node) {
|
||||
ret = of_get_phy_mode(mac_np, &interface);
|
||||
if (ret && ret != -ENODEV) {
|
||||
of_node_put(mac_np);
|
@ -0,0 +1,176 @@
|
||||
From c25c961fc7f36682f0a530150f1b7453ebc344cd Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Date: Tue, 18 Jun 2024 09:17:12 +0200
|
||||
Subject: [PATCH 1/2] net: dsa: mt7530: factor out bridge join/leave logic
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
As preparation for implementing bridge port isolation, move the logic to
|
||||
add and remove bits in the port matrix into a new helper
|
||||
mt7530_update_port_member(), which is called from
|
||||
mt7530_port_bridge_join() and mt7530_port_bridge_leave().
|
||||
|
||||
Another part of the preparation is using dsa_port_offloads_bridge_dev()
|
||||
instead of dsa_port_offloads_bridge() to check for bridge membership, as
|
||||
we don't have a struct dsa_bridge in mt7530_port_bridge_flags().
|
||||
|
||||
The port matrix setting is slightly streamlined, now always first setting
|
||||
the mt7530_port's pm field and then writing the port matrix from that
|
||||
field into the hardware register, instead of duplicating the bit
|
||||
manipulation for both the struct field and the register.
|
||||
|
||||
mt7530_port_bridge_join() was previously using |= to update the port
|
||||
matrix with the port bitmap, which was unnecessary, as pm would only
|
||||
have the CPU port set before joining a bridge; a simple assignment can
|
||||
be used for both joining and leaving (and will also work when individual
|
||||
bits are added/removed in port_bitmap with regard to the previous port
|
||||
matrix, which is what happens with port isolation).
|
||||
|
||||
No functional change intended.
|
||||
|
||||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Reviewed-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 105 ++++++++++++++++++---------------------
|
||||
1 file changed, 48 insertions(+), 57 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1302,6 +1302,52 @@ mt7530_stp_state_set(struct dsa_switch *
|
||||
FID_PST(FID_BRIDGED, stp_state));
|
||||
}
|
||||
|
||||
+static void mt7530_update_port_member(struct mt7530_priv *priv, int port,
|
||||
+ const struct net_device *bridge_dev,
|
||||
+ bool join) __must_hold(&priv->reg_mutex)
|
||||
+{
|
||||
+ struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp;
|
||||
+ struct mt7530_port *p = &priv->ports[port], *other_p;
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
+ u32 port_bitmap = BIT(cpu_dp->index);
|
||||
+ int other_port;
|
||||
+
|
||||
+ dsa_switch_for_each_user_port(other_dp, priv->ds) {
|
||||
+ other_port = other_dp->index;
|
||||
+ other_p = &priv->ports[other_port];
|
||||
+
|
||||
+ if (dp == other_dp)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Add/remove this port to/from the port matrix of the other
|
||||
+ * ports in the same bridge. If the port is disabled, port
|
||||
+ * matrix is kept and not being setup until the port becomes
|
||||
+ * enabled.
|
||||
+ */
|
||||
+ if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
|
||||
+ continue;
|
||||
+
|
||||
+ if (join) {
|
||||
+ other_p->pm |= PCR_MATRIX(BIT(port));
|
||||
+ port_bitmap |= BIT(other_port);
|
||||
+ } else {
|
||||
+ other_p->pm &= ~PCR_MATRIX(BIT(port));
|
||||
+ }
|
||||
+
|
||||
+ if (other_p->enable)
|
||||
+ mt7530_rmw(priv, MT7530_PCR_P(other_port),
|
||||
+ PCR_MATRIX_MASK, other_p->pm);
|
||||
+ }
|
||||
+
|
||||
+ /* Add/remove the all other ports to this port matrix. For !join
|
||||
+ * (leaving the bridge), only the CPU port will remain in the port matrix
|
||||
+ * of this port.
|
||||
+ */
|
||||
+ p->pm = PCR_MATRIX(port_bitmap);
|
||||
+ if (priv->ports[port].enable)
|
||||
+ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, p->pm);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
mt7530_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
||||
struct switchdev_brport_flags flags,
|
||||
@@ -1345,39 +1391,11 @@ mt7530_port_bridge_join(struct dsa_switc
|
||||
struct dsa_bridge bridge, bool *tx_fwd_offload,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
- struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
- u32 port_bitmap = BIT(cpu_dp->index);
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
- dsa_switch_for_each_user_port(other_dp, ds) {
|
||||
- int other_port = other_dp->index;
|
||||
-
|
||||
- if (dp == other_dp)
|
||||
- continue;
|
||||
-
|
||||
- /* Add this port to the port matrix of the other ports in the
|
||||
- * same bridge. If the port is disabled, port matrix is kept
|
||||
- * and not being setup until the port becomes enabled.
|
||||
- */
|
||||
- if (!dsa_port_offloads_bridge(other_dp, &bridge))
|
||||
- continue;
|
||||
-
|
||||
- if (priv->ports[other_port].enable)
|
||||
- mt7530_set(priv, MT7530_PCR_P(other_port),
|
||||
- PCR_MATRIX(BIT(port)));
|
||||
- priv->ports[other_port].pm |= PCR_MATRIX(BIT(port));
|
||||
-
|
||||
- port_bitmap |= BIT(other_port);
|
||||
- }
|
||||
-
|
||||
- /* Add the all other ports to this port matrix. */
|
||||
- if (priv->ports[port].enable)
|
||||
- mt7530_rmw(priv, MT7530_PCR_P(port),
|
||||
- PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
|
||||
- priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
|
||||
+ mt7530_update_port_member(priv, port, bridge.dev, true);
|
||||
|
||||
/* Set to fallback mode for independent VLAN learning */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
@@ -1478,38 +1496,11 @@ static void
|
||||
mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
|
||||
struct dsa_bridge bridge)
|
||||
{
|
||||
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
- struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
- dsa_switch_for_each_user_port(other_dp, ds) {
|
||||
- int other_port = other_dp->index;
|
||||
-
|
||||
- if (dp == other_dp)
|
||||
- continue;
|
||||
-
|
||||
- /* Remove this port from the port matrix of the other ports
|
||||
- * in the same bridge. If the port is disabled, port matrix
|
||||
- * is kept and not being setup until the port becomes enabled.
|
||||
- */
|
||||
- if (!dsa_port_offloads_bridge(other_dp, &bridge))
|
||||
- continue;
|
||||
-
|
||||
- if (priv->ports[other_port].enable)
|
||||
- mt7530_clear(priv, MT7530_PCR_P(other_port),
|
||||
- PCR_MATRIX(BIT(port)));
|
||||
- priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port));
|
||||
- }
|
||||
-
|
||||
- /* Set the cpu port to be the only one in the port matrix of
|
||||
- * this port.
|
||||
- */
|
||||
- if (priv->ports[port].enable)
|
||||
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
|
||||
- PCR_MATRIX(BIT(cpu_dp->index)));
|
||||
- priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));
|
||||
+ mt7530_update_port_member(priv, port, bridge.dev, false);
|
||||
|
||||
/* When a port is removed from the bridge, the port would be set up
|
||||
* back to the default as is at initial boot which is a VLAN-unaware
|
@ -0,0 +1,79 @@
|
||||
From 3d49ee2127c26fd2c77944fd2e3168c057f99439 Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Date: Tue, 18 Jun 2024 09:17:13 +0200
|
||||
Subject: [PATCH 2/2] net: dsa: mt7530: add support for bridge port isolation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Remove a pair of ports from the port matrix when both ports have the
|
||||
isolated flag set.
|
||||
|
||||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Reviewed-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++--
|
||||
drivers/net/dsa/mt7530.h | 1 +
|
||||
2 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1311,6 +1311,7 @@ static void mt7530_update_port_member(st
|
||||
struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
u32 port_bitmap = BIT(cpu_dp->index);
|
||||
int other_port;
|
||||
+ bool isolated;
|
||||
|
||||
dsa_switch_for_each_user_port(other_dp, priv->ds) {
|
||||
other_port = other_dp->index;
|
||||
@@ -1327,7 +1328,9 @@ static void mt7530_update_port_member(st
|
||||
if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
|
||||
continue;
|
||||
|
||||
- if (join) {
|
||||
+ isolated = p->isolated && other_p->isolated;
|
||||
+
|
||||
+ if (join && !isolated) {
|
||||
other_p->pm |= PCR_MATRIX(BIT(port));
|
||||
port_bitmap |= BIT(other_port);
|
||||
} else {
|
||||
@@ -1354,7 +1357,7 @@ mt7530_port_pre_bridge_flags(struct dsa_
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
|
||||
- BR_BCAST_FLOOD))
|
||||
+ BR_BCAST_FLOOD | BR_ISOLATED))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -1383,6 +1386,17 @@ mt7530_port_bridge_flags(struct dsa_swit
|
||||
mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)),
|
||||
flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
|
||||
|
||||
+ if (flags.mask & BR_ISOLATED) {
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
+ struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp);
|
||||
+
|
||||
+ priv->ports[port].isolated = !!(flags.val & BR_ISOLATED);
|
||||
+
|
||||
+ mutex_lock(&priv->reg_mutex);
|
||||
+ mt7530_update_port_member(priv, port, bridge_dev, true);
|
||||
+ mutex_unlock(&priv->reg_mutex);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -721,6 +721,7 @@ struct mt7530_fdb {
|
||||
*/
|
||||
struct mt7530_port {
|
||||
bool enable;
|
||||
+ bool isolated;
|
||||
u32 pm;
|
||||
u16 pvid;
|
||||
struct phylink_pcs *sgmii_pcs;
|
@ -0,0 +1,122 @@
|
||||
From c11d5dbbe73fa7b450aaa77bb18df86a9714b422 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 1 Jun 2024 01:35:02 +0200
|
||||
Subject: [PATCH 1/2] net: phy: aquantia: move priv and hw stat to header
|
||||
|
||||
In preparation for LEDs support, move priv and hw stat to header to
|
||||
reference priv struct also in other .c outside aquantia.main
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/aquantia/aquantia.h | 38 ++++++++++++++++++++++++
|
||||
drivers/net/phy/aquantia/aquantia_main.c | 37 -----------------------
|
||||
2 files changed, 38 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/aquantia/aquantia.h
|
||||
+++ b/drivers/net/phy/aquantia/aquantia.h
|
||||
@@ -82,6 +82,18 @@
|
||||
#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
|
||||
#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
|
||||
|
||||
+/* MDIO_MMD_C22EXT */
|
||||
+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
|
||||
+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
|
||||
+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
|
||||
+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
|
||||
+
|
||||
#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
|
||||
#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
|
||||
|
||||
@@ -108,6 +120,32 @@
|
||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
||||
|
||||
+struct aqr107_hw_stat {
|
||||
+ const char *name;
|
||||
+ int reg;
|
||||
+ int size;
|
||||
+};
|
||||
+
|
||||
+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
|
||||
+static const struct aqr107_hw_stat aqr107_hw_stats[] = {
|
||||
+ SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
|
||||
+ SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
|
||||
+ SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
|
||||
+ SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
|
||||
+ SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
|
||||
+ SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
|
||||
+ SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
|
||||
+ SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
|
||||
+ SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
|
||||
+ SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
|
||||
+};
|
||||
+
|
||||
+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
|
||||
+
|
||||
+struct aqr107_priv {
|
||||
+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
|
||||
+};
|
||||
+
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
int aqr_hwmon_probe(struct phy_device *phydev);
|
||||
#else
|
||||
--- a/drivers/net/phy/aquantia/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_main.c
|
||||
@@ -84,49 +84,12 @@
|
||||
#define MDIO_AN_RX_VEND_STAT3 0xe832
|
||||
#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
|
||||
|
||||
-/* MDIO_MMD_C22EXT */
|
||||
-#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
|
||||
-#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
|
||||
-#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
|
||||
-#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
|
||||
-
|
||||
/* Sleep and timeout for checking if the Processor-Intensive
|
||||
* MDIO operation is finished
|
||||
*/
|
||||
#define AQR107_OP_IN_PROG_SLEEP 1000
|
||||
#define AQR107_OP_IN_PROG_TIMEOUT 100000
|
||||
|
||||
-struct aqr107_hw_stat {
|
||||
- const char *name;
|
||||
- int reg;
|
||||
- int size;
|
||||
-};
|
||||
-
|
||||
-#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
|
||||
-static const struct aqr107_hw_stat aqr107_hw_stats[] = {
|
||||
- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
|
||||
- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
|
||||
- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
|
||||
- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
|
||||
- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
|
||||
- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
|
||||
- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
|
||||
- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
|
||||
- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
|
||||
- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
|
||||
-};
|
||||
-#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
|
||||
-
|
||||
-struct aqr107_priv {
|
||||
- u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
|
||||
-};
|
||||
-
|
||||
static int aqr107_get_sset_count(struct phy_device *phydev)
|
||||
{
|
||||
return AQR107_SGMII_STAT_SZ;
|
@ -0,0 +1,395 @@
|
||||
From 61578f67937881abf54c8bd258eb913312dbe4c1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 1 Jun 2024 01:35:03 +0200
|
||||
Subject: [PATCH 2/2] net: phy: aquantia: add support for PHY LEDs
|
||||
|
||||
Aquantia Ethernet PHYs got 3 LED output pins which are typically used
|
||||
to indicate link status and activity.
|
||||
Add a minimal LED controller driver supporting the most common uses
|
||||
with the 'netdev' trigger as well as software-driven forced control of
|
||||
the LEDs.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
[ rework indentation, fix checkpatch error and improve some functions ]
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/aquantia/Makefile | 2 +-
|
||||
drivers/net/phy/aquantia/aquantia.h | 40 ++++++
|
||||
drivers/net/phy/aquantia/aquantia_leds.c | 150 +++++++++++++++++++++++
|
||||
drivers/net/phy/aquantia/aquantia_main.c | 63 +++++++++-
|
||||
4 files changed, 252 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/net/phy/aquantia/aquantia_leds.c
|
||||
|
||||
--- a/drivers/net/phy/aquantia/Makefile
|
||||
+++ b/drivers/net/phy/aquantia/Makefile
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-aquantia-objs += aquantia_main.o aquantia_firmware.o
|
||||
+aquantia-objs += aquantia_main.o aquantia_firmware.o aquantia_leds.o
|
||||
ifdef CONFIG_HWMON
|
||||
aquantia-objs += aquantia_hwmon.o
|
||||
endif
|
||||
--- a/drivers/net/phy/aquantia/aquantia.h
|
||||
+++ b/drivers/net/phy/aquantia/aquantia.h
|
||||
@@ -58,6 +58,28 @@
|
||||
#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
|
||||
#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
|
||||
|
||||
+#define VEND1_GLOBAL_LED_PROV 0xc430
|
||||
+#define AQR_LED_PROV(x) (VEND1_GLOBAL_LED_PROV + (x))
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK2500 BIT(14)
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK5000 BIT(15)
|
||||
+#define VEND1_GLOBAL_LED_PROV_FORCE_ON BIT(8)
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK10000 BIT(7)
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK1000 BIT(6)
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK100 BIT(5)
|
||||
+#define VEND1_GLOBAL_LED_PROV_RX_ACT BIT(3)
|
||||
+#define VEND1_GLOBAL_LED_PROV_TX_ACT BIT(2)
|
||||
+#define VEND1_GLOBAL_LED_PROV_ACT_STRETCH GENMASK(0, 1)
|
||||
+
|
||||
+#define VEND1_GLOBAL_LED_PROV_LINK_MASK (VEND1_GLOBAL_LED_PROV_LINK100 | \
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK1000 | \
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK10000 | \
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK5000 | \
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK2500)
|
||||
+
|
||||
+#define VEND1_GLOBAL_LED_DRIVE 0xc438
|
||||
+#define VEND1_GLOBAL_LED_DRIVE_VDD BIT(1)
|
||||
+#define AQR_LED_DRIVE(x) (VEND1_GLOBAL_LED_DRIVE + (x))
|
||||
+
|
||||
#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
|
||||
#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
|
||||
#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
|
||||
@@ -120,6 +142,8 @@
|
||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
||||
|
||||
+#define AQR_MAX_LEDS 3
|
||||
+
|
||||
struct aqr107_hw_stat {
|
||||
const char *name;
|
||||
int reg;
|
||||
@@ -144,6 +168,7 @@ static const struct aqr107_hw_stat aqr10
|
||||
|
||||
struct aqr107_priv {
|
||||
u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
|
||||
+ unsigned long leds_active_low;
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
@@ -153,3 +178,18 @@ static inline int aqr_hwmon_probe(struct
|
||||
#endif
|
||||
|
||||
int aqr_firmware_load(struct phy_device *phydev);
|
||||
+
|
||||
+int aqr_phy_led_blink_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off);
|
||||
+int aqr_phy_led_brightness_set(struct phy_device *phydev,
|
||||
+ u8 index, enum led_brightness value);
|
||||
+int aqr_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *rules);
|
||||
+int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable);
|
||||
+int aqr_phy_led_polarity_set(struct phy_device *phydev, int index,
|
||||
+ unsigned long modes);
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_leds.c
|
||||
@@ -0,0 +1,150 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/* LED driver for Aquantia PHY
|
||||
+ *
|
||||
+ * Author: Daniel Golle <daniel@makrotopia.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/phy.h>
|
||||
+
|
||||
+#include "aquantia.h"
|
||||
+
|
||||
+int aqr_phy_led_brightness_set(struct phy_device *phydev,
|
||||
+ u8 index, enum led_brightness value)
|
||||
+{
|
||||
+ if (index >= AQR_MAX_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index),
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK_MASK |
|
||||
+ VEND1_GLOBAL_LED_PROV_FORCE_ON |
|
||||
+ VEND1_GLOBAL_LED_PROV_RX_ACT |
|
||||
+ VEND1_GLOBAL_LED_PROV_TX_ACT,
|
||||
+ value ? VEND1_GLOBAL_LED_PROV_FORCE_ON : 0);
|
||||
+}
|
||||
+
|
||||
+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_2500) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_5000) |
|
||||
+ BIT(TRIGGER_NETDEV_LINK_10000) |
|
||||
+ BIT(TRIGGER_NETDEV_RX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX));
|
||||
+
|
||||
+int aqr_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ if (index >= AQR_MAX_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* All combinations of the supported triggers are allowed */
|
||||
+ if (rules & ~supported_triggers)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *rules)
|
||||
+{
|
||||
+ int val;
|
||||
+
|
||||
+ if (index >= AQR_MAX_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index));
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ *rules = 0;
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_LINK100)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_LINK_100);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_LINK1000)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_LINK2500)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_LINK5000)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_LINK_5000);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_LINK10000)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_LINK_10000);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_RX_ACT)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_RX);
|
||||
+
|
||||
+ if (val & VEND1_GLOBAL_LED_PROV_TX_ACT)
|
||||
+ *rules |= BIT(TRIGGER_NETDEV_TX);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ u16 val = 0;
|
||||
+
|
||||
+ if (index >= AQR_MAX_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_LINK100;
|
||||
+
|
||||
+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_LINK1000;
|
||||
+
|
||||
+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_LINK2500;
|
||||
+
|
||||
+ if (rules & (BIT(TRIGGER_NETDEV_LINK_5000) | BIT(TRIGGER_NETDEV_LINK)))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_LINK5000;
|
||||
+
|
||||
+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10000) | BIT(TRIGGER_NETDEV_LINK)))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_LINK10000;
|
||||
+
|
||||
+ if (rules & BIT(TRIGGER_NETDEV_RX))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_RX_ACT;
|
||||
+
|
||||
+ if (rules & BIT(TRIGGER_NETDEV_TX))
|
||||
+ val |= VEND1_GLOBAL_LED_PROV_TX_ACT;
|
||||
+
|
||||
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index),
|
||||
+ VEND1_GLOBAL_LED_PROV_LINK_MASK |
|
||||
+ VEND1_GLOBAL_LED_PROV_FORCE_ON |
|
||||
+ VEND1_GLOBAL_LED_PROV_RX_ACT |
|
||||
+ VEND1_GLOBAL_LED_PROV_TX_ACT, val);
|
||||
+}
|
||||
+
|
||||
+int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable)
|
||||
+{
|
||||
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_DRIVE(index),
|
||||
+ VEND1_GLOBAL_LED_DRIVE_VDD, enable);
|
||||
+}
|
||||
+
|
||||
+int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes)
|
||||
+{
|
||||
+ struct aqr107_priv *priv = phydev->priv;
|
||||
+ bool active_low = false;
|
||||
+ u32 mode;
|
||||
+
|
||||
+ if (index >= AQR_MAX_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
|
||||
+ switch (mode) {
|
||||
+ case PHY_LED_ACTIVE_LOW:
|
||||
+ active_low = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Save LED driver vdd state to restore on SW reset */
|
||||
+ if (active_low)
|
||||
+ priv->leds_active_low |= BIT(index);
|
||||
+
|
||||
+ return aqr_phy_led_active_low_set(phydev, index, active_low);
|
||||
+}
|
||||
--- a/drivers/net/phy/aquantia/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_main.c
|
||||
@@ -475,7 +475,9 @@ static void aqr107_chip_info(struct phy_
|
||||
|
||||
static int aqr107_config_init(struct phy_device *phydev)
|
||||
{
|
||||
- int ret;
|
||||
+ struct aqr107_priv *priv = phydev->priv;
|
||||
+ u32 led_active_low;
|
||||
+ int ret, index = 0;
|
||||
|
||||
/* Check that the PHY interface type is compatible */
|
||||
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
|
||||
@@ -496,7 +498,19 @@ static int aqr107_config_init(struct phy
|
||||
if (!ret)
|
||||
aqr107_chip_info(phydev);
|
||||
|
||||
- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
|
||||
+ ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Restore LED polarity state after reset */
|
||||
+ for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
|
||||
+ ret = aqr_phy_led_active_low_set(phydev, index, led_active_low);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ index++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int aqcs109_config_init(struct phy_device *phydev)
|
||||
@@ -703,6 +717,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
|
||||
@@ -722,6 +741,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
|
||||
@@ -741,6 +765,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
|
||||
@@ -760,6 +789,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
|
||||
@@ -786,6 +820,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
|
||||
@@ -823,6 +862,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
|
||||
@@ -842,6 +886,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
|
||||
@@ -861,6 +910,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
|
||||
@@ -880,6 +934,11 @@ static struct phy_driver aqr_driver[] =
|
||||
.get_strings = aqr107_get_strings,
|
||||
.get_stats = aqr107_get_stats,
|
||||
.link_change_notify = aqr107_link_change_notify,
|
||||
+ .led_brightness_set = aqr_phy_led_brightness_set,
|
||||
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
|
||||
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
|
||||
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
|
||||
+ .led_polarity_set = aqr_phy_led_polarity_set,
|
||||
},
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
From 87c33315af380ca12a2e59ac94edad4fe0481b4c Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@linaro.org>
|
||||
Date: Fri, 5 Apr 2024 13:08:59 +0300
|
||||
Subject: [PATCH] net: phy: air_en8811h: fix some error codes
|
||||
|
||||
These error paths accidentally return "ret" which is zero/success
|
||||
instead of the correct error code.
|
||||
|
||||
Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver")
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://lore.kernel.org/r/7ef2e230-dfb7-4a77-8973-9e5be1a99fc2@moroto.mountain
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/air_en8811h.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/air_en8811h.c
|
||||
+++ b/drivers/net/phy/air_en8811h.c
|
||||
@@ -272,11 +272,11 @@ static int __air_buckpbus_reg_read(struc
|
||||
|
||||
pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
|
||||
if (pbus_data_high < 0)
|
||||
- return ret;
|
||||
+ return pbus_data_high;
|
||||
|
||||
pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
|
||||
if (pbus_data_low < 0)
|
||||
- return ret;
|
||||
+ return pbus_data_low;
|
||||
|
||||
*pbus_data = pbus_data_low | (pbus_data_high << 16);
|
||||
return 0;
|
||||
@@ -323,11 +323,11 @@ static int __air_buckpbus_reg_modify(str
|
||||
|
||||
pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
|
||||
if (pbus_data_high < 0)
|
||||
- return ret;
|
||||
+ return pbus_data_high;
|
||||
|
||||
pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
|
||||
if (pbus_data_low < 0)
|
||||
- return ret;
|
||||
+ return pbus_data_low;
|
||||
|
||||
pbus_data_old = pbus_data_low | (pbus_data_high << 16);
|
||||
pbus_data_new = (pbus_data_old & ~mask) | set;
|
@ -0,0 +1,34 @@
|
||||
From ec18a2a83b8b9f7e39c80105ea148c769c46227b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Wed, 17 Jan 2024 16:17:36 +0100
|
||||
Subject: [PATCH] dt-bindings: leds: Add FUNCTION defines for per-band WLANs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Most wireless routers and access points can operate in multiple bands
|
||||
simultaneously. Vendors often equip their devices with per-band LEDs.
|
||||
|
||||
Add defines for those very common functions to allow cleaner & clearer
|
||||
bindings.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20240117151736.27440-1-zajec5@gmail.com
|
||||
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||
---
|
||||
include/dt-bindings/leds/common.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/include/dt-bindings/leds/common.h
|
||||
+++ b/include/dt-bindings/leds/common.h
|
||||
@@ -101,6 +101,9 @@
|
||||
#define LED_FUNCTION_USB "usb"
|
||||
#define LED_FUNCTION_WAN "wan"
|
||||
#define LED_FUNCTION_WLAN "wlan"
|
||||
+#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
|
||||
+#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
|
||||
+#define LED_FUNCTION_WLAN_6GHZ "wlan-6ghz"
|
||||
#define LED_FUNCTION_WPS "wps"
|
||||
|
||||
#endif /* __DT_BINDINGS_LEDS_H */
|
@ -0,0 +1,35 @@
|
||||
From 64e558500d2d04878b8a6d6578850c475171d6ba Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 23 Feb 2024 12:22:23 +0100
|
||||
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet
|
||||
access
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It's common for routers to have LED indicating link on the WAN port.
|
||||
|
||||
Some devices however have an extra LED that's meant to be used if WAN
|
||||
connection is actually "online" (there is Internet access available).
|
||||
|
||||
It was suggested to add #define for such use case.
|
||||
|
||||
Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com/T/#u
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Link: https://lore.kernel.org/r/20240223112223.1368-1-zajec5@gmail.com
|
||||
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||
---
|
||||
include/dt-bindings/leds/common.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/include/dt-bindings/leds/common.h
|
||||
+++ b/include/dt-bindings/leds/common.h
|
||||
@@ -100,6 +100,7 @@
|
||||
#define LED_FUNCTION_TX "tx"
|
||||
#define LED_FUNCTION_USB "usb"
|
||||
#define LED_FUNCTION_WAN "wan"
|
||||
+#define LED_FUNCTION_WAN_ONLINE "wan-online"
|
||||
#define LED_FUNCTION_WLAN "wlan"
|
||||
#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
|
||||
#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user