kernel: upgrade the Linux kernel to 6.12.18
This commit upgrades the Linux kernel to 6.12.18 from 6.6.x, which comes from the linux-yocto upstream. The following changes we made to support the kernel upgrade. For linux debian package deb_patches folder. We adapt the kernel related patch for 6.12.18, and cherry pick the following 8 commits to support to build the kernel 6.12.x. 1) commit f77deecbb5d4 "d/rules.real: Unset KBUILD_HOSTCFLAGS etc. instead of overriding to be empty" https://salsa.debian.org/kernel-team/linux/-/commit/f77deecbb5d4 2) commit 0d0d62b7d1cc "d/rules.d/Makefile.inc: Add scripts/include to header include path" https://salsa.debian.org/kernel-team/linux/-/commit/0d0d62b7d1cc 3) commit 4ad01663251d "[x86] linux-cpupower: Update turbostat Makefile to define BUILD_BUG_HEADER" https://salsa.debian.org/kernel-team/linux/-/commit/4ad01663251d 4) commit fced95b415be "hyperv-daemons: Update for upstream removal of hv_fcopy_daemon" https://salsa.debian.org/kernel-team/linux/-/commit/fced95b415be 5) commit 3a17dcbfe0be "d/rules.d/certs: Add newly required include directory to CPPFLAGS" https://salsa.debian.org/kernel-team/linux/-/commit/3a17dcbfe0be 6) commit 15b6859742d4 "Disable building rtla, since bullseye's libtraceevent and libtracefs are too old" https://salsa.debian.org/kernel-team/linux/-/commit/15b6859742d4 7) commit b4b93560d441 "[ia64] Drop all ia64 configs due to upstream dropping IA64 arch" https://salsa.debian.org/kernel-team/linux/-/commit/b4b93560d441 8) commit b93faa99519d "linux-kbuild: Add scripts/module-common.c (Closes: #1087495)" https://salsa.debian.org/kernel-team/linux/-/commit/b93faa99519d For the Linux source code patches folder. 1) We adapt the patch 0001, 0003, 0005, 0006, 0010, 0014 and 0017 based on kernel-6.12.18. 2) Remove all the ice port back patches because that has been included in our source code. For the kernel config. We enable CONFIG_CPUSETS_V1 and CONFIG_MEMCG_V1 to fix install issue. Verification: - Build kernel and out of tree modules success for rt and std. - Build iso success for rt and std. - Install success onto a All-in-One lab with rt kernel, and can switch to std kernel. - Boot up successfully in the lab. - The sanity testing was run and the test results PASS. - The cyclictest benchmark was also run on the starlingx lab, the result is "samples: 43199996 avg: 1656.295 std_dev: 67.617 max: 8827 99.9999th percentile: 8652“,It is worse than linux-6.6.x. - The network performance test had been done. For TCP, better than kernel-6.6.x, for UDP, a little worse than kernel-6.6.x, for STCP, can not do the test that is same with kernel-6.6.x. Story: 2011384 Task: 51856 Change-Id: I06ff2f3ab3620fe887f1e5e72ea9022a0cea6102 Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
This commit is contained in:
parent
553d7bd2cf
commit
443773aaa9
@ -28,14 +28,14 @@ libbnxt-re
|
||||
|
||||
#kernel-std/kernel-rt
|
||||
linux-compiler-gcc-10-x86
|
||||
linux-headers-6.6.0-1-amd64
|
||||
linux-rt-headers-6.6.0-1-rt-amd64
|
||||
linux-headers-6.6.0-1-common
|
||||
linux-rt-headers-6.6.0-1-rt-common
|
||||
linux-image-6.6.0-1-amd64-unsigned
|
||||
linux-rt-image-6.6.0-1-rt-amd64-unsigned
|
||||
linux-kbuild-6.6
|
||||
linux-rt-kbuild-6.6
|
||||
linux-headers-6.12.0-1-amd64
|
||||
linux-rt-headers-6.12.0-1-rt-amd64
|
||||
linux-headers-6.12.0-1-common
|
||||
linux-rt-headers-6.12.0-1-rt-common
|
||||
linux-image-6.12.0-1-amd64-unsigned
|
||||
linux-rt-image-6.12.0-1-rt-amd64-unsigned
|
||||
linux-kbuild-6.12
|
||||
linux-rt-kbuild-6.12
|
||||
linux-libc-dev
|
||||
linux-perf
|
||||
|
||||
|
@ -0,0 +1,479 @@
|
||||
From bc68f1325d88d333af7953908536957ac1851601 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Sun, 16 Mar 2025 10:41:37 +0000
|
||||
Subject: [PATCH 13/19] Correct the patches for the linux kernel 6.12.x
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
...-module.lds-under-arch-directory-too.patch | 29 +++---
|
||||
debian/patches/debian/kernelvariables.patch | 4 +-
|
||||
...support-asciidoctor-for-documentatio.patch | 3 +-
|
||||
debian/patches/debian/version.patch | 95 ++++++-------------
|
||||
...ecure_boot-flag-to-indicate-secure-b.patch | 12 +--
|
||||
...e-kernel-if-booted-in-secure-boot-mo.patch | 71 ++++++--------
|
||||
6 files changed, 84 insertions(+), 130 deletions(-)
|
||||
|
||||
diff --git a/debian/patches/debian/kbuild-look-for-module.lds-under-arch-directory-too.patch b/debian/patches/debian/kbuild-look-for-module.lds-under-arch-directory-too.patch
|
||||
index eea69e4558..9f550a1cfa 100644
|
||||
--- a/debian/patches/debian/kbuild-look-for-module.lds-under-arch-directory-too.patch
|
||||
+++ b/debian/patches/debian/kbuild-look-for-module.lds-under-arch-directory-too.patch
|
||||
@@ -22,31 +22,32 @@ Therefore, we move module.lds under the arch build directory in
|
||||
rules.real and change Makefile.modfinal to look for it in both places.
|
||||
|
||||
---
|
||||
-Index: linux/scripts/Makefile.modfinal
|
||||
-===================================================================
|
||||
---- linux.orig/scripts/Makefile.modfinal
|
||||
-+++ linux/scripts/Makefile.modfinal
|
||||
-@@ -29,12 +29,13 @@ quiet_cmd_cc_o_c = CC [M] $@
|
||||
+ scripts/Makefile.modfinal | 6 ++++--
|
||||
+ 1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
+
|
||||
+--- a/scripts/Makefile.modfinal
|
||||
++++ b/scripts/Makefile.modfinal
|
||||
+@@ -33,11 +33,13 @@ quiet_cmd_cc_o_c = CC [M] $@
|
||||
+ $(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
|
||||
- ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
|
||||
+ARCH_MODULE_LDS := $(word 1,$(wildcard scripts/module.lds arch/$(SRCARCH)/module.lds))
|
||||
-
|
||||
++
|
||||
quiet_cmd_ld_ko_o = LD [M] $@
|
||||
- cmd_ld_ko_o += \
|
||||
+ cmd_ld_ko_o = \
|
||||
$(LD) -r $(KBUILD_LDFLAGS) \
|
||||
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
|
||||
-- -T scripts/module.lds -o $@ $(filter %.o, $^); \
|
||||
-+ -T $(ARCH_MODULE_LDS) -o $@ $(filter %.o, $^); \
|
||||
- $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
|
||||
+- -T scripts/module.lds -o $@ $(filter %.o, $^)
|
||||
++ -T $(ARCH_MODULE_LDS) -o $@ $(filter %.o, $^)
|
||||
|
||||
quiet_cmd_btf_ko = BTF [M] $@
|
||||
-@@ -57,7 +58,7 @@ if_changed_except = $(if $(call newer_pr
|
||||
+ cmd_btf_ko = \
|
||||
+@@ -57,7 +59,7 @@ if_changed_except = $(if $(call newer_pr
|
||||
printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
|
||||
|
||||
# Re-generate module BTFs if either module's .ko or vmlinux changed
|
||||
--%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
|
||||
-+%.ko: %.o %.mod.o $(ARCH_MODULE_LDS) $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
|
||||
+-%.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
|
||||
++%.ko: %.o %.mod.o $(extmod_prefix).module-common.o $(ARCH_MODULE_LDS) $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
|
||||
+$(call if_changed_except,ld_ko_o,vmlinux)
|
||||
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
|
||||
+$(if $(newer-prereqs),$(call cmd,btf_ko))
|
||||
diff --git a/debian/patches/debian/kernelvariables.patch b/debian/patches/debian/kernelvariables.patch
|
||||
index 2196c8a435..ef427ab195 100644
|
||||
--- a/debian/patches/debian/kernelvariables.patch
|
||||
+++ b/debian/patches/debian/kernelvariables.patch
|
||||
@@ -17,7 +17,7 @@ use of $(ARCH) needs to be moved after this.
|
||||
---
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
-@@ -395,36 +395,6 @@ include $(srctree)/scripts/subarch.inclu
|
||||
+@@ -406,36 +406,6 @@ include $(srctree)/scripts/subarch.inclu
|
||||
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
|
||||
ARCH ?= $(SUBARCH)
|
||||
|
||||
@@ -54,7 +54,7 @@ use of $(ARCH) needs to be moved after this.
|
||||
KCONFIG_CONFIG ?= .config
|
||||
export KCONFIG_CONFIG
|
||||
|
||||
-@@ -540,6 +510,35 @@ RUSTFLAGS_KERNEL =
|
||||
+@@ -551,6 +521,35 @@ RUSTFLAGS_KERNEL =
|
||||
AFLAGS_KERNEL =
|
||||
LDFLAGS_vmlinux =
|
||||
|
||||
diff --git a/debian/patches/debian/perf-traceevent-support-asciidoctor-for-documentatio.patch b/debian/patches/debian/perf-traceevent-support-asciidoctor-for-documentatio.patch
|
||||
index 3971218b68..a1cbb2c0bd 100644
|
||||
--- a/debian/patches/debian/perf-traceevent-support-asciidoctor-for-documentatio.patch
|
||||
+++ b/debian/patches/debian/perf-traceevent-support-asciidoctor-for-documentatio.patch
|
||||
@@ -6,9 +6,8 @@ Forwarded: not-needed
|
||||
|
||||
---
|
||||
tools/lib/perf/Documentation/Makefile | 2 +-
|
||||
- tools/lib/traceevent/Documentation/Makefile | 2 +-
|
||||
tools/perf/Documentation/Makefile | 2 +-
|
||||
- 3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
+ 2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/lib/perf/Documentation/Makefile b/tools/lib/perf/Documentation/Makefile
|
||||
index 972754082a85..272d06173a3e 100644
|
||||
diff --git a/debian/patches/debian/version.patch b/debian/patches/debian/version.patch
|
||||
index 47fc6c0dce..7093df77ae 100644
|
||||
--- a/debian/patches/debian/version.patch
|
||||
+++ b/debian/patches/debian/version.patch
|
||||
@@ -7,19 +7,16 @@ For distribution binary packages we assume
|
||||
$DISTRIBUTION_OFFICIAL_BUILD, $DISTRIBUTOR and $DISTRIBUTION_VERSION
|
||||
are set.
|
||||
---
|
||||
- Makefile | 15 ++++++++++++++-
|
||||
- arch/ia64/kernel/process.c | 5 +++--
|
||||
+ Makefile | 16 +++++++++++++++-
|
||||
arch/powerpc/kernel/process.c | 6 ++++--
|
||||
arch/x86/um/sysrq_64.c | 6 ++++--
|
||||
kernel/hung_task.c | 6 ++++--
|
||||
- lib/dump_stack.c | 6 ++++--
|
||||
- 6 files changed, 33 insertions(+), 11 deletions(-)
|
||||
+ lib/dump_stack.c | 7 +++++--
|
||||
+ 5 files changed, 32 insertions(+), 9 deletions(-)
|
||||
|
||||
-Index: linux/Makefile
|
||||
-===================================================================
|
||||
---- linux.orig/Makefile
|
||||
-+++ linux/Makefile
|
||||
-@@ -1263,7 +1263,8 @@ PHONY += prepare archprepare
|
||||
+--- a/Makefile
|
||||
++++ b/Makefile
|
||||
+@@ -1196,7 +1196,8 @@ PHONY += prepare archprepare
|
||||
|
||||
archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
|
||||
asm-generic $(version_h) include/generated/utsrelease.h \
|
||||
@@ -29,7 +26,7 @@ Index: linux/Makefile
|
||||
|
||||
prepare0: archprepare
|
||||
$(Q)$(MAKE) $(build)=scripts/mod
|
||||
-@@ -1321,6 +1322,16 @@ define filechk_version.h
|
||||
+@@ -1254,6 +1255,16 @@ define filechk_version.h
|
||||
echo \#define LINUX_VERSION_SUBLEVEL $(SUBLEVEL)
|
||||
endef
|
||||
|
||||
@@ -43,10 +40,10 @@ Index: linux/Makefile
|
||||
+endef
|
||||
+endif
|
||||
+
|
||||
- $(version_h): PATCHLEVEL := $(or $(PATCHLEVEL), 0)
|
||||
- $(version_h): SUBLEVEL := $(or $(SUBLEVEL), 0)
|
||||
+ $(version_h): private PATCHLEVEL := $(or $(PATCHLEVEL), 0)
|
||||
+ $(version_h): private SUBLEVEL := $(or $(SUBLEVEL), 0)
|
||||
$(version_h): FORCE
|
||||
-@@ -1335,6 +1346,9 @@ filechk_compile.h = $(srctree)/scripts/m
|
||||
+@@ -1268,6 +1279,9 @@ filechk_compile.h = $(srctree)/scripts/m
|
||||
include/generated/compile.h: FORCE
|
||||
$(call filechk,compile.h)
|
||||
|
||||
@@ -56,34 +53,8 @@ Index: linux/Makefile
|
||||
PHONY += headerdep
|
||||
headerdep:
|
||||
$(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \
|
||||
-Index: linux/arch/ia64/kernel/process.c
|
||||
-===================================================================
|
||||
---- linux.orig/arch/ia64/kernel/process.c
|
||||
-+++ linux/arch/ia64/kernel/process.c
|
||||
-@@ -35,6 +35,7 @@
|
||||
- #include <linux/utsname.h>
|
||||
- #include <linux/resume_user_mode.h>
|
||||
- #include <linux/rcupdate.h>
|
||||
-+#include <generated/package.h>
|
||||
-
|
||||
- #include <asm/cpu.h>
|
||||
- #include <asm/delay.h>
|
||||
-@@ -102,9 +103,9 @@ show_regs (struct pt_regs *regs)
|
||||
- print_modules();
|
||||
- printk("\n");
|
||||
- show_regs_print_info(KERN_DEFAULT);
|
||||
-- printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
|
||||
-+ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s%s)\n",
|
||||
- regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
|
||||
-- init_utsname()->release);
|
||||
-+ init_utsname()->release, LINUX_PACKAGE_ID);
|
||||
- printk("ip is at %pS\n", (void *)ip);
|
||||
- printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
|
||||
- regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
|
||||
-Index: linux/arch/powerpc/kernel/process.c
|
||||
-===================================================================
|
||||
---- linux.orig/arch/powerpc/kernel/process.c
|
||||
-+++ linux/arch/powerpc/kernel/process.c
|
||||
+--- a/arch/powerpc/kernel/process.c
|
||||
++++ b/arch/powerpc/kernel/process.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/pkeys.h>
|
||||
@@ -92,7 +63,7 @@ Index: linux/arch/powerpc/kernel/process.c
|
||||
|
||||
#include <asm/interrupt.h>
|
||||
#include <asm/io.h>
|
||||
-@@ -1520,8 +1521,9 @@ static void __show_regs(struct pt_regs *
|
||||
+@@ -1560,8 +1561,9 @@ static void __show_regs(struct pt_regs *
|
||||
|
||||
printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
|
||||
regs->nip, regs->link, regs->ctr);
|
||||
@@ -104,18 +75,16 @@ Index: linux/arch/powerpc/kernel/process.c
|
||||
printk("MSR: "REG" ", regs->msr);
|
||||
print_msr_bits(regs->msr);
|
||||
pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
|
||||
-Index: linux/arch/x86/um/sysrq_64.c
|
||||
-===================================================================
|
||||
---- linux.orig/arch/x86/um/sysrq_64.c
|
||||
-+++ linux/arch/x86/um/sysrq_64.c
|
||||
-@@ -9,6 +9,7 @@
|
||||
+--- a/arch/x86/um/sysrq_64.c
|
||||
++++ b/arch/x86/um/sysrq_64.c
|
||||
+@@ -10,6 +10,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/utsname.h>
|
||||
+#include <generated/package.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/ptrace.h>
|
||||
- #include <asm/sysrq.h>
|
||||
+
|
||||
@@ -17,8 +18,9 @@ void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
printk("\n");
|
||||
@@ -128,10 +97,8 @@ Index: linux/arch/x86/um/sysrq_64.c
|
||||
printk(KERN_INFO "RIP: %04lx:%pS\n", PT_REGS_CS(regs) & 0xffff,
|
||||
(void *)PT_REGS_IP(regs));
|
||||
printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs),
|
||||
-Index: linux/kernel/hung_task.c
|
||||
-===================================================================
|
||||
---- linux.orig/kernel/hung_task.c
|
||||
-+++ linux/kernel/hung_task.c
|
||||
+--- a/kernel/hung_task.c
|
||||
++++ b/kernel/hung_task.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/sched/sysctl.h>
|
||||
|
||||
@@ -140,7 +107,7 @@ Index: linux/kernel/hung_task.c
|
||||
|
||||
/*
|
||||
* The number of tasks checked:
|
||||
-@@ -131,10 +132,11 @@ static void check_hung_task(struct task_
|
||||
+@@ -132,10 +133,11 @@ static void check_hung_task(struct task_
|
||||
sysctl_hung_task_warnings--;
|
||||
pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n",
|
||||
t->comm, t->pid, (jiffies - t->last_switch_time) / HZ);
|
||||
@@ -154,10 +121,8 @@ Index: linux/kernel/hung_task.c
|
||||
pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""
|
||||
" disables this message.\n");
|
||||
sched_show_task(t);
|
||||
-Index: linux/lib/dump_stack.c
|
||||
-===================================================================
|
||||
---- linux.orig/lib/dump_stack.c
|
||||
-+++ linux/lib/dump_stack.c
|
||||
+--- a/lib/dump_stack.c
|
||||
++++ b/lib/dump_stack.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/utsname.h>
|
||||
@@ -166,14 +131,16 @@ Index: linux/lib/dump_stack.c
|
||||
|
||||
static char dump_stack_arch_desc_str[128];
|
||||
|
||||
-@@ -54,13 +55,15 @@ void __init dump_stack_set_arch_desc(con
|
||||
+@@ -54,7 +55,7 @@ void __init dump_stack_set_arch_desc(con
|
||||
*/
|
||||
void dump_stack_print_info(const char *log_lvl)
|
||||
{
|
||||
-- printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s" BUILD_ID_FMT "\n",
|
||||
-+ printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s %s" BUILD_ID_FMT "\n",
|
||||
- log_lvl, raw_smp_processor_id(), current->pid, current->comm,
|
||||
- kexec_crash_loaded() ? "Kdump: loaded " : "",
|
||||
+- printk("%sCPU: %d UID: %u PID: %d Comm: %.20s %s%s %s %.*s" BUILD_ID_FMT "\n",
|
||||
++ printk("%sCPU: %d UID: %u PID: %d Comm: %.20s %s%s %s %.*s %s" BUILD_ID_FMT "\n",
|
||||
+ log_lvl, raw_smp_processor_id(),
|
||||
+ __kuid_val(current_real_cred()->euid),
|
||||
+ current->pid, current->comm,
|
||||
+@@ -62,7 +63,9 @@ void dump_stack_print_info(const char *l
|
||||
print_tainted(),
|
||||
init_utsname()->release,
|
||||
(int)strcspn(init_utsname()->version, " "),
|
||||
@@ -182,5 +149,5 @@ Index: linux/lib/dump_stack.c
|
||||
+ LINUX_PACKAGE_ID,
|
||||
+ BUILD_ID_VAL);
|
||||
|
||||
- if (dump_stack_arch_desc_str[0] != '\0')
|
||||
- printk("%sHardware name: %s\n",
|
||||
+ if (get_taint())
|
||||
+ printk("%s%s\n", log_lvl, print_tainted_verbose());
|
||||
diff --git a/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch
|
||||
index 6a8940da52..822beab21c 100644
|
||||
--- a/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch
|
||||
+++ b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch
|
||||
@@ -31,7 +31,7 @@ cc: linux-efi@vger.kernel.org
|
||||
|
||||
--- a/arch/x86/kernel/setup.c
|
||||
+++ b/arch/x86/kernel/setup.c
|
||||
-@@ -1205,19 +1205,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
+@@ -1193,19 +1193,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
/* Allocate bigger log buffer */
|
||||
setup_log_buf(1);
|
||||
|
||||
@@ -54,7 +54,7 @@ cc: linux-efi@vger.kernel.org
|
||||
|
||||
--- a/drivers/firmware/efi/Makefile
|
||||
+++ b/drivers/firmware/efi/Makefile
|
||||
-@@ -27,6 +27,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m
|
||||
+@@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m
|
||||
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
|
||||
obj-$(CONFIG_EFI_TEST) += test/
|
||||
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
|
||||
@@ -106,7 +106,7 @@ cc: linux-efi@vger.kernel.org
|
||||
+}
|
||||
--- a/include/linux/efi.h
|
||||
+++ b/include/linux/efi.h
|
||||
-@@ -849,6 +849,14 @@ extern int __init efi_setup_pcdp_console
|
||||
+@@ -871,6 +871,14 @@ extern int __init efi_setup_pcdp_console
|
||||
#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
|
||||
#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */
|
||||
#define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */
|
||||
@@ -121,7 +121,7 @@ cc: linux-efi@vger.kernel.org
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
/*
|
||||
-@@ -873,6 +881,7 @@ static inline bool efi_rt_services_suppo
|
||||
+@@ -895,6 +903,7 @@ static inline bool efi_rt_services_suppo
|
||||
return (efi.runtime_supported_mask & mask) == mask;
|
||||
}
|
||||
extern void efi_find_mirror(void);
|
||||
@@ -129,7 +129,7 @@ cc: linux-efi@vger.kernel.org
|
||||
#else
|
||||
static inline bool efi_enabled(int feature)
|
||||
{
|
||||
-@@ -892,6 +901,7 @@ static inline bool efi_rt_services_suppo
|
||||
+@@ -914,6 +923,7 @@ static inline bool efi_rt_services_suppo
|
||||
}
|
||||
|
||||
static inline void efi_find_mirror(void) {}
|
||||
@@ -137,7 +137,7 @@ cc: linux-efi@vger.kernel.org
|
||||
#endif
|
||||
|
||||
extern int efi_status_to_err(efi_status_t status);
|
||||
-@@ -1107,13 +1117,6 @@ static inline bool efi_runtime_disabled(
|
||||
+@@ -1133,13 +1143,6 @@ static inline bool efi_runtime_disabled(
|
||||
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
|
||||
extern unsigned long efi_call_virt_save_flags(void);
|
||||
|
||||
diff --git a/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
|
||||
index 0ab4db9957..6fff3f8967 100644
|
||||
--- a/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
|
||||
+++ b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
|
||||
@@ -13,22 +13,20 @@ description:
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the
|
||||
-help text for LOCK_DOWN_IN_EFI_SECURE_BOOT needs to be adjusted to
|
||||
-mention that lockdown is triggered in integrity mode]
|
||||
+help text for LOCK_DOWN_IN_EFI_SECURE_BOOT was adjusted to mention that
|
||||
+lockdown is triggered in integrity mode (https://bugs.debian.org/1025417)]
|
||||
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
|
||||
---
|
||||
- arch/x86/kernel/setup.c | 4 ++--
|
||||
- drivers/firmware/efi/secureboot.c | 5 +++++
|
||||
- include/linux/security.h | 6 ++++++
|
||||
- security/lockdown/Kconfig | 15 +++++++++++++++
|
||||
- security/lockdown/lockdown.c | 2 +-
|
||||
- 5 files changed, 29 insertions(+), 3 deletions(-)
|
||||
+ arch/x86/kernel/setup.c | 4 ++--
|
||||
+ drivers/firmware/efi/secureboot.c | 3 +++
|
||||
+ include/linux/security.h | 6 ++++++
|
||||
+ security/lockdown/Kconfig | 15 +++++++++++++++
|
||||
+ security/lockdown/lockdown.c | 2 +-
|
||||
+ 5 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
-Index: debian-kernel/arch/x86/kernel/setup.c
|
||||
-===================================================================
|
||||
---- debian-kernel.orig/arch/x86/kernel/setup.c
|
||||
-+++ debian-kernel/arch/x86/kernel/setup.c
|
||||
-@@ -1028,6 +1028,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
+--- a/arch/x86/kernel/setup.c
|
||||
++++ b/arch/x86/kernel/setup.c
|
||||
+@@ -904,6 +904,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
if (efi_enabled(EFI_BOOT))
|
||||
efi_init();
|
||||
|
||||
@@ -37,7 +35,7 @@ Index: debian-kernel/arch/x86/kernel/setup.c
|
||||
reserve_ibft_region();
|
||||
x86_init.resources.dmi_setup();
|
||||
|
||||
-@@ -1190,8 +1192,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
+@@ -1070,8 +1072,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
/* Allocate bigger log buffer */
|
||||
setup_log_buf(1);
|
||||
|
||||
@@ -46,10 +44,8 @@ Index: debian-kernel/arch/x86/kernel/setup.c
|
||||
reserve_initrd();
|
||||
|
||||
acpi_table_upgrade();
|
||||
-Index: debian-kernel/drivers/firmware/efi/secureboot.c
|
||||
-===================================================================
|
||||
---- debian-kernel.orig/drivers/firmware/efi/secureboot.c
|
||||
-+++ debian-kernel/drivers/firmware/efi/secureboot.c
|
||||
+--- a/drivers/firmware/efi/secureboot.c
|
||||
++++ b/drivers/firmware/efi/secureboot.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/efi.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -69,19 +65,17 @@ Index: debian-kernel/drivers/firmware/efi/secureboot.c
|
||||
pr_info("Secure boot enabled\n");
|
||||
break;
|
||||
default:
|
||||
-Index: debian-kernel/include/linux/security.h
|
||||
-===================================================================
|
||||
---- debian-kernel.orig/include/linux/security.h
|
||||
-+++ debian-kernel/include/linux/security.h
|
||||
-@@ -486,6 +486,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
|
||||
+--- a/include/linux/security.h
|
||||
++++ b/include/linux/security.h
|
||||
+@@ -522,6 +522,7 @@ int security_inode_notifysecctx(struct i
|
||||
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
|
||||
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
|
||||
int security_locked_down(enum lockdown_reason what);
|
||||
+int lock_kernel_down(const char *where, enum lockdown_reason level);
|
||||
- #else /* CONFIG_SECURITY */
|
||||
-
|
||||
- static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
|
||||
-@@ -1404,6 +1405,11 @@ static inline int security_locked_down(enum lockdown_reason what)
|
||||
+ int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
|
||||
+ void *val, size_t val_len, u64 id, u64 flags);
|
||||
+ int security_bdev_alloc(struct block_device *bdev);
|
||||
+@@ -1504,6 +1505,11 @@ static inline int security_locked_down(e
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -90,13 +84,11 @@ Index: debian-kernel/include/linux/security.h
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
- #endif /* CONFIG_SECURITY */
|
||||
-
|
||||
- #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
|
||||
-Index: debian-kernel/security/lockdown/Kconfig
|
||||
-===================================================================
|
||||
---- debian-kernel.orig/security/lockdown/Kconfig
|
||||
-+++ debian-kernel/security/lockdown/Kconfig
|
||||
+ static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
|
||||
+ u32 *uctx_len, void *val, size_t val_len,
|
||||
+ u64 id, u64 flags)
|
||||
+--- a/security/lockdown/Kconfig
|
||||
++++ b/security/lockdown/Kconfig
|
||||
@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTI
|
||||
disabled.
|
||||
|
||||
@@ -116,11 +108,9 @@ Index: debian-kernel/security/lockdown/Kconfig
|
||||
+
|
||||
+ Enabling this option results in kernel lockdown being
|
||||
+ triggered in integrity mode if EFI Secure Boot is set.
|
||||
-Index: debian-kernel/security/lockdown/lockdown.c
|
||||
-===================================================================
|
||||
---- debian-kernel.orig/security/lockdown/lockdown.c
|
||||
-+++ debian-kernel/security/lockdown/lockdown.c
|
||||
-@@ -23,7 +23,7 @@ static const enum lockdown_reason lockdo
|
||||
+--- a/security/lockdown/lockdown.c
|
||||
++++ b/security/lockdown/lockdown.c
|
||||
+@@ -24,7 +24,7 @@ static const enum lockdown_reason lockdo
|
||||
/*
|
||||
* Put the kernel into lock-down mode.
|
||||
*/
|
||||
@@ -129,6 +119,3 @@ Index: debian-kernel/security/lockdown/lockdown.c
|
||||
{
|
||||
if (kernel_locked_down >= level)
|
||||
return -EPERM;
|
||||
---
|
||||
-2.43.0
|
||||
-
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 7002ca5a870f7deb4e40fda2d2f8834b2af16176 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Mon, 5 Aug 2024 04:30:36 +0200
|
||||
Subject: [PATCH 14/20] d/rules.real: Unset KBUILD_HOSTCFLAGS etc. instead of
|
||||
overriding to be empty
|
||||
|
||||
The upstream Makefile tries to add some flags to KBUILD_HOSTCFLAGS,
|
||||
and now fails to build anything if we override it to be empty:
|
||||
|
||||
.../scripts/kconfig/util.c:11:10: fatal error: hashtable.h: No such file or directory
|
||||
11 | #include <hashtable.h>
|
||||
| ^~~~~~~~~~~~~
|
||||
compilation terminated.
|
||||
|
||||
Instead of overriding these flags variables to be empty, unset them in
|
||||
the environment.
|
||||
|
||||
(cherry picked from commit f77deecbb5d46f1f5034f348952152b0c2d584f7)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/rules.real | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/debian/rules.real b/debian/rules.real
|
||||
index 19b3d7d..00f2a33 100644
|
||||
--- a/debian/rules.real
|
||||
+++ b/debian/rules.real
|
||||
@@ -42,10 +42,12 @@ undefine LANGUAGE
|
||||
stamp = [ -d $(dir $@) ] || mkdir $(dir $@); touch $@
|
||||
|
||||
setup_env := env -u ABINAME -u ARCH -u FEATURESET -u FLAVOUR -u VERSION -u LOCALVERSION
|
||||
+# XXX: All the tools leak flags between host and build all the time, just don't care. See #1050991.
|
||||
+setup_env += -u KBUILD_HOSTCFLAGS -u HOSTCFLAGS -u KBUILD_HOSTLDFLAGS
|
||||
setup_env += DISTRIBUTION_OFFICIAL_BUILD=1 DISTRIBUTOR="$(DISTRIBUTOR)" DISTRIBUTION_VERSION="$(SOURCEVERSION)" KBUILD_BUILD_TIMESTAMP="$(SOURCE_DATE)" KBUILD_BUILD_VERSION_TIMESTAMP="StarlingX $(DISTRIBUTOR) $(SOURCEVERSION) ($(SOURCE_DATE_UTC_ISO))"
|
||||
setup_env += KBUILD_VERBOSE=$(if $(filter terse,$(DEB_BUILD_OPTIONS)),0,1)
|
||||
|
||||
-MAKE_CLEAN = $(setup_env) $(MAKE) KCFLAGS=-fdebug-prefix-map=$(CURDIR)/= KBUILD_HOSTCFLAGS='$(CFLAGS) $(CPPFLAGS)' HOSTCFLAGS='$(CFLAGS) $(CPPFLAGS)' KBUILD_HOSTLDFLAGS='$(LDFLAGS)'
|
||||
+MAKE_CLEAN = $(setup_env) $(MAKE) KCFLAGS=-fdebug-prefix-map=$(CURDIR)/=
|
||||
MAKE_SELF := $(MAKE) -f debian/rules.real $(MAKEOVERRIDES)
|
||||
MAKEOVERRIDES =
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,31 @@
|
||||
From b0947b6fad8cd0774a3709c721a6cfc7c71fb957 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Mon, 5 Aug 2024 04:40:27 +0200
|
||||
Subject: [PATCH 15/20] d/rules.d/Makefile.inc: Add scripts/include to header
|
||||
include path
|
||||
|
||||
In 6.11 some headers used by user-space tools have been moved under
|
||||
scripts/include, and the upstream Makefile now adds scripts/include to
|
||||
the header include path for these tools. We need to do the same.
|
||||
|
||||
(cherry picked from commit 0d0d62b7d1cc23f87e921629ca51d2989392d8fb)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/rules.d/Makefile.inc | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/debian/rules.d/Makefile.inc b/debian/rules.d/Makefile.inc
|
||||
index 55eae14..386217b 100644
|
||||
--- a/debian/rules.d/Makefile.inc
|
||||
+++ b/debian/rules.d/Makefile.inc
|
||||
@@ -12,6 +12,7 @@ CFLAGS := $(shell dpkg-buildflags --get CFLAGS) -Wall
|
||||
CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS) \
|
||||
-I$(top_srcdir)/$(OUTDIR) \
|
||||
-I$(top_srcdir)/debian/build/build-tools/$(OUTDIR) \
|
||||
+ -I$(top_srcdir)/scripts/include \
|
||||
-isystem $(top_srcdir)/debian/build/build-tools/include
|
||||
CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) -Wall
|
||||
LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS)
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 97e8ebe05e2b4572a39954ad64101bedb062228e Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Sat, 6 Jul 2024 06:32:05 +0200
|
||||
Subject: [PATCH 16/20] linux-cpupower: Update turbostat Makefile to define
|
||||
BUILD_BUG_HEADER
|
||||
|
||||
turbostat continues to abuse headers not meant for-user-space, now
|
||||
including <linux/build_bug.h>. Define the necessary macro so it can
|
||||
find that.
|
||||
|
||||
(cherry picked from commit 4ad01663251dc89c2290aa29aef5917b4c9f1cb9)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/rules.d/tools/power/x86/turbostat/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/debian/rules.d/tools/power/x86/turbostat/Makefile b/debian/rules.d/tools/power/x86/turbostat/Makefile
|
||||
index eb5124d..9f5275c 100644
|
||||
--- a/debian/rules.d/tools/power/x86/turbostat/Makefile
|
||||
+++ b/debian/rules.d/tools/power/x86/turbostat/Makefile
|
||||
@@ -4,6 +4,6 @@ installdir = /usr/sbin
|
||||
|
||||
include $(top_rulesdir)/Makefile.inc
|
||||
|
||||
-CPPFLAGS += -I"$(top_srcdir)/tools/include" -DMSRHEADER='"$(top_srcdir)/arch/x86/include/asm/msr-index.h"' -DINTEL_FAMILY_HEADER='"$(top_srcdir)/arch/x86/include/asm/intel-family.h"'
|
||||
+CPPFLAGS += -I"$(top_srcdir)/tools/include" -DMSRHEADER='"$(top_srcdir)/arch/x86/include/asm/msr-index.h"' -DINTEL_FAMILY_HEADER='"$(top_srcdir)/arch/x86/include/asm/intel-family.h"' -DBUILD_BUG_HEADER='"$(top_srcdir)/include/linux/build_bug.h"'
|
||||
|
||||
LDLIBS += -lcap -lrt
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,252 @@
|
||||
From 6e811f58e0ba18b827893b56f10d30632fca72de Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Sat, 6 Jul 2024 06:28:03 +0200
|
||||
Subject: [PATCH 17/20] hyperv-daemons: Update for upstream removal of
|
||||
hv_fcopy_daemon
|
||||
|
||||
- Don't try to build it.
|
||||
- Remove the init script, service file, and udev rule.
|
||||
- Use dpkg-maintscript rm_conffile to remove the init script on
|
||||
upgrade.
|
||||
- In preinst, stop the service only if upgrading from an older
|
||||
version. In postinst do nothing with it.
|
||||
- Remove it from the package description.
|
||||
|
||||
(cherry picked from commit fced95b415be4c1fbeec29e02a667168f00ee8e4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/hyperv-daemons.hv-fcopy-daemon.init | 109 ------------------
|
||||
debian/hyperv-daemons.hv-fcopy-daemon.service | 10 --
|
||||
debian/hyperv-daemons.maintscript | 1 +
|
||||
debian/hyperv-daemons.postinst | 2 +-
|
||||
debian/hyperv-daemons.preinst | 6 +-
|
||||
debian/hyperv-daemons.udev | 1 -
|
||||
debian/rules.d/tools/hv/Makefile | 1 -
|
||||
debian/rules.real | 2 +-
|
||||
debian/templates/tools-unversioned.control.in | 5 +-
|
||||
9 files changed, 9 insertions(+), 128 deletions(-)
|
||||
delete mode 100644 debian/hyperv-daemons.hv-fcopy-daemon.init
|
||||
delete mode 100644 debian/hyperv-daemons.hv-fcopy-daemon.service
|
||||
|
||||
diff --git a/debian/hyperv-daemons.hv-fcopy-daemon.init b/debian/hyperv-daemons.hv-fcopy-daemon.init
|
||||
deleted file mode 100644
|
||||
index 5866dc6..0000000
|
||||
--- a/debian/hyperv-daemons.hv-fcopy-daemon.init
|
||||
+++ /dev/null
|
||||
@@ -1,109 +0,0 @@
|
||||
-#! /bin/sh
|
||||
-### BEGIN INIT INFO
|
||||
-# Provides: hv-fcopy-daemon
|
||||
-# Required-Start: $remote_fs $syslog
|
||||
-# Required-Stop: $remote_fs $syslog
|
||||
-# Default-Start: 2 3 4 5
|
||||
-# Default-Stop: 0 1 6
|
||||
-# Short-Description: Hyper-V file copy service (FCOPY) daemon
|
||||
-### END INIT INFO
|
||||
-
|
||||
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
-DESC="Hyper-V file copy service (FCOPY) daemon"
|
||||
-NAME=hv_fcopy_daemon
|
||||
-DAEMON=/usr/sbin/$NAME
|
||||
-PIDFILE=/run/$NAME.pid
|
||||
-SCRIPTNAME=/etc/init.d/hv-fcopy-daemon
|
||||
-
|
||||
-# Exit if the package is not installed
|
||||
-[ -x "$DAEMON" ] || exit 0
|
||||
-
|
||||
-# Exit if the kernel device does not exist
|
||||
-[ -e "/dev/vmbus/hv_fcopy" ] || exit 0
|
||||
-
|
||||
-# Load the VERBOSE setting and other rcS variables
|
||||
-. /lib/init/vars.sh
|
||||
-
|
||||
-# Define LSB log_* functions.
|
||||
-. /lib/lsb/init-functions
|
||||
-
|
||||
-#
|
||||
-# Function that starts the daemon/service
|
||||
-#
|
||||
-do_start()
|
||||
-{
|
||||
- # Return
|
||||
- # 0 if daemon has been started
|
||||
- # 1 if daemon was already running
|
||||
- # 2 if daemon could not be started
|
||||
- start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
- || return 1
|
||||
- start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background --make-pidfile -- -n \
|
||||
- || return 2
|
||||
-}
|
||||
-
|
||||
-#
|
||||
-# Function that stops the daemon/service
|
||||
-#
|
||||
-do_stop()
|
||||
-{
|
||||
- # Return
|
||||
- # 0 if daemon has been stopped
|
||||
- # 1 if daemon was already stopped
|
||||
- # 2 if daemon could not be stopped
|
||||
- # other if a failure occurred
|
||||
- start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
|
||||
- [ "$?" = 2 ] && return 2
|
||||
- start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
- RETVAL=$?
|
||||
- [ "$RETVAL" = 2 ] && return 2
|
||||
- # Many daemons don't delete their pidfiles when they exit.
|
||||
- rm -f $PIDFILE
|
||||
- return "$RETVAL"
|
||||
-}
|
||||
-
|
||||
-case "$1" in
|
||||
- start)
|
||||
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
- do_start
|
||||
- case "$?" in
|
||||
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
- esac
|
||||
- ;;
|
||||
- stop)
|
||||
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
- do_stop
|
||||
- case "$?" in
|
||||
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
- esac
|
||||
- ;;
|
||||
- status)
|
||||
- status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME"
|
||||
- ;;
|
||||
- restart|force-reload)
|
||||
- log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
- do_stop
|
||||
- case "$?" in
|
||||
- 0|1)
|
||||
- do_start
|
||||
- case "$?" in
|
||||
- 0) log_end_msg 0 ;;
|
||||
- 1) log_end_msg 1 ;; # Old process is still running
|
||||
- *) log_end_msg 1 ;; # Failed to start
|
||||
- esac
|
||||
- ;;
|
||||
- *)
|
||||
- # Failed to stop
|
||||
- log_end_msg 1
|
||||
- ;;
|
||||
- esac
|
||||
- ;;
|
||||
- *)
|
||||
- echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
- exit 3
|
||||
- ;;
|
||||
-esac
|
||||
-
|
||||
-:
|
||||
diff --git a/debian/hyperv-daemons.hv-fcopy-daemon.service b/debian/hyperv-daemons.hv-fcopy-daemon.service
|
||||
deleted file mode 100644
|
||||
index d8e4d3b..0000000
|
||||
--- a/debian/hyperv-daemons.hv-fcopy-daemon.service
|
||||
+++ /dev/null
|
||||
@@ -1,10 +0,0 @@
|
||||
-[Unit]
|
||||
-Description=Hyper-V file copy service (FCOPY) daemon
|
||||
-Conflicts=hyperv-daemons.hv-fcopy-daemon.service
|
||||
-BindsTo=sys-devices-virtual-misc-vmbus\x21hv_fcopy.device
|
||||
-
|
||||
-[Service]
|
||||
-ExecStart=/usr/sbin/hv_fcopy_daemon -n
|
||||
-
|
||||
-[Install]
|
||||
-WantedBy=multi-user.target
|
||||
diff --git a/debian/hyperv-daemons.maintscript b/debian/hyperv-daemons.maintscript
|
||||
index a2f28e4..96ed55f 100644
|
||||
--- a/debian/hyperv-daemons.maintscript
|
||||
+++ b/debian/hyperv-daemons.maintscript
|
||||
@@ -1,3 +1,4 @@
|
||||
mv_conffile /etc/init.d/hyperv-daemons.hv-fcopy-daemon /etc/init.d/hv-fcopy-daemon 5.8~rc7-1~exp1
|
||||
+rm_conffile /etc/init.d/hv-fcopy-daemon 6.10~rc6-1~exp1
|
||||
mv_conffile /etc/init.d/hyperv-daemons.hv-kvp-daemon /etc/init.d/hv-kvp-daemon 5.8~rc7-1~exp1
|
||||
mv_conffile /etc/init.d/hyperv-daemons.hv-vss-daemon /etc/init.d/hv-vss-daemon 5.8~rc7-1~exp1
|
||||
diff --git a/debian/hyperv-daemons.postinst b/debian/hyperv-daemons.postinst
|
||||
index 3573c9c..9bee3f6 100644
|
||||
--- a/debian/hyperv-daemons.postinst
|
||||
+++ b/debian/hyperv-daemons.postinst
|
||||
@@ -8,7 +8,7 @@ if [ "$1" = "configure" ]; then
|
||||
udevadm trigger || true
|
||||
else
|
||||
# On upgrade make sure running daemons are restarted
|
||||
- systemctl try-restart hv-fcopy-daemon.service hv-kvp-daemon.service hv-vss-daemon.service
|
||||
+ systemctl try-restart hv-kvp-daemon.service hv-vss-daemon.service
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
diff --git a/debian/hyperv-daemons.preinst b/debian/hyperv-daemons.preinst
|
||||
index 5810d29..fc13e51 100644
|
||||
--- a/debian/hyperv-daemons.preinst
|
||||
+++ b/debian/hyperv-daemons.preinst
|
||||
@@ -2,7 +2,11 @@
|
||||
set -e
|
||||
|
||||
if [ "$1" = "upgrade" ]; then
|
||||
- for i in fcopy kvp vss; do
|
||||
+ services='kvp vss'
|
||||
+ if dpkg --compare-versions "$2" lt 6.10~rc6-1~exp1; then
|
||||
+ services="fcopy $services"
|
||||
+ fi
|
||||
+ for i in $services; do
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl stop hyperv-daemons.hv-$i-daemon.service 2>/dev/null || true
|
||||
fi
|
||||
diff --git a/debian/hyperv-daemons.udev b/debian/hyperv-daemons.udev
|
||||
index 1daacac..60e9102 100644
|
||||
--- a/debian/hyperv-daemons.udev
|
||||
+++ b/debian/hyperv-daemons.udev
|
||||
@@ -1,3 +1,2 @@
|
||||
-KERNEL=="vmbus/hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-fcopy-daemon.service"
|
||||
KERNEL=="vmbus/hv_kvp", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-kvp-daemon.service"
|
||||
KERNEL=="vmbus/hv_vss", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-vss-daemon.service"
|
||||
diff --git a/debian/rules.d/tools/hv/Makefile b/debian/rules.d/tools/hv/Makefile
|
||||
index 5f00f55..8e4c305 100644
|
||||
--- a/debian/rules.d/tools/hv/Makefile
|
||||
+++ b/debian/rules.d/tools/hv/Makefile
|
||||
@@ -6,7 +6,6 @@ include $(top_rulesdir)/Makefile.inc
|
||||
else
|
||||
|
||||
PROGS = \
|
||||
- hv_fcopy_daemon \
|
||||
hv_kvp_daemon \
|
||||
hv_vss_daemon
|
||||
|
||||
diff --git a/debian/rules.real b/debian/rules.real
|
||||
index 00f2a33..0e681da 100644
|
||||
--- a/debian/rules.real
|
||||
+++ b/debian/rules.real
|
||||
@@ -714,7 +714,7 @@ binary_hyperv-daemons: build_hyperv-daemons
|
||||
ifeq (,$(filter nodoc,$(DEB_BUILD_PROFILES)))
|
||||
dh_installdocs
|
||||
endif
|
||||
- for service in fcopy kvp vss; do \
|
||||
+ for service in kvp vss; do \
|
||||
dh_installsystemd --name hv-$$service-daemon --no-enable --no-start \
|
||||
|| break; \
|
||||
dh_installinit --name hv-$$service-daemon \
|
||||
diff --git a/debian/templates/tools-unversioned.control.in b/debian/templates/tools-unversioned.control.in
|
||||
index e899567..b4ff16f 100644
|
||||
--- a/debian/templates/tools-unversioned.control.in
|
||||
+++ b/debian/templates/tools-unversioned.control.in
|
||||
@@ -124,10 +124,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Section: admin
|
||||
Description: Support daemons for Linux running on Hyper-V
|
||||
Suite of daemons for Linux guests running on Hyper-V, consisting of
|
||||
- hv_fcopy_daemon, hv_kvp_daemon and hv_vss_daemon.
|
||||
- .
|
||||
- hv_fcopy_daemon provides the file copy service, allowing the host to
|
||||
- copy files into the guest.
|
||||
+ hv_kvp_daemon and hv_vss_daemon.
|
||||
.
|
||||
hv_kvp_daemon provides the key-value pair (KVP) service, allowing the
|
||||
host to get and set the IP networking configuration of the guest.
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From cefab4ea0b88f7fd09881ba5f297fa51f75fb812 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Mon, 7 Oct 2024 16:45:27 +0200
|
||||
Subject: [PATCH 18/20] d/rules.d/certs: Add newly required include directory
|
||||
to CPPFLAGS
|
||||
|
||||
(cherry picked from commit 3a17dcbfe0be6bf2b8f5e79692decb8fe26153b3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/rules.d/certs/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/debian/rules.d/certs/Makefile b/debian/rules.d/certs/Makefile
|
||||
index 7ff7bae..12f01ef 100644
|
||||
--- a/debian/rules.d/certs/Makefile
|
||||
+++ b/debian/rules.d/certs/Makefile
|
||||
@@ -3,5 +3,5 @@ PROGS = \
|
||||
|
||||
include $(top_rulesdir)/Makefile.inc
|
||||
|
||||
-CPPFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
+CPPFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I$(top_srcdir)/scripts
|
||||
extract-cert: LDLIBS += -lcrypto
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 8158acbc7b23f4b4ce6fa302504fa4c6590a794d Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Mon, 3 Oct 2022 03:06:12 +0200
|
||||
Subject: [PATCH 19/20] Disable building rtla, since bullseye's libtraceevent
|
||||
and libtracefs are too old
|
||||
|
||||
The build-dependencies for rtla aren't currently versioned, but the
|
||||
upstream Makefile checks for libtraceevent >= 1.5 and libtracefs >=
|
||||
1.3 which are not satisfiable in bullseye. For now, disable building
|
||||
rtla. This can be reverted if newer versions of those libraries are
|
||||
added to bullseye-backports.
|
||||
|
||||
See discussion at merge request kernel-team/linux!539.
|
||||
|
||||
(cherry picked from commit 15b6859742d404abdcd68bcb589f8a8e2dfb6ce4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/templates/tools-unversioned.control.in | 24 +++++++++----------
|
||||
1 file changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/debian/templates/tools-unversioned.control.in b/debian/templates/tools-unversioned.control.in
|
||||
index b4ff16f..72cac03 100644
|
||||
--- a/debian/templates/tools-unversioned.control.in
|
||||
+++ b/debian/templates/tools-unversioned.control.in
|
||||
@@ -133,15 +133,15 @@ Description: Support daemons for Linux running on Hyper-V
|
||||
hv_vss_daemon provides the volume shadow copy service (VSS), allowing
|
||||
the host to freeze the guest filesystems while taking a snapshot.
|
||||
|
||||
-Package: rtla
|
||||
-Meta-Rules-Target: rtla
|
||||
-Build-Profiles: <!stage1 !pkg.linux.notools>
|
||||
-Architecture: amd64 arm64 armhf i386 x32
|
||||
-Build-Depends: libtracefs-dev (>= 1.3), libtraceevent-dev (>= 1:1.5), python3-docutils
|
||||
-Depends: ${shlibs:Depends}
|
||||
-Section: devel
|
||||
-Description: Real-Time Linux Analysis tools
|
||||
- rtla provides a set of commands for analysing the real-time
|
||||
- properties of Linux. rtla uses kernel tracing capabilities to
|
||||
- provide precise information about the properties and root causes of
|
||||
- unexpected results.
|
||||
+#Package: rtla
|
||||
+#Meta-Rules-Target: rtla
|
||||
+#Build-Profiles: <!stage1 !pkg.linux.notools>
|
||||
+#Architecture: amd64 arm64 armhf i386 x32
|
||||
+#Build-Depends: libtracefs-dev (>= 1.3), libtraceevent-dev (>= 1:1.5), python3-docutils
|
||||
+#Depends: ${shlibs:Depends}
|
||||
+#Section: devel
|
||||
+#Description: Real-Time Linux Analysis tools
|
||||
+# rtla provides a set of commands for analysing the real-time
|
||||
+# properties of Linux. rtla uses kernel tracing capabilities to
|
||||
+# provide precise information about the properties and root causes of
|
||||
+# unexpected results.
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From ebfc1ceafd46d2d1e96e95cfd89078ba1812ce54 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Tue, 18 Mar 2025 05:48:02 +0000
|
||||
Subject: [PATCH 20/20] Drop all ia64 configs due to upstream dropping IA64
|
||||
arch
|
||||
|
||||
In upstream commit cf8e8658100d4eae80ce9b21f7a81cb024dd5057 the whole
|
||||
IA64 architecture was dropped, so remove Debian's configuration files
|
||||
wrt IA64 as well.
|
||||
|
||||
(cherry picked from commit b4b93560d441770b1bfe2429d17ac5bbde17f237)
|
||||
[jm: Remove ia64 in debian/config/defines.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/config/defines | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/debian/config/defines b/debian/config/defines
|
||||
index f1ca81b..ef01dc9 100644
|
||||
--- a/debian/config/defines
|
||||
+++ b/debian/config/defines
|
||||
@@ -117,7 +117,6 @@ arches:
|
||||
armhf
|
||||
hppa
|
||||
i386
|
||||
- ia64
|
||||
m68k
|
||||
mips
|
||||
mips64
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,34 @@
|
||||
From f2ba48fc0e28bdba0f80473f960763a4cdac1708 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <benh@debian.org>
|
||||
Date: Sat, 16 Nov 2024 23:50:11 +0100
|
||||
Subject: [PATCH] linux-kbuild: Add scripts/module-common.c (Closes: #1087495)
|
||||
|
||||
Since upstream commit fdf94e4403ec "kbuild: compile constant module
|
||||
information only once", some module information is compiled from
|
||||
scripts/module-common.c and this needs to be available to out-of-tree
|
||||
module builds.
|
||||
|
||||
This was previously not noticed due to the accidentally disabled
|
||||
headers-kbuild tests.
|
||||
|
||||
(cherry picked from commit b93faa99519d9788617b7d73f8334190e53442a3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
debian/rules.d/scripts/Makefile | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/debian/rules.d/scripts/Makefile b/debian/rules.d/scripts/Makefile
|
||||
index c913e25e9c..a858eeb17e 100644
|
||||
--- a/debian/rules.d/scripts/Makefile
|
||||
+++ b/debian/rules.d/scripts/Makefile
|
||||
@@ -8,6 +8,7 @@ DATA = \
|
||||
Kbuild.include \
|
||||
Makefile.* \
|
||||
mkversion \
|
||||
+ module-common.c \
|
||||
module-common.lds \
|
||||
subarch.include
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
@ -11,3 +11,12 @@
|
||||
0011-Update-the-patch-for-kernel-6.6.40.patch
|
||||
0012-mod-fix-the-undefined-errors.patch
|
||||
0013-build-size.patch
|
||||
0014-Correct-the-patches-for-the-linux-kernel-6.12.x.patch
|
||||
0015-d-rules.real-Unset-KBUILD_HOSTCFLAGS-etc.-instead-of.patch
|
||||
0016-d-rules.d-Makefile.inc-Add-scripts-include-to-header.patch
|
||||
0017-linux-cpupower-Update-turbostat-Makefile-to-define-B.patch
|
||||
0018-hyperv-daemons-Update-for-upstream-removal-of-hv_fco.patch
|
||||
0019-d-rules.d-certs-Add-newly-required-include-directory.patch
|
||||
0020-Disable-building-rtla-since-bullseye-s-libtraceevent.patch
|
||||
0021-Drop-all-ia64-configs-due-to-upstream-dropping-IA64-.patch
|
||||
0022-linux-kbuild-Add-scripts-module-common.c-Closes-1087.patch
|
||||
|
@ -24,7 +24,7 @@
|
||||
# building.
|
||||
# Tools needed: tar/sed
|
||||
|
||||
KERNEL_HEAD_COMMIT=94762e4ed9eafc254a5522cf9107e2f450f79dc8
|
||||
KERNEL_HEAD_COMMIT=7c2d49c69f3f7e59a598fa8f618b37836fd56404
|
||||
DEBIAN_FILE=linux_6.1.27-1~bpo11%2B1.debian.tar.xz
|
||||
|
||||
tar xvf linux-yocto-${KERNEL_HEAD_COMMIT}.tar.gz
|
||||
|
@ -1,14 +1,14 @@
|
||||
---
|
||||
debver: 6.6.71
|
||||
debver: 6.12.18
|
||||
debname: linux-rt
|
||||
dl_hook: dl_hook
|
||||
dl_files:
|
||||
linux-yocto-94762e4ed9eafc254a5522cf9107e2f450f79dc8.tar.gz:
|
||||
linux-yocto-7c2d49c69f3f7e59a598fa8f618b37836fd56404.tar.gz:
|
||||
topdir: null
|
||||
url:
|
||||
"https://git.yoctoproject.org/linux-yocto/snapshot/\
|
||||
linux-yocto-94762e4ed9eafc254a5522cf9107e2f450f79dc8.tar.gz"
|
||||
sha256sum: a6ec1d5108e798fd3bf7b3e977976412a333aef2d553920b677995e60ad5c5fe
|
||||
linux-yocto-7c2d49c69f3f7e59a598fa8f618b37836fd56404.tar.gz"
|
||||
sha256sum: ab33bb25e83816f94093dcf3fbce6efc8dbba06254bcf55e882cd8ca6a5bb393
|
||||
linux_6.1.27-1~bpo11%2B1.debian.tar.xz:
|
||||
topdir: null
|
||||
url:
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 52de1a7c4bcaf87293a85cc80324bb23ca6c1508 Mon Sep 17 00:00:00 2001
|
||||
From 4642b81ace18e84ce74a4389f8ef0b771431f3f5 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Friesen <chris.friesen@windriver.com>
|
||||
Date: Thu, 17 Jun 2021 07:44:04 +0000
|
||||
Subject: [PATCH 01/17] Notification of death of arbitrary processes
|
||||
Subject: [PATCH 01/16] Notification of death of arbitrary processes
|
||||
|
||||
Note: this commit was copied from Titanium Cloud Rel2
|
||||
|
||||
@ -28,6 +28,8 @@ Signed-off-by: Peng Zhang <Peng.Zhang2@windriver.com>
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for context changes.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
[jm: Adapted the patch for context changes.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
include/linux/init_task.h | 9 ++
|
||||
include/linux/sched.h | 6 +
|
||||
@ -38,15 +40,15 @@ Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
kernel/death_notify.c | 228 +++++++++++++++++++++++++++++++++++++
|
||||
kernel/death_notify.h | 46 ++++++++
|
||||
kernel/exit.c | 6 +
|
||||
kernel/fork.c | 4 +
|
||||
kernel/signal.c | 11 ++
|
||||
kernel/fork.c | 5 +-
|
||||
kernel/signal.c | 9 ++
|
||||
kernel/sys.c | 8 ++
|
||||
12 files changed, 351 insertions(+)
|
||||
12 files changed, 349 insertions(+), 1 deletion(-)
|
||||
create mode 100644 kernel/death_notify.c
|
||||
create mode 100644 kernel/death_notify.h
|
||||
|
||||
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
|
||||
index 40fc5813cf93..4fe260a1c280 100644
|
||||
index bccb3f1f6262..88275e28ccad 100644
|
||||
--- a/include/linux/init_task.h
|
||||
+++ b/include/linux/init_task.h
|
||||
@@ -25,6 +25,15 @@
|
||||
@ -66,11 +68,11 @@ index 40fc5813cf93..4fe260a1c280 100644
|
||||
|
||||
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 77f01ac385f7..7b92c4d35ddd 100644
|
||||
index 8982820dae21..a94c5f5e5c20 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -1254,6 +1254,12 @@ struct task_struct {
|
||||
short il_prev;
|
||||
@@ -1313,6 +1313,12 @@ struct task_struct {
|
||||
u8 il_weight;
|
||||
short pref_node_fork;
|
||||
#endif
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
@ -83,15 +85,15 @@ index 77f01ac385f7..7b92c4d35ddd 100644
|
||||
int numa_scan_seq;
|
||||
unsigned int numa_scan_period;
|
||||
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
|
||||
index 370ed14b1ae0..4d5d1c7b7902 100644
|
||||
index 35791791a879..27852b28ab88 100644
|
||||
--- a/include/uapi/linux/prctl.h
|
||||
+++ b/include/uapi/linux/prctl.h
|
||||
@@ -63,6 +63,22 @@
|
||||
# define PR_ENDIAN_LITTLE 1 /* True little endian mode */
|
||||
# define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little endian */
|
||||
|
||||
+#define PR_DO_NOTIFY_TASK_STATE 17 /* Set/get notification for task
|
||||
+ state changes */
|
||||
+#define PR_DO_NOTIFY_TASK_STATE 17 /* Set/get notification for task
|
||||
+ state changes */
|
||||
+
|
||||
+/* This is the data structure for requestion process death
|
||||
+ * (and other state change) information. Sig of -1 means
|
||||
@ -110,36 +112,36 @@ index 370ed14b1ae0..4d5d1c7b7902 100644
|
||||
#define PR_GET_SECCOMP 21
|
||||
#define PR_SET_SECCOMP 22
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
index e403a2925635..b946cfd059b9 100644
|
||||
index 7256fa127530..38737731dbed 100644
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -1866,6 +1866,21 @@ config DEBUG_PERF_USE_VMALLOC
|
||||
@@ -1927,6 +1927,21 @@ config DEBUG_PERF_USE_VMALLOC
|
||||
|
||||
endmenu
|
||||
|
||||
+config SIGEXIT
|
||||
+ bool "Notification of death of arbitrary processes"
|
||||
+ default n
|
||||
+ help
|
||||
+ When enabled this exposes a new feature which may be called to request
|
||||
+ notification when an arbitrary process changes state. The caller specifies
|
||||
+ a pid, signal number, and event mask, and when that pid dies, or is
|
||||
+ stopped, or anything else that would normally cause a SIGCHLD, the
|
||||
+ kernel will send the specified signal to the caller if the event is in
|
||||
+ the event mask originally passed down. The siginfo_t struct will
|
||||
+ contain the same information as would be included with SIGCHLD.
|
||||
+ bool "Notification of death of arbitrary processes"
|
||||
+ default n
|
||||
+ help
|
||||
+ When enabled this exposes a new feature which may be called to request
|
||||
+ notification when an arbitrary process changes state. The caller specifies
|
||||
+ a pid, signal number, and event mask, and when that pid dies, or is
|
||||
+ stopped, or anything else that would normally cause a SIGCHLD, the
|
||||
+ kernel will send the specified signal to the caller if the event is in
|
||||
+ the event mask originally passed down. The siginfo_t struct will
|
||||
+ contain the same information as would be included with SIGCHLD.
|
||||
+
|
||||
+ This is exposed to userspace via the prctl()
|
||||
+ call with the PR_DO_NOTIFY_TASK_STATE option
|
||||
+ This is exposed to userspace via the prctl()
|
||||
+ call with the PR_DO_NOTIFY_TASK_STATE option
|
||||
+
|
||||
config SYSTEM_DATA_VERIFICATION
|
||||
def_bool n
|
||||
select SYSTEM_TRUSTED_KEYRING
|
||||
diff --git a/init/init_task.c b/init/init_task.c
|
||||
index ff6c4b9bfe6b..ce224088251c 100644
|
||||
index 136a8231355a..7cabef0ca921 100644
|
||||
--- a/init/init_task.c
|
||||
+++ b/init/init_task.c
|
||||
@@ -129,6 +129,7 @@ struct task_struct init_task
|
||||
@@ -138,6 +138,7 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = {
|
||||
.alloc_lock = __SPIN_LOCK_UNLOCKED(init_task.alloc_lock),
|
||||
.journal_info = NULL,
|
||||
INIT_CPU_TIMERS(init_task)
|
||||
@ -148,17 +150,17 @@ index ff6c4b9bfe6b..ce224088251c 100644
|
||||
.timer_slack_ns = 50000, /* 50 usec default slack */
|
||||
.thread_pid = &init_struct_pid,
|
||||
diff --git a/kernel/Makefile b/kernel/Makefile
|
||||
index ce105a5558fc..11fec2c76af0 100644
|
||||
index 87866b037fbe..a5d38470e0b3 100644
|
||||
--- a/kernel/Makefile
|
||||
+++ b/kernel/Makefile
|
||||
@@ -113,6 +113,7 @@ obj-$(CONFIG_KCSAN) += kcsan/
|
||||
@@ -115,6 +115,7 @@ obj-$(CONFIG_KCSAN) += kcsan/
|
||||
obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
|
||||
obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
|
||||
obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call_inline.o
|
||||
+obj-$(CONFIG_SIGEXIT) += death_notify.o
|
||||
obj-$(CONFIG_CFI_CLANG) += cfi.o
|
||||
obj-$(CONFIG_NUMA) += numa.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += events/
|
||||
diff --git a/kernel/death_notify.c b/kernel/death_notify.c
|
||||
new file mode 100644
|
||||
index 000000000000..5819d35a2564
|
||||
@ -446,49 +448,50 @@ index 000000000000..14a0995b79af
|
||||
+#endif
|
||||
+
|
||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||
index 21a59a6e1f2e..0b1bf34a1550 100644
|
||||
index 619f0014c33b..12eefc9f3e24 100644
|
||||
--- a/kernel/exit.c
|
||||
+++ b/kernel/exit.c
|
||||
@@ -73,6 +73,9 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
@@ -77,6 +77,9 @@
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
#include "exit.h"
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
+#include "death_notify.h"
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* The default value should be high enough to not crash a system that randomly
|
||||
@@ -251,6 +254,9 @@ void release_task(struct task_struct *p)
|
||||
@@ -253,6 +256,9 @@ void release_task(struct task_struct *p)
|
||||
cgroup_release(p);
|
||||
|
||||
write_lock_irq(&tasklist_lock);
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
+ release_notify_others(p);
|
||||
+#endif
|
||||
+#endif
|
||||
ptrace_release_task(p);
|
||||
thread_pid = get_pid(p->thread_pid);
|
||||
__exit_signal(p);
|
||||
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||
index 869467885640..9a79ab5b7d77 100644
|
||||
index 8434ff53ab23..00f2f7392078 100644
|
||||
--- a/kernel/fork.c
|
||||
+++ b/kernel/fork.c
|
||||
@@ -2466,6 +2466,10 @@ __latent_entropy struct task_struct *copy_process(
|
||||
@@ -2358,7 +2358,10 @@ __latent_entropy struct task_struct *copy_process(
|
||||
RCU_INIT_POINTER(p->bpf_storage, NULL);
|
||||
p->bpf_ctx = NULL;
|
||||
#endif
|
||||
-
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
+ INIT_LIST_HEAD(&p->notify);
|
||||
+ INIT_LIST_HEAD(&p->monitor);
|
||||
+#endif
|
||||
|
||||
/* Perform scheduler related setup. Assign this task to a CPU. */
|
||||
retval = sched_fork(clone_flags, p);
|
||||
if (retval)
|
||||
diff --git a/kernel/signal.c b/kernel/signal.c
|
||||
index 09019017d669..883f7fa7f738 100644
|
||||
index 2ae45e6eb6bb..c181894345b9 100644
|
||||
--- a/kernel/signal.c
|
||||
+++ b/kernel/signal.c
|
||||
@@ -57,6 +57,9 @@
|
||||
@@ -58,6 +58,9 @@
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/syscall.h> /* for syscall_get_* */
|
||||
@ -498,22 +501,20 @@ index 09019017d669..883f7fa7f738 100644
|
||||
|
||||
/*
|
||||
* SLAB caches for signal bits.
|
||||
@@ -2150,6 +2153,10 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
|
||||
@@ -2145,6 +2148,9 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
|
||||
__wake_up_parent(tsk, tsk->parent);
|
||||
spin_unlock_irqrestore(&psig->siglock, flags);
|
||||
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
+ do_notify_others(tsk, &info);
|
||||
+#endif
|
||||
+
|
||||
return autoreap;
|
||||
}
|
||||
|
||||
@@ -2222,6 +2229,10 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
|
||||
@@ -2217,6 +2223,9 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
|
||||
*/
|
||||
__wake_up_parent(tsk, parent);
|
||||
spin_unlock_irqrestore(&sighand->siglock, flags);
|
||||
+
|
||||
+#ifdef CONFIG_SIGEXIT
|
||||
+ do_notify_others(tsk, &info);
|
||||
+#endif
|
||||
@ -521,7 +522,7 @@ index 09019017d669..883f7fa7f738 100644
|
||||
|
||||
/*
|
||||
diff --git a/kernel/sys.c b/kernel/sys.c
|
||||
index 44b575990333..4db207723ff9 100644
|
||||
index 4da31f28fda8..ad4f05c66e9f 100644
|
||||
--- a/kernel/sys.c
|
||||
+++ b/kernel/sys.c
|
||||
@@ -76,6 +76,9 @@
|
||||
@ -534,7 +535,7 @@ index 44b575990333..4db207723ff9 100644
|
||||
|
||||
#ifndef SET_UNALIGN_CTL
|
||||
# define SET_UNALIGN_CTL(a, b) (-EINVAL)
|
||||
@@ -2575,6 +2578,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
||||
@@ -2599,6 +2602,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
||||
else
|
||||
error = PR_MCE_KILL_DEFAULT;
|
||||
break;
|
||||
@ -547,5 +548,5 @@ index 44b575990333..4db207723ff9 100644
|
||||
error = prctl_set_mm(arg2, arg3, arg4, arg5);
|
||||
break;
|
||||
--
|
||||
2.43.0
|
||||
2.47.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 004708f2e02a4ae97672d2c618effa7cdbbe38a6 Mon Sep 17 00:00:00 2001
|
||||
From 0213e30fa1f6d2a9015b4bf136d10f07a6b91d3b Mon Sep 17 00:00:00 2001
|
||||
From: Chris Friesen <chris.friesen@windriver.com>
|
||||
Date: Tue, 24 Nov 2015 16:27:28 -0500
|
||||
Subject: [PATCH] affine compute kernel threads
|
||||
Subject: [PATCH 03/16] affine compute kernel threads
|
||||
|
||||
This is a kernel enhancement to configure the cpu affinity of kernel
|
||||
threads via kernel boot option kthread_cpus=<cpulist>. The compute
|
||||
@ -32,6 +32,8 @@ Signed-off-by: Vefa Bicakci <vefa.bicakci@windriver.com>
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
[lz: Adapted the patch for upgrading kernel from 5.10 to 6.6]
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for upgrading kernel from 6.6 to 6.12]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../admin-guide/kernel-parameters.txt | 10 ++++++++
|
||||
include/linux/cpumask.h | 3 +++
|
||||
@ -42,46 +44,47 @@ Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
6 files changed, 43 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
||||
index 59f7b400d..acc7025c1 100644
|
||||
index bf3aacb1ceb7..b6d995d47ea1 100644
|
||||
--- a/Documentation/admin-guide/kernel-parameters.txt
|
||||
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
||||
@@ -2473,6 +2473,16 @@
|
||||
@@ -2637,6 +2637,16 @@
|
||||
See also Documentation/trace/kprobetrace.rst "Kernel
|
||||
Boot Parameter" section.
|
||||
|
||||
+ kthread_cpus= [KNL, SMP] Only run kernel threads on the specified
|
||||
+ list of processors. The kernel will start threads
|
||||
+ on the indicated processors only (unless there
|
||||
+ are specific reasons to run a thread with
|
||||
+ different affinities). This can be used to make
|
||||
+ init start on certain processors and also to
|
||||
+ control where kmod and other user space threads
|
||||
+ are being spawned. Allows to keep kernel threads
|
||||
+ away from certain cores unless absoluteluy necessary.
|
||||
+ kthread_cpus= [KNL, SMP] Only run kernel threads on the specified
|
||||
+ list of processors. The kernel will start threads
|
||||
+ on the indicated processors only (unless there
|
||||
+ are specific reasons to run a thread with
|
||||
+ different affinities). This can be used to make
|
||||
+ init start on certain processors and also to
|
||||
+ control where kmod and other user space threads
|
||||
+ are being spawned. Allows to keep kernel threads
|
||||
+ away from certain cores unless absoluteluy necessary.
|
||||
+
|
||||
kpti= [ARM64] Control page table isolation of user
|
||||
and kernel address spaces.
|
||||
kpti= [ARM64,EARLY] Control page table isolation of
|
||||
user and kernel address spaces.
|
||||
Default: enabled on cores which need mitigation.
|
||||
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
|
||||
index c2aa0aa26..2919c2aef 100644
|
||||
index 9278a50d514f..2b91ee73365b 100644
|
||||
--- a/include/linux/cpumask.h
|
||||
+++ b/include/linux/cpumask.h
|
||||
@@ -61,6 +61,7 @@ static inline void set_nr_cpu_ids(unsigned int nr)
|
||||
* cpu_present_mask - has bit 'cpu' set iff cpu is populated
|
||||
@@ -84,6 +84,7 @@ static __always_inline void set_nr_cpu_ids(unsigned int nr)
|
||||
* cpu_enabled_mask - has bit 'cpu' set iff cpu can be brought online
|
||||
* cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler
|
||||
* cpu_active_mask - has bit 'cpu' set iff cpu available to migration
|
||||
+ * cpu_kthread_mask - has bit 'cpu' set iff general kernel threads allowed
|
||||
*
|
||||
* If !CONFIG_HOTPLUG_CPU, present == possible, and active == online.
|
||||
*
|
||||
@@ -93,11 +94,13 @@ extern struct cpumask __cpu_possible_mask;
|
||||
extern struct cpumask __cpu_online_mask;
|
||||
@@ -117,12 +118,14 @@ extern struct cpumask __cpu_online_mask;
|
||||
extern struct cpumask __cpu_enabled_mask;
|
||||
extern struct cpumask __cpu_present_mask;
|
||||
extern struct cpumask __cpu_active_mask;
|
||||
+extern struct cpumask __cpu_kthread_mask;
|
||||
extern struct cpumask __cpu_dying_mask;
|
||||
#define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask)
|
||||
#define cpu_online_mask ((const struct cpumask *)&__cpu_online_mask)
|
||||
#define cpu_enabled_mask ((const struct cpumask *)&__cpu_enabled_mask)
|
||||
#define cpu_present_mask ((const struct cpumask *)&__cpu_present_mask)
|
||||
#define cpu_active_mask ((const struct cpumask *)&__cpu_active_mask)
|
||||
+#define cpu_kthread_mask ((const struct cpumask *)&__cpu_kthread_mask)
|
||||
@ -89,10 +92,10 @@ index c2aa0aa26..2919c2aef 100644
|
||||
|
||||
extern atomic_t __num_online_cpus;
|
||||
diff --git a/init/main.c b/init/main.c
|
||||
index bd4ce7345..c40b2c441 100644
|
||||
index a7aaae73743e..569c18d1622c 100644
|
||||
--- a/init/main.c
|
||||
+++ b/init/main.c
|
||||
@@ -1633,6 +1633,8 @@ static noinline void __init kernel_init_freeable(void)
|
||||
@@ -1593,6 +1593,8 @@ static noinline void __init kernel_init_freeable(void)
|
||||
|
||||
do_basic_setup();
|
||||
|
||||
@ -102,10 +105,10 @@ index bd4ce7345..c40b2c441 100644
|
||||
|
||||
wait_for_initramfs();
|
||||
diff --git a/kernel/cpu.c b/kernel/cpu.c
|
||||
index 98a7a7b14..d051b4097 100644
|
||||
index 9ee6c9145b1d..7ab2274c0b8b 100644
|
||||
--- a/kernel/cpu.c
|
||||
+++ b/kernel/cpu.c
|
||||
@@ -2651,6 +2651,29 @@ EXPORT_SYMBOL(__cpu_dying_mask);
|
||||
@@ -3121,6 +3121,29 @@ EXPORT_SYMBOL(__cpu_dying_mask);
|
||||
atomic_t __num_online_cpus __read_mostly;
|
||||
EXPORT_SYMBOL(__num_online_cpus);
|
||||
|
||||
@ -136,10 +139,10 @@ index 98a7a7b14..d051b4097 100644
|
||||
{
|
||||
cpumask_copy(&__cpu_present_mask, src);
|
||||
diff --git a/kernel/kthread.c b/kernel/kthread.c
|
||||
index f97fd01a2..2bd5d136e 100644
|
||||
index 9bb36897b6c6..77d2b3f577f4 100644
|
||||
--- a/kernel/kthread.c
|
||||
+++ b/kernel/kthread.c
|
||||
@@ -355,7 +355,7 @@ static int kthread(void *_create)
|
||||
@@ -368,7 +368,7 @@ static int kthread(void *_create)
|
||||
* back to default in case they have been changed.
|
||||
*/
|
||||
sched_setscheduler_nocheck(current, SCHED_NORMAL, ¶m);
|
||||
@ -148,7 +151,7 @@ index f97fd01a2..2bd5d136e 100644
|
||||
|
||||
/* OK, tell user we're spawned, wait for stop or wakeup */
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
@@ -722,7 +722,7 @@ int kthreadd(void *unused)
|
||||
@@ -743,7 +743,7 @@ int kthreadd(void *unused)
|
||||
/* Setup a clean context for our children to inherit. */
|
||||
set_task_comm(tsk, "kthreadd");
|
||||
ignore_signals(tsk);
|
||||
@ -158,10 +161,10 @@ index f97fd01a2..2bd5d136e 100644
|
||||
|
||||
current->flags |= PF_NOFREEZE;
|
||||
diff --git a/kernel/umh.c b/kernel/umh.c
|
||||
index fbf872c62..43e3f4567 100644
|
||||
index ff1f13a27d29..0dec76b539a7 100644
|
||||
--- a/kernel/umh.c
|
||||
+++ b/kernel/umh.c
|
||||
@@ -82,6 +82,9 @@ static int call_usermodehelper_exec_async(void *data)
|
||||
@@ -79,6 +79,9 @@ static int call_usermodehelper_exec_async(void *data)
|
||||
*/
|
||||
current->fs->umask = 0022;
|
||||
|
||||
@ -172,5 +175,5 @@ index fbf872c62..43e3f4567 100644
|
||||
* Our parent (unbound workqueue) runs with elevated scheduling
|
||||
* priority. Avoid propagating that into the userspace child.
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 130eb445c6abc1dec0cb9d24b2b7e4cba13f7037 Mon Sep 17 00:00:00 2001
|
||||
From b40833737594a50e69a505f0da82168c5d998ca6 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Friesen <chris.friesen@windriver.com>
|
||||
Date: Thu, 12 May 2016 18:00:00 -0400
|
||||
Subject: [PATCH] Make kernel start eth devices at offset
|
||||
Subject: [PATCH 05/16] Make kernel start eth devices at offset
|
||||
|
||||
In order to avoid naming collisions, we want to make the kernel
|
||||
start naming its "ethX" devices at eth1000 instead of eth0. This
|
||||
@ -12,27 +12,29 @@ Signed-off-by: Zhang Zhiguo <zhangzhg@neusoft.com>
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
[lz: Adapted the patch for context changes.]
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for context changes.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
net/core/dev.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
index 9bf90b2a7..9526361a0 100644
|
||||
index c761f862bc5a..d91ad9228b19 100644
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -1119,6 +1119,12 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf)
|
||||
__set_bit(i, inuse);
|
||||
}
|
||||
|
||||
+ /* STX extension, want kernel to start at eth1000 */
|
||||
+ if (strcmp(name, "eth%d") == 0) {
|
||||
+ for (i=0; i < 1000; i++)
|
||||
+ set_bit(i, inuse);
|
||||
+ }
|
||||
+
|
||||
i = find_first_zero_bit(inuse, max_netdevices);
|
||||
bitmap_free(inuse);
|
||||
@@ -1203,6 +1203,12 @@ static int __dev_alloc_name(struct net *net, const char *name, char *res)
|
||||
__set_bit(i, inuse);
|
||||
}
|
||||
|
||||
+ /* STX extension, want kernel to start at eth1000 */
|
||||
+ if (strcmp(name, "eth%d") == 0) {
|
||||
+ for (i=0; i < 1000; i++)
|
||||
+ set_bit(i, inuse);
|
||||
+ }
|
||||
+
|
||||
i = find_first_zero_bit(inuse, max_netdevices);
|
||||
bitmap_free(inuse);
|
||||
if (i == max_netdevices)
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
From f311c0cd55b9fb90696350d8545cf46381ccc805 Mon Sep 17 00:00:00 2001
|
||||
From 43085ada69718fca39228c84919732d445fa1235 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Peters <matt.peters@windriver.com>
|
||||
Date: Mon, 30 May 2016 10:51:02 -0400
|
||||
Subject: [PATCH] intel-iommu: allow ignoring Ethernet device RMRR with IOMMU
|
||||
passthrough
|
||||
Subject: [PATCH 06/16] intel-iommu: allow ignoring Ethernet device RMRR with
|
||||
IOMMU passthrough
|
||||
|
||||
Some BIOS's are reporting DMAR RMRR entries for Ethernet devices
|
||||
which is causing problems when PCI passthrough is enabled. These
|
||||
@ -23,6 +23,8 @@ Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
[lz: Adapted the patch for upgrading kernel from 5.10 to 6.6.]
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for upgrading kernel from 6.6 to 6.12.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../admin-guide/kernel-parameters.txt | 5 +++++
|
||||
Documentation/arch/x86/iommu.rst | 18 +++++++++++++++
|
||||
@ -30,23 +32,23 @@ Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
3 files changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
||||
index 44b3c3f8c..d7c13e702 100644
|
||||
index b6d995d47ea1..c182de48eabb 100644
|
||||
--- a/Documentation/admin-guide/kernel-parameters.txt
|
||||
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
||||
@@ -2115,6 +2115,11 @@
|
||||
@@ -2218,6 +2218,11 @@
|
||||
bypassed by not enabling DMAR with this option. In
|
||||
this case, gfx device will use physical address for
|
||||
DMA.
|
||||
+ eth_no_rmrr [Default Off]
|
||||
+ With this option provided, the kernel will ignore
|
||||
+ any specified RMRR regions specified by the BIOS
|
||||
+ for PCI ethernet devices. Confirm with your hardware
|
||||
+ vendor the RMRR regions are indeed invalid first.
|
||||
+ With this option provided, the kernel will ignore
|
||||
+ any specified RMRR regions specified by the BIOS
|
||||
+ for PCI ethernet devices. Confirm with your hardware
|
||||
+ vendor the RMRR regions are indeed invalid first.
|
||||
strict [Default Off]
|
||||
Deprecated, equivalent to iommu.strict=1.
|
||||
sp_off [Default Off]
|
||||
diff --git a/Documentation/arch/x86/iommu.rst b/Documentation/arch/x86/iommu.rst
|
||||
index 42c7a6faa..edcbff38c 100644
|
||||
index 41fbadfe2221..5a02c241774d 100644
|
||||
--- a/Documentation/arch/x86/iommu.rst
|
||||
+++ b/Documentation/arch/x86/iommu.rst
|
||||
@@ -35,6 +35,24 @@ regions will fail. Hence BIOS uses RMRR to specify these regions along with
|
||||
@ -75,18 +77,18 @@ index 42c7a6faa..edcbff38c 100644
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
|
||||
index 4c3707384..6b185695a 100644
|
||||
index 9c46a4cd3848..ea0ffcf82d7e 100644
|
||||
--- a/drivers/iommu/intel/iommu.c
|
||||
+++ b/drivers/iommu/intel/iommu.c
|
||||
@@ -293,6 +293,7 @@ EXPORT_SYMBOL_GPL(intel_iommu_enabled);
|
||||
@@ -209,6 +209,7 @@ int intel_iommu_enabled = 0;
|
||||
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
|
||||
|
||||
static int dmar_map_gfx = 1;
|
||||
static int intel_iommu_superpage = 1;
|
||||
+static int intel_iommu_ethrmrr = 1;
|
||||
static int iommu_identity_mapping;
|
||||
static int iommu_skip_te_disable;
|
||||
|
||||
@@ -339,6 +340,15 @@ static int __init intel_iommu_setup(char *str)
|
||||
static int disable_igfx_iommu;
|
||||
@@ -256,6 +257,15 @@ static int __init intel_iommu_setup(char *str)
|
||||
} else if (!strncmp(str, "forcedac", 8)) {
|
||||
pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n");
|
||||
iommu_dma_forcedac = true;
|
||||
@ -102,7 +104,7 @@ index 4c3707384..6b185695a 100644
|
||||
} else if (!strncmp(str, "strict", 6)) {
|
||||
pr_warn("intel_iommu=strict deprecated; use iommu.strict=1 instead\n");
|
||||
iommu_set_dma_strict();
|
||||
@@ -2518,8 +2528,18 @@ static bool device_rmrr_is_relaxable(struct device *dev)
|
||||
@@ -2025,8 +2035,18 @@ static bool device_rmrr_is_relaxable(struct device *dev)
|
||||
pdev = to_pci_dev(dev);
|
||||
if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
|
||||
return true;
|
||||
@ -121,7 +123,7 @@ index 4c3707384..6b185695a 100644
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
static int device_def_domain_type(struct device *dev)
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From c335a673dea2fd4c0452d88975cc2045d0934d14 Mon Sep 17 00:00:00 2001
|
||||
From b51ab594903af7cc209b4d8ca905db403a99772c Mon Sep 17 00:00:00 2001
|
||||
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
|
||||
Date: Thu, 9 Sep 2021 04:56:46 -0400
|
||||
Subject: [PATCH] workqueue: Affine rescuer threads and unbound wqs
|
||||
Subject: [PATCH 10/16] workqueue: Affine rescuer threads and unbound wqs
|
||||
|
||||
This commit ensures that workqueue rescuer threads are affined to the
|
||||
platform CPUs specified by the "kthread_cpus" kernel argument. Prior to
|
||||
@ -27,24 +27,29 @@ Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
[lz: Adapted the patch for upgrading kernel from 5.10 to 6.6
|
||||
according to M. Vefa Bicakci's suggestion.]
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for upgrading kernel from 6.6 to 6.12.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
kernel/workqueue.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
kernel/workqueue.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
|
||||
index e6a95bb74..a15ad43c8 100644
|
||||
index 3f0f7cf15ed2..d39a4db6bb65 100644
|
||||
--- a/kernel/workqueue.c
|
||||
+++ b/kernel/workqueue.c
|
||||
@@ -4659,7 +4659,7 @@ static int init_rescuer(struct workqueue_struct *wq)
|
||||
@@ -5559,10 +5559,7 @@ static int init_rescuer(struct workqueue_struct *wq)
|
||||
}
|
||||
|
||||
wq->rescuer = rescuer;
|
||||
- kthread_bind_mask(rescuer->task, cpu_possible_mask);
|
||||
- if (wq->flags & WQ_UNBOUND)
|
||||
- kthread_bind_mask(rescuer->task, unbound_effective_cpumask(wq));
|
||||
- else
|
||||
- kthread_bind_mask(rescuer->task, cpu_possible_mask);
|
||||
+ kthread_bind_mask(rescuer->task, cpu_kthread_mask);
|
||||
wake_up_process(rescuer->task);
|
||||
|
||||
return 0;
|
||||
@@ -6545,6 +6545,7 @@ void __init workqueue_init_early(void)
|
||||
@@ -7727,6 +7724,7 @@ void __init workqueue_init_early(void)
|
||||
cpumask_copy(wq_unbound_cpumask, cpu_possible_mask);
|
||||
restrict_unbound_cpumask("HK_TYPE_WQ", housekeeping_cpumask(HK_TYPE_WQ));
|
||||
restrict_unbound_cpumask("HK_TYPE_DOMAIN", housekeeping_cpumask(HK_TYPE_DOMAIN));
|
||||
@ -53,5 +58,5 @@ index e6a95bb74..a15ad43c8 100644
|
||||
restrict_unbound_cpumask("workqueue.unbound_cpus", &wq_cmdline_cpumask);
|
||||
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
From ed051d788e0f7d177bec80d7b594e7b889b975bd Mon Sep 17 00:00:00 2001
|
||||
From ac36a126f58faacde2237fc06dc38600f9d3789c Mon Sep 17 00:00:00 2001
|
||||
From: "M. Vefa Bicakci" <vefa.bicakci@windriver.com>
|
||||
Date: Wed, 4 Jan 2023 20:36:53 -0500
|
||||
Subject: [PATCH] Revert "sched/idle: Move quiet_vmstate() into the NOHZ code"
|
||||
Subject: [PATCH 13/16] Revert "sched/idle: Move quiet_vmstate() into the NOHZ
|
||||
code"
|
||||
|
||||
This reverts commit 62cb1188ed86a9cf082fd2f757d4dd9b54741f24.
|
||||
|
||||
@ -78,16 +79,18 @@ Jim Somerville <jim.somerville@windriver.com> during the debugging and
|
||||
investigation of this issue.
|
||||
|
||||
Signed-off-by: M. Vefa Bicakci <vefa.bicakci@windriver.com>
|
||||
[Adjust the patch to adapt to the kernel 6.12.x.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
kernel/sched/idle.c | 1 +
|
||||
kernel/time/tick-sched.c | 2 --
|
||||
2 files changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
|
||||
index f26ab2675..9298330c5 100644
|
||||
index 53bb9193c537..e7c4d47f9537 100644
|
||||
--- a/kernel/sched/idle.c
|
||||
+++ b/kernel/sched/idle.c
|
||||
@@ -274,6 +274,7 @@ static void do_idle(void)
|
||||
@@ -268,6 +268,7 @@ static void do_idle(void)
|
||||
*/
|
||||
|
||||
__current_set_polling();
|
||||
@ -96,10 +99,10 @@ index f26ab2675..9298330c5 100644
|
||||
|
||||
while (!need_resched()) {
|
||||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
|
||||
index 1ad89eec2..468e756f1 100644
|
||||
index e0c47259e91a..31bbff551ed9 100644
|
||||
--- a/kernel/time/tick-sched.c
|
||||
+++ b/kernel/time/tick-sched.c
|
||||
@@ -25,7 +25,6 @@
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/posix-timers.h>
|
||||
#include <linux/context_tracking.h>
|
||||
@ -107,14 +110,14 @@ index 1ad89eec2..468e756f1 100644
|
||||
|
||||
#include <asm/irq_regs.h>
|
||||
|
||||
@@ -932,7 +931,6 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
|
||||
@@ -1047,7 +1046,6 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
|
||||
*/
|
||||
if (!ts->tick_stopped) {
|
||||
if (!tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {
|
||||
calc_load_nohz_start();
|
||||
- quiet_vmstat();
|
||||
|
||||
ts->last_tick = hrtimer_get_expires(&ts->sched_timer);
|
||||
ts->tick_stopped = 1;
|
||||
tick_sched_flag_set(ts, TS_FLAG_STOPPED);
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From d3a94bc5b2139aeb6f6d1f05c2bd47a8f9ad2650 Mon Sep 17 00:00:00 2001
|
||||
From fc7e2942cbc9864da546678d65f201244b6685dc Mon Sep 17 00:00:00 2001
|
||||
From: Jim Somerville <jim.somerville@windriver.com>
|
||||
Date: Fri, 14 Apr 2023 15:29:22 -0400
|
||||
Subject: [PATCH] Port negative dentries limit feature from 3.10
|
||||
Subject: [PATCH 14/16] Port negative dentries limit feature from 3.10
|
||||
|
||||
This ports the Redhat feature forward from the 3.10 kernel version.
|
||||
|
||||
@ -34,12 +34,14 @@ Replace "&zero_ul" with "SYSCTL_LONG_ZERO" according to:
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
|
||||
commit/?id=b1f2aff888af54a057c2c3c0d88a13ef5d37b52a.]
|
||||
Signed-off-by: Li Zhou <li.zhou@windriver.com>
|
||||
[jm: Adapted the patch for 6.12.x.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
fs/dcache.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 183 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/dcache.c b/fs/dcache.c
|
||||
index 576ad162c..0fff744af 100644
|
||||
index 3a01c42c6639..bef98597df07 100644
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@ -50,7 +52,7 @@ index 576ad162c..0fff744af 100644
|
||||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
|
||||
@@ -124,6 +125,65 @@ struct dentry_stat_t {
|
||||
@@ -132,6 +133,65 @@ struct dentry_stat_t {
|
||||
long dummy; /* Reserved for future use */
|
||||
};
|
||||
|
||||
@ -80,7 +82,7 @@ index 576ad162c..0fff744af 100644
|
||||
+/*
|
||||
+ * Sysctl proc handler for dcache_negativ3_dentry_limit_sysctl.
|
||||
+ */
|
||||
+int proc_dcache_negative_dentry_limit(struct ctl_table *ctl, int write,
|
||||
+static int proc_dcache_negative_dentry_limit(const struct ctl_table *ctl, int write,
|
||||
+ void __user *buffer, size_t *lenp,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
@ -116,7 +118,7 @@ index 576ad162c..0fff744af 100644
|
||||
static DEFINE_PER_CPU(long, nr_dentry);
|
||||
static DEFINE_PER_CPU(long, nr_dentry_unused);
|
||||
static DEFINE_PER_CPU(long, nr_dentry_negative);
|
||||
@@ -191,6 +251,15 @@ static struct ctl_table fs_dcache_sysctls[] = {
|
||||
@@ -199,6 +259,15 @@ static struct ctl_table fs_dcache_sysctls[] = {
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_nr_dentry,
|
||||
},
|
||||
@ -129,10 +131,10 @@ index 576ad162c..0fff744af 100644
|
||||
+ .extra1 = SYSCTL_LONG_ZERO,
|
||||
+ .extra2 = SYSCTL_ONE_HUNDRED,
|
||||
+ },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1202,8 +1271,9 @@ void shrink_dentry_list(struct list_head *list)
|
||||
static int __init init_fs_dcache_sysctls(void)
|
||||
@@ -1088,8 +1157,9 @@ void shrink_dentry_list(struct list_head *list)
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +146,7 @@ index 576ad162c..0fff744af 100644
|
||||
{
|
||||
struct list_head *freeable = arg;
|
||||
struct dentry *dentry = container_of(item, struct dentry, d_lru);
|
||||
@@ -1254,12 +1324,29 @@ static enum lru_status dentry_lru_isolate(struct list_head *item,
|
||||
@@ -1140,12 +1210,29 @@ static enum lru_status dentry_lru_isolate(struct list_head *item,
|
||||
return LRU_ROTATE;
|
||||
}
|
||||
|
||||
@ -174,7 +176,7 @@ index 576ad162c..0fff744af 100644
|
||||
/**
|
||||
* prune_dcache_sb - shrink the dcache
|
||||
* @sb: superblock
|
||||
@@ -1283,6 +1370,20 @@ long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc)
|
||||
@@ -1169,6 +1256,20 @@ long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc)
|
||||
return freed;
|
||||
}
|
||||
|
||||
@ -195,7 +197,7 @@ index 576ad162c..0fff744af 100644
|
||||
static enum lru_status dentry_lru_isolate_shrink(struct list_head *item,
|
||||
struct list_lru_one *lru, spinlock_t *lru_lock, void *arg)
|
||||
{
|
||||
@@ -1677,6 +1778,86 @@ static enum d_walk_ret umount_check(void *_data, struct dentry *dentry)
|
||||
@@ -1549,6 +1650,86 @@ static enum d_walk_ret umount_check(void *_data, struct dentry *dentry)
|
||||
return D_WALK_CONTINUE;
|
||||
}
|
||||
|
||||
@ -283,5 +285,5 @@ index 576ad162c..0fff744af 100644
|
||||
{
|
||||
shrink_dcache_parent(dentry);
|
||||
--
|
||||
2.17.1
|
||||
2.47.1
|
||||
|
||||
|
@ -1,282 +0,0 @@
|
||||
From b866d25ee24d62641b9e16a509d08ed4a4e0e1c7 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Sun, 31 Mar 2024 20:13:57 -0700
|
||||
Subject: [PATCH] Add driver versions for ice, i40e and iavf
|
||||
|
||||
As we need driver version to track driver information, add
|
||||
the necessary driver version for the Intel drivers.
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Makefile | 8 +++++++-
|
||||
drivers/net/ethernet/intel/i40e/i40e.h | 1 +
|
||||
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 ++
|
||||
drivers/net/ethernet/intel/i40e/i40e_main.c | 16 ++++++++++------
|
||||
drivers/net/ethernet/intel/iavf/iavf.h | 1 +
|
||||
drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 1 +
|
||||
drivers/net/ethernet/intel/iavf/iavf_main.c | 8 ++++++--
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 15 +++++++++------
|
||||
10 files changed, 39 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 8ed7620308d1..2235636756b9 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1227,6 +1227,9 @@ uapi-asm-generic:
|
||||
|
||||
# KERNELRELEASE can change from a few different places, meaning version.h
|
||||
# needs to be updated, so this check is forced on all builds
|
||||
+ICE_STX = "-stx.0"
|
||||
+I40E_STX = "-stx.0"
|
||||
+IAVF_STX = "-stx.0"
|
||||
|
||||
uts_len := 64
|
||||
define filechk_utsrelease.h
|
||||
@@ -1249,7 +1252,10 @@ define filechk_version.h
|
||||
((c) > 255 ? 255 : (c)))'; \
|
||||
echo \#define LINUX_VERSION_MAJOR $(VERSION); \
|
||||
echo \#define LINUX_VERSION_PATCHLEVEL $(PATCHLEVEL); \
|
||||
- echo \#define LINUX_VERSION_SUBLEVEL $(SUBLEVEL)
|
||||
+ echo \#define LINUX_VERSION_SUBLEVEL $(SUBLEVEL); \
|
||||
+ echo \#define LINUX_ICE_DRIVER_VERSION \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(ICE_STX)\"; \
|
||||
+ echo \#define LINUX_I40E_DRIVER_VERSION \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(I40E_STX)\"; \
|
||||
+ echo \#define LINUX_IAVF_DRIVER_VERSION \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(IAVF_STX)\"
|
||||
endef
|
||||
|
||||
ifneq ($(DISTRIBUTION_OFFICIAL_BUILD),)
|
||||
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
|
||||
index 3e6839ac1f0f..a72be4e1b318 100644
|
||||
--- a/drivers/net/ethernet/intel/i40e/i40e.h
|
||||
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
|
||||
@@ -1102,6 +1102,7 @@ static inline u32 i40e_get_pf_count(struct i40e_hw *hw)
|
||||
int i40e_up(struct i40e_vsi *vsi);
|
||||
void i40e_down(struct i40e_vsi *vsi);
|
||||
extern const char i40e_driver_name[];
|
||||
+extern const char i40e_driver_version_str[];
|
||||
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
|
||||
void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired);
|
||||
int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
|
||||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
|
||||
index 4e90570ba780..d6a019b27add 100644
|
||||
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
|
||||
@@ -2005,6 +2005,8 @@ static void i40e_get_drvinfo(struct net_device *netdev,
|
||||
struct i40e_pf *pf = vsi->back;
|
||||
|
||||
strscpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
|
||||
+ strlcpy(drvinfo->version, i40e_driver_version_str,
|
||||
+ sizeof(drvinfo->version));
|
||||
strscpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw),
|
||||
sizeof(drvinfo->fw_version));
|
||||
strscpy(drvinfo->bus_info, pci_name(pf->pdev),
|
||||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
|
||||
index f8d1a994c2f6..b8043e8cb9e2 100644
|
||||
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
|
||||
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
|
||||
@@ -1,13 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2013 - 2021 Intel Corporation. */
|
||||
|
||||
-#include <generated/utsrelease.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <linux/if_macvlan.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/xdp_sock_drv.h>
|
||||
+#include <linux/version.h>
|
||||
|
||||
/* Local includes */
|
||||
#include "i40e.h"
|
||||
@@ -28,6 +28,8 @@ const char i40e_driver_name[] = "i40e";
|
||||
static const char i40e_driver_string[] =
|
||||
"Intel(R) Ethernet Connection XL710 Network Driver";
|
||||
|
||||
+#define DRV_VERSION LINUX_I40E_DRIVER_VERSION
|
||||
+const char i40e_driver_version_str[] = DRV_VERSION;
|
||||
static const char i40e_copyright[] = "Copyright (c) 2013 - 2019 Intel Corporation.";
|
||||
|
||||
/* a bit of forward declarations */
|
||||
@@ -101,6 +103,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all), Debug mask (0x8XXXXXXX
|
||||
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
|
||||
MODULE_DESCRIPTION("Intel(R) Ethernet Connection XL710 Network Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
+MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
static struct workqueue_struct *i40e_wq;
|
||||
|
||||
@@ -10783,11 +10786,11 @@ static void i40e_send_version(struct i40e_pf *pf)
|
||||
{
|
||||
struct i40e_driver_version dv;
|
||||
|
||||
- dv.major_version = 0xff;
|
||||
- dv.minor_version = 0xff;
|
||||
- dv.build_version = 0xff;
|
||||
+ dv.major_version = LINUX_VERSION_MAJOR;
|
||||
+ dv.minor_version = LINUX_VERSION_PATCHLEVEL;
|
||||
+ dv.build_version = LINUX_VERSION_SUBLEVEL;
|
||||
dv.subbuild_version = 0;
|
||||
- strscpy(dv.driver_string, UTS_RELEASE, sizeof(dv.driver_string));
|
||||
+ strscpy(dv.driver_string, DRV_VERSION, sizeof(dv.driver_string));
|
||||
i40e_aq_send_driver_version(&pf->hw, &dv, NULL);
|
||||
}
|
||||
|
||||
@@ -16768,7 +16771,8 @@ static int __init i40e_init_module(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
- pr_info("%s: %s\n", i40e_driver_name, i40e_driver_string);
|
||||
+ pr_info("%s: %s - version %s\n", i40e_driver_name,
|
||||
+ i40e_driver_string, i40e_driver_version_str);
|
||||
pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
|
||||
|
||||
/* There is no need to throttle the number of active tasks because
|
||||
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
|
||||
index 431d9d62c8c6..fec2e5bb77df 100644
|
||||
--- a/drivers/net/ethernet/intel/iavf/iavf.h
|
||||
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
|
||||
@@ -468,6 +468,7 @@ struct iavf_device {
|
||||
|
||||
/* needed by iavf_ethtool.c */
|
||||
extern char iavf_driver_name[];
|
||||
+extern const char iavf_driver_version[];
|
||||
|
||||
static inline const char *iavf_state_str(enum iavf_state_t state)
|
||||
{
|
||||
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
|
||||
index 1ac97bd606e3..204f8305f728 100644
|
||||
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
|
||||
@@ -586,6 +586,7 @@ static void iavf_get_drvinfo(struct net_device *netdev,
|
||||
struct iavf_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
strscpy(drvinfo->driver, iavf_driver_name, 32);
|
||||
+ strlcpy(drvinfo->version, iavf_driver_version, 32);
|
||||
strscpy(drvinfo->fw_version, "N/A", 4);
|
||||
strscpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
|
||||
drvinfo->n_priv_flags = IAVF_PRIV_FLAGS_STR_LEN;
|
||||
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
|
||||
index ce0b91999526..10a96793c123 100644
|
||||
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
|
||||
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
||||
|
||||
+#include <linux/version.h>
|
||||
#include "iavf.h"
|
||||
#include "iavf_prototype.h"
|
||||
#include "iavf_client.h"
|
||||
@@ -21,6 +22,8 @@ char iavf_driver_name[] = "iavf";
|
||||
static const char iavf_driver_string[] =
|
||||
"Intel(R) Ethernet Adaptive Virtual Function Network Driver";
|
||||
|
||||
+#define DRV_VERSION LINUX_IAVF_DRIVER_VERSION
|
||||
+const char iavf_driver_version[] = DRV_VERSION;
|
||||
static const char iavf_copyright[] =
|
||||
"Copyright (c) 2013 - 2018 Intel Corporation.";
|
||||
|
||||
@@ -47,6 +50,7 @@ MODULE_ALIAS("i40evf");
|
||||
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
|
||||
MODULE_DESCRIPTION("Intel(R) Ethernet Adaptive Virtual Function Network Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
+MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
static const struct net_device_ops iavf_netdev_ops;
|
||||
|
||||
@@ -5326,8 +5330,8 @@ static struct pci_driver iavf_driver = {
|
||||
**/
|
||||
static int __init iavf_init_module(void)
|
||||
{
|
||||
- pr_info("iavf: %s\n", iavf_driver_string);
|
||||
-
|
||||
+ pr_info("iavf: %s - version %s\n", iavf_driver_string,
|
||||
+ iavf_driver_version);
|
||||
pr_info("%s\n", iavf_copyright);
|
||||
|
||||
return pci_register_driver(&iavf_driver);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index c7962f322db2..2695794a5df7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "ice_gnss.h"
|
||||
#include "ice_irq.h"
|
||||
|
||||
+extern const char ice_drv_ver[];
|
||||
#define ICE_BAR0 0
|
||||
#define ICE_REQ_DESC_MULTIPLE 32
|
||||
#define ICE_MIN_NUM_DESC 64
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 39b5f24be7e4..456cf4785c74 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -358,6 +358,7 @@ __ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo,
|
||||
orom = &hw->flash.orom;
|
||||
|
||||
strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
|
||||
+ strscpy(drvinfo->version, ice_drv_ver, sizeof(drvinfo->version));
|
||||
|
||||
/* Display NVM version (from which the firmware version can be
|
||||
* determined) which contains more pertinent information.
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 600a2f537087..149984fb8ab0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
-#include <generated/utsrelease.h>
|
||||
+#include <linux/version.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include "ice.h"
|
||||
#include "ice_base.h"
|
||||
@@ -25,7 +25,9 @@
|
||||
#include "ice_vsi_vlan_ops.h"
|
||||
#include <net/xdp_sock_drv.h>
|
||||
|
||||
+#define DRV_VERSION LINUX_ICE_DRIVER_VERSION
|
||||
#define DRV_SUMMARY "Intel(R) Ethernet Connection E800 Series Linux Driver"
|
||||
+const char ice_drv_ver[] = DRV_VERSION;
|
||||
static const char ice_driver_string[] = DRV_SUMMARY;
|
||||
static const char ice_copyright[] = "Copyright (c) 2018, Intel Corporation.";
|
||||
|
||||
@@ -36,6 +38,7 @@ static const char ice_copyright[] = "Copyright (c) 2018, Intel Corporation.";
|
||||
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
|
||||
MODULE_DESCRIPTION(DRV_SUMMARY);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
+MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_FIRMWARE(ICE_DDP_PKG_FILE);
|
||||
|
||||
static int debug = -1;
|
||||
@@ -4198,11 +4201,11 @@ static int ice_send_version(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_driver_ver dv;
|
||||
|
||||
- dv.major_ver = 0xff;
|
||||
- dv.minor_ver = 0xff;
|
||||
- dv.build_ver = 0xff;
|
||||
+ dv.major_ver = LINUX_VERSION_MAJOR;
|
||||
+ dv.minor_ver = LINUX_VERSION_PATCHLEVEL;
|
||||
+ dv.build_ver = LINUX_VERSION_SUBLEVEL;
|
||||
dv.subbuild_ver = 0;
|
||||
- strscpy((char *)dv.driver_string, UTS_RELEASE,
|
||||
+ strscpy((char *)dv.driver_string, DRV_VERSION,
|
||||
sizeof(dv.driver_string));
|
||||
return ice_aq_send_driver_ver(&pf->hw, &dv, NULL);
|
||||
}
|
||||
@@ -5657,7 +5660,7 @@ static int __init ice_module_init(void)
|
||||
{
|
||||
int status = -ENOMEM;
|
||||
|
||||
- pr_info("%s\n", ice_driver_string);
|
||||
+ pr_info("%s - version %s\n", ice_driver_string, ice_drv_ver);
|
||||
pr_info("%s\n", ice_copyright);
|
||||
|
||||
ice_wq = alloc_workqueue("%s", 0, 0, KBUILD_MODNAME);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,78 @@
|
||||
From ca2a6b12ce2421e4e70705059b143e2f43c65efe Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Tue, 18 Mar 2025 07:24:15 +0000
|
||||
Subject: [PATCH 16/16] tools: Fix the build errors
|
||||
|
||||
Add "{ }" in the code block of case to fix the following build error.
|
||||
|
||||
tools/power/x86/turbostat/turbostat.c:2811:4: error: a label can
|
||||
only be part of a statement and a declaration is not a statement
|
||||
2811 | const unsigned long value_raw = t->pmt_counter[i];
|
||||
| ^~~~~
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
tools/power/x86/turbostat/turbostat.c | 30 ++++++++++++++++-----------
|
||||
1 file changed, 18 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
|
||||
index 235e82fe7d0a..9a3d38259042 100644
|
||||
--- a/tools/power/x86/turbostat/turbostat.c
|
||||
+++ b/tools/power/x86/turbostat/turbostat.c
|
||||
@@ -2808,11 +2808,13 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
||||
break;
|
||||
|
||||
case PMT_TYPE_XTAL_TIME:
|
||||
- const unsigned long value_raw = t->pmt_counter[i];
|
||||
- const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
+ {
|
||||
+ const unsigned long value_raw = t->pmt_counter[i];
|
||||
+ const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
|
||||
- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
- break;
|
||||
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2889,11 +2891,13 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
||||
break;
|
||||
|
||||
case PMT_TYPE_XTAL_TIME:
|
||||
- const unsigned long value_raw = c->pmt_counter[i];
|
||||
- const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
+ {
|
||||
+ const unsigned long value_raw = c->pmt_counter[i];
|
||||
+ const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
|
||||
- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
- break;
|
||||
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3088,11 +3092,13 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
||||
break;
|
||||
|
||||
case PMT_TYPE_XTAL_TIME:
|
||||
- const unsigned long value_raw = p->pmt_counter[i];
|
||||
- const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
+ {
|
||||
+ const unsigned long value_raw = p->pmt_counter[i];
|
||||
+ const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||
|
||||
- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
- break;
|
||||
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
@ -1,59 +0,0 @@
|
||||
From 6cdb8d6b6ca8d1cdc7e7f6dbc2469fb81fc4062e Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Fri, 10 May 2024 20:24:31 -0700
|
||||
Subject: [PATCH] ice: Use irq_update_affinity_hint
|
||||
|
||||
This commit makes the ice device driver use the irq_update_affinity_hint
|
||||
function instead of the irq_set_affinity_hint function. This is done
|
||||
because the latter function sets the IRQ CPU affinities, whereas the
|
||||
former does not, and this allows the use of the default IRQ affinity CPU
|
||||
mask provided via the irqaffinity= kernel command line option.
|
||||
|
||||
Please note that this patch was not cherry-picked from an upstream
|
||||
commit. The changes have been inspired by the i40e and iavf device
|
||||
driver patches in the following patch series:
|
||||
https://lore.kernel.org/netdev/20210903152430.244937-1-nitesh@redhat.com/t/#u
|
||||
|
||||
The aforementioned patches have been mainlined as of this writing with
|
||||
the following merge commit by Linus Torvalds:
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=147cc5838c0f5c76e908b816e924ca378e0d4735
|
||||
|
||||
And the i40e and iavf patches are accessible at:
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34c54d1739c2cdf2e4437b74e6da269147f4987
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f9744f4ed539f2e847d7ed41993b243e3ba5cff
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 2235636756b9..b545b2a4e667 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1227,7 +1227,7 @@ uapi-asm-generic:
|
||||
|
||||
# KERNELRELEASE can change from a few different places, meaning version.h
|
||||
# needs to be updated, so this check is forced on all builds
|
||||
-ICE_STX = "-stx.0"
|
||||
+ICE_STX = "-stx.1"
|
||||
I40E_STX = "-stx.0"
|
||||
IAVF_STX = "-stx.0"
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 149984fb8ab0..c5ef2f422c34 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -2574,7 +2574,7 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename)
|
||||
irq_num = vsi->q_vectors[vector]->irq.virq;
|
||||
if (!IS_ENABLED(CONFIG_RFS_ACCEL))
|
||||
irq_set_affinity_notifier(irq_num, NULL);
|
||||
- irq_set_affinity_hint(irq_num, NULL);
|
||||
+ irq_update_affinity_hint(irq_num, NULL);
|
||||
devm_free_irq(dev, irq_num, &vsi->q_vectors[vector]);
|
||||
}
|
||||
return err;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,106 +0,0 @@
|
||||
From 3fda533e3df1a170a69c0634f7d182501d92a430 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Zhang <Peng.Zhang2@windriver.com>
|
||||
Date: Tue, 1 Apr 2025 15:39:34 +0800
|
||||
Subject: [PATCH] sched/debug: Fix the runnable tasks output
|
||||
|
||||
The current runnable tasks output looks like:
|
||||
|
||||
runnable tasks:
|
||||
S task PID tree-key switches prio wait-time sum-exec sum-sleep
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
Ikworker/R-rcu_g 4 0.129049 E 0.620179 0.750000 0.002920 2 100 0.000000 0.002920 0.000000 0.000000 0 0 /
|
||||
Ikworker/R-sync_ 5 0.125328 E 0.624147 0.750000 0.001840 2 100 0.000000 0.001840 0.000000 0.000000 0 0 /
|
||||
Ikworker/R-slub_ 6 0.120835 E 0.628680 0.750000 0.001800 2 100 0.000000 0.001800 0.000000 0.000000 0 0 /
|
||||
Ikworker/R-netns 7 0.114294 E 0.634701 0.750000 0.002400 2 100 0.000000 0.002400 0.000000 0.000000 0 0 /
|
||||
I kworker/0:1 9 508.781746 E 511.754666 3.000000 151.575240 224 120 0.000000 151.575240 0.000000 0.000000 0 0 /
|
||||
|
||||
Which is messy. Remove the duplicate printing of sum_exec_runtime and
|
||||
tidy up the layout to make it look like:
|
||||
|
||||
runnable tasks:
|
||||
S task PID vruntime eligible deadline slice sum-exec switches prio wait-time sum-sleep sum-block node group-id group-path
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
I kworker/0:3 1698 295.001459 E 297.977619 3.000000 38.862920 9 120 0.000000 0.000000 0.000000 0 0 /
|
||||
I kworker/0:4 1702 278.026303 E 281.026303 3.000000 9.918760 3 120 0.000000 0.000000 0.000000 0 0 /
|
||||
S NetworkManager 2646 0.377936 E 2.598104 3.000000 98.535880 314 120 0.000000 0.000000 0.000000 0 0 /system.slice/NetworkManager.service
|
||||
S virtqemud 2689 0.541016 E 2.440104 3.000000 50.967960 80 120 0.000000 0.000000 0.000000 0 0 /system.slice/virtqemud.service
|
||||
S gsd-smartcard 3058 73.604144 E 76.475904 3.000000 74.033320 88 120 0.000000 0.000000 0.000000 0 0 /user.slice/user-42.slice/session-c1.scope
|
||||
|
||||
Reviewed-by: Christoph Lameter (Ampere) <cl@linux.com>
|
||||
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
|
||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
||||
Link: https://lkml.kernel.org/r/20240906053019.7874-1-shijie@os.amperecomputing.com
|
||||
(Adapted for context change)
|
||||
Signed-off-by: Peng Zhang <Peng.Zhang2@windriver.com>
|
||||
(cherry picked from commit 2cab4bd024d23f658e40dce209dfd012f4e8b19a)
|
||||
---
|
||||
kernel/sched/debug.c | 31 +++++++++++++++++++++++--------
|
||||
1 file changed, 23 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
|
||||
index 4c3d0d9f3..acdce2ee1 100644
|
||||
--- a/kernel/sched/debug.c
|
||||
+++ b/kernel/sched/debug.c
|
||||
@@ -579,7 +579,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
|
||||
else
|
||||
SEQ_printf(m, " %c", task_state_to_char(p));
|
||||
|
||||
- SEQ_printf(m, "%15s %5d %9Ld.%06ld %c %9Ld.%06ld %9Ld.%06ld %9Ld.%06ld %9Ld %5d ",
|
||||
+ SEQ_printf(m, " %15s %5d %9Ld.%06ld %c %9Ld.%06ld %9Ld.%06ld %9Ld.%06ld %9Ld %5d ",
|
||||
p->comm, task_pid_nr(p),
|
||||
SPLIT_NS(p->se.vruntime),
|
||||
entity_eligible(cfs_rq_of(&p->se), &p->se) ? 'E' : 'N',
|
||||
@@ -589,17 +589,16 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
|
||||
(long long)(p->nvcsw + p->nivcsw),
|
||||
p->prio);
|
||||
|
||||
- SEQ_printf(m, "%9lld.%06ld %9lld.%06ld %9lld.%06ld %9lld.%06ld",
|
||||
+ SEQ_printf(m, "%9lld.%06ld %9lld.%06ld %9lld.%06ld",
|
||||
SPLIT_NS(schedstat_val_or_zero(p->stats.wait_sum)),
|
||||
- SPLIT_NS(p->se.sum_exec_runtime),
|
||||
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_sleep_runtime)),
|
||||
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime)));
|
||||
|
||||
#ifdef CONFIG_NUMA_BALANCING
|
||||
- SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p));
|
||||
+ SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p));
|
||||
#endif
|
||||
#ifdef CONFIG_CGROUP_SCHED
|
||||
- SEQ_printf_task_group_path(m, task_group(p), " %s")
|
||||
+ SEQ_printf_task_group_path(m, task_group(p), " %s")
|
||||
#endif
|
||||
|
||||
SEQ_printf(m, "\n");
|
||||
@@ -611,10 +610,26 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
|
||||
|
||||
SEQ_printf(m, "\n");
|
||||
SEQ_printf(m, "runnable tasks:\n");
|
||||
- SEQ_printf(m, " S task PID tree-key switches prio"
|
||||
- " wait-time sum-exec sum-sleep\n");
|
||||
+ SEQ_printf(m, " S task PID vruntime eligible "
|
||||
+ "deadline slice sum-exec switches "
|
||||
+ "prio wait-time sum-sleep sum-block"
|
||||
+#ifdef CONFIG_NUMA_BALANCING
|
||||
+ " node group-id"
|
||||
+#endif
|
||||
+#ifdef CONFIG_CGROUP_SCHED
|
||||
+ " group-path"
|
||||
+#endif
|
||||
+ "\n");
|
||||
SEQ_printf(m, "-------------------------------------------------------"
|
||||
- "------------------------------------------------------\n");
|
||||
+ "------------------------------------------------------"
|
||||
+ "------------------------------------------------------"
|
||||
+#ifdef CONFIG_NUMA_BALANCING
|
||||
+ "--------------"
|
||||
+#endif
|
||||
+#ifdef CONFIG_CGROUP_SCHED
|
||||
+ "--------------"
|
||||
+#endif
|
||||
+ "\n");
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_process_thread(g, p) {
|
||||
--
|
||||
2.34.1
|
||||
|
@ -1,207 +0,0 @@
|
||||
From a616a8c8e5e479cc01a752f93a9887ed51bb150e Mon Sep 17 00:00:00 2001
|
||||
From: Jon Maxwell <jmaxwell37@gmail.com>
|
||||
Date: Thu, 12 Jan 2023 12:25:32 +1100
|
||||
Subject: [PATCH] ipv6: remove max_size check inline with ipv4
|
||||
|
||||
In ip6_dst_gc() replace:
|
||||
|
||||
if (entries > gc_thresh)
|
||||
|
||||
With:
|
||||
|
||||
if (entries > ops->gc_thresh)
|
||||
|
||||
Sending Ipv6 packets in a loop via a raw socket triggers an issue where a
|
||||
route is cloned by ip6_rt_cache_alloc() for each packet sent. This quickly
|
||||
consumes the Ipv6 max_size threshold which defaults to 4096 resulting in
|
||||
these warnings:
|
||||
|
||||
[1] 99.187805] dst_alloc: 7728 callbacks suppressed
|
||||
[2] Route cache is full: consider increasing sysctl net.ipv6.route.max_size.
|
||||
.
|
||||
.
|
||||
[300] Route cache is full: consider increasing sysctl net.ipv6.route.max_size.
|
||||
|
||||
When this happens the packet is dropped and sendto() gets a network is
|
||||
unreachable error:
|
||||
|
||||
remaining pkt 200557 errno 101
|
||||
remaining pkt 196462 errno 101
|
||||
.
|
||||
.
|
||||
remaining pkt 126821 errno 101
|
||||
|
||||
Implement David Aherns suggestion to remove max_size check seeing that Ipv6
|
||||
has a GC to manage memory usage. Ipv4 already does not check max_size.
|
||||
|
||||
Here are some memory comparisons for Ipv4 vs Ipv6 with the patch:
|
||||
|
||||
Test by running 5 instances of a program that sends UDP packets to a raw
|
||||
socket 5000000 times. Compare Ipv4 and Ipv6 performance with a similar
|
||||
program.
|
||||
|
||||
Ipv4:
|
||||
|
||||
Before test:
|
||||
|
||||
MemFree: 29427108 kB
|
||||
Slab: 237612 kB
|
||||
|
||||
ip6_dst_cache 1912 2528 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 2881 3990 192 42 2 : tunables 0 0 0
|
||||
|
||||
During test:
|
||||
|
||||
MemFree: 29417608 kB
|
||||
Slab: 247712 kB
|
||||
|
||||
ip6_dst_cache 1912 2528 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 44394 44394 192 42 2 : tunables 0 0 0
|
||||
|
||||
After test:
|
||||
|
||||
MemFree: 29422308 kB
|
||||
Slab: 238104 kB
|
||||
|
||||
ip6_dst_cache 1912 2528 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 3048 4116 192 42 2 : tunables 0 0 0
|
||||
|
||||
Ipv6 with patch:
|
||||
|
||||
Errno 101 errors are not observed anymore with the patch.
|
||||
|
||||
Before test:
|
||||
|
||||
MemFree: 29422308 kB
|
||||
Slab: 238104 kB
|
||||
|
||||
ip6_dst_cache 1912 2528 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 3048 4116 192 42 2 : tunables 0 0 0
|
||||
|
||||
During Test:
|
||||
|
||||
MemFree: 29431516 kB
|
||||
Slab: 240940 kB
|
||||
|
||||
ip6_dst_cache 11980 12064 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 3048 4116 192 42 2 : tunables 0 0 0
|
||||
|
||||
After Test:
|
||||
|
||||
MemFree: 29441816 kB
|
||||
Slab: 238132 kB
|
||||
|
||||
ip6_dst_cache 1902 2432 256 32 2 : tunables 0 0 0
|
||||
xfrm_dst_cache 0 0 320 25 2 : tunables 0 0 0
|
||||
ip_dst_cache 3048 4116 192 42 2 : tunables 0 0 0
|
||||
|
||||
Tested-by: Andrea Mayer <andrea.mayer@uniroma2.it>
|
||||
Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
|
||||
Reviewed-by: David Ahern <dsahern@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20230112012532.311021-1-jmaxwell37@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit af6d10345ca76670c1b7c37799f0d5576ccef277)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
include/net/dst_ops.h | 2 +-
|
||||
net/core/dst.c | 8 ++------
|
||||
net/ipv6/route.c | 13 +++++--------
|
||||
3 files changed, 8 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
|
||||
index 88ff7bb2bb9b..632086b2f644 100644
|
||||
--- a/include/net/dst_ops.h
|
||||
+++ b/include/net/dst_ops.h
|
||||
@@ -16,7 +16,7 @@ struct dst_ops {
|
||||
unsigned short family;
|
||||
unsigned int gc_thresh;
|
||||
|
||||
- int (*gc)(struct dst_ops *ops);
|
||||
+ void (*gc)(struct dst_ops *ops);
|
||||
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
|
||||
unsigned int (*default_advmss)(const struct dst_entry *);
|
||||
unsigned int (*mtu)(const struct dst_entry *);
|
||||
diff --git a/net/core/dst.c b/net/core/dst.c
|
||||
index fb3bcba87744..453ec8aafc4a 100644
|
||||
--- a/net/core/dst.c
|
||||
+++ b/net/core/dst.c
|
||||
@@ -83,12 +83,8 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
|
||||
|
||||
if (ops->gc &&
|
||||
!(flags & DST_NOCOUNT) &&
|
||||
- dst_entries_get_fast(ops) > ops->gc_thresh) {
|
||||
- if (ops->gc(ops)) {
|
||||
- pr_notice_ratelimited("Route cache is full: consider increasing sysctl net.ipv6.route.max_size.\n");
|
||||
- return NULL;
|
||||
- }
|
||||
- }
|
||||
+ dst_entries_get_fast(ops) > ops->gc_thresh)
|
||||
+ ops->gc(ops);
|
||||
|
||||
dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC);
|
||||
if (!dst)
|
||||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
|
||||
index a6d5c99f65a3..b23e42efb3df 100644
|
||||
--- a/net/ipv6/route.c
|
||||
+++ b/net/ipv6/route.c
|
||||
@@ -89,7 +89,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *);
|
||||
static void ip6_dst_destroy(struct dst_entry *);
|
||||
static void ip6_dst_ifdown(struct dst_entry *,
|
||||
struct net_device *dev, int how);
|
||||
-static int ip6_dst_gc(struct dst_ops *ops);
|
||||
+static void ip6_dst_gc(struct dst_ops *ops);
|
||||
|
||||
static int ip6_pkt_discard(struct sk_buff *skb);
|
||||
static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||
@@ -3184,11 +3184,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
|
||||
return dst;
|
||||
}
|
||||
|
||||
-static int ip6_dst_gc(struct dst_ops *ops)
|
||||
+static void ip6_dst_gc(struct dst_ops *ops)
|
||||
{
|
||||
struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops);
|
||||
int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval;
|
||||
- int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size;
|
||||
int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
|
||||
int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout;
|
||||
unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc;
|
||||
@@ -3196,11 +3195,10 @@ static int ip6_dst_gc(struct dst_ops *ops)
|
||||
int entries;
|
||||
|
||||
entries = dst_entries_get_fast(ops);
|
||||
- if (entries > rt_max_size)
|
||||
+ if (entries > ops->gc_thresh)
|
||||
entries = dst_entries_get_slow(ops);
|
||||
|
||||
- if (time_after(rt_last_gc + rt_min_interval, jiffies) &&
|
||||
- entries <= rt_max_size)
|
||||
+ if (time_after(rt_last_gc + rt_min_interval, jiffies))
|
||||
goto out;
|
||||
|
||||
fib6_run_gc(atomic_inc_return(&net->ipv6.ip6_rt_gc_expire), net, true);
|
||||
@@ -3210,7 +3208,6 @@ static int ip6_dst_gc(struct dst_ops *ops)
|
||||
out:
|
||||
val = atomic_read(&net->ipv6.ip6_rt_gc_expire);
|
||||
atomic_set(&net->ipv6.ip6_rt_gc_expire, val - (val >> rt_elasticity));
|
||||
- return entries > rt_max_size;
|
||||
}
|
||||
|
||||
static int ip6_nh_lookup_table(struct net *net, struct fib6_config *cfg,
|
||||
@@ -6363,7 +6360,7 @@ static int __net_init ip6_route_net_init(struct net *net)
|
||||
#endif
|
||||
|
||||
net->ipv6.sysctl.flush_delay = 0;
|
||||
- net->ipv6.sysctl.ip6_rt_max_size = 4096;
|
||||
+ net->ipv6.sysctl.ip6_rt_max_size = INT_MAX;
|
||||
net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
|
||||
net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
|
||||
net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,684 +0,0 @@
|
||||
From ba0d88d4ff54805aac7aec77cc5b05d0df9114da Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:34 +0200
|
||||
Subject: [PATCH 01/36] ice: Auxbus devices & driver for E822 TS
|
||||
|
||||
There is a problem in HW in E822-based devices leading to race
|
||||
condition.
|
||||
It might happen that, in order:
|
||||
- PF0 (which owns the PHC) requests few timestamps,
|
||||
- PF1 requests a timestamp,
|
||||
- interrupt is being triggered and both PF0 and PF1 threads are woken
|
||||
up,
|
||||
- PF0 got one timestamp, still waiting for others so not going to sleep,
|
||||
- PF1 gets it's timestamp, process it and go to sleep,
|
||||
- PF1 requests a timestamp again,
|
||||
- just before PF0 goes to sleep timestamp of PF1 appear,
|
||||
- PF0 finishes all it's timestamps and go to sleep (PF1 also sleeping).
|
||||
That leaves PF1 timestamp memory not read, which lead to blocking the
|
||||
next interrupt from arriving.
|
||||
|
||||
Fix it by adding auxiliary devices and only one driver to handle all the
|
||||
timestamps for all PF's by PHC owner. In the past each PF requested it's
|
||||
own timestamps and process it from the start till the end which causes
|
||||
problem described above. Currently each PF requests the timestamps as
|
||||
before, but the actual reading of the completed timestamps is being done
|
||||
by the PTP auxiliary driver, which is registered by the PF which owns PHC.
|
||||
|
||||
Additionally, the newly introduced auxiliary driver/devices for PTP clock
|
||||
owner will be used for other features in all products (including E810).
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d938a8cca88a5f02f523f95fe3d2d1214f4b4a8d)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 12 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 11 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 393 +++++++++++++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 30 ++
|
||||
5 files changed, 430 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index b9cd0113b859..0a3d76d184ba 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -671,6 +671,18 @@ static inline bool ice_vector_ch_enabled(struct ice_q_vector *qv)
|
||||
return !!qv->ch; /* Enable it to run with TC */
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_pf_handles_tx_interrupt - Check if PF handles Tx interrupt
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Return true if this PF should respond to the Tx timestamp interrupt
|
||||
+ * indication in the miscellaneous OICR interrupt handler.
|
||||
+ */
|
||||
+static inline bool ice_ptp_pf_handles_tx_interrupt(struct ice_pf *pf)
|
||||
+{
|
||||
+ return pf->ptp.tx_interrupt_mode != ICE_PTP_TX_INTERRUPT_NONE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_irq_dynamic_ena - Enable default interrupt generation settings
|
||||
* @hw: pointer to HW struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 531cc2194741..6756f3d51d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -231,6 +231,7 @@
|
||||
#define PFINT_SB_CTL 0x0016B600
|
||||
#define PFINT_SB_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
|
||||
#define PFINT_SB_CTL_CAUSE_ENA_M BIT(30)
|
||||
+#define PFINT_TSYN_MSK 0x0016C980
|
||||
#define QINT_RQCTL(_QRX) (0x00150000 + ((_QRX) * 4))
|
||||
#define QINT_RQCTL_MSIX_INDX_S 0
|
||||
#define QINT_RQCTL_MSIX_INDX_M ICE_M(0x7FF, 0)
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8a6acb5a722e..39cb6ee52abe 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_TX_M) {
|
||||
ena_mask &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- if (!hw->reset_ongoing)
|
||||
+ if (!hw->reset_ongoing && ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
}
|
||||
|
||||
@@ -7444,8 +7444,13 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
}
|
||||
|
||||
/* configure PTP timestamping after VSI rebuild */
|
||||
- if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
+ ice_ptp_cfg_timestamp(pf, false);
|
||||
+ else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL)
|
||||
+ /* for E82x PHC owner always need to have interrupts */
|
||||
+ ice_ptp_cfg_timestamp(pf, true);
|
||||
+ }
|
||||
|
||||
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
|
||||
if (err) {
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 3648d3cccacc..e3012608c9dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -255,6 +255,24 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
return ice_ptp_set_sma_e810t(info, pin, func);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
+ * @pf: The PF pointer to search in
|
||||
+ * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ */
|
||||
+static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Configure the Tx timestamp interrupt */
|
||||
+ val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
+ if (on)
|
||||
+ val |= PFINT_OICR_TSYN_TX_M;
|
||||
+ else
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -263,7 +281,6 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
struct ice_vsi *vsi;
|
||||
- u32 val;
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
@@ -277,13 +294,8 @@ static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
vsi->tx_rings[i]->ptp_tx = on;
|
||||
}
|
||||
|
||||
- /* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
- val |= PFINT_OICR_TSYN_TX_M;
|
||||
- else
|
||||
- val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
+ ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
}
|
||||
@@ -674,9 +686,6 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
int err;
|
||||
u8 idx;
|
||||
|
||||
- if (!tx->init)
|
||||
- return;
|
||||
-
|
||||
ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
pf = ptp_port_to_pf(ptp_port);
|
||||
hw = &pf->hw;
|
||||
@@ -774,6 +783,39 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ mutex_lock(&pf->ptp.ports_owner.lock);
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) {
|
||||
+ struct ice_ptp_tx *tx = &port->tx;
|
||||
+
|
||||
+ if (!tx || !tx->init)
|
||||
+ continue;
|
||||
+
|
||||
+ ice_ptp_process_tx_tstamp(tx);
|
||||
+ }
|
||||
+ mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Read the Tx ready status first */
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (err || tstamp_ready)
|
||||
+ return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
+ }
|
||||
+
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_tx_tstamp - Process Tx timestamps for this function.
|
||||
* @tx: Tx tracking structure to initialize
|
||||
@@ -2448,7 +2490,21 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
*/
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
- return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* This device has the clock owner handle timestamps for it */
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ /* This device handles its own timestamps */
|
||||
+ return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* This device handles timestamps for all ports */
|
||||
+ return ice_ptp_tx_tstamp_owner(pf);
|
||||
+ default:
|
||||
+ WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n",
|
||||
+ pf->ptp.tx_interrupt_mode);
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
@@ -2557,6 +2613,187 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the auxiliary PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_aux_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port *aux_port;
|
||||
+ struct ice_ptp *aux_ptp;
|
||||
+
|
||||
+ aux_port = container_of(aux_dev, struct ice_ptp_port, aux_dev);
|
||||
+ aux_ptp = container_of(aux_port, struct ice_ptp, port);
|
||||
+
|
||||
+ return container_of(aux_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_owner_pf - Get PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_owner_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port_owner *ports_owner;
|
||||
+ struct auxiliary_driver *aux_drv;
|
||||
+ struct ice_ptp *owner_ptp;
|
||||
+
|
||||
+ if (!aux_dev->dev.driver)
|
||||
+ return NULL;
|
||||
+
|
||||
+ aux_drv = to_auxiliary_drv(aux_dev->dev.driver);
|
||||
+ ports_owner = container_of(aux_drv, struct ice_ptp_port_owner,
|
||||
+ aux_driver);
|
||||
+ owner_ptp = container_of(ports_owner, struct ice_ptp, ports_owner);
|
||||
+ return container_of(owner_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_probe - Probe auxiliary devices
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @id: Auxiliary device ID
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev,
|
||||
+ const struct auxiliary_device_id *id)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ if (WARN_ON(!owner_pf))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_add(&aux_pf->ptp.port.list_member,
|
||||
+ &owner_pf->ptp.ports_owner.ports);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_remove - Remove auxiliary devices from the bus
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_del(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_shutdown
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_shutdown(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_suspend
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @state: power management state indicator
|
||||
+ */
|
||||
+static int
|
||||
+ice_ptp_auxbus_suspend(struct auxiliary_device *aux_dev, pm_message_t state)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_resume
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_resume(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_create_id_table - Create auxiliary device ID table
|
||||
+ * @pf: Board private structure
|
||||
+ * @name: auxiliary bus driver name
|
||||
+ */
|
||||
+static struct auxiliary_device_id *
|
||||
+ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name)
|
||||
+{
|
||||
+ struct auxiliary_device_id *ids;
|
||||
+
|
||||
+ /* Second id left empty to terminate the array */
|
||||
+ ids = devm_kcalloc(ice_pf_to_dev(pf), 2,
|
||||
+ sizeof(struct auxiliary_device_id), GFP_KERNEL);
|
||||
+ if (!ids)
|
||||
+ return NULL;
|
||||
+
|
||||
+ snprintf(ids[0].name, sizeof(ids[0].name), "ice.%s", name);
|
||||
+
|
||||
+ return ids;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+ aux_driver = &ptp->ports_owner.aux_driver;
|
||||
+ INIT_LIST_HEAD(&ptp->ports_owner.ports);
|
||||
+ mutex_init(&ptp->ports_owner.lock);
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_driver->name = name;
|
||||
+ aux_driver->shutdown = ice_ptp_auxbus_shutdown;
|
||||
+ aux_driver->suspend = ice_ptp_auxbus_suspend;
|
||||
+ aux_driver->remove = ice_ptp_auxbus_remove;
|
||||
+ aux_driver->resume = ice_ptp_auxbus_resume;
|
||||
+ aux_driver->probe = ice_ptp_auxbus_probe;
|
||||
+ aux_driver->id_table = ice_ptp_auxbus_create_id_table(pf, name);
|
||||
+ if (!aux_driver->id_table)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = auxiliary_driver_register(aux_driver);
|
||||
+ if (err) {
|
||||
+ devm_kfree(dev, aux_driver->id_table);
|
||||
+ dev_err(dev, "Failed registering aux_driver, name <%s>\n",
|
||||
+ name);
|
||||
+ }
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver;
|
||||
+
|
||||
+ auxiliary_driver_unregister(aux_driver);
|
||||
+ devm_kfree(ice_pf_to_dev(pf), aux_driver->id_table);
|
||||
+
|
||||
+ mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -2635,7 +2872,15 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (!ice_is_e810(hw)) {
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
+ /* The clock owner for this device type handles the timestamp
|
||||
+ * interrupt for all ports.
|
||||
+ */
|
||||
+ ice_ptp_configure_tx_tstamp(pf, true);
|
||||
+
|
||||
+ /* React on all quads interrupts for E82x */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2650,8 +2895,16 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Store the PTP clock index for other PFs */
|
||||
ice_set_ptp_clock_index(pf);
|
||||
|
||||
- return 0;
|
||||
+ err = ice_ptp_register_auxbus_driver(pf);
|
||||
+ if (err) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
+ goto err_aux;
|
||||
+ }
|
||||
|
||||
+ return 0;
|
||||
+err_aux:
|
||||
+ ice_clear_ptp_clock_index(pf);
|
||||
+ ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
err_exit:
|
||||
@@ -2701,6 +2954,13 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
+ /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
+ * neither on own quad nor on others
|
||||
+ */
|
||||
+ if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ ice_ptp_configure_tx_tstamp(pf, false);
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -2711,6 +2971,101 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_release_auxbus_device
|
||||
+ * @dev: device that utilizes the auxbus
|
||||
+ */
|
||||
+static void ice_ptp_release_auxbus_device(struct device *dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbux device must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_create_auxbus_device - Create PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_create_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+ u32 id;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ id = ptp->port.port_num;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+
|
||||
+ aux_dev = &ptp->port.aux_dev;
|
||||
+
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_dev->name = name;
|
||||
+ aux_dev->id = id;
|
||||
+ aux_dev->dev.release = ice_ptp_release_auxbus_device;
|
||||
+ aux_dev->dev.parent = dev;
|
||||
+
|
||||
+ err = auxiliary_device_init(aux_dev);
|
||||
+ if (err)
|
||||
+ goto aux_err;
|
||||
+
|
||||
+ err = auxiliary_device_add(aux_dev);
|
||||
+ if (err) {
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+ goto aux_err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+aux_err:
|
||||
+ dev_err(dev, "Failed to create PTP auxiliary bus device <%s>\n", name);
|
||||
+ devm_kfree(dev, name);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev;
|
||||
+
|
||||
+ auxiliary_device_delete(aux_dev);
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+
|
||||
+ memset(aux_dev, 0, sizeof(*aux_dev));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_init_tx_interrupt_mode - Initialize device Tx interrupt mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Initialize the Tx timestamp interrupt mode for this device. For most device
|
||||
+ * types, each PF processes the interrupt and manages its own timestamps. For
|
||||
+ * E822-based devices, only the clock owner processes the timestamps. Other
|
||||
+ * PFs disable the interrupt and do not process their own timestamps.
|
||||
+ */
|
||||
+static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ switch (pf->hw.phy_model) {
|
||||
+ case ICE_PHY_E822:
|
||||
+ /* E822 based PHY has the clock owner process the interrupt
|
||||
+ * for all ports.
|
||||
+ */
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL;
|
||||
+ else
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_NONE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* other PHY types handle their own Tx interrupt */
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_SELF;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_init - Initialize PTP hardware clock support
|
||||
* @pf: Board private structure
|
||||
@@ -2731,6 +3086,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
+ ice_ptp_init_tx_interrupt_mode(pf);
|
||||
+
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
@@ -2753,6 +3110,10 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
+ if (err)
|
||||
+ goto err;
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
|
||||
return;
|
||||
|
||||
@@ -2781,6 +3142,8 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_cfg_timestamp(pf, false);
|
||||
|
||||
+ ice_ptp_remove_auxbus_device(pf);
|
||||
+
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
@@ -2804,5 +3167,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 995a57019ba7..d94c22329df0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -157,7 +157,9 @@ struct ice_ptp_tx {
|
||||
* ready for PTP functionality. It is used to track the port initialization
|
||||
* and determine when the port's PHY offset is valid.
|
||||
*
|
||||
+ * @list_member: list member structure of auxiliary device
|
||||
* @tx: Tx timestamp tracking for this port
|
||||
+ * @aux_dev: auxiliary device associated with this port
|
||||
* @ov_work: delayed work task for tracking when PHY offset is valid
|
||||
* @ps_lock: mutex used to protect the overall PTP PHY start procedure
|
||||
* @link_up: indicates whether the link is up
|
||||
@@ -165,7 +167,9 @@ struct ice_ptp_tx {
|
||||
* @port_num: the port number this structure represents
|
||||
*/
|
||||
struct ice_ptp_port {
|
||||
+ struct list_head list_member;
|
||||
struct ice_ptp_tx tx;
|
||||
+ struct auxiliary_device aux_dev;
|
||||
struct kthread_delayed_work ov_work;
|
||||
struct mutex ps_lock; /* protects overall PTP PHY start procedure */
|
||||
bool link_up;
|
||||
@@ -173,11 +177,35 @@ struct ice_ptp_port {
|
||||
u8 port_num;
|
||||
};
|
||||
|
||||
+enum ice_ptp_tx_interrupt {
|
||||
+ ICE_PTP_TX_INTERRUPT_NONE = 0,
|
||||
+ ICE_PTP_TX_INTERRUPT_SELF,
|
||||
+ ICE_PTP_TX_INTERRUPT_ALL,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct ice_ptp_port_owner - data used to handle the PTP clock owner info
|
||||
+ *
|
||||
+ * This structure contains data necessary for the PTP clock owner to correctly
|
||||
+ * handle the timestamping feature for all attached ports.
|
||||
+ *
|
||||
+ * @aux_driver: the structure carring the auxiliary driver information
|
||||
+ * @ports: list of porst handled by this port owner
|
||||
+ * @lock: protect access to ports list
|
||||
+ */
|
||||
+struct ice_ptp_port_owner {
|
||||
+ struct auxiliary_driver aux_driver;
|
||||
+ struct list_head ports;
|
||||
+ struct mutex lock;
|
||||
+};
|
||||
+
|
||||
#define GLTSYN_TGT_H_IDX_MAX 4
|
||||
|
||||
/**
|
||||
* struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
|
||||
+ * @tx_interrupt_mode: the TX interrupt mode for the PTP clock
|
||||
* @port: data for the PHY port initialization procedure
|
||||
+ * @ports_owner: data for the auxiliary driver owner
|
||||
* @work: delayed work function for periodic tasks
|
||||
* @cached_phc_time: a cached copy of the PHC time for timestamp extension
|
||||
* @cached_phc_jiffies: jiffies when cached_phc_time was last updated
|
||||
@@ -197,7 +225,9 @@ struct ice_ptp_port {
|
||||
* @late_cached_phc_updates: number of times cached PHC update is late
|
||||
*/
|
||||
struct ice_ptp {
|
||||
+ enum ice_ptp_tx_interrupt tx_interrupt_mode;
|
||||
struct ice_ptp_port port;
|
||||
+ struct ice_ptp_port_owner ports_owner;
|
||||
struct kthread_delayed_work work;
|
||||
u64 cached_phc_time;
|
||||
unsigned long cached_phc_jiffies;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,95 +0,0 @@
|
||||
From f6af978ef435067b4c9f5ff5e159f8b65d969268 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 8 Sep 2023 14:37:14 -0700
|
||||
Subject: [PATCH 02/36] ice: introduce ice_pf_src_tmr_owned
|
||||
|
||||
Add ice_pf_src_tmr_owned() macro to check the function capability bit
|
||||
indicating if the current function owns the PTP hardware clock. This is
|
||||
slightly shorter than the more verbose access via
|
||||
hw.func_caps.ts_func_info.src_tmr_owned. Use this where possible rather
|
||||
than open coding its equivalent.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 42d40bb21e332151da6fb689bf7d4af8195866ed)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 6 +++---
|
||||
4 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 0a3d76d184ba..54a98c4032b7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -197,6 +197,8 @@ extern const char ice_drv_ver[];
|
||||
|
||||
#define ice_pf_to_dev(pf) (&((pf)->pdev->dev))
|
||||
|
||||
+#define ice_pf_src_tmr_owned(pf) ((pf)->hw.func_caps.ts_func_info.src_tmr_owned)
|
||||
+
|
||||
enum ice_feature {
|
||||
ICE_F_DSCP,
|
||||
ICE_F_PHY_RCLK,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 632091487413..106ef843f4b5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -4010,7 +4010,7 @@ void ice_init_feature_support(struct ice_pf *pf)
|
||||
if (ice_is_phy_rclk_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_PHY_RCLK);
|
||||
/* If we don't own the timer - don't enable other caps */
|
||||
- if (!pf->hw.func_caps.ts_func_info.src_tmr_owned)
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
break;
|
||||
if (ice_is_cgu_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_CGU);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 39cb6ee52abe..e957529b3fd6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3200,7 +3200,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
|
||||
ena_mask &= ~PFINT_OICR_TSYN_EVNT_M;
|
||||
|
||||
- if (hw->func_caps.ts_func_info.src_tmr_owned) {
|
||||
+ if (ice_pf_src_tmr_owned(pf)) {
|
||||
/* Save EVENTs from GLTSYN register */
|
||||
pf->ptp.ext_ts_irq |= gltsyn_stat &
|
||||
(GLTSYN_STAT_EVENT0_M |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index e3012608c9dd..b1951357ba9f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -448,7 +448,7 @@ static void ice_clear_ptp_clock_index(struct ice_pf *pf)
|
||||
int err;
|
||||
|
||||
/* Do not clear the index if we don't own the timer */
|
||||
- if (!hw->func_caps.ts_func_info.src_tmr_owned)
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
return;
|
||||
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
@@ -2538,7 +2538,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
goto pfr;
|
||||
|
||||
- if (!hw->func_caps.ts_func_info.src_tmr_owned)
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
goto reset_ts;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
@@ -3091,7 +3091,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
- if (hw->func_caps.ts_func_info.src_tmr_owned) {
|
||||
+ if (ice_pf_src_tmr_owned(pf)) {
|
||||
err = ice_ptp_init_owner(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,93 +0,0 @@
|
||||
From 3c155fbf8e2a0546302a01cc06e8ece18468148e Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:42 -0800
|
||||
Subject: [PATCH 03/36] ice: Re-enable timestamping correctly after reset
|
||||
|
||||
During reset, TX_TSYN interrupt should be processed as it may process
|
||||
timestamps in brief moments before and after reset.
|
||||
Timestamping should be enabled on VSIs at the end of reset procedure.
|
||||
On ice_get_phy_tx_tstamp_ready error, interrupt should not be rearmed
|
||||
because error only happens on resets.
|
||||
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1cc5b6eaad92d69fe4d84bbee5c12ee297d56296)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 19 ++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index e957529b3fd6..d2f3b4374d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_TX_M) {
|
||||
ena_mask &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- if (!hw->reset_ongoing && ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b1951357ba9f..92459589f6ce 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -809,7 +809,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
- if (err || tstamp_ready)
|
||||
+ if (err)
|
||||
+ break;
|
||||
+ else if (tstamp_ready)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
}
|
||||
|
||||
@@ -2535,12 +2537,10 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
+ !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- goto reset_ts;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
goto err;
|
||||
@@ -2584,10 +2584,6 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-reset_ts:
|
||||
- /* Restart the PHY timestamping block */
|
||||
- ice_ptp_reset_phy_timestamping(pf);
|
||||
-
|
||||
pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
@@ -2603,6 +2599,11 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
+ /* Restart the PHY timestamping block */
|
||||
+ if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
+ ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,121 +0,0 @@
|
||||
From 214f06259ade960e3790b62f96bc1b75e5b76e79 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:43 -0800
|
||||
Subject: [PATCH 04/36] ice: periodically kick Tx timestamp interrupt
|
||||
|
||||
The E822 hardware for Tx timestamping keeps track of how many
|
||||
outstanding timestamps are still in the PHY memory block. It will not
|
||||
generate a new interrupt to the MAC until all of the timestamps in the
|
||||
region have been read.
|
||||
|
||||
If somehow all the available data is not read, but the driver has exited
|
||||
its interrupt routine already, the PHY will not generate a new interrupt
|
||||
even if new timestamp data is captured. Because no interrupt is
|
||||
generated, the driver never processes the timestamp data. This state
|
||||
results in a permanent failure for all future Tx timestamps.
|
||||
|
||||
It is not clear how the driver and hardware could enter this state.
|
||||
However, if it does, there is currently no recovery mechanism.
|
||||
|
||||
Add a recovery mechanism via the periodic PTP work thread which invokes
|
||||
ice_ptp_periodic_work(). Introduce a new check,
|
||||
ice_ptp_maybe_trigger_tx_interrupt() which checks the PHY timestamp
|
||||
ready bitmask. If any bits are set, trigger a software interrupt by
|
||||
writing to PFINT_OICR.
|
||||
|
||||
Once triggered, the main timestamp processing thread will read through
|
||||
the PHY data and clear the outstanding timestamp data. Once cleared, new
|
||||
data should trigger interrupts as expected.
|
||||
|
||||
This should allow recovery from such a state rather than leaving the
|
||||
device in a state where we cannot process Tx timestamps.
|
||||
|
||||
It is possible that this function checks for timestamp data
|
||||
simultaneously with the interrupt, and it might trigger additional
|
||||
unnecessary interrupts. This will cause a small amount of additional
|
||||
processing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Andrii Staikov <andrii.staikov@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 712e876371f8350c446a33577cf4a0aedcd4742a)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 50 ++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 92459589f6ce..0d6c7215e0c1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2509,6 +2509,54 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_maybe_trigger_tx_interrupt - Trigger Tx timstamp interrupt
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * The device PHY issues Tx timestamp interrupts to the driver for processing
|
||||
+ * timestamp data from the PHY. It will not interrupt again until all
|
||||
+ * current timestamp data is read. In rare circumstances, it is possible that
|
||||
+ * the driver fails to read all outstanding data.
|
||||
+ *
|
||||
+ * To avoid getting permanently stuck, periodically check if the PHY has
|
||||
+ * outstanding timestamp data. If so, trigger an interrupt from software to
|
||||
+ * process this data.
|
||||
+ */
|
||||
+static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool trigger_oicr = false;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (ice_is_e810(hw))
|
||||
+ return;
|
||||
+
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (!err && tstamp_ready) {
|
||||
+ trigger_oicr = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (trigger_oicr) {
|
||||
+ /* Trigger a software interrupt, to ensure this data
|
||||
+ * gets processed.
|
||||
+ */
|
||||
+ dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
|
||||
+
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
{
|
||||
struct ice_ptp *ptp = container_of(work, struct ice_ptp, work.work);
|
||||
@@ -2520,6 +2568,8 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
|
||||
+ ice_ptp_maybe_trigger_tx_interrupt(pf);
|
||||
+
|
||||
/* Run twice a second or reschedule if phc update failed */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work,
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,81 +0,0 @@
|
||||
From c25fc364d599195403ed9ba51ef8fa6ed3b642ff Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:44 -0700
|
||||
Subject: [PATCH 05/36] ice: PTP: Rename macros used for PHY/QUAD port
|
||||
definitions
|
||||
|
||||
The ice_fill_phy_msg_e822 function uses several macros to specify the
|
||||
correct address when sending a sideband message to the PHY block in
|
||||
hardware.
|
||||
|
||||
The names of these macros are fairly generic and confusing. Future
|
||||
development is going to extend the driver to support new hardware families
|
||||
which have different relationships between PHY and QUAD. Rename the macros
|
||||
for clarity and to indicate that they are E822 specific. This also matches
|
||||
closer to the hardware specification in the data sheet.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 64fd7de2469dd52a7f1517ce95ae22fcb391a8a1)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 8 ++++----
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 14 +++++++-------
|
||||
2 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index a299af39a7c4..03c4aa995e8d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -294,9 +294,9 @@ ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY;
|
||||
- phy = port / ICE_PORTS_PER_PHY;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_NUM_QUAD_TYPE;
|
||||
+ phy_port = port % ICE_PORTS_PER_PHY_E822;
|
||||
+ phy = port / ICE_PORTS_PER_PHY_E822;
|
||||
+ quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E822;
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -628,7 +628,7 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_NUM_QUAD_TYPE) == 0)
|
||||
+ if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 4cd131546aa9..bb5d8b681bc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -909,13 +909,13 @@ struct ice_hw {
|
||||
/* INTRL granularity in 1 us */
|
||||
u8 intrl_gran;
|
||||
|
||||
-#define ICE_PHY_PER_NAC 1
|
||||
-#define ICE_MAX_QUAD 2
|
||||
-#define ICE_NUM_QUAD_TYPE 2
|
||||
-#define ICE_PORTS_PER_QUAD 4
|
||||
-#define ICE_PHY_0_LAST_QUAD 1
|
||||
-#define ICE_PORTS_PER_PHY 8
|
||||
-#define ICE_NUM_EXTERNAL_PORTS ICE_PORTS_PER_PHY
|
||||
+#define ICE_PHY_PER_NAC_E822 1
|
||||
+#define ICE_MAX_QUAD 2
|
||||
+#define ICE_QUADS_PER_PHY_E822 2
|
||||
+#define ICE_PORTS_PER_PHY_E822 8
|
||||
+#define ICE_PORTS_PER_QUAD 4
|
||||
+#define ICE_PORTS_PER_PHY_E810 4
|
||||
+#define ICE_NUM_EXTERNAL_PORTS (ICE_MAX_QUAD * ICE_PORTS_PER_QUAD)
|
||||
|
||||
/* Active package version (currently active) */
|
||||
struct ice_pkg_ver active_pkg_ver;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,80 +0,0 @@
|
||||
From 13f48f4c94ad4d317e7c7ccaa188a11850a8aa32 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:45 -0700
|
||||
Subject: [PATCH 06/36] ice: PTP: move quad value check inside
|
||||
ice_fill_phy_msg_e822
|
||||
|
||||
The callers of ice_fill_phy_msg_e822 check for whether the quad number is
|
||||
within the expected range. Move this check inside the ice_fill_phy_msg_e822
|
||||
function instead of duplicating it twice.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit dd84744cf5ea967c8d53aae6b6a45703dbc5c5c4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 19 ++++++++++++-------
|
||||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 03c4aa995e8d..e024b88ce32b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -621,11 +621,14 @@ ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
*/
|
||||
-static void
|
||||
+static int
|
||||
ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
+ if (quad >= ICE_MAX_QUAD)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
@@ -635,6 +638,8 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->msg_addr_low = lower_16_bits(addr);
|
||||
msg->msg_addr_high = upper_16_bits(addr);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,10 +658,10 @@ ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -687,10 +692,10 @@ ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 7dae9333af82f6c9e2db1940c3a10ae38dabea7b Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:55 -0800
|
||||
Subject: [PATCH 07/36] ice: remove ptp_tx ring parameter flag
|
||||
|
||||
Before performing a Tx timestamp in ice_stamp(), the driver checks a ptp_tx
|
||||
ring variable to see if timestamping is enabled on that ring. This value is
|
||||
set for all rings whenever userspace configures Tx timestamping.
|
||||
|
||||
Ostensibly this was done to avoid wasting cycles checking other fields when
|
||||
timestamping has not been enabled. However, for Tx timestamps we already
|
||||
get an individual per-SKB flag indicating whether userspace wants to
|
||||
request a timestamp on that packet. We do not gain much by also having
|
||||
a separate flag to check for whether timestamping was enabled.
|
||||
|
||||
In fact, the driver currently fails to restore the field after a PF reset.
|
||||
Because of this, if a PF reset occurs, timestamps will be disabled.
|
||||
|
||||
Since this flag doesn't add value in the hotpath, remove it and always
|
||||
provide a timestamp if the SKB flag has been set.
|
||||
|
||||
A following change will fix the reset path to properly restore user
|
||||
timestamping configuration completely.
|
||||
|
||||
This went unnoticed for some time because one of the most common
|
||||
applications using Tx timestamps, ptp4l, will reconfigure the socket as
|
||||
part of its fault recovery logic.
|
||||
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 0ffb08b1a45bd6b7694e01da0e1d9e3e788418fb)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 14 --------------
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.c | 3 ---
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.h | 1 -
|
||||
3 files changed, 18 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 0d6c7215e0c1..c03153bdb7c3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -280,20 +280,6 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- struct ice_vsi *vsi;
|
||||
- u16 i;
|
||||
-
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- /* Set the timestamp enable flag for all the Tx rings */
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (!vsi->tx_rings[i])
|
||||
- continue;
|
||||
- vsi->tx_rings[i]->ptp_tx = on;
|
||||
- }
|
||||
-
|
||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
index 24c914015973..9170a3e8f088 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
@@ -2305,9 +2305,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb,
|
||||
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
|
||||
return;
|
||||
|
||||
- if (!tx_ring->ptp_tx)
|
||||
- return;
|
||||
-
|
||||
/* Tx timestamps cannot be sampled when doing TSO */
|
||||
if (first->tx_flags & ICE_TX_FLAGS_TSO)
|
||||
return;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
index 407d4c320097..b28b9826bbcd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
@@ -381,7 +381,6 @@ struct ice_tx_ring {
|
||||
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
|
||||
u8 flags;
|
||||
u8 dcb_tc; /* Traffic class of ring */
|
||||
- u8 ptp_tx;
|
||||
} ____cacheline_internodealigned_in_smp;
|
||||
|
||||
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,160 +0,0 @@
|
||||
From 99007ca6255e2c35256bd97fa141705d301eb934 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:56 -0800
|
||||
Subject: [PATCH 08/36] ice: unify logic for programming PFINT_TSYN_MSK
|
||||
|
||||
Commit d938a8cca88a ("ice: Auxbus devices & driver for E822 TS") modified
|
||||
how Tx timestamps are handled for E822 devices. On these devices, only the
|
||||
clock owner handles reading the Tx timestamp data from firmware. To do
|
||||
this, the PFINT_TSYN_MSK register is modified from the default value to one
|
||||
which enables reacting to a Tx timestamp on all PHY ports.
|
||||
|
||||
The driver currently programs PFINT_TSYN_MSK in different places depending
|
||||
on whether the port is the clock owner or not. For the clock owner, the
|
||||
PFINT_TSYN_MSK value is programmed during ice_ptp_init_owner just before
|
||||
calling ice_ptp_tx_ena_intr to program the PHY ports.
|
||||
|
||||
For the non-clock owner ports, the PFINT_TSYN_MSK is programmed during
|
||||
ice_ptp_init_port.
|
||||
|
||||
If a large enough device reset occurs, the PFINT_TSYN_MSK register will be
|
||||
reset to the default value in which only the PHY associated directly with
|
||||
the PF will cause the Tx timestamp interrupt to trigger.
|
||||
|
||||
The driver lacks logic to reprogram the PFINT_TSYN_MSK register after a
|
||||
device reset. For the E822 device, this results in the PF no longer
|
||||
responding to interrupts for other ports. This results in failure to
|
||||
deliver Tx timestamps to user space applications.
|
||||
|
||||
Rename ice_ptp_configure_tx_tstamp to ice_ptp_cfg_tx_interrupt, and unify
|
||||
the logic for programming PFINT_TSYN_MSK and PFINT_OICR_ENA into one place.
|
||||
This function will program both registers according to the combination of
|
||||
user configuration and device requirements.
|
||||
|
||||
This ensures that PFINT_TSYN_MSK is always restored when we configure the
|
||||
Tx timestamp interrupt.
|
||||
|
||||
Fixes: d938a8cca88a ("ice: Auxbus devices & driver for E822 TS")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7d606a1e2d0575b6c3a2600f43f90d1e409f9661)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 60 ++++++++++++++----------
|
||||
1 file changed, 34 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c03153bdb7c3..b0bba866e8a2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -256,21 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ * ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Program the device to respond appropriately to the Tx timestamp interrupt
|
||||
+ * cause.
|
||||
*/
|
||||
-static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable;
|
||||
u32 val;
|
||||
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* React to interrupts across all quads. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+ enable = true;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* Do not react to interrupts on any quad. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ enable = false;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ default:
|
||||
+ enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ if (enable)
|
||||
val |= PFINT_OICR_TSYN_TX_M;
|
||||
else
|
||||
val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,10 +301,9 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
- ice_ptp_configure_tx_tstamp(pf, on);
|
||||
-
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2909,15 +2929,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
- /* The clock owner for this device type handles the timestamp
|
||||
- * interrupt for all ports.
|
||||
- */
|
||||
- ice_ptp_configure_tx_tstamp(pf, true);
|
||||
-
|
||||
- /* React on all quads interrupts for E82x */
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
-
|
||||
+ if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2991,13 +3003,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
- /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
- * neither on own quad nor on others
|
||||
- */
|
||||
- if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
- ice_ptp_configure_tx_tstamp(pf, false);
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
- }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -3142,6 +3147,9 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Start the PHY timestamping block */
|
||||
ice_ptp_reset_phy_timestamping(pf);
|
||||
|
||||
+ /* Configure initial Tx interrupt settings */
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,147 +0,0 @@
|
||||
From e5a65377977e338a8f7baf92892481acf1c62403 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:43 -0700
|
||||
Subject: [PATCH 09/36] ice: PTP: Clean up timestamp registers correctly
|
||||
|
||||
E822 PHY TS registers should not be written and the only way to clean up
|
||||
them is to reset QUAD memory.
|
||||
|
||||
To ensure that the status bit for the timestamp index is cleared, ensure
|
||||
that ice_clear_phy_tstamp implementations first read the timestamp out.
|
||||
Implementations which can write the register continue to do so.
|
||||
|
||||
Add a note to indicate this function should only be called on timestamps
|
||||
which have their valid bit set. Update the dynamic debug messages to
|
||||
reflect the actual action taken.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit be65a1a33bdee3912daac50aa6c5270ec9c37010)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 70 +++++++++++++--------
|
||||
1 file changed, 45 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index e024b88ce32b..cd28430cfdda 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -759,29 +759,32 @@ ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
|
||||
* @quad: the quad to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the PHY quad block that is
|
||||
- * shared between the internal PHYs on the E822 devices.
|
||||
+ * Read the timestamp out of the quad to clear its timestamp status bit from
|
||||
+ * the PHY quad block that is shared between the internal PHYs of the E822
|
||||
+ * devices.
|
||||
+ *
|
||||
+ * Note that unlike E810, software cannot directly write to the quad memory
|
||||
+ * bank registers. E822 relies on the ice_get_phy_tx_tstamp_ready() function
|
||||
+ * to determine which timestamps are valid. Reading a timestamp auto-clears
|
||||
+ * the valid bit.
|
||||
+ *
|
||||
+ * To directly clear the contents of the timestamp block entirely, discarding
|
||||
+ * all timestamp data at once, software should instead use
|
||||
+ * ice_ptp_reset_ts_memory_quad_e822().
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int
|
||||
ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
|
||||
{
|
||||
- u16 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
- lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
- hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
|
||||
- if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
|
||||
+ err = ice_read_phy_tstamp_e822(hw, quad, idx, &unused_tstamp);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for quad %u, idx %u, err %d\n",
|
||||
+ quad, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2816,28 +2819,39 @@ ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
|
||||
* @lport: the lport to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block of the
|
||||
- * external PHY on the E810 device.
|
||||
+ * Read the timestamp and then forcibly overwrite its value to clear the valid
|
||||
+ * bit from the timestamp block of the external PHY on the E810 device.
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
{
|
||||
u32 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
+ err = ice_read_phy_tstamp_e810(hw, lport, idx, &unused_tstamp);
|
||||
+ if (err) {
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
|
||||
hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, lo_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, hi_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3519,9 +3533,15 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
* @block: the block to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block. For
|
||||
- * E822 devices, the block is the quad to clear from. For E810 devices, the
|
||||
- * block is the logical port to clear from.
|
||||
+ * Clear a timestamp from the timestamp block, discarding its value without
|
||||
+ * returning it. This resets the memory status bit for the timestamp index
|
||||
+ * allowing it to be reused for another timestamp in the future.
|
||||
+ *
|
||||
+ * For E822 devices, the block number is the PHY quad to clear from. For E810
|
||||
+ * devices, the block number is the logical port to clear from.
|
||||
+ *
|
||||
+ * This function must only be called on a timestamp index whose valid bit is
|
||||
+ * set according to ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,65 +0,0 @@
|
||||
From e2a74a0a7dd399b0ee2ddd4889c609dedb85bfb5 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:35 +0200
|
||||
Subject: [PATCH 10/36] ice: Use PTP auxbus for all PHYs restart in E822
|
||||
|
||||
The E822 (and other devices based on the same PHY) is having issue while
|
||||
setting the PHC timer - the PHY timers are drifting from the PHC. After
|
||||
such a set all PHYs need to be restarted and resynchronised - do it
|
||||
using auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit af3c5c8748e6d286d4f2dd9800f9d27f29b8e2ef)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 24 +++++++++++++++++++++---
|
||||
1 file changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b0bba866e8a2..42eb1418eb90 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1496,6 +1496,24 @@ static void ice_ptp_reset_phy_timestamping(struct ice_pf *pf)
|
||||
ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_restart_all_phy - Restart all PHYs to recalibrate timestamping
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_restart_all_phy(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct list_head *entry;
|
||||
+
|
||||
+ list_for_each(entry, &pf->ptp.ports_owner.ports) {
|
||||
+ struct ice_ptp_port *port = list_entry(entry,
|
||||
+ struct ice_ptp_port,
|
||||
+ list_member);
|
||||
+
|
||||
+ if (port->link_up)
|
||||
+ ice_ptp_port_phy_restart(port);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_adjfine - Adjust clock increment rate
|
||||
* @info: the driver's PTP info structure
|
||||
@@ -1933,9 +1951,9 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
/* Reenable periodic outputs */
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
- /* Recalibrate and re-enable timestamp block */
|
||||
- if (pf->ptp.port.link_up)
|
||||
- ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
+ /* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
+ if (hw->phy_model == ICE_PHY_E822)
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err);
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,104 +0,0 @@
|
||||
From 3b37119a08ffe4be182ade746a6b1fe3bcf65921 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:22 +0100
|
||||
Subject: [PATCH 12/36] ice: Schedule service task in IRQ top half
|
||||
|
||||
Schedule service task and EXTTS in the top half to avoid bottom half
|
||||
scheduling if possible, which significantly reduces timestamping delay.
|
||||
|
||||
Co-developed-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 00d50001444ef5c75c8ab476a6674708f3ff613b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 20 +++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 54a98c4032b7..efe78d5e4da1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -517,7 +517,6 @@ enum ice_pf_flags {
|
||||
};
|
||||
|
||||
enum ice_misc_thread_tasks {
|
||||
- ICE_MISC_THREAD_EXTTS_EVENT,
|
||||
ICE_MISC_THREAD_TX_TSTAMP,
|
||||
ICE_MISC_THREAD_NBITS /* must be last */
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d2f3b4374d14..2acaa17a12bf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3109,6 +3109,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
{
|
||||
struct ice_pf *pf = (struct ice_pf *)data;
|
||||
+ irqreturn_t ret = IRQ_HANDLED;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct device *dev;
|
||||
u32 oicr, ena_mask;
|
||||
@@ -3190,8 +3191,10 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_TX_M) {
|
||||
ena_mask &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- if (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
+ ret = IRQ_WAKE_THREAD;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_EVNT_M) {
|
||||
@@ -3207,7 +3210,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
GLTSYN_STAT_EVENT1_M |
|
||||
GLTSYN_STAT_EVENT2_M);
|
||||
|
||||
- set_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread);
|
||||
+ ice_ptp_extts_event(pf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,8 +3233,11 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
set_bit(ICE_PFR_REQ, pf->state);
|
||||
}
|
||||
}
|
||||
+ ice_service_task_schedule(pf);
|
||||
+ if (ret == IRQ_HANDLED)
|
||||
+ ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
- return IRQ_WAKE_THREAD;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3247,12 +3253,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
hw = &pf->hw;
|
||||
|
||||
if (ice_is_reset_in_progress(pf->state))
|
||||
- return IRQ_HANDLED;
|
||||
-
|
||||
- ice_service_task_schedule(pf);
|
||||
-
|
||||
- if (test_and_clear_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread))
|
||||
- ice_ptp_extts_event(pf);
|
||||
+ goto skip_irq;
|
||||
|
||||
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
|
||||
/* Process outstanding Tx timestamps. If there is more work,
|
||||
@@ -3264,6 +3265,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
+skip_irq:
|
||||
ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,660 +0,0 @@
|
||||
From c4ab92eb3ee89178a012702f2a98477d683fad31 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:23 +0100
|
||||
Subject: [PATCH 13/36] ice: Enable SW interrupt from FW for LL TS
|
||||
|
||||
Introduce new capability - Low Latency Timestamping with Interrupt.
|
||||
On supported devices, driver can request a single timestamp from FW
|
||||
without polling the register afterwards. Instead, FW can issue
|
||||
a dedicated interrupt when the timestamp was read from the PHY register
|
||||
and its value is available to read from the register.
|
||||
This eliminates the need of bottom half scheduling, which results in
|
||||
minimal delay for timestamping.
|
||||
|
||||
For this mode, allocate TS indices sequentially, so that timestamps are
|
||||
always completed in FIFO manner.
|
||||
|
||||
Co-developed-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Signed-off-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 82e71b226e0ef770d7bc143701c8b4960b4eb3d5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 3 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 120 +++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 ++++++++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 9 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 2 +
|
||||
8 files changed, 274 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index efe78d5e4da1..ee42a504c2f4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -594,6 +594,7 @@ struct ice_pf {
|
||||
u32 hw_csum_rx_error;
|
||||
u32 oicr_err_reg;
|
||||
struct msi_map oicr_irq; /* Other interrupt cause MSIX vector */
|
||||
+ struct msi_map ll_ts_irq; /* LL_TS interrupt MSIX vector */
|
||||
u16 max_pf_txqs; /* Total Tx queues PF wide */
|
||||
u16 max_pf_rxqs; /* Total Rx queues PF wide */
|
||||
u16 num_lan_msix; /* Total MSIX vectors for base driver */
|
||||
@@ -618,6 +619,7 @@ struct ice_pf {
|
||||
unsigned long tx_timeout_last_recovery;
|
||||
u32 tx_timeout_recovery_level;
|
||||
char int_name[ICE_INT_NAME_STR_LEN];
|
||||
+ char int_name_ll_ts[ICE_INT_NAME_STR_LEN];
|
||||
struct auxiliary_device *adev;
|
||||
int aux_idx;
|
||||
u32 sw_int_count;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 7674267a2d90..acf6ac00f804 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -2624,6 +2624,7 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
|
||||
|
||||
info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0);
|
||||
+ info->ts_ll_int_read = ((number & ICE_TS_LL_TX_TS_INT_READ_M) != 0);
|
||||
|
||||
info->ena_ports = logical_id;
|
||||
info->tmr_own_map = phys_id;
|
||||
@@ -2644,6 +2645,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_read = %u\n",
|
||||
info->ts_ll_read);
|
||||
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_int_read = %u\n",
|
||||
+ info->ts_ll_int_read);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n",
|
||||
info->ena_ports);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 6756f3d51d14..fa730bca7f15 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -200,6 +200,8 @@
|
||||
#define GLINT_VECT2FUNC_PF_NUM_M ICE_M(0x7, 12)
|
||||
#define GLINT_VECT2FUNC_IS_PF_S 16
|
||||
#define GLINT_VECT2FUNC_IS_PF_M BIT(16)
|
||||
+#define PFINT_ALLOC 0x001D2600
|
||||
+#define PFINT_ALLOC_FIRST ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL 0x0016C800
|
||||
#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL_ITR_INDX_S 11
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 2acaa17a12bf..9163a72368b3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3071,6 +3071,7 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
|
||||
static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ u32 pf_intr_start_offset;
|
||||
u32 val;
|
||||
|
||||
/* Disable anti-spoof detection interrupt to prevent spurious event
|
||||
@@ -3099,6 +3100,47 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
/* SW_ITR_IDX = 0, but don't change INTENA */
|
||||
wr32(hw, GLINT_DYN_CTL(pf->oicr_irq.index),
|
||||
GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ return;
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ll_ts_intr - ll_ts interrupt handler
|
||||
+ * @irq: interrupt number
|
||||
+ * @data: pointer to a q_vector
|
||||
+ */
|
||||
+static irqreturn_t ice_ll_ts_intr(int __always_unused irq, void *data)
|
||||
+{
|
||||
+ struct ice_pf *pf = data;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct ice_ptp_tx *tx;
|
||||
+ unsigned long flags;
|
||||
+ struct ice_hw *hw;
|
||||
+ u32 val;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ hw = &pf->hw;
|
||||
+ tx = &pf->ptp.port.tx;
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ ice_ptp_complete_tx_single_tstamp(tx);
|
||||
+
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+
|
||||
+ val = GLINT_DYN_CTL_INTENA_M | GLINT_DYN_CTL_CLEARPBA_M |
|
||||
+ (ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S);
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ val);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3191,7 +3233,19 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_TX_M) {
|
||||
ena_mask &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ if (ice_pf_state_is_nominal(pf) &&
|
||||
+ pf->hw.dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ struct ice_ptp_tx *tx = &pf->ptp.port.tx;
|
||||
+ unsigned long flags;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+ } else if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
@@ -3295,6 +3349,20 @@ static void ice_dis_ctrlq_interrupts(struct ice_hw *hw)
|
||||
ice_flush(hw);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_free_irq_msix_ll_ts- Unroll ll_ts vector setup
|
||||
+ * @pf: board private structure
|
||||
+ */
|
||||
+static void ice_free_irq_msix_ll_ts(struct ice_pf *pf)
|
||||
+{
|
||||
+ int irq_num = pf->ll_ts_irq.virq;
|
||||
+
|
||||
+ synchronize_irq(irq_num);
|
||||
+ devm_free_irq(ice_pf_to_dev(pf), irq_num, pf);
|
||||
+
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_free_irq_msix_misc - Unroll misc vector setup
|
||||
* @pf: board private structure
|
||||
@@ -3314,6 +3382,8 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
|
||||
devm_free_irq(ice_pf_to_dev(pf), misc_irq_num, pf);
|
||||
|
||||
ice_free_irq(pf, pf->oicr_irq);
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ ice_free_irq_msix_ll_ts(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3339,10 +3409,12 @@ static void ice_ena_ctrlq_interrupts(struct ice_hw *hw, u16 reg_idx)
|
||||
PFINT_MBX_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, PFINT_MBX_CTL, val);
|
||||
|
||||
- /* This enables Sideband queue Interrupt causes */
|
||||
- val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
- PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
- wr32(hw, PFINT_SB_CTL, val);
|
||||
+ if (!hw->dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ /* enable Sideband queue Interrupt causes */
|
||||
+ val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
+ PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
+ wr32(hw, PFINT_SB_CTL, val);
|
||||
+ }
|
||||
|
||||
ice_flush(hw);
|
||||
}
|
||||
@@ -3359,13 +3431,17 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
- struct msi_map oicr_irq;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct msi_map irq;
|
||||
int err = 0;
|
||||
|
||||
if (!pf->int_name[0])
|
||||
snprintf(pf->int_name, sizeof(pf->int_name) - 1, "%s-%s:misc",
|
||||
dev_driver_string(dev), dev_name(dev));
|
||||
|
||||
+ if (!pf->int_name_ll_ts[0])
|
||||
+ snprintf(pf->int_name_ll_ts, sizeof(pf->int_name_ll_ts) - 1,
|
||||
+ "%s-%s:ll_ts", dev_driver_string(dev), dev_name(dev));
|
||||
/* Do not request IRQ but do enable OICR interrupt since settings are
|
||||
* lost during reset. Note that this function is called only during
|
||||
* rebuild path and not while reset is in progress.
|
||||
@@ -3374,11 +3450,11 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
goto skip_req_irq;
|
||||
|
||||
/* reserve one vector in irq_tracker for misc interrupts */
|
||||
- oicr_irq = ice_alloc_irq(pf, false);
|
||||
- if (oicr_irq.index < 0)
|
||||
- return oicr_irq.index;
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
|
||||
- pf->oicr_irq = oicr_irq;
|
||||
+ pf->oicr_irq = irq;
|
||||
err = devm_request_threaded_irq(dev, pf->oicr_irq.virq, ice_misc_intr,
|
||||
ice_misc_intr_thread_fn, 0,
|
||||
pf->int_name, pf);
|
||||
@@ -3389,10 +3465,34 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
+ /* reserve one vector in irq_tracker for ll_ts interrupt */
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ goto skip_req_irq;
|
||||
+
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
+
|
||||
+ pf->ll_ts_irq = irq;
|
||||
+ err = devm_request_irq(dev, pf->ll_ts_irq.virq, ice_ll_ts_intr, 0,
|
||||
+ pf->int_name_ll_ts, pf);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "devm_request_irq for %s failed: %d\n",
|
||||
+ pf->int_name_ll_ts, err);
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
skip_req_irq:
|
||||
ice_ena_misc_vector(pf);
|
||||
|
||||
ice_ena_ctrlq_interrupts(hw, pf->oicr_irq.index);
|
||||
+ /* This enables LL TS interrupt */
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ wr32(hw, PFINT_SB_CTL,
|
||||
+ ((pf->ll_ts_irq.index + pf_intr_start_offset) &
|
||||
+ PFINT_SB_CTL_MSIX_INDX_M) | PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_irq.index),
|
||||
ITR_REG_ALIGN(ICE_ITR_8K) >> ICE_ITR_GRAN_S);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 2e6e1fc84d11..75038d826f71 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -634,6 +634,119 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
return tx->init && !tx->calibrating;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_req_tx_single_tstamp - Request Tx timestamp for a port from FW
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ * @idx: index of the timestamp to request
|
||||
+ */
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+
|
||||
+ if (!tx->init)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ /* Drop packets which have waited for more than 2 seconds */
|
||||
+ if (time_is_before_jiffies(tx->tstamps[idx].start + 2 * HZ)) {
|
||||
+ /* Count the number of Tx timestamps that timed out */
|
||||
+ pf->ptp.tx_hwtstamp_timeouts++;
|
||||
+
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_req, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ /* Write TS index to read to the PF register so the FW can read it */
|
||||
+ wr32(&pf->hw, PF_SB_ATQBAL,
|
||||
+ TS_LL_READ_TS_INTR | FIELD_PREP(TS_LL_READ_TS_IDX, idx) |
|
||||
+ TS_LL_READ_TS);
|
||||
+ tx->last_ll_ts_idx_read = idx;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_complete_tx_single_tstamp - Complete Tx timestamp for a port
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ */
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
+{
|
||||
+ struct skb_shared_hwtstamps shhwtstamps = {};
|
||||
+ u8 idx = tx->last_ll_ts_idx_read;
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ u64 raw_tstamp, tstamp;
|
||||
+ bool drop_ts = false;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (!tx->init || tx->last_ll_ts_idx_read < 0)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ val = rd32(&pf->hw, PF_SB_ATQBAL);
|
||||
+
|
||||
+ /* When the bit is cleared, the TS is ready in the register */
|
||||
+ if (val & TS_LL_READ_TS) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to get the Tx tstamp - FW not ready");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* High 8 bit value of the TS is on the bits 16:23 */
|
||||
+ raw_tstamp = FIELD_GET(TS_LL_READ_TS_HIGH, val);
|
||||
+ raw_tstamp <<= 32;
|
||||
+
|
||||
+ /* Read the low 32 bit value */
|
||||
+ raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
+
|
||||
+ /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
+ * verify that the timestamp value is different from the last cached
|
||||
+ * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
+ * been captured by hardware.
|
||||
+ */
|
||||
+ if (!drop_ts && tx->verify_cached &&
|
||||
+ raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ return;
|
||||
+
|
||||
+ if (tx->verify_cached && raw_tstamp)
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ if (test_and_clear_bit(idx, tx->stale))
|
||||
+ drop_ts = true;
|
||||
+
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ if (drop_ts) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Extend the timestamp using cached PHC time */
|
||||
+ tstamp = ice_ptp_extend_40b_ts(pf, raw_tstamp);
|
||||
+ if (tstamp) {
|
||||
+ shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
|
||||
+ ice_trace(tx_tstamp_complete, skb, idx);
|
||||
+ }
|
||||
+
|
||||
+ skb_tstamp_tx(skb, &shhwtstamps);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_process_tx_tstamp - Process Tx timestamps for a port
|
||||
* @tx: the PTP Tx timestamp tracker
|
||||
@@ -685,6 +798,7 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_ptp_port *ptp_port;
|
||||
+ unsigned long flags;
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u64 tstamp_ready;
|
||||
@@ -756,7 +870,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
drop_ts = true;
|
||||
|
||||
skip_ts_read:
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
if (tx->verify_cached && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
@@ -764,7 +878,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
if (test_and_clear_bit(idx, tx->stale))
|
||||
drop_ts = true;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* It is unlikely but possible that the SKB will have been
|
||||
* flushed at this point due to link change or teardown.
|
||||
@@ -834,6 +948,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
bool more_timestamps;
|
||||
+ unsigned long flags;
|
||||
|
||||
if (!tx->init)
|
||||
return ICE_TX_TSTAMP_WORK_DONE;
|
||||
@@ -842,9 +957,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
ice_ptp_process_tx_tstamp(tx);
|
||||
|
||||
/* Check if there are outstanding Tx timestamps */
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
if (more_timestamps)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
@@ -881,6 +996,7 @@ ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx)
|
||||
tx->in_use = in_use;
|
||||
tx->stale = stale;
|
||||
tx->init = 1;
|
||||
+ tx->last_ll_ts_idx_read = -1;
|
||||
|
||||
spin_lock_init(&tx->lock);
|
||||
|
||||
@@ -898,6 +1014,7 @@ static void
|
||||
ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
u8 idx;
|
||||
@@ -921,12 +1038,12 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
if (!hw->reset_ongoing && (tstamp_ready & BIT_ULL(phy_idx)))
|
||||
ice_clear_phy_tstamp(hw, tx->block, phy_idx);
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
clear_bit(idx, tx->in_use);
|
||||
clear_bit(idx, tx->stale);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* Count the number of Tx timestamps flushed */
|
||||
pf->ptp.tx_hwtstamp_flushed++;
|
||||
@@ -950,9 +1067,11 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
bitmap_or(tx->stale, tx->stale, tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -965,9 +1084,11 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
tx->init = 0;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* wait for potentially outstanding interrupt to complete */
|
||||
synchronize_irq(pf->oicr_irq.virq);
|
||||
@@ -1367,6 +1488,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
struct ice_pf *pf = ptp_port_to_pf(ptp_port);
|
||||
u8 port = ptp_port->port_num;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
int err;
|
||||
|
||||
if (ice_is_e810(hw))
|
||||
@@ -1380,9 +1502,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
kthread_cancel_delayed_work_sync(&ptp_port->ov_work);
|
||||
|
||||
/* temporarily disable Tx timestamps while calibrating PHY offset */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = true;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx_fifo_busy_cnt = 0;
|
||||
|
||||
/* Start the PHY timer in Vernier mode */
|
||||
@@ -1391,9 +1513,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
goto out_unlock;
|
||||
|
||||
/* Enable Tx timestamps right away */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = false;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
|
||||
kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work, 0);
|
||||
|
||||
@@ -2471,18 +2593,23 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
*/
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
{
|
||||
+ unsigned long flags;
|
||||
u8 idx;
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
|
||||
/* Check that this tracker is accepting new timestamp requests */
|
||||
if (!ice_ptp_is_tx_tracker_up(tx)) {
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find and set the first available index */
|
||||
- idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+ idx = find_next_zero_bit(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx == tx->len)
|
||||
+ idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+
|
||||
if (idx < tx->len) {
|
||||
/* We got a valid index that no other thread could have set. Store
|
||||
* a reference to the skb and the start time to allow discarding old
|
||||
@@ -2496,7 +2623,7 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
ice_trace(tx_tstamp_request, skb, idx);
|
||||
}
|
||||
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* return the appropriate PHY timestamp register index, -1 if no
|
||||
* indexes were available.
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index a3ae008a3539..64679d3d2c49 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -131,6 +131,7 @@ enum ice_tx_tstamp_work {
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
* @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
spinlock_t lock; /* lock protecting in_use bitmap */
|
||||
@@ -143,6 +144,7 @@ struct ice_ptp_tx {
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
u8 verify_cached : 1;
|
||||
+ s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
/* Quad and port information for initializing timestamp blocks */
|
||||
@@ -296,6 +298,8 @@ int ice_get_ptp_clock_index(struct ice_pf *pf);
|
||||
|
||||
void ice_ptp_extts_event(struct ice_pf *pf);
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx);
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx);
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
|
||||
void
|
||||
@@ -330,6 +334,11 @@ ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static inline void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{ }
|
||||
+
|
||||
+static inline void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { }
|
||||
+
|
||||
static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
return true;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 0cc285614c72..7e8fd369ef7c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -509,6 +509,7 @@ int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
#define TS_LL_READ_RETRIES 200
|
||||
#define TS_LL_READ_TS_HIGH GENMASK(23, 16)
|
||||
#define TS_LL_READ_TS_IDX GENMASK(29, 24)
|
||||
+#define TS_LL_READ_TS_INTR BIT(30)
|
||||
#define TS_LL_READ_TS BIT(31)
|
||||
|
||||
/* Internal PHY timestamp address */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index f8b658386552..b0f1f4db1d8b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -350,6 +350,7 @@ struct ice_ts_func_info {
|
||||
#define ICE_TS_TMR0_ENA_M BIT(25)
|
||||
#define ICE_TS_TMR1_ENA_M BIT(26)
|
||||
#define ICE_TS_LL_TX_TS_READ_M BIT(28)
|
||||
+#define ICE_TS_LL_TX_TS_INT_READ_M BIT(29)
|
||||
|
||||
struct ice_ts_dev_info {
|
||||
/* Device specific info */
|
||||
@@ -363,6 +364,7 @@ struct ice_ts_dev_info {
|
||||
u8 tmr0_ena;
|
||||
u8 tmr1_ena;
|
||||
u8 ts_ll_read;
|
||||
+ u8 ts_ll_int_read;
|
||||
};
|
||||
|
||||
/* Function specific capabilities */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,310 +0,0 @@
|
||||
From f267daca86600496d536f85c4d1945558b982427 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:36 +0200
|
||||
Subject: [PATCH 14/36] ice: PTP: add clock domain number to auxiliary
|
||||
interface
|
||||
|
||||
The PHC clock id used to be moved between PFs using FW admin queue
|
||||
shared parameters - move the implementation to auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit fcd2c1e3139a27766ef263bd2011195dbc8a79f5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 5 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 +++---------------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 11 +-
|
||||
4 files changed, 34 insertions(+), 147 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 353ac55bdb9d..9bacb69ead8c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2360,11 +2360,6 @@ struct ice_aqc_driver_shared_params {
|
||||
};
|
||||
|
||||
enum ice_aqc_driver_params {
|
||||
- /* OS clock index for PTP timer Domain 0 */
|
||||
- ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0 = 0,
|
||||
- /* OS clock index for PTP timer Domain 1 */
|
||||
- ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1,
|
||||
-
|
||||
/* Add new parameters above */
|
||||
ICE_AQC_DRIVER_PARAM_MAX = 16,
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 456cf4785c74..057453d589d5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3286,7 +3286,7 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
|
||||
SOF_TIMESTAMPING_RX_HARDWARE |
|
||||
SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||
|
||||
- info->phc_index = ice_get_ptp_clock_index(pf);
|
||||
+ info->phc_index = ice_ptp_clock_index(pf);
|
||||
|
||||
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 75038d826f71..a2d0da7dfe83 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -345,131 +345,6 @@ void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
ice_set_rx_tstamp(pf, ena);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_ptp_clock_index - Get the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Determine the clock index of the PTP clock associated with this device. If
|
||||
- * this is the PF controlling the clock, just use the local access to the
|
||||
- * clock device pointer.
|
||||
- *
|
||||
- * Otherwise, read from the driver shared parameters to determine the clock
|
||||
- * index value.
|
||||
- *
|
||||
- * Returns: the index of the PTP clock associated with this device, or -1 if
|
||||
- * there is no associated clock.
|
||||
- */
|
||||
-int ice_get_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- /* Use the ptp_clock structure if we're the main PF */
|
||||
- if (pf->ptp.clock)
|
||||
- return ptp_clock_index(pf->ptp.clock);
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_get_driver_param(hw, param_idx, &value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to read PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* The PTP clock index is an integer, and will be between 0 and
|
||||
- * INT_MAX. The highest bit of the driver shared parameter is used to
|
||||
- * indicate whether or not the currently stored clock index is valid.
|
||||
- */
|
||||
- if (!(value & PTP_SHARED_CLK_IDX_VALID))
|
||||
- return -1;
|
||||
-
|
||||
- return value & ~PTP_SHARED_CLK_IDX_VALID;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_set_ptp_clock_index - Set the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Set the PTP clock index for this device into the shared driver parameters,
|
||||
- * so that other PFs associated with this device can read it.
|
||||
- *
|
||||
- * If the PF is unable to store the clock index, it will log an error, but
|
||||
- * will continue operating PTP.
|
||||
- */
|
||||
-static void ice_set_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- if (!pf->ptp.clock)
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- value = (u32)ptp_clock_index(pf->ptp.clock);
|
||||
- if (value > INT_MAX) {
|
||||
- dev_err(dev, "PTP Clock index is too large to store\n");
|
||||
- return;
|
||||
- }
|
||||
- value |= PTP_SHARED_CLK_IDX_VALID;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to set PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_clear_ptp_clock_index - Clear the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Clear the PTP clock index for this device. Must be called when
|
||||
- * unregistering the PTP clock, in order to ensure other PFs stop reporting
|
||||
- * a clock object that no longer exists.
|
||||
- */
|
||||
-static void ice_clear_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- int err;
|
||||
-
|
||||
- /* Do not clear the index if we don't own the timer */
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, 0, NULL);
|
||||
- if (err) {
|
||||
- dev_dbg(dev, "Failed to clear PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_read_src_clk_reg - Read the source clock register
|
||||
* @pf: Board private structure
|
||||
@@ -2564,7 +2439,6 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
|
||||
static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
{
|
||||
struct ptp_clock_info *info;
|
||||
- struct ptp_clock *clock;
|
||||
struct device *dev;
|
||||
|
||||
/* No need to create a clock device if we already have one */
|
||||
@@ -2577,11 +2451,11 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
/* Attempt to register the clock before enabling the hardware. */
|
||||
- clock = ptp_clock_register(info, dev);
|
||||
- if (IS_ERR(clock))
|
||||
- return PTR_ERR(clock);
|
||||
-
|
||||
- pf->ptp.clock = clock;
|
||||
+ pf->ptp.clock = ptp_clock_register(info, dev);
|
||||
+ if (IS_ERR(pf->ptp.clock)) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP clock device");
|
||||
+ return PTR_ERR(pf->ptp.clock);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2996,6 +2870,28 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_clock_index - Get the PTP clock index for this device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Returns: the PTP clock index associated with this PF, or -1 if no PTP clock
|
||||
+ * is associated.
|
||||
+ */
|
||||
+int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_pf *owner_pf;
|
||||
+ struct ptp_clock *clock;
|
||||
+
|
||||
+ aux_dev = &pf->ptp.port.aux_dev;
|
||||
+ owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ if (!owner_pf)
|
||||
+ return -1;
|
||||
+ clock = owner_pf->ptp.clock;
|
||||
+
|
||||
+ return clock ? ptp_clock_index(clock) : -1;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -3086,9 +2982,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err_clk;
|
||||
|
||||
- /* Store the PTP clock index for other PFs */
|
||||
- ice_set_ptp_clock_index(pf);
|
||||
-
|
||||
err = ice_ptp_register_auxbus_driver(pf);
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
@@ -3097,7 +2990,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
return 0;
|
||||
err_aux:
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
@@ -3353,7 +3245,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable periodic outputs */
|
||||
ice_ptp_disable_all_clkout(pf);
|
||||
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 64679d3d2c49..95ebd7a048ec 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -290,11 +290,11 @@ struct ice_ptp {
|
||||
#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4))
|
||||
|
||||
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
||||
+int ice_ptp_clock_index(struct ice_pf *pf);
|
||||
struct ice_pf;
|
||||
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
|
||||
-int ice_get_ptp_clock_index(struct ice_pf *pf);
|
||||
|
||||
void ice_ptp_extts_event(struct ice_pf *pf);
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
|
||||
@@ -322,10 +322,6 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
}
|
||||
|
||||
static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
|
||||
-static inline int ice_get_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- return -1;
|
||||
-}
|
||||
|
||||
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
||||
static inline s8
|
||||
@@ -353,5 +349,10 @@ static inline void ice_ptp_release(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
{
|
||||
}
|
||||
+
|
||||
+static inline int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
+{
|
||||
+ return -1;
|
||||
+}
|
||||
#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
|
||||
#endif /* _ICE_PTP_H_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,266 +0,0 @@
|
||||
From eb63973adae478fdcc324f5490d6803646f0cc76 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:57 -0800
|
||||
Subject: [PATCH 15/36] ice: restore timestamp configuration after device reset
|
||||
|
||||
The driver calls ice_ptp_cfg_timestamp() during ice_ptp_prepare_for_reset()
|
||||
to disable timestamping while the device is resetting. This operation
|
||||
destroys the user requested configuration. While the driver does call
|
||||
ice_ptp_cfg_timestamp in ice_rebuild() to restore some hardware settings
|
||||
after a reset, it unconditionally passes true or false, resulting in
|
||||
failure to restore previous user space configuration.
|
||||
|
||||
This results in a device reset forcibly disabling timestamp configuration
|
||||
regardless of current user settings.
|
||||
|
||||
This was not detected previously due to a quirk of the LinuxPTP ptp4l
|
||||
application. If ptp4l detects a missing timestamp, it enters a fault state
|
||||
and performs recovery logic which includes executing SIOCSHWTSTAMP again,
|
||||
restoring the now accidentally cleared configuration.
|
||||
|
||||
Not every application does this, and for these applications, timestamps
|
||||
will mysteriously stop after a PF reset, without being restored until an
|
||||
application restart.
|
||||
|
||||
Fix this by replacing ice_ptp_cfg_timestamp() with two new functions:
|
||||
|
||||
1) ice_ptp_disable_timestamp_mode() which unconditionally disables the
|
||||
timestamping logic in ice_ptp_prepare_for_reset() and ice_ptp_release()
|
||||
|
||||
2) ice_ptp_restore_timestamp_mode() which calls
|
||||
ice_ptp_restore_tx_interrupt() to restore Tx timestamping configuration,
|
||||
calls ice_set_rx_tstamp() to restore Rx timestamping configuration, and
|
||||
issues an immediate TSYN_TX interrupt to ensure that timestamps which
|
||||
may have occurred during the device reset get processed.
|
||||
|
||||
Modify the ice_ptp_set_timestamp_mode to directly save the user
|
||||
configuration and then call ice_ptp_restore_timestamp_mode. This way, reset
|
||||
no longer destroys the saved user configuration.
|
||||
|
||||
This obsoletes the ice_set_tx_tstamp() function which can now be safely
|
||||
removed.
|
||||
|
||||
With this change, all devices should now restore Tx and Rx timestamping
|
||||
functionality correctly after a PF reset without application intervention.
|
||||
|
||||
Fixes: 77a781155a65 ("ice: enable receive hardware timestamping")
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7758017911a4f2578d54c318e8fe77bcb5899054)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 12 +---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 74 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 5 +-
|
||||
3 files changed, 51 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 9163a72368b3..8cfb923198e9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7545,15 +7545,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err_vsi_rebuild;
|
||||
}
|
||||
|
||||
- /* configure PTP timestamping after VSI rebuild */
|
||||
- if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
- else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL)
|
||||
- /* for E82x PHC owner always need to have interrupts */
|
||||
- ice_ptp_cfg_timestamp(pf, true);
|
||||
- }
|
||||
-
|
||||
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
|
||||
if (err) {
|
||||
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
|
||||
@@ -7605,6 +7596,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_plug_aux_dev(pf);
|
||||
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
|
||||
ice_lag_rebuild(pf);
|
||||
+
|
||||
+ /* Restore timestamp mode settings after VSI rebuild */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
return;
|
||||
|
||||
err_vsi_rebuild:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a2d0da7dfe83..8fc6905b0f79 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -294,18 +294,6 @@ static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamps are enabled or disabled
|
||||
- */
|
||||
-static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
-{
|
||||
- pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
-
|
||||
- ice_ptp_cfg_tx_interrupt(pf);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_set_rx_tstamp - Enable or disable Rx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -317,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
+ if (!vsi || !vsi->rx_rings)
|
||||
return;
|
||||
|
||||
/* Set the timestamp flag for all the Rx rings */
|
||||
@@ -326,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
continue;
|
||||
vsi->rx_rings[i]->ptp_rx = on;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_disable_timestamp_mode - Disable current timestamp mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called during preparation for reset to temporarily disable timestamping on
|
||||
+ * the device. Called during remove to disable timestamping while cleaning up
|
||||
+ * driver resources.
|
||||
+ */
|
||||
+static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
|
||||
- pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
|
||||
- HWTSTAMP_FILTER_NONE;
|
||||
+ ice_set_rx_tstamp(pf, false);
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
|
||||
+ * ice_ptp_restore_timestamp_mode - Restore timestamp configuration
|
||||
* @pf: Board private structure
|
||||
- * @ena: bool value to enable or disable time stamp
|
||||
*
|
||||
- * This function will configure timestamping during PTP initialization
|
||||
- * and deinitialization
|
||||
+ * Called at the end of rebuild to restore timestamp configuration after
|
||||
+ * a device reset.
|
||||
*/
|
||||
-void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
+void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
|
||||
{
|
||||
- ice_set_tx_tstamp(pf, ena);
|
||||
- ice_set_rx_tstamp(pf, ena);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable_rx;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
+ enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL;
|
||||
+ ice_set_rx_tstamp(pf, enable_rx);
|
||||
+
|
||||
+ /* Trigger an immediate software interrupt to ensure that timestamps
|
||||
+ * which occurred during reset are handled now.
|
||||
+ */
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2152,10 +2167,10 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
{
|
||||
switch (config->tx_type) {
|
||||
case HWTSTAMP_TX_OFF:
|
||||
- ice_set_tx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
|
||||
break;
|
||||
case HWTSTAMP_TX_ON:
|
||||
- ice_set_tx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
@@ -2163,7 +2178,7 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
|
||||
switch (config->rx_filter) {
|
||||
case HWTSTAMP_FILTER_NONE:
|
||||
- ice_set_rx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
@@ -2179,12 +2194,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_NTP_ALL:
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
- ice_set_rx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
+ /* Immediately update the device timestamping mode */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2904,7 +2922,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
@@ -3222,7 +3240,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
ice_ptp_remove_auxbus_device(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 95ebd7a048ec..130e6d2ae9a5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -294,7 +294,7 @@ int ice_ptp_clock_index(struct ice_pf *pf);
|
||||
struct ice_pf;
|
||||
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
-void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
|
||||
+void ice_ptp_restore_timestamp_mode(struct ice_pf *pf);
|
||||
|
||||
void ice_ptp_extts_event(struct ice_pf *pf);
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
|
||||
@@ -321,8 +321,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
-static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
|
||||
-
|
||||
+static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
||||
static inline s8
|
||||
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,316 +0,0 @@
|
||||
From 5c6115d27a377927d6392b3bfbe9739188c8153c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:49 -0800
|
||||
Subject: [PATCH 16/36] ice: introduce PTP state machine
|
||||
|
||||
Add PTP state machine so that the driver can correctly identify PTP
|
||||
state around resets.
|
||||
When the driver got information about ungraceful reset, PTP was not
|
||||
prepared for reset and it returned error. When this situation occurs,
|
||||
prepare PTP before rebuilding its structures.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 8293e4cb2ff54b1ec4f7206dcb74c908f62a3fb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 110 +++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 10 ++
|
||||
4 files changed, 74 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index ee42a504c2f4..3278d032a2bd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -492,7 +492,6 @@ enum ice_pf_flags {
|
||||
ICE_FLAG_DCB_ENA,
|
||||
ICE_FLAG_FD_ENA,
|
||||
ICE_FLAG_PTP_SUPPORTED, /* PTP is supported by NVM */
|
||||
- ICE_FLAG_PTP, /* PTP is enabled by software */
|
||||
ICE_FLAG_ADV_FEATURES,
|
||||
ICE_FLAG_TC_MQPRIO, /* support for Multi queue TC */
|
||||
ICE_FLAG_CLS_FLOWER,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 057453d589d5..9e949c493c38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3276,7 +3276,7 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
|
||||
struct ice_pf *pf = ice_netdev_to_pf(dev);
|
||||
|
||||
/* only report timestamping if PTP is enabled */
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return ethtool_op_get_ts_info(dev, info);
|
||||
|
||||
info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 8fc6905b0f79..36c81c5ee83b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1430,7 +1430,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
struct ice_ptp_port *ptp_port;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
@@ -2148,7 +2148,7 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
{
|
||||
struct hwtstamp_config *config;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EIO;
|
||||
|
||||
config = &pf->ptp.tstamp_config;
|
||||
@@ -2218,7 +2218,7 @@ int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
struct hwtstamp_config config;
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EAGAIN;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
@@ -2606,7 +2606,7 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp);
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
@@ -2618,6 +2618,42 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ u8 src_tmr;
|
||||
+
|
||||
+ if (ptp->state != ICE_PTP_READY)
|
||||
+ return;
|
||||
+
|
||||
+ ptp->state = ICE_PTP_RESETTING;
|
||||
+
|
||||
+ /* Disable timestamping for both Tx and Rx */
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
+
|
||||
+ kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
+
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ return;
|
||||
+
|
||||
+ ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
+
|
||||
+ /* Disable periodic outputs */
|
||||
+ ice_ptp_disable_all_clkout(pf);
|
||||
+
|
||||
+ src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
+
|
||||
+ /* Disable source clock */
|
||||
+ wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
+
|
||||
+ /* Acquire PHC and system timer to restore after reset */
|
||||
+ ptp->reset_time = ktime_get_real_ns();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
@@ -2630,6 +2666,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
!ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
@@ -2690,7 +2734,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Restart the PHY timestamping block */
|
||||
if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
@@ -2704,6 +2748,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
err:
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -2910,39 +2955,6 @@ int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
return clock ? ptp_clock_index(clock) : -1;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
- * @pf: Board private structure
|
||||
- */
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_ptp *ptp = &pf->ptp;
|
||||
- u8 src_tmr;
|
||||
-
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
- /* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_disable_timestamp_mode(pf);
|
||||
-
|
||||
- kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
-
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
- return;
|
||||
-
|
||||
- ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
-
|
||||
- /* Disable periodic outputs */
|
||||
- ice_ptp_disable_all_clkout(pf);
|
||||
-
|
||||
- src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
-
|
||||
- /* Disable source clock */
|
||||
- wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
-
|
||||
- /* Acquire PHC and system timer to restore after reset */
|
||||
- ptp->reset_time = ktime_get_real_ns();
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_init_owner - Initialize PTP_1588_CLOCK device
|
||||
* @pf: Board private structure
|
||||
@@ -3181,6 +3193,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err;
|
||||
|
||||
+ ptp->state = ICE_PTP_INITIALIZING;
|
||||
+
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
@@ -3205,12 +3219,13 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Configure initial Tx interrupt settings */
|
||||
ice_ptp_cfg_tx_interrupt(pf);
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
- err = ice_ptp_init_work(pf, ptp);
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- err = ice_ptp_create_auxbus_device(pf);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
+
|
||||
+ err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
@@ -3223,7 +3238,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
ptp_clock_unregister(ptp->clock);
|
||||
pf->ptp.clock = NULL;
|
||||
}
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -3236,9 +3251,11 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
*/
|
||||
void ice_ptp_release(struct ice_pf *pf)
|
||||
{
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
+ pf->ptp.state = ICE_PTP_UNINIT;
|
||||
+
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
@@ -3246,8 +3263,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
kthread_cancel_delayed_work_sync(&pf->ptp.work);
|
||||
|
||||
ice_ptp_port_phy_stop(&pf->ptp.port);
|
||||
@@ -3257,6 +3272,9 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
pf->ptp.kworker = NULL;
|
||||
}
|
||||
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
if (!pf->ptp.clock)
|
||||
return;
|
||||
|
||||
@@ -3266,7 +3284,5 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
- ice_ptp_unregister_auxbus_driver(pf);
|
||||
-
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 130e6d2ae9a5..e3cc69692405 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -203,8 +203,17 @@ struct ice_ptp_port_owner {
|
||||
|
||||
#define GLTSYN_TGT_H_IDX_MAX 4
|
||||
|
||||
+enum ice_ptp_state {
|
||||
+ ICE_PTP_UNINIT = 0,
|
||||
+ ICE_PTP_INITIALIZING,
|
||||
+ ICE_PTP_READY,
|
||||
+ ICE_PTP_RESETTING,
|
||||
+ ICE_PTP_ERROR,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
|
||||
+ * @state: current state of PTP state machine
|
||||
* @tx_interrupt_mode: the TX interrupt mode for the PTP clock
|
||||
* @port: data for the PHY port initialization procedure
|
||||
* @ports_owner: data for the auxiliary driver owner
|
||||
@@ -227,6 +236,7 @@ struct ice_ptp_port_owner {
|
||||
* @late_cached_phc_updates: number of times cached PHC update is late
|
||||
*/
|
||||
struct ice_ptp {
|
||||
+ enum ice_ptp_state state;
|
||||
enum ice_ptp_tx_interrupt tx_interrupt_mode;
|
||||
struct ice_ptp_port port;
|
||||
struct ice_ptp_port_owner ports_owner;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,150 +0,0 @@
|
||||
From 68d481b41ee5c177a1376fb82a98c09c148d982a Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:50 -0800
|
||||
Subject: [PATCH 17/36] ice: pass reset type to PTP reset functions
|
||||
|
||||
The ice_ptp_prepare_for_reset() and ice_ptp_reset() functions currently
|
||||
check the pf->flags ICE_FLAG_PFR_REQ bit to determine if the current
|
||||
reset is a PF reset or not.
|
||||
|
||||
This is problematic, because it is possible that a PF reset and a higher
|
||||
level reset (CORE reset, GLOBAL reset, EMP reset) are requested
|
||||
simultaneously. In that case, the driver performs the highest level
|
||||
reset requested. However, the ICE_FLAG_PFR_REQ flag will still be set.
|
||||
|
||||
The main driver reset functions take an enum ice_reset_req indicating
|
||||
which reset is actually being performed. Pass this data into the PTP
|
||||
functions and rely on this instead of relying on the driver flags.
|
||||
|
||||
This ensures that the PTP code performs the proper level of reset that
|
||||
the driver is actually undergoing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit c75d5e675a8542274fa0f7e52f3c4db1d4859a0c)
|
||||
[Adjust the ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 4 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 13 +++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 17 +++++++++++++----
|
||||
3 files changed, 22 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8cfb923198e9..d5321410f2d7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -615,7 +615,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_pf_dis_all_vsi(pf, false);
|
||||
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_exit(pf);
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf);
|
||||
+ ice_ptp_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 36c81c5ee83b..20d1d22235d3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2621,8 +2621,9 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
u8 src_tmr;
|
||||
@@ -2637,7 +2638,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (reset_type == ICE_RESET_PFR)
|
||||
return;
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
@@ -2657,8 +2658,9 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,15 +2669,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
u64 time_diff;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
} else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
err = -EINVAL;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
- !ice_pf_src_tmr_owned(pf))
|
||||
+ if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index e3cc69692405..cd74712a17a1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -315,8 +315,9 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf);
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf);
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
void ice_ptp_release(struct ice_pf *pf);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
|
||||
@@ -351,8 +352,16 @@ static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf) { }
|
||||
-static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { }
|
||||
+
|
||||
+static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_release(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,119 +0,0 @@
|
||||
From 084497314e63f3d92178bc44500a27a277abc378 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:51 -0800
|
||||
Subject: [PATCH 18/36] ice: rename verify_cached to has_ready_bitmap
|
||||
|
||||
The tx->verify_cached flag is used to inform the Tx timestamp tracking
|
||||
code whether it needs to verify the cached Tx timestamp value against
|
||||
a previous captured value. This is necessary on E810 hardware which does
|
||||
not have a Tx timestamp ready bitmap.
|
||||
|
||||
In addition, we currently rely on the fact that the
|
||||
ice_get_phy_tx_tstamp_ready() function returns all 1s for E810 hardware.
|
||||
Instead of introducing a brand new flag, rename and verify_cached to
|
||||
has_ready_bitmap, inverting the relevant checks.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 3f2216e8dbce04da5376ea7df410541f7b687cb0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 +++++---
|
||||
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 20d1d22235d3..a8c6b83579e6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -606,11 +606,11 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
* timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
* been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -751,7 +751,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* from the last cached timestamp. If it is not, skip this for
|
||||
* now assuming it hasn't yet been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
continue;
|
||||
|
||||
@@ -761,7 +761,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
|
||||
skip_ts_read:
|
||||
spin_lock_irqsave(&tx->lock, flags);
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -1014,7 +1014,7 @@ ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
- tx->verify_cached = 0;
|
||||
+ tx->has_ready_bitmap = 1;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
* verify new timestamps against cached copy of the last read
|
||||
* timestamp.
|
||||
*/
|
||||
- tx->verify_cached = 1;
|
||||
+ tx->has_ready_bitmap = 0;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index cd74712a17a1..1486a0b3b016 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -100,7 +100,7 @@ struct ice_perout_channel {
|
||||
* the last timestamp we read for a given index. If the current timestamp
|
||||
* value is the same as the cached value, we assume a new timestamp hasn't
|
||||
* been captured. This avoids reporting stale timestamps to the stack. This is
|
||||
- * only done if the verify_cached flag is set in ice_ptp_tx structure.
|
||||
+ * only done if the has_ready_bitmap flag is not set in ice_ptp_tx structure.
|
||||
*/
|
||||
struct ice_tx_tstamp {
|
||||
struct sk_buff *skb;
|
||||
@@ -130,7 +130,9 @@ enum ice_tx_tstamp_work {
|
||||
* @init: if true, the tracker is initialized;
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
- * @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @has_ready_bitmap: if true, the hardware has a valid Tx timestamp ready
|
||||
+ * bitmap register. If false, fall back to verifying new
|
||||
+ * timestamp values against previously cached copy.
|
||||
* @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
@@ -143,7 +145,7 @@ struct ice_ptp_tx {
|
||||
u8 len;
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
- u8 verify_cached : 1;
|
||||
+ u8 has_ready_bitmap : 1;
|
||||
s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,77 +0,0 @@
|
||||
From 375bced6b51243a8c8708204dd32960d076d5b83 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:52 -0800
|
||||
Subject: [PATCH 19/36] ice: don't check has_ready_bitmap in E810 functions
|
||||
|
||||
E810 hardware does not have a Tx timestamp ready bitmap. Don't check
|
||||
has_ready_bitmap in E810-specific functions.
|
||||
Add has_ready_bitmap check in ice_ptp_process_tx_tstamp() to stop
|
||||
relying on the fact that ice_get_phy_tx_tstamp_ready() returns all 1s.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit fea82915fca626eaa83f36d8a23194e8593ef4b4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 23 +++++++++++------------
|
||||
1 file changed, 11 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a8c6b83579e6..ddc2dd0b2a28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -601,17 +601,13 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
/* Read the low 32 bit value */
|
||||
raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
|
||||
- /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
- * verify that the timestamp value is different from the last cached
|
||||
- * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
- * been captured by hardware.
|
||||
+ /* Devices using this interface always verify the timestamp differs
|
||||
+ * relative to the last cached timestamp value.
|
||||
*/
|
||||
- if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
- raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ if (raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
- tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
@@ -701,9 +697,11 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
hw = &pf->hw;
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
- err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
- if (err)
|
||||
- return;
|
||||
+ if (tx->has_ready_bitmap) {
|
||||
+ err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
+ if (err)
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* Drop packets if the link went down */
|
||||
link_up = ptp_port->link_up;
|
||||
@@ -731,7 +729,8 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* If we do not, the hardware logic for generating a new
|
||||
* interrupt can get stuck on some devices.
|
||||
*/
|
||||
- if (!(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
+ if (tx->has_ready_bitmap &&
|
||||
+ !(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
if (drop_ts)
|
||||
goto skip_ts_read;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,88 +0,0 @@
|
||||
From a5318a3a04ed9535ab18ef0f0537b3d33862bee9 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:53 -0800
|
||||
Subject: [PATCH 20/36] ice: rename ice_ptp_tx_cfg_intr
|
||||
|
||||
The ice_ptp_tx_cfg_intr() function sends a control queue message to
|
||||
configure the PHY timestamp interrupt block. This is a very similar name
|
||||
to a function which is used to configure the MAC Other Interrupt Cause
|
||||
Enable register.
|
||||
|
||||
Rename this function to ice_ptp_cfg_phy_interrupt in order to make it
|
||||
more obvious to the reader what action it performs, and distinguish it
|
||||
from other similarly named functions.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1abefdca85e8664374f53c7bc80d5f5f827ce711)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ddc2dd0b2a28..c6e9d77fc59b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1455,14 +1455,14 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_tx_ena_intr - Enable or disable the Tx timestamp interrupt
|
||||
+ * ice_ptp_cfg_phy_interrupt - Configure PHY interrupt settings
|
||||
* @pf: PF private structure
|
||||
* @ena: bool value to enable or disable interrupt
|
||||
* @threshold: Minimum number of packets at which intr is triggered
|
||||
*
|
||||
* Utility function to enable or disable Tx timestamp interrupt and threshold
|
||||
*/
|
||||
-static int ice_ptp_tx_ena_intr(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
+static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err = 0;
|
||||
@@ -2664,8 +2664,8 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
u64 time_diff;
|
||||
+ int err;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
@@ -2716,7 +2716,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
@@ -2967,7 +2967,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
+ int err;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err) {
|
||||
@@ -3002,7 +3002,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,191 +0,0 @@
|
||||
From 9411c5b82a7196b9712488631fd14e67e2d919fa Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:54 -0800
|
||||
Subject: [PATCH 21/36] ice: factor out ice_ptp_rebuild_owner()
|
||||
|
||||
The ice_ptp_reset() function uses a goto to skip past clock owner
|
||||
operations if performing a PF reset or if the device is not the clock
|
||||
owner. This is a bit confusing. Factor this out into
|
||||
ice_ptp_rebuild_owner() instead.
|
||||
|
||||
The ice_ptp_reset() function is called by ice_rebuild() to restore PTP
|
||||
functionality after a device reset. Follow the convention set by the
|
||||
ice_main.c file and rename this function to ice_ptp_rebuild(), in the
|
||||
same way that we have ice_prepare_for_reset() and
|
||||
ice_ptp_prepare_for_reset().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 803bef817807d2d36c930dada20c96fffae0dd19)
|
||||
[Adjust ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 62 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 6 +--
|
||||
3 files changed, 42 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d5321410f2d7..a04dcc89c35d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf, reset_type);
|
||||
+ ice_ptp_rebuild(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c6e9d77fc59b..780aa242c86b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2655,11 +2655,13 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
+ * ice_ptp_rebuild_owner - Initialize PTP clock owner after reset
|
||||
* @pf: Board private structure
|
||||
- * @reset_type: the reset type being performed
|
||||
+ *
|
||||
+ * Companion function for ice_ptp_rebuild() which handles tasks that only the
|
||||
+ * PTP clock owner instance should perform.
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,32 +2669,21 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
u64 time_diff;
|
||||
int err;
|
||||
|
||||
- if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
- } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
- err = -EINVAL;
|
||||
- dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
- goto pfr;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
- goto err;
|
||||
+ return err;
|
||||
|
||||
/* Acquire the global hardware lock */
|
||||
if (!ice_ptp_lock(hw)) {
|
||||
err = -EBUSY;
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the increment time value to PHY and LAN */
|
||||
err = ice_ptp_write_incval(hw, ice_base_incval(pf));
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the initial Time value to PHY and LAN using the cached PHC
|
||||
@@ -2708,7 +2699,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
err = ice_ptp_write_init(pf, &ts);
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Release the global hardware lock */
|
||||
@@ -2717,11 +2708,39 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_rebuild - Initialize PTP hardware clock support after reset
|
||||
+ * @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
+ */
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ int err;
|
||||
+
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (ice_pf_src_tmr_owned(pf) && reset_type != ICE_RESET_PFR) {
|
||||
+ err = ice_ptp_rebuild_owner(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
@@ -2736,11 +2755,6 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
- /* Restart the PHY timestamping block */
|
||||
- if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
- ice_pf_src_tmr_owned(pf))
|
||||
- ice_ptp_restart_all_phy(pf);
|
||||
-
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 1486a0b3b016..352405a2daf2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -317,7 +317,7 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
@@ -355,8 +355,8 @@ static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
- enum ice_reset_req reset_type)
|
||||
+static inline void ice_ptp_rebuild(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
{
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,93 +0,0 @@
|
||||
From 1c89a9e26f669bead5ebcac38fa98c20c517769c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:55 -0800
|
||||
Subject: [PATCH 22/36] ice: stop destroying and reinitalizing Tx tracker
|
||||
during reset
|
||||
|
||||
The ice driver currently attempts to destroy and re-initialize the Tx
|
||||
timestamp tracker during the reset flow. The release of the Tx tracker
|
||||
only happened during CORE reset or GLOBAL reset. The ice_ptp_rebuild()
|
||||
function always calls the ice_ptp_init_tx function which will allocate
|
||||
a new tracker data structure, resulting in memory leaks during PF reset.
|
||||
|
||||
Certainly the driver should not be allocating a new tracker without
|
||||
removing the old tracker data, as this results in a memory leak.
|
||||
Additionally, there's no reason to remove the tracker memory during a
|
||||
reset. Remove this logic from the reset and rebuild flow. Instead of
|
||||
releasing the Tx tracker, flush outstanding timestamps just before we
|
||||
reset the PHY timestamp block in ice_ptp_cfg_phy_interrupt().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7a25fe5cd5fb2265065ac6765c53c0a1f1e874d3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 33 +++++++++++++++---------
|
||||
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 780aa242c86b..48ec59fc5d87 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -963,6 +963,22 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_flush_all_tx_tracker - Flush all timestamp trackers on this clock
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called by the clock owner to flush all the Tx timestamp trackers associated
|
||||
+ * with the clock.
|
||||
+ */
|
||||
+static void
|
||||
+ice_ptp_flush_all_tx_tracker(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member)
|
||||
+ ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_release_tx_tracker - Release allocated memory for Tx tracker
|
||||
* @pf: Board private structure
|
||||
@@ -2705,6 +2721,11 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
+ /* Flush software tracking of any outstanding timestamps since we're
|
||||
+ * about to flush the PHY timestamp block.
|
||||
+ */
|
||||
+ ice_ptp_flush_all_tx_tracker(pf);
|
||||
+
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
@@ -2741,18 +2762,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- /* Init Tx structures */
|
||||
- if (ice_is_e810(&pf->hw)) {
|
||||
- err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
- } else {
|
||||
- kthread_init_delayed_work(&ptp->port.ov_work,
|
||||
- ice_ptp_wait_for_offsets);
|
||||
- err = ice_ptp_init_tx_e82x(pf, &ptp->port.tx,
|
||||
- ptp->port.port_num);
|
||||
- }
|
||||
- if (err)
|
||||
- goto err;
|
||||
-
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Start periodic work going */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,457 +0,0 @@
|
||||
From 6f1d1fa58f58ff3f6ce61ab502bd29227ca1bb3f Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:56 +0100
|
||||
Subject: [PATCH 23/36] ice: Remove and readd netdev during devlink reload
|
||||
|
||||
Recent changes to the devlink reload (commit 9b2348e2d6c9
|
||||
("devlink: warn about existing entities during reload-reinit"))
|
||||
force the drivers to destroy devlink ports during reinit.
|
||||
Adjust ice driver to this requirement, unregister netdvice, destroy
|
||||
devlink port. ice_init_eth() was removed and all the common code
|
||||
between probe and reload was moved to ice_load().
|
||||
|
||||
During devlink reload we can't take devl_lock (it's already taken)
|
||||
and in ice_probe() we have to lock it. Use devl_* variant of the API
|
||||
which does not acquire and release devl_lock. Guard ice_load()
|
||||
with devl_lock only in case of probe.
|
||||
|
||||
Suggested-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 41cc4e53934c30f1cf7745c257154e538c78a1f5)
|
||||
[Adjust ice.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_devlink.c | 68 ++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 186 ++++++-------------
|
||||
3 files changed, 125 insertions(+), 131 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 3278d032a2bd..d3f72f9fbcd7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -978,6 +978,8 @@ int ice_stop(struct net_device *netdev);
|
||||
void ice_service_task_schedule(struct ice_pf *pf);
|
||||
int ice_load(struct ice_pf *pf);
|
||||
void ice_unload(struct ice_pf *pf);
|
||||
+int ice_init_dev(struct ice_pf *pf);
|
||||
+void ice_deinit_dev(struct ice_pf *pf);
|
||||
|
||||
/**
|
||||
* ice_set_rdma_cap - enable RDMA support
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
index 3a2261823d93..43007e3674c4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
@@ -444,6 +444,20 @@ ice_devlink_reload_empr_start(struct ice_pf *pf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_down - unload given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static void ice_devlink_reinit_down(struct ice_pf *pf)
|
||||
+{
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ ice_unload(pf);
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
+ rtnl_unlock();
|
||||
+ ice_deinit_dev(pf);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_down - prepare for reload
|
||||
* @devlink: pointer to the devlink instance to reload
|
||||
@@ -477,7 +491,7 @@ ice_devlink_reload_down(struct devlink *devlink, bool netns_change,
|
||||
"Remove all VFs before doing reinit\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
- ice_unload(pf);
|
||||
+ ice_devlink_reinit_down(pf);
|
||||
return 0;
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
return ice_devlink_reload_empr_start(pf, extack);
|
||||
@@ -1240,6 +1254,45 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_up - do reinit of the given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static int ice_devlink_reinit_up(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+ struct ice_vsi_cfg_params params;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_init_dev(pf);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ params = ice_vsi_to_params(vsi);
|
||||
+ params.flags = ICE_VSI_FLAG_INIT;
|
||||
+
|
||||
+ rtnl_lock();
|
||||
+ err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ rtnl_unlock();
|
||||
+ if (err)
|
||||
+ goto err_vsi_cfg;
|
||||
+
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ err = ice_load(pf);
|
||||
+ if (err)
|
||||
+ goto err_load;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_load:
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(vsi);
|
||||
+ rtnl_unlock();
|
||||
+err_vsi_cfg:
|
||||
+ ice_deinit_dev(pf);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_up - do reload up after reinit
|
||||
* @devlink: pointer to the devlink instance reloading
|
||||
@@ -1260,7 +1313,7 @@ ice_devlink_reload_up(struct devlink *devlink,
|
||||
switch (action) {
|
||||
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
||||
- return ice_load(pf);
|
||||
+ return ice_devlink_reinit_up(pf);
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
|
||||
return ice_devlink_reload_empr_finish(pf, extack);
|
||||
@@ -1540,6 +1593,7 @@ static const struct devlink_port_ops ice_devlink_port_ops = {
|
||||
* @pf: the PF to create a devlink port for
|
||||
*
|
||||
* Create and register a devlink_port for this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*
|
||||
* Return: zero on success or an error code on failure.
|
||||
*/
|
||||
@@ -1552,6 +1606,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
struct device *dev;
|
||||
int err;
|
||||
|
||||
+ devlink = priv_to_devlink(pf);
|
||||
+
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
devlink_port = &pf->devlink_port;
|
||||
@@ -1572,10 +1628,9 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
ice_devlink_set_switch_id(pf, &attrs.switch_id);
|
||||
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
- devlink = priv_to_devlink(pf);
|
||||
|
||||
- err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
- &ice_devlink_port_ops);
|
||||
+ err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
+ &ice_devlink_port_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
|
||||
pf->hw.pf_id, err);
|
||||
@@ -1590,10 +1645,11 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
* @pf: the PF to cleanup
|
||||
*
|
||||
* Unregisters the devlink_port structure associated with this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_devlink_destroy_pf_port(struct ice_pf *pf)
|
||||
{
|
||||
- devlink_port_unregister(&pf->devlink_port);
|
||||
+ devl_port_unregister(&pf->devlink_port);
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index a04dcc89c35d..d3340114297a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -4588,90 +4588,6 @@ static void ice_decfg_netdev(struct ice_vsi *vsi)
|
||||
vsi->netdev = NULL;
|
||||
}
|
||||
|
||||
-static int ice_start_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- int err;
|
||||
-
|
||||
- err = ice_init_mac_fltr(vsi->back);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- err = ice_vsi_open(vsi);
|
||||
- if (err)
|
||||
- ice_fltr_remove_all(vsi);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_stop_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- ice_fltr_remove_all(vsi);
|
||||
- ice_vsi_close(vsi);
|
||||
-}
|
||||
-
|
||||
-static int ice_init_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
- int err;
|
||||
-
|
||||
- if (!vsi)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- /* init channel list */
|
||||
- INIT_LIST_HEAD(&vsi->ch_list);
|
||||
-
|
||||
- err = ice_cfg_netdev(vsi);
|
||||
- if (err)
|
||||
- return err;
|
||||
- /* Setup DCB netlink interface */
|
||||
- ice_dcbnl_setup(vsi);
|
||||
-
|
||||
- err = ice_init_mac_fltr(pf);
|
||||
- if (err)
|
||||
- goto err_init_mac_fltr;
|
||||
-
|
||||
- err = ice_devlink_create_pf_port(pf);
|
||||
- if (err)
|
||||
- goto err_devlink_create_pf_port;
|
||||
-
|
||||
- SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
-
|
||||
- err = ice_register_netdev(vsi);
|
||||
- if (err)
|
||||
- goto err_register_netdev;
|
||||
-
|
||||
- err = ice_tc_indir_block_register(vsi);
|
||||
- if (err)
|
||||
- goto err_tc_indir_block_register;
|
||||
-
|
||||
- ice_napi_add(vsi);
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-err_tc_indir_block_register:
|
||||
- ice_unregister_netdev(vsi);
|
||||
-err_register_netdev:
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
-err_devlink_create_pf_port:
|
||||
-err_init_mac_fltr:
|
||||
- ice_decfg_netdev(vsi);
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_deinit_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
-
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- ice_vsi_close(vsi);
|
||||
- ice_unregister_netdev(vsi);
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
- ice_tc_indir_block_unregister(vsi);
|
||||
- ice_decfg_netdev(vsi);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_wait_for_fw - wait for full FW readiness
|
||||
* @hw: pointer to the hardware structure
|
||||
@@ -4697,7 +4613,7 @@ static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
-static int ice_init_dev(struct ice_pf *pf)
|
||||
+int ice_init_dev(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -4790,7 +4706,7 @@ static int ice_init_dev(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void ice_deinit_dev(struct ice_pf *pf)
|
||||
+void ice_deinit_dev(struct ice_pf *pf)
|
||||
{
|
||||
ice_free_irq_msix_misc(pf);
|
||||
ice_deinit_pf(pf);
|
||||
@@ -5091,31 +5007,47 @@ static void ice_deinit(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_load - load pf by init hw and starting VSI
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
int ice_load(struct ice_pf *pf)
|
||||
{
|
||||
- struct ice_vsi_cfg_params params = {};
|
||||
struct ice_vsi *vsi;
|
||||
int err;
|
||||
|
||||
- err = ice_init_dev(pf);
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
+ vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ /* init channel list */
|
||||
+ INIT_LIST_HEAD(&vsi->ch_list);
|
||||
+
|
||||
+ err = ice_cfg_netdev(vsi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
+ /* Setup DCB netlink interface */
|
||||
+ ice_dcbnl_setup(vsi);
|
||||
|
||||
- params = ice_vsi_to_params(vsi);
|
||||
- params.flags = ICE_VSI_FLAG_INIT;
|
||||
+ err = ice_init_mac_fltr(pf);
|
||||
+ if (err)
|
||||
+ goto err_init_mac_fltr;
|
||||
|
||||
- rtnl_lock();
|
||||
- err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ err = ice_devlink_create_pf_port(pf);
|
||||
if (err)
|
||||
- goto err_vsi_cfg;
|
||||
+ goto err_devlink_create_pf_port;
|
||||
|
||||
- err = ice_start_eth(ice_get_main_vsi(pf));
|
||||
+ SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
+
|
||||
+ err = ice_register_netdev(vsi);
|
||||
+ if (err)
|
||||
+ goto err_register_netdev;
|
||||
+
|
||||
+ err = ice_tc_indir_block_register(vsi);
|
||||
if (err)
|
||||
- goto err_start_eth;
|
||||
- rtnl_unlock();
|
||||
+ goto err_tc_indir_block_register;
|
||||
+
|
||||
+ ice_napi_add(vsi);
|
||||
|
||||
err = ice_init_rdma(pf);
|
||||
if (err)
|
||||
@@ -5129,29 +5061,35 @@ int ice_load(struct ice_pf *pf)
|
||||
return 0;
|
||||
|
||||
err_init_rdma:
|
||||
- ice_vsi_close(ice_get_main_vsi(pf));
|
||||
- rtnl_lock();
|
||||
-err_start_eth:
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
-err_vsi_cfg:
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+err_tc_indir_block_register:
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+err_register_netdev:
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+err_devlink_create_pf_port:
|
||||
+err_init_mac_fltr:
|
||||
+ ice_decfg_netdev(vsi);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_unload - unload pf by stopping VSI and deinit hw
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_unload(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
ice_deinit_features(pf);
|
||||
ice_deinit_rdma(pf);
|
||||
- rtnl_lock();
|
||||
- ice_stop_eth(ice_get_main_vsi(pf));
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+ ice_decfg_netdev(vsi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5249,27 +5187,23 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
|
||||
if (err)
|
||||
goto err_init;
|
||||
|
||||
- err = ice_init_eth(pf);
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ err = ice_load(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
if (err)
|
||||
- goto err_init_eth;
|
||||
-
|
||||
- err = ice_init_rdma(pf);
|
||||
- if (err)
|
||||
- goto err_init_rdma;
|
||||
+ goto err_load;
|
||||
|
||||
err = ice_init_devlink(pf);
|
||||
if (err)
|
||||
goto err_init_devlink;
|
||||
|
||||
- ice_init_features(pf);
|
||||
-
|
||||
return 0;
|
||||
|
||||
err_init_devlink:
|
||||
- ice_deinit_rdma(pf);
|
||||
-err_init_rdma:
|
||||
- ice_deinit_eth(pf);
|
||||
-err_init_eth:
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+err_load:
|
||||
ice_deinit(pf);
|
||||
err_init:
|
||||
pci_disable_device(pdev);
|
||||
@@ -5363,12 +5297,14 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
|
||||
if (!ice_is_safe_mode(pf))
|
||||
ice_remove_arfs(pf);
|
||||
- ice_deinit_features(pf);
|
||||
+
|
||||
ice_deinit_devlink(pf);
|
||||
- ice_deinit_rdma(pf);
|
||||
- ice_deinit_eth(pf);
|
||||
- ice_deinit(pf);
|
||||
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+
|
||||
+ ice_deinit(pf);
|
||||
ice_vsi_release_all(pf);
|
||||
|
||||
ice_setup_mc_magic_wake(pf);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,434 +0,0 @@
|
||||
From e110839c4d9bfa4c885877a69573f48c008d3edd Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:11 -0800
|
||||
Subject: [PATCH 24/36] ice: remove FW logging code
|
||||
|
||||
The FW logging code doesn't work because there is no way to set
|
||||
cq_ena or uart_ena so remove the code. This code is the original
|
||||
(v1) way of FW logging so it should be replaced with the v2 way.
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1953fc720e603721764f31daae216a2851664167)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 78 -------
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 217 ------------------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 -
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 20 --
|
||||
5 files changed, 319 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 9bacb69ead8c..3b289e6a225b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2032,78 +2032,6 @@ struct ice_aqc_add_rdma_qset_data {
|
||||
struct ice_aqc_add_tx_rdma_qset_entry rdma_qsets[];
|
||||
};
|
||||
|
||||
-/* Configure Firmware Logging Command (indirect 0xFF09)
|
||||
- * Logging Information Read Response (indirect 0xFF10)
|
||||
- * Note: The 0xFF10 command has no input parameters.
|
||||
- */
|
||||
-struct ice_aqc_fw_logging {
|
||||
- u8 log_ctrl;
|
||||
-#define ICE_AQC_FW_LOG_AQ_EN BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_EN BIT(1)
|
||||
- u8 rsvd0;
|
||||
- u8 log_ctrl_valid; /* Not used by 0xFF10 Response */
|
||||
-#define ICE_AQC_FW_LOG_AQ_VALID BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_VALID BIT(1)
|
||||
- u8 rsvd1[5];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
-enum ice_aqc_fw_logging_mod {
|
||||
- ICE_AQC_FW_LOG_ID_GENERAL = 0,
|
||||
- ICE_AQC_FW_LOG_ID_CTRL,
|
||||
- ICE_AQC_FW_LOG_ID_LINK,
|
||||
- ICE_AQC_FW_LOG_ID_LINK_TOPO,
|
||||
- ICE_AQC_FW_LOG_ID_DNL,
|
||||
- ICE_AQC_FW_LOG_ID_I2C,
|
||||
- ICE_AQC_FW_LOG_ID_SDP,
|
||||
- ICE_AQC_FW_LOG_ID_MDIO,
|
||||
- ICE_AQC_FW_LOG_ID_ADMINQ,
|
||||
- ICE_AQC_FW_LOG_ID_HDMA,
|
||||
- ICE_AQC_FW_LOG_ID_LLDP,
|
||||
- ICE_AQC_FW_LOG_ID_DCBX,
|
||||
- ICE_AQC_FW_LOG_ID_DCB,
|
||||
- ICE_AQC_FW_LOG_ID_NETPROXY,
|
||||
- ICE_AQC_FW_LOG_ID_NVM,
|
||||
- ICE_AQC_FW_LOG_ID_AUTH,
|
||||
- ICE_AQC_FW_LOG_ID_VPD,
|
||||
- ICE_AQC_FW_LOG_ID_IOSF,
|
||||
- ICE_AQC_FW_LOG_ID_PARSER,
|
||||
- ICE_AQC_FW_LOG_ID_SW,
|
||||
- ICE_AQC_FW_LOG_ID_SCHEDULER,
|
||||
- ICE_AQC_FW_LOG_ID_TXQ,
|
||||
- ICE_AQC_FW_LOG_ID_RSVD,
|
||||
- ICE_AQC_FW_LOG_ID_POST,
|
||||
- ICE_AQC_FW_LOG_ID_WATCHDOG,
|
||||
- ICE_AQC_FW_LOG_ID_TASK_DISPATCH,
|
||||
- ICE_AQC_FW_LOG_ID_MNG,
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
-};
|
||||
-
|
||||
-/* Defines for both above FW logging command/response buffers */
|
||||
-#define ICE_AQC_FW_LOG_ID_S 0
|
||||
-#define ICE_AQC_FW_LOG_ID_M (0xFFF << ICE_AQC_FW_LOG_ID_S)
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_CONF_SUCCESS 0 /* Used by response */
|
||||
-#define ICE_AQC_FW_LOG_CONF_BAD_INDX BIT(12) /* Used by response */
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_EN_S 12
|
||||
-#define ICE_AQC_FW_LOG_EN_M (0xF << ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_AQC_FW_LOG_INFO_EN BIT(12) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_INIT_EN BIT(13) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_FLOW_EN BIT(14) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_ERR_EN BIT(15) /* Used by command */
|
||||
-
|
||||
-/* Get/Clear FW Log (indirect 0xFF11) */
|
||||
-struct ice_aqc_get_clear_fw_log {
|
||||
- u8 flags;
|
||||
-#define ICE_AQC_FW_LOG_CLEAR BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_MORE_DATA_AVAIL BIT(1)
|
||||
- u8 rsvd1[7];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
/* Download Package (indirect 0x0C40) */
|
||||
/* Also used for Update Package (indirect 0x0C41 and 0x0C42) */
|
||||
struct ice_aqc_download_pkg {
|
||||
@@ -2448,8 +2376,6 @@ struct ice_aq_desc {
|
||||
struct ice_aqc_add_rdma_qset add_rdma_qset;
|
||||
struct ice_aqc_add_get_update_free_vsi vsi_cmd;
|
||||
struct ice_aqc_add_update_free_vsi_resp add_update_free_vsi_res;
|
||||
- struct ice_aqc_fw_logging fw_logging;
|
||||
- struct ice_aqc_get_clear_fw_log get_clear_fw_log;
|
||||
struct ice_aqc_download_pkg download_pkg;
|
||||
struct ice_aqc_set_cgu_input_config set_cgu_input_config;
|
||||
struct ice_aqc_get_cgu_input_config get_cgu_input_config;
|
||||
@@ -2657,10 +2583,6 @@ enum ice_adminq_opc {
|
||||
|
||||
/* Standalone Commands/Events */
|
||||
ice_aqc_opc_event_lan_overflow = 0x1001,
|
||||
-
|
||||
- /* debug commands */
|
||||
- ice_aqc_opc_fw_logging = 0xFF09,
|
||||
- ice_aqc_opc_fw_logging_info = 0xFF10,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index acf6ac00f804..a5c4b7ad6a20 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -897,216 +897,6 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
|
||||
devm_kfree(ice_hw_to_dev(hw), sw);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_fw_log_cfg - get FW logging configuration
|
||||
- * @hw: pointer to the HW struct
|
||||
- */
|
||||
-static int ice_get_fw_log_cfg(struct ice_hw *hw)
|
||||
-{
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *config;
|
||||
- int status;
|
||||
- u16 size;
|
||||
-
|
||||
- size = sizeof(*config) * ICE_AQC_FW_LOG_ID_MAX;
|
||||
- config = kzalloc(size, GFP_KERNEL);
|
||||
- if (!config)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging_info);
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, config, size, NULL);
|
||||
- if (!status) {
|
||||
- u16 i;
|
||||
-
|
||||
- /* Save FW logging information into the HW structure */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 v, m, flgs;
|
||||
-
|
||||
- v = le16_to_cpu(config[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- flgs = (v & ICE_AQC_FW_LOG_EN_M) >> ICE_AQC_FW_LOG_EN_S;
|
||||
-
|
||||
- if (m < ICE_AQC_FW_LOG_ID_MAX)
|
||||
- hw->fw_log.evnts[m].cur = flgs;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- kfree(config);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_cfg_fw_log - configure FW logging
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @enable: enable certain FW logging events if true, disable all if false
|
||||
- *
|
||||
- * This function enables/disables the FW logging via Rx CQ events and a UART
|
||||
- * port based on predetermined configurations. FW logging via the Rx CQ can be
|
||||
- * enabled/disabled for individual PF's. However, FW logging via the UART can
|
||||
- * only be enabled/disabled for all PFs on the same device.
|
||||
- *
|
||||
- * To enable overall FW logging, the "cq_en" and "uart_en" enable bits in
|
||||
- * hw->fw_log need to be set accordingly, e.g. based on user-provided input,
|
||||
- * before initializing the device.
|
||||
- *
|
||||
- * When re/configuring FW logging, callers need to update the "cfg" elements of
|
||||
- * the hw->fw_log.evnts array with the desired logging event configurations for
|
||||
- * modules of interest. When disabling FW logging completely, the callers can
|
||||
- * just pass false in the "enable" parameter. On completion, the function will
|
||||
- * update the "cur" element of the hw->fw_log.evnts array with the resulting
|
||||
- * logging event configurations of the modules that are being re/configured. FW
|
||||
- * logging modules that are not part of a reconfiguration operation retain their
|
||||
- * previous states.
|
||||
- *
|
||||
- * Before resetting the device, it is recommended that the driver disables FW
|
||||
- * logging before shutting down the control queue. When disabling FW logging
|
||||
- * ("enable" = false), the latest configurations of FW logging events stored in
|
||||
- * hw->fw_log.evnts[] are not overridden to allow them to be reconfigured after
|
||||
- * a device reset.
|
||||
- *
|
||||
- * When enabling FW logging to emit log messages via the Rx CQ during the
|
||||
- * device's initialization phase, a mechanism alternative to interrupt handlers
|
||||
- * needs to be used to extract FW log messages from the Rx CQ periodically and
|
||||
- * to prevent the Rx CQ from being full and stalling other types of control
|
||||
- * messages from FW to SW. Interrupts are typically disabled during the device's
|
||||
- * initialization phase.
|
||||
- */
|
||||
-static int ice_cfg_fw_log(struct ice_hw *hw, bool enable)
|
||||
-{
|
||||
- struct ice_aqc_fw_logging *cmd;
|
||||
- u16 i, chgs = 0, len = 0;
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *data = NULL;
|
||||
- u8 actv_evnts = 0;
|
||||
- void *buf = NULL;
|
||||
- int status = 0;
|
||||
-
|
||||
- if (!hw->fw_log.cq_en && !hw->fw_log.uart_en)
|
||||
- return 0;
|
||||
-
|
||||
- /* Disable FW logging only when the control queue is still responsive */
|
||||
- if (!enable &&
|
||||
- (!hw->fw_log.actv_evnts || !ice_check_sq_alive(hw, &hw->adminq)))
|
||||
- return 0;
|
||||
-
|
||||
- /* Get current FW log settings */
|
||||
- status = ice_get_fw_log_cfg(hw);
|
||||
- if (status)
|
||||
- return status;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging);
|
||||
- cmd = &desc.params.fw_logging;
|
||||
-
|
||||
- /* Indicate which controls are valid */
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_AQ_VALID;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_UART_VALID;
|
||||
-
|
||||
- if (enable) {
|
||||
- /* Fill in an array of entries with FW logging modules and
|
||||
- * logging events being reconfigured.
|
||||
- */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 val;
|
||||
-
|
||||
- /* Keep track of enabled event types */
|
||||
- actv_evnts |= hw->fw_log.evnts[i].cfg;
|
||||
-
|
||||
- if (hw->fw_log.evnts[i].cfg == hw->fw_log.evnts[i].cur)
|
||||
- continue;
|
||||
-
|
||||
- if (!data) {
|
||||
- data = devm_kcalloc(ice_hw_to_dev(hw),
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
- sizeof(*data),
|
||||
- GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- val = i << ICE_AQC_FW_LOG_ID_S;
|
||||
- val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
|
||||
- data[chgs++] = cpu_to_le16(val);
|
||||
- }
|
||||
-
|
||||
- /* Only enable FW logging if at least one module is specified.
|
||||
- * If FW logging is currently enabled but all modules are not
|
||||
- * enabled to emit log messages, disable FW logging altogether.
|
||||
- */
|
||||
- if (actv_evnts) {
|
||||
- /* Leave if there is effectively no change */
|
||||
- if (!chgs)
|
||||
- goto out;
|
||||
-
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_AQ_EN;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
|
||||
-
|
||||
- buf = data;
|
||||
- len = sizeof(*data) * chgs;
|
||||
- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, buf, len, NULL);
|
||||
- if (!status) {
|
||||
- /* Update the current configuration to reflect events enabled.
|
||||
- * hw->fw_log.cq_en and hw->fw_log.uart_en indicate if the FW
|
||||
- * logging mode is enabled for the device. They do not reflect
|
||||
- * actual modules being enabled to emit log messages. So, their
|
||||
- * values remain unchanged even when all modules are disabled.
|
||||
- */
|
||||
- u16 cnt = enable ? chgs : (u16)ICE_AQC_FW_LOG_ID_MAX;
|
||||
-
|
||||
- hw->fw_log.actv_evnts = actv_evnts;
|
||||
- for (i = 0; i < cnt; i++) {
|
||||
- u16 v, m;
|
||||
-
|
||||
- if (!enable) {
|
||||
- /* When disabling all FW logging events as part
|
||||
- * of device's de-initialization, the original
|
||||
- * configurations are retained, and can be used
|
||||
- * to reconfigure FW logging later if the device
|
||||
- * is re-initialized.
|
||||
- */
|
||||
- hw->fw_log.evnts[i].cur = 0;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- v = le16_to_cpu(data[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-out:
|
||||
- devm_kfree(ice_hw_to_dev(hw), data);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_output_fw_log
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @desc: pointer to the AQ message descriptor
|
||||
- * @buf: pointer to the buffer accompanying the AQ message
|
||||
- *
|
||||
- * Formats a FW Log message and outputs it via the standard driver logs.
|
||||
- */
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
|
||||
-{
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg Start ]\n");
|
||||
- ice_debug_array(hw, ICE_DBG_FW_LOG, 16, 1, (u8 *)buf,
|
||||
- le16_to_cpu(desc->datalen));
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg End ]\n");
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_get_itr_intrl_gran
|
||||
* @hw: pointer to the HW struct
|
||||
@@ -1164,11 +954,6 @@ int ice_init_hw(struct ice_hw *hw)
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
|
||||
- /* Enable FW logging. Not fatal if this fails. */
|
||||
- status = ice_cfg_fw_log(hw, true);
|
||||
- if (status)
|
||||
- ice_debug(hw, ICE_DBG_INIT, "Failed to enable FW logging.\n");
|
||||
-
|
||||
status = ice_clear_pf_cfg(hw);
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
@@ -1318,8 +1103,6 @@ void ice_deinit_hw(struct ice_hw *hw)
|
||||
ice_free_hw_tbls(hw);
|
||||
mutex_destroy(&hw->tnl_lock);
|
||||
|
||||
- /* Attempt to disable FW logging before shutting down control queues */
|
||||
- ice_cfg_fw_log(hw, false);
|
||||
ice_destroy_all_ctrlq(hw);
|
||||
|
||||
/* Clear VSI contexts if not already cleared */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 7a966a0c224f..d47e5400351f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -199,7 +199,6 @@ ice_aq_cfg_lan_txq(struct ice_hw *hw, struct ice_aqc_cfg_txqs_buf *buf,
|
||||
struct ice_sq_cd *cd);
|
||||
int ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
|
||||
void ice_replay_post(struct ice_hw *hw);
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
|
||||
struct ice_q_ctx *
|
||||
ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
|
||||
int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d3340114297a..e5cc9790969c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1535,9 +1535,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
- case ice_aqc_opc_fw_logging:
|
||||
- ice_output_fw_log(hw, &event.desc, event.msg_buf);
|
||||
- break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index b0f1f4db1d8b..6e1fed0d7384 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -731,24 +731,6 @@ struct ice_switch_info {
|
||||
DECLARE_BITMAP(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS);
|
||||
};
|
||||
|
||||
-/* FW logging configuration */
|
||||
-struct ice_fw_log_evnt {
|
||||
- u8 cfg : 4; /* New event enables to configure */
|
||||
- u8 cur : 4; /* Current/active event enables */
|
||||
-};
|
||||
-
|
||||
-struct ice_fw_log_cfg {
|
||||
- u8 cq_en : 1; /* FW logging is enabled via the control queue */
|
||||
- u8 uart_en : 1; /* FW logging is enabled via UART for all PFs */
|
||||
- u8 actv_evnts; /* Cumulation of currently enabled log events */
|
||||
-
|
||||
-#define ICE_FW_LOG_EVNT_INFO (ICE_AQC_FW_LOG_INFO_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_INIT (ICE_AQC_FW_LOG_INIT_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_FLOW (ICE_AQC_FW_LOG_FLOW_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_ERR (ICE_AQC_FW_LOG_ERR_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
- struct ice_fw_log_evnt evnts[ICE_AQC_FW_LOG_ID_MAX];
|
||||
-};
|
||||
-
|
||||
/* Enum defining the different states of the mailbox snapshot in the
|
||||
* PF-VF mailbox overflow detection algorithm. The snapshot can be in
|
||||
* states:
|
||||
@@ -890,8 +872,6 @@ struct ice_hw {
|
||||
u8 fw_patch; /* firmware patch version */
|
||||
u32 fw_build; /* firmware build number */
|
||||
|
||||
- struct ice_fw_log_cfg fw_log;
|
||||
-
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
* initialization.
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,281 +0,0 @@
|
||||
From 189d58473481cf01b493fca4e9dd2ab8380d0ce5 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:13 -0800
|
||||
Subject: [PATCH 26/36] ice: enable FW logging
|
||||
|
||||
Once users have configured the FW logging then allow them to enable it
|
||||
by writing to the 'fwlog/enable' file. The file accepts a boolean value
|
||||
(0 or 1) where 1 means enable FW logging and 0 means disable FW logging.
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Where <value> is 0 or 1.
|
||||
|
||||
The user can read the 'fwlog/enable' file to see whether logging is
|
||||
enabled or not. Reading the actual data is a separate patch. To see the
|
||||
current value then:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 73671c3162c83a689342fd57f00b5f261682e49b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 3 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 98 +++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 67 +++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 2 +
|
||||
4 files changed, 170 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 347e4fed5e0d..11391be4efc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2336,6 +2336,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
};
|
||||
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
+ * Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
@@ -2344,6 +2345,7 @@ struct ice_aqc_fw_log {
|
||||
#define ICE_AQC_FW_LOG_CONF_AQ_EN BIT(1)
|
||||
#define ICE_AQC_FW_LOG_QUERY_REGISTERED BIT(2)
|
||||
#define ICE_AQC_FW_LOG_CONF_SET_VALID BIT(3)
|
||||
+#define ICE_AQC_FW_LOG_AQ_REGISTER BIT(0)
|
||||
#define ICE_AQC_FW_LOG_AQ_QUERY BIT(2)
|
||||
|
||||
u8 rsp_flag;
|
||||
@@ -2662,6 +2664,7 @@ enum ice_adminq_opc {
|
||||
|
||||
/* FW Logging Commands */
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
+ ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3b0d9b214fd1..3dde99969132 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -281,6 +281,101 @@ static const struct file_operations ice_debugfs_nr_messages_fops = {
|
||||
.write = ice_debugfs_nr_messages_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_enable_read - read from 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_enable_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+
|
||||
+ snprintf(buff, sizeof(buff), "%u\n",
|
||||
+ (u16)(hw->fwlog_cfg.options &
|
||||
+ ICE_FWLOG_OPTION_IS_REGISTERED) >> 3);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_enable_write - write into 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_enable_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ bool enable;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 2)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = kstrtobool(user_val, &enable);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+
|
||||
+ ret = ice_fwlog_set(hw, &hw->fwlog_cfg);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ ret = ice_fwlog_register(hw);
|
||||
+ else
|
||||
+ ret = ice_fwlog_unregister(hw);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+enable_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_enable_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_enable_read,
|
||||
+ .write = ice_debugfs_enable_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -332,6 +427,9 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = fw_modules;
|
||||
|
||||
+ debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_enable_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 307e0d04f3fe..25a17cbc1d34 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -63,6 +63,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
kfree(pf->ice_debugfs_pf_fwlog_modules);
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = NULL;
|
||||
+
|
||||
+ status = ice_fwlog_unregister(hw);
|
||||
+ if (status)
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
+ status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,6 +202,8 @@ static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
|
||||
cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
|
||||
+ if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
|
||||
+ cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;
|
||||
|
||||
@@ -226,6 +233,66 @@ int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
return ice_aq_fwlog_get(hw, cfg);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @reg: true to register and false to unregister
|
||||
+ */
|
||||
+static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
|
||||
+{
|
||||
+ struct ice_aq_desc desc;
|
||||
+
|
||||
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);
|
||||
+
|
||||
+ if (reg)
|
||||
+ desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;
|
||||
+
|
||||
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_register - Register the PF for firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * After this call the PF will start to receive firmware logging based on the
|
||||
+ * configuration set in ice_fwlog_set.
|
||||
+ */
|
||||
+int ice_fwlog_register(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, true);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_unregister - Unregister the PF from firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ */
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, false);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_set_supported - Set if FW logging is supported by FW
|
||||
* @hw: pointer to the HW struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 8e68ee02713b..45865558425d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -53,4 +53,6 @@ int ice_fwlog_init(struct ice_hw *hw);
|
||||
void ice_fwlog_deinit(struct ice_hw *hw);
|
||||
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
+int ice_fwlog_register(struct ice_hw *hw);
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,572 +0,0 @@
|
||||
From a584ea88cfdc8ac3f782be1d5d67fa92c3423290 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:14 -0800
|
||||
Subject: [PATCH 27/36] ice: add ability to read and configure FW log data
|
||||
|
||||
Once logging is enabled the user should read the data from the 'data'
|
||||
file. The data is in the form of a binary blob that can be sent to Intel
|
||||
for decoding. To read the data use a command like:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data > log_data.bin
|
||||
|
||||
If the user wants to clear the FW log data that has been stored in the
|
||||
driver then they can write any value to the 'data' file and that will clear
|
||||
the data. An example is:
|
||||
|
||||
# echo 34 > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data
|
||||
|
||||
In addition to being able to read the data the user can configure how
|
||||
much memory is used to store FW log data. This allows the user to
|
||||
increase/decrease the amount of memory based on the users situation.
|
||||
The data is stored such that if the memory fills up then the oldest data
|
||||
will get overwritten in a circular manner. To change the amount of
|
||||
memory the user can write to the 'log_size' file like this:
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Where <value> is one of 128K, 256K, 512K, 1M, and 2M. The default value
|
||||
is 1M.
|
||||
|
||||
The user can see the current value of 'log_size' by reading the file:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 9d3535e71985beb738c4ad2b772c6f0efdce0202)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 210 ++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 142 ++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 21 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 29 +++
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 1 +
|
||||
6 files changed, 405 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 11391be4efc2..f63b57ff2a3d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2338,6 +2338,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
* Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
+ * FW Log Event (indirect 0xFF33)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
u8 cmd_flags;
|
||||
@@ -2666,6 +2667,7 @@ enum ice_adminq_opc {
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
+ ice_aqc_opc_fw_logs_event = 0xFF33,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3dde99969132..c2bfba6b9ead 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -64,6 +64,17 @@ static const char * const ice_fwlog_level_string[] = {
|
||||
"verbose",
|
||||
};
|
||||
|
||||
+/* the order in this array is important. it matches the ordering of the
|
||||
+ * values in the FW so the index is the same value as in ice_fwlog_level
|
||||
+ */
|
||||
+static const char * const ice_fwlog_log_size[] = {
|
||||
+ "128K",
|
||||
+ "256K",
|
||||
+ "512K",
|
||||
+ "1M",
|
||||
+ "2M",
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_print_module_cfg - print current FW logging module configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -376,6 +387,199 @@ static const struct file_operations ice_debugfs_enable_fops = {
|
||||
.write = ice_debugfs_enable_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_read - read from 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_log_size_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+ int index;
|
||||
+
|
||||
+ index = hw->fwlog_ring.index;
|
||||
+ snprintf(buff, sizeof(buff), "%s\n", ice_fwlog_log_size[index]);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_write - write into 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_log_size_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ ssize_t ret;
|
||||
+ int index;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 5)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ index = sysfs_match_string(ice_fwlog_log_size, user_val);
|
||||
+ if (index < 0) {
|
||||
+ dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n",
|
||||
+ user_val);
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ } else if (hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) {
|
||||
+ dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* free all the buffers and the tracking info and resize */
|
||||
+ ice_fwlog_realloc_rings(hw, index);
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+log_size_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_log_size_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_log_size_read,
|
||||
+ .write = ice_debugfs_log_size_write,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_read - read from 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_data_read(struct file *filp, char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ int data_copied = 0;
|
||||
+ bool done = false;
|
||||
+
|
||||
+ if (ice_fwlog_ring_empty(&hw->fwlog_ring))
|
||||
+ return 0;
|
||||
+
|
||||
+ while (!ice_fwlog_ring_empty(&hw->fwlog_ring) && !done) {
|
||||
+ struct ice_fwlog_data *log;
|
||||
+ u16 cur_buf_len;
|
||||
+
|
||||
+ log = &hw->fwlog_ring.rings[hw->fwlog_ring.head];
|
||||
+ cur_buf_len = log->data_size;
|
||||
+ if (cur_buf_len >= count) {
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_to_user(buffer, log->data, cur_buf_len)) {
|
||||
+ /* if there is an error then bail and return whatever
|
||||
+ * the driver has copied so far
|
||||
+ */
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ data_copied += cur_buf_len;
|
||||
+ buffer += cur_buf_len;
|
||||
+ count -= cur_buf_len;
|
||||
+ *ppos += cur_buf_len;
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+
|
||||
+ return data_copied;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_write - write into 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_data_write(struct file *filp, const char __user *buf, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes */
|
||||
+ if (*ppos != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* any value is allowed to clear the buffer so no need to even look at
|
||||
+ * what the value is
|
||||
+ */
|
||||
+ if (!(hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED)) {
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+ } else {
|
||||
+ dev_info(dev, "Can't clear FW log data while FW log running\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto nr_buffs_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+nr_buffs_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_data_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_data_read,
|
||||
+ .write = ice_debugfs_data_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -430,6 +634,12 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
pf, &ice_debugfs_enable_fops);
|
||||
|
||||
+ debugfs_create_file("log_size", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_log_size_fops);
|
||||
+
|
||||
+ debugfs_create_file("data", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_data_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 25a17cbc1d34..92b5dac481cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -1,10 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2022, Intel Corporation. */
|
||||
|
||||
+#include <linux/vmalloc.h>
|
||||
#include "ice.h"
|
||||
#include "ice_common.h"
|
||||
#include "ice_fwlog.h"
|
||||
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ u16 head, tail;
|
||||
+
|
||||
+ head = rings->head;
|
||||
+ tail = rings->tail;
|
||||
+
|
||||
+ if (head < tail && (tail - head == (rings->size - 1)))
|
||||
+ return true;
|
||||
+ else if (head > tail && (tail == (head - 1)))
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ return rings->head == rings->tail;
|
||||
+}
|
||||
+
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size)
|
||||
+{
|
||||
+ *item = (*item + 1) & (size - 1);
|
||||
+}
|
||||
+
|
||||
+static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i, nr_bytes;
|
||||
+ u8 *mem;
|
||||
+
|
||||
+ nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN;
|
||||
+ mem = vzalloc(nr_bytes);
|
||||
+ if (!mem)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ ring->data_size = ICE_AQ_MAX_BUF_LEN;
|
||||
+ ring->data = mem;
|
||||
+ mem += ICE_AQ_MAX_BUF_LEN;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ /* the first ring is the base memory for the whole range so
|
||||
+ * free it
|
||||
+ */
|
||||
+ if (!i)
|
||||
+ vfree(ring->data);
|
||||
+
|
||||
+ ring->data = NULL;
|
||||
+ ring->data_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n))
|
||||
+/**
|
||||
+ * ice_fwlog_realloc_rings - reallocate the FW log rings
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @index: the new index to use to allocate memory for the log data
|
||||
+ *
|
||||
+ */
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index)
|
||||
+{
|
||||
+ struct ice_fwlog_ring ring;
|
||||
+ int status, ring_size;
|
||||
+
|
||||
+ /* convert the number of bytes into a number of 4K buffers. externally
|
||||
+ * the driver presents the interface to the FW log data as a number of
|
||||
+ * bytes because that's easy for users to understand. internally the
|
||||
+ * driver uses a ring of buffers because the driver doesn't know where
|
||||
+ * the beginning and end of any line of log data is so the driver has
|
||||
+ * to overwrite data as complete blocks. when the data is returned to
|
||||
+ * the user the driver knows that the data is correct and the FW log
|
||||
+ * can be correctly parsed by the tools
|
||||
+ */
|
||||
+ ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN;
|
||||
+ if (ring_size == hw->fwlog_ring.size)
|
||||
+ return;
|
||||
+
|
||||
+ /* allocate space for the new rings and buffers then release the
|
||||
+ * old rings and buffers. that way if we don't have enough
|
||||
+ * memory then we at least have what we had before
|
||||
+ */
|
||||
+ ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL);
|
||||
+ if (!ring.rings)
|
||||
+ return;
|
||||
+
|
||||
+ ring.size = ring_size;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&ring);
|
||||
+ kfree(ring.rings);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+
|
||||
+ hw->fwlog_ring.rings = ring.rings;
|
||||
+ hw->fwlog_ring.size = ring.size;
|
||||
+ hw->fwlog_ring.index = index;
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_init - Initialize FW logging configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -28,6 +146,25 @@ int ice_fwlog_init(struct ice_hw *hw)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
+ hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT,
|
||||
+ sizeof(*hw->fwlog_ring.rings),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!hw->fwlog_ring.rings) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT;
|
||||
+ hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
ice_debugfs_fwlog_init(hw->back);
|
||||
} else {
|
||||
dev_warn(ice_hw_to_dev(hw), "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n");
|
||||
@@ -68,6 +205,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (status)
|
||||
dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
status);
|
||||
+
|
||||
+ if (hw->fwlog_ring.rings) {
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 45865558425d..287e71fa4b86 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -47,6 +47,26 @@ struct ice_fwlog_cfg {
|
||||
u16 log_resolution;
|
||||
};
|
||||
|
||||
+struct ice_fwlog_data {
|
||||
+ u16 data_size;
|
||||
+ u8 *data;
|
||||
+};
|
||||
+
|
||||
+struct ice_fwlog_ring {
|
||||
+ struct ice_fwlog_data *rings;
|
||||
+ u16 index;
|
||||
+ u16 size;
|
||||
+ u16 head;
|
||||
+ u16 tail;
|
||||
+};
|
||||
+
|
||||
+#define ICE_FWLOG_RING_SIZE_INDEX_DFLT 3
|
||||
+#define ICE_FWLOG_RING_SIZE_DFLT 256
|
||||
+#define ICE_FWLOG_RING_SIZE_MAX 512
|
||||
+
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings);
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings);
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size);
|
||||
void ice_fwlog_set_supported(struct ice_hw *hw);
|
||||
bool ice_fwlog_supported(struct ice_hw *hw);
|
||||
int ice_fwlog_init(struct ice_hw *hw);
|
||||
@@ -55,4 +75,5 @@ int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_register(struct ice_hw *hw);
|
||||
int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 614e10ab4159..6c6ca5353f28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1254,6 +1254,32 @@ ice_handle_link_event(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_get_fwlog_data - copy the FW log data from ARQ event
|
||||
+ * @pf: PF that the FW log event is associated with
|
||||
+ * @event: event structure containing FW log data
|
||||
+ */
|
||||
+static void
|
||||
+ice_get_fwlog_data(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
+{
|
||||
+ struct ice_fwlog_data *fwlog;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+
|
||||
+ fwlog = &hw->fwlog_ring.rings[hw->fwlog_ring.tail];
|
||||
+
|
||||
+ memset(fwlog->data, 0, PAGE_SIZE);
|
||||
+ fwlog->data_size = le16_to_cpu(event->desc.datalen);
|
||||
+
|
||||
+ memcpy(fwlog->data, event->msg_buf, fwlog->data_size);
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.tail, hw->fwlog_ring.size);
|
||||
+
|
||||
+ if (ice_fwlog_ring_full(&hw->fwlog_ring)) {
|
||||
+ /* the rings are full so bump the head to create room */
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_aq_prep_for_event - Prepare to wait for an AdminQ event from firmware
|
||||
* @pf: pointer to the PF private structure
|
||||
@@ -1535,6 +1561,9 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
+ case ice_aqc_opc_fw_logs_event:
|
||||
+ ice_get_fwlog_data(pf, &event);
|
||||
+ break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 84bb61aa7409..28e47bb78eaf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -875,6 +875,7 @@ struct ice_hw {
|
||||
|
||||
struct ice_fwlog_cfg fwlog_cfg;
|
||||
bool fwlog_supported; /* does hardware support FW logging? */
|
||||
+ struct ice_fwlog_ring fwlog_ring;
|
||||
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,98 +0,0 @@
|
||||
From 8a7f6d8b2105c39f236c51c558e21b787c223861 Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:57 +0100
|
||||
Subject: [PATCH 28/36] ice: Fix debugfs with devlink reload
|
||||
|
||||
During devlink reload it is needed to remove debugfs entries
|
||||
correlated with only one PF. ice_debugfs_exit() removes all
|
||||
entries created by ice driver so we can't use it.
|
||||
|
||||
Introduce ice_debugfs_pf_deinit() in order to release PF's
|
||||
debugfs entries. Move ice_debugfs_exit() call to ice_module_exit(),
|
||||
it makes more sense since ice_debugfs_init() is called in
|
||||
ice_module_init() and not in ice_probe().
|
||||
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 500d0df5b4b2394a06b949bab05f7ed0242b9858)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 10 ++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 +--
|
||||
4 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 7966ac61154c..ed1c6cdedeff 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -895,6 +895,7 @@ static inline bool ice_is_adq_active(struct ice_pf *pf)
|
||||
}
|
||||
|
||||
void ice_debugfs_fwlog_init(struct ice_pf *pf);
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf);
|
||||
void ice_debugfs_init(void);
|
||||
void ice_debugfs_exit(void);
|
||||
void ice_pf_fwlog_update_module(struct ice_pf *pf, int log_level, int module);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index c2bfba6b9ead..ba396b22bb7d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -647,6 +647,16 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
kfree(fw_modules);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_pf_deinit - cleanup PF's debugfs
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf)
|
||||
+{
|
||||
+ debugfs_remove_recursive(pf->ice_debugfs_pf);
|
||||
+ pf->ice_debugfs_pf = NULL;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_init - create root directory for debugfs entries
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 92b5dac481cd..4fd15387a7e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -188,6 +188,8 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (hw->bus.func)
|
||||
return;
|
||||
|
||||
+ ice_debugfs_pf_deinit(hw->back);
|
||||
+
|
||||
/* make sure FW logging is disabled to not put the FW in a weird state
|
||||
* for the next driver load
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 6c6ca5353f28..c882c218281a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -5325,8 +5325,6 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
- ice_debugfs_exit();
|
||||
-
|
||||
if (test_bit(ICE_FLAG_SRIOV_ENA, pf->flags)) {
|
||||
set_bit(ICE_VF_RESETS_DISABLED, pf->state);
|
||||
ice_free_vfs(pf);
|
||||
@@ -5823,6 +5821,7 @@ module_init(ice_module_init);
|
||||
static void __exit ice_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ice_driver);
|
||||
+ ice_debugfs_exit();
|
||||
destroy_workqueue(ice_wq);
|
||||
destroy_workqueue(ice_lag_wq);
|
||||
pr_info("module unloaded\n");
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,78 +0,0 @@
|
||||
From 861015cbb4cf4cb258a1da9e80550fe991be7808 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 16 Feb 2024 14:06:38 -0800
|
||||
Subject: [PATCH 29/36] ice: remove vf->lan_vsi_num field
|
||||
|
||||
The lan_vsi_num field of the VF structure is no longer used for any
|
||||
purpose. Remove it.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1cf94cbfc61bac89cddeb075fbc100ebd3aea81b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_sriov.c | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 +---
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.h | 5 -----
|
||||
3 files changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
index 442162be23ea..3366ac976c44 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
@@ -239,7 +239,6 @@ static struct ice_vsi *ice_vf_vsi_setup(struct ice_vf *vf)
|
||||
}
|
||||
|
||||
vf->lan_vsi_idx = vsi->idx;
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return vsi;
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
index 03b9d7d74851..303fdf8555cf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
@@ -298,7 +298,6 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf)
|
||||
* vf->lan_vsi_idx
|
||||
*/
|
||||
vsi->vsi_num = ice_get_hw_vsi_num(&pf->hw, vsi->idx);
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1299,13 +1298,12 @@ int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_vf_invalidate_vsi - invalidate vsi_idx/vsi_num to remove VSI access
|
||||
+ * ice_vf_invalidate_vsi - invalidate vsi_idx to remove VSI access
|
||||
* @vf: VF to remove access to VSI for
|
||||
*/
|
||||
void ice_vf_invalidate_vsi(struct ice_vf *vf)
|
||||
{
|
||||
vf->lan_vsi_idx = ICE_NO_VSI;
|
||||
- vf->lan_vsi_num = ICE_NO_VSI;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
index 48fea6fa0362..1de07accbc5c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
@@ -110,11 +110,6 @@ struct ice_vf {
|
||||
u8 spoofchk:1;
|
||||
u8 link_forced:1;
|
||||
u8 link_up:1; /* only valid if VF link is forced */
|
||||
- /* VSI indices - actual VSI pointers are maintained in the PF structure
|
||||
- * When assigned, these will be non-zero, because VSI 0 is always
|
||||
- * the main LAN VSI for the PF.
|
||||
- */
|
||||
- u16 lan_vsi_num; /* ID as used by firmware */
|
||||
unsigned int min_tx_rate; /* Minimum Tx bandwidth limit in Mbps */
|
||||
unsigned int max_tx_rate; /* Maximum Tx bandwidth limit in Mbps */
|
||||
DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,150 +0,0 @@
|
||||
From 6b7fae8669a04943af9f83ef89d39a922ed179fd Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:54 -0800
|
||||
Subject: [PATCH 30/36] ice: rename ice_write_* functions to ice_pack_ctx_*
|
||||
|
||||
In ice_common.c there are 4 functions used for converting the unpacked
|
||||
software Tx and Rx context structure data into the packed format used by
|
||||
hardware. These functions have extremely generic names:
|
||||
|
||||
* ice_write_byte
|
||||
* ice_write_word
|
||||
* ice_write_dword
|
||||
* ice_write_qword
|
||||
|
||||
When I saw these function names my first thought was "write what? to
|
||||
where?". Understanding what these functions do requires looking at the
|
||||
implementation details. The functions take bits from an unpacked structure
|
||||
and copy them into the packed layout used by hardware.
|
||||
|
||||
As part of live migration, we will want functions which perform the inverse
|
||||
operation of reading bits from the packed layout and copying them into the
|
||||
unpacked format. Naming these as "ice_read_byte", etc would be very
|
||||
confusing since they appear to write data.
|
||||
|
||||
In preparation for adding this new inverse operation, rename the existing
|
||||
functions to use the prefix "ice_pack_ctx_". This makes it clear that they
|
||||
perform the bit packing while copying from the unpacked software context
|
||||
structure to the packed hardware context.
|
||||
|
||||
The inverse operations can then neatly be named ice_unpack_ctx_*, clearly
|
||||
indicating they perform the bit unpacking while copying from the packed
|
||||
hardware context to the unpacked software context structure.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1260b45dbe2dbc415f3bc1e841c6c098083bcfb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 56 ++++++++++-----------
|
||||
1 file changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 6dcba0577633..17f60a98c8ed 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4267,13 +4267,13 @@ ice_aq_add_rdma_qsets(struct ice_hw *hw, u8 num_qset_grps,
|
||||
/* End of FW Admin Queue command wrappers */
|
||||
|
||||
/**
|
||||
- * ice_write_byte - write a byte to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_byte - write a byte to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u8 src_byte, dest_byte, mask;
|
||||
u8 *from, *dest;
|
||||
@@ -4306,13 +4306,13 @@ ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_word - write a word to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_word - write a word to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u16 src_word, mask;
|
||||
__le16 dest_word;
|
||||
@@ -4349,13 +4349,13 @@ ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_dword - write a dword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_dword - write a dword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u32 src_dword, mask;
|
||||
__le32 dest_dword;
|
||||
@@ -4400,13 +4400,13 @@ ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_qword - write a qword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_qword - write a qword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u64 src_qword, mask;
|
||||
__le64 dest_qword;
|
||||
@@ -4475,16 +4475,16 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
}
|
||||
switch (ce_info[f].size_of) {
|
||||
case sizeof(u8):
|
||||
- ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
- ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
- ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u64):
|
||||
- ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,129 +0,0 @@
|
||||
From 619e0e61b39cf051137613459d36c4fe8f435e57 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:55 -0800
|
||||
Subject: [PATCH 31/36] ice: use GENMASK instead of BIT(n) - 1 in pack
|
||||
functions
|
||||
|
||||
The functions used to pack the Tx and Rx context into the hardware format
|
||||
rely on using BIT() and then subtracting 1 to get a bitmask. These
|
||||
functions even have a comment about how x86 machines can't use this method
|
||||
for certain widths because the SHL instructions will not work properly.
|
||||
|
||||
The Linux kernel already provides the GENMASK macro for generating a
|
||||
suitable bitmask. Further, GENMASK is capable of generating the mask
|
||||
including the shift_width. Since width is the total field width, take care
|
||||
to subtract one to get the final bit position.
|
||||
|
||||
Since we now include the shifted bits as part of the mask, shift the source
|
||||
value first before applying the mask.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit a45d1bf516c097bb7ae4983d3128ebf139be952c)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 44 ++++-----------------
|
||||
1 file changed, 8 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 17f60a98c8ed..55a2e264dd69 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4284,14 +4284,11 @@ static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = (u8)(BIT(ce_info->width) - 1);
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
src_byte = *from;
|
||||
- src_byte &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_byte <<= shift_width;
|
||||
+ src_byte &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4324,17 +4321,14 @@ static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_word = *(u16 *)from;
|
||||
- src_word &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_word <<= shift_width;
|
||||
+ src_word &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4367,25 +4361,14 @@ static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 32 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 5 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 32)
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u32)~0;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_dword = *(u32 *)from;
|
||||
- src_dword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_dword <<= shift_width;
|
||||
+ src_dword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4418,25 +4401,14 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 64 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 6 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 64)
|
||||
- mask = BIT_ULL(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u64)~0;
|
||||
+ mask = GENMASK_ULL(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_qword = *(u64 *)from;
|
||||
- src_qword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_qword <<= shift_width;
|
||||
+ src_qword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,89 +0,0 @@
|
||||
From 6502dd63a7bd436c72d2ee8b328985b93fa7e2a5 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:56 -0800
|
||||
Subject: [PATCH 32/36] ice: cleanup line splitting for context set functions
|
||||
|
||||
The indentation for ice_set_ctx and ice_write_rxq_ctx breaks the function
|
||||
name after the return type. This style of breaking is used a lot throughout
|
||||
the ice driver, even in cases where its not actually helpful for
|
||||
readability. We no longer prefer this style of line splitting in the
|
||||
driver, and new code is avoiding it.
|
||||
|
||||
Normally, I would leave this alone unless the actual function contents or
|
||||
description needed updating. However, a future change is going to add
|
||||
inverse functions for converting packed context to unpacked context
|
||||
structures. To keep this code uniform with the existing set functions, fix
|
||||
up the style to the modern format of keeping the type on the same line.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 979c2c049fbea107ce9f8d31f3ba9dba83ddb0a2)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 12 +++++-------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 10 ++++------
|
||||
2 files changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 55a2e264dd69..59ede77a1473 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -1329,9 +1329,8 @@ static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
|
||||
* it to HW register space and enables the hardware to prefetch descriptors
|
||||
* instead of only fetching them on demand
|
||||
*/
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index)
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index)
|
||||
{
|
||||
u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
|
||||
|
||||
@@ -4427,11 +4426,10 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
* @hw: pointer to the hardware structure
|
||||
* @src_ctx: pointer to a generic non-packed context structure
|
||||
* @dest_ctx: pointer to memory for the packed structure
|
||||
- * @ce_info: a description of the structure to be transformed
|
||||
+ * @ce_info: List of Rx context elements
|
||||
*/
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info)
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
int f;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index d47e5400351f..1c3c29d30815 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -52,9 +52,8 @@ int ice_get_caps(struct ice_hw *hw);
|
||||
|
||||
void ice_set_safe_mode_caps(struct ice_hw *hw);
|
||||
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index);
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index);
|
||||
|
||||
int
|
||||
ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params);
|
||||
@@ -71,9 +70,8 @@ bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);
|
||||
int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
|
||||
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);
|
||||
extern const struct ice_ctx_ele ice_tlan_ctx_info[];
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info);
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info);
|
||||
|
||||
extern struct mutex ice_global_cfg_lock_sw;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,161 +0,0 @@
|
||||
From 675a8843a0de1411666389eeabeea452161f8cc5 Mon Sep 17 00:00:00 2001
|
||||
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Date: Fri, 23 Feb 2024 17:06:27 +0100
|
||||
Subject: [PATCH 33/36] ice: do not disable Tx queues twice in ice_down()
|
||||
|
||||
ice_down() clears QINT_TQCTL_CAUSE_ENA_M bit twice, which is not
|
||||
necessary. First clearing happens in ice_vsi_dis_irq() and second in
|
||||
ice_vsi_stop_tx_ring() - remove the first one.
|
||||
|
||||
While at it, make ice_vsi_dis_irq() static as ice_down() is the only
|
||||
current caller of it.
|
||||
|
||||
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d5926e01e3739542bb047b77f850d7f641eaa7bc)
|
||||
[Adjust ice_lib.c with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 55 -----------------------
|
||||
drivers/net/ethernet/intel/ice/ice_lib.h | 2 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 44 ++++++++++++++++++
|
||||
3 files changed, 44 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 106ef843f4b5..f23cb9c8e3dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -2877,61 +2877,6 @@ void ice_dis_vsi(struct ice_vsi *vsi, bool locked)
|
||||
}
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
- * @vsi: the VSI being un-configured
|
||||
- */
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
-{
|
||||
- struct ice_pf *pf = vsi->back;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u32 val;
|
||||
- int i;
|
||||
-
|
||||
- /* disable interrupt causation from each queue */
|
||||
- if (vsi->tx_rings) {
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (vsi->tx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->tx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_TQCTL(reg));
|
||||
- val &= ~QINT_TQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_TQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (vsi->rx_rings) {
|
||||
- ice_for_each_rxq(vsi, i) {
|
||||
- if (vsi->rx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->rx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_RQCTL(reg));
|
||||
- val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_RQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* disable each interrupt */
|
||||
- ice_for_each_q_vector(vsi, i) {
|
||||
- if (!vsi->q_vectors[i])
|
||||
- continue;
|
||||
- wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
- }
|
||||
-
|
||||
- ice_flush(hw);
|
||||
-
|
||||
- /* don't call synchronize_irq() for VF's from the host */
|
||||
- if (vsi->type == ICE_VSI_VF)
|
||||
- return;
|
||||
-
|
||||
- ice_for_each_q_vector(vsi, i)
|
||||
- synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_vsi_release - Delete a VSI and free its resources
|
||||
* @vsi: the VSI being removed
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
index f24f5d1e6f9c..dbd0f3409323 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
@@ -110,8 +110,6 @@ void
|
||||
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio,
|
||||
bool ena_ts);
|
||||
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi);
|
||||
-
|
||||
void ice_vsi_free_irq(struct ice_vsi *vsi);
|
||||
|
||||
void ice_vsi_free_rx_rings(struct ice_vsi *vsi);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index c882c218281a..685635a22616 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7023,6 +7023,50 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
+ * @vsi: the VSI being un-configured
|
||||
+ */
|
||||
+static void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
+{
|
||||
+ struct ice_pf *pf = vsi->back;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ /* disable interrupt causation from each Rx queue; Tx queues are
|
||||
+ * handled in ice_vsi_stop_tx_ring()
|
||||
+ */
|
||||
+ if (vsi->rx_rings) {
|
||||
+ ice_for_each_rxq(vsi, i) {
|
||||
+ if (vsi->rx_rings[i]) {
|
||||
+ u16 reg;
|
||||
+
|
||||
+ reg = vsi->rx_rings[i]->reg_idx;
|
||||
+ val = rd32(hw, QINT_RQCTL(reg));
|
||||
+ val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
+ wr32(hw, QINT_RQCTL(reg), val);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* disable each interrupt */
|
||||
+ ice_for_each_q_vector(vsi, i) {
|
||||
+ if (!vsi->q_vectors[i])
|
||||
+ continue;
|
||||
+ wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
+ }
|
||||
+
|
||||
+ ice_flush(hw);
|
||||
+
|
||||
+ /* don't call synchronize_irq() for VF's from the host */
|
||||
+ if (vsi->type == ICE_VSI_VF)
|
||||
+ return;
|
||||
+
|
||||
+ ice_for_each_q_vector(vsi, i)
|
||||
+ synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_down - Shutdown the connection
|
||||
* @vsi: The VSI being stopped
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,274 +0,0 @@
|
||||
From e53280c20bbe58015a91178268244d5e831276f4 Mon Sep 17 00:00:00 2001
|
||||
From: Milena Olech <milena.olech@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:54 -0700
|
||||
Subject: [PATCH 34/36] ice: Fix improper extts handling
|
||||
|
||||
Extts events are disabled and enabled by the application ts2phc.
|
||||
However, in case where the driver is removed when the application is
|
||||
running, a specific extts event remains enabled and can cause a kernel
|
||||
crash.
|
||||
As a side effect, when the driver is reloaded and application is started
|
||||
again, remaining extts event for the channel from a previous run will
|
||||
keep firing and the message "extts on unexpected channel" might be
|
||||
printed to the user.
|
||||
|
||||
To avoid that, extts events shall be disabled when PTP is released.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Milena Olech <milena.olech@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-2-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 00d3b4f54582d4e4a02cda5886bb336eeab268cc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 105 ++++++++++++++++++-----
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 ++
|
||||
2 files changed, 91 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 48ec59fc5d87..6e06c5d596b9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1603,27 +1603,24 @@ void ice_ptp_extts_event(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_ptp_cfg_extts - Configure EXTTS pin and channel
|
||||
* @pf: Board private structure
|
||||
- * @ena: true to enable; false to disable
|
||||
* @chan: GPIO channel (0-3)
|
||||
- * @gpio_pin: GPIO pin
|
||||
- * @extts_flags: request flags from the ptp_extts_request.flags
|
||||
+ * @config: desired EXTTS configuration.
|
||||
+ * @store: If set to true, the values will be stored
|
||||
+ *
|
||||
+ * Configure an external timestamp event on the requested channel.
|
||||
*/
|
||||
-static int
|
||||
-ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
|
||||
- unsigned int extts_flags)
|
||||
+static void ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan,
|
||||
+ struct ice_extts_channel *config, bool store)
|
||||
{
|
||||
u32 func, aux_reg, gpio_reg, irq_reg;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
u8 tmr_idx;
|
||||
|
||||
- if (chan > (unsigned int)pf->ptp.info.n_ext_ts)
|
||||
- return -EINVAL;
|
||||
-
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
|
||||
irq_reg = rd32(hw, PFINT_OICR_ENA);
|
||||
|
||||
- if (ena) {
|
||||
+ if (config->ena) {
|
||||
/* Enable the interrupt */
|
||||
irq_reg |= PFINT_OICR_TSYN_EVNT_M;
|
||||
aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M;
|
||||
@@ -1632,9 +1629,9 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
|
||||
#define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1)
|
||||
|
||||
/* set event level to requested edge */
|
||||
- if (extts_flags & PTP_FALLING_EDGE)
|
||||
+ if (config->flags & PTP_FALLING_EDGE)
|
||||
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE;
|
||||
- if (extts_flags & PTP_RISING_EDGE)
|
||||
+ if (config->flags & PTP_RISING_EDGE)
|
||||
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE;
|
||||
|
||||
/* Write GPIO CTL reg.
|
||||
@@ -1656,9 +1653,47 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
|
||||
|
||||
wr32(hw, PFINT_OICR_ENA, irq_reg);
|
||||
wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg);
|
||||
- wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg);
|
||||
+ wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg);
|
||||
|
||||
- return 0;
|
||||
+ if (store)
|
||||
+ memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_disable_all_extts - Disable all EXTTS channels
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_disable_all_extts(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_extts_channel extts_cfg = {};
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
|
||||
+ if (pf->ptp.extts_channels[i].ena) {
|
||||
+ extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin;
|
||||
+ extts_cfg.ena = false;
|
||||
+ ice_ptp_cfg_extts(pf, i, &extts_cfg, false);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ synchronize_irq(pf->oicr_irq.virq);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_enable_all_extts - Enable all EXTTS channels
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called during reset to restore user configuration.
|
||||
+ */
|
||||
+static void ice_ptp_enable_all_extts(struct ice_pf *pf)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
|
||||
+ if (pf->ptp.extts_channels[i].ena)
|
||||
+ ice_ptp_cfg_extts(pf, i, &pf->ptp.extts_channels[i],
|
||||
+ false);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1815,7 +1850,6 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
struct ptp_clock_request *rq, int on)
|
||||
{
|
||||
struct ice_pf *pf = ptp_info_to_pf(info);
|
||||
- struct ice_perout_channel clk_cfg = {0};
|
||||
bool sma_pres = false;
|
||||
unsigned int chan;
|
||||
u32 gpio_pin;
|
||||
@@ -1826,6 +1860,9 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
switch (rq->type) {
|
||||
case PTP_CLK_REQ_PEROUT:
|
||||
+ {
|
||||
+ struct ice_perout_channel clk_cfg = {};
|
||||
+
|
||||
chan = rq->perout.index;
|
||||
if (sma_pres) {
|
||||
if (chan == ice_pin_desc_e810t[SMA1].chan)
|
||||
@@ -1853,7 +1890,11 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
|
||||
break;
|
||||
+ }
|
||||
case PTP_CLK_REQ_EXTTS:
|
||||
+ {
|
||||
+ struct ice_extts_channel extts_cfg = {};
|
||||
+
|
||||
chan = rq->extts.index;
|
||||
if (sma_pres) {
|
||||
if (chan < ice_pin_desc_e810t[SMA2].chan)
|
||||
@@ -1869,9 +1910,13 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
gpio_pin = chan;
|
||||
}
|
||||
|
||||
- err = ice_ptp_cfg_extts(pf, !!on, chan, gpio_pin,
|
||||
- rq->extts.flags);
|
||||
- break;
|
||||
+ extts_cfg.flags = rq->extts.flags;
|
||||
+ extts_cfg.gpio_pin = gpio_pin;
|
||||
+ extts_cfg.ena = !!on;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -1889,21 +1934,31 @@ static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info,
|
||||
struct ptp_clock_request *rq, int on)
|
||||
{
|
||||
struct ice_pf *pf = ptp_info_to_pf(info);
|
||||
- struct ice_perout_channel clk_cfg = {0};
|
||||
int err;
|
||||
|
||||
switch (rq->type) {
|
||||
case PTP_CLK_REQ_PPS:
|
||||
+ {
|
||||
+ struct ice_perout_channel clk_cfg = {};
|
||||
+
|
||||
clk_cfg.gpio_pin = PPS_PIN_INDEX;
|
||||
clk_cfg.period = NSEC_PER_SEC;
|
||||
clk_cfg.ena = !!on;
|
||||
|
||||
err = ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
|
||||
break;
|
||||
+ }
|
||||
case PTP_CLK_REQ_EXTTS:
|
||||
- err = ice_ptp_cfg_extts(pf, !!on, rq->extts.index,
|
||||
- TIME_SYNC_PIN_INDEX, rq->extts.flags);
|
||||
- break;
|
||||
+ {
|
||||
+ struct ice_extts_channel extts_cfg = {};
|
||||
+
|
||||
+ extts_cfg.flags = rq->extts.flags;
|
||||
+ extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX;
|
||||
+ extts_cfg.ena = !!on;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -2735,6 +2790,10 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
ice_ptp_restart_all_phy(pf);
|
||||
}
|
||||
|
||||
+ /* Re-enable all periodic outputs and external timestamp events */
|
||||
+ ice_ptp_enable_all_clkout(pf);
|
||||
+ ice_ptp_enable_all_extts(pf);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3286,6 +3345,8 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
+ ice_ptp_disable_all_extts(pf);
|
||||
+
|
||||
kthread_cancel_delayed_work_sync(&pf->ptp.work);
|
||||
|
||||
ice_ptp_port_phy_stop(&pf->ptp.port);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 352405a2daf2..c6469a5a7afb 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -33,6 +33,12 @@ struct ice_perout_channel {
|
||||
u64 start_time;
|
||||
};
|
||||
|
||||
+struct ice_extts_channel {
|
||||
+ bool ena;
|
||||
+ u32 gpio_pin;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
/* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp
|
||||
* is stored in a buffer of registers. Depending on the specific hardware,
|
||||
* this buffer might be shared across multiple PHY ports.
|
||||
@@ -226,6 +232,7 @@ enum ice_ptp_state {
|
||||
* @ext_ts_irq: the external timestamp IRQ in use
|
||||
* @kworker: kwork thread for handling periodic work
|
||||
* @perout_channels: periodic output data
|
||||
+ * @extts_channels: channels for external timestamps
|
||||
* @info: structure defining PTP hardware capabilities
|
||||
* @clock: pointer to registered PTP clock device
|
||||
* @tstamp_config: hardware timestamping configuration
|
||||
@@ -249,6 +256,7 @@ struct ice_ptp {
|
||||
u8 ext_ts_irq;
|
||||
struct kthread_worker *kworker;
|
||||
struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX];
|
||||
+ struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX];
|
||||
struct ptp_clock_info info;
|
||||
struct ptp_clock *clock;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 6c24a32820031f9713d0c0cf7ac6f4ead6b58052 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:55 -0700
|
||||
Subject: [PATCH 35/36] ice: Don't process extts if PTP is disabled
|
||||
|
||||
The ice_ptp_extts_event() function can race with ice_ptp_release() and
|
||||
result in a NULL pointer dereference which leads to a kernel panic.
|
||||
|
||||
Panic occurs because the ice_ptp_extts_event() function calls
|
||||
ptp_clock_event() with a NULL pointer. The ice driver has already
|
||||
released the PTP clock by the time the interrupt for the next external
|
||||
timestamp event occurs.
|
||||
|
||||
To fix this, modify the ice_ptp_extts_event() function to check the
|
||||
PTP state and bail early if PTP is not ready.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-3-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 996422e3230e41468f652d754fefd1bdbcd4604e)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 6e06c5d596b9..ceb4ba19c511 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1578,6 +1578,10 @@ void ice_ptp_extts_event(struct ice_pf *pf)
|
||||
u8 chan, tmr_idx;
|
||||
u32 hi, lo;
|
||||
|
||||
+ /* Don't process timestamp events if PTP is not ready */
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
+ return;
|
||||
+
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
/* Event time is captured by one of the two matched registers
|
||||
* GLTSYN_EVNT_L: 32 LSB of sampled time event
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,628 +0,0 @@
|
||||
From 1ce01cb7cdb0bf4c18a546a62f224c8032d75ebd Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:51 -0700
|
||||
Subject: [PATCH 36/36] ice: Introduce ice_ptp_hw struct
|
||||
|
||||
Create new ice_ptp_hw struct and use it for all HW and PTP-related
|
||||
fields from struct ice_hw.
|
||||
Replace definitions with struct fields, which values are set accordingly
|
||||
to a specific device.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-1-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit d551d075b043821880b8afc0010ef70d050716d0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 24 ++++
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 22 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 134 ++++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 4 +-
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 17 ++-
|
||||
6 files changed, 126 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 59ede77a1473..147004e0170b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -209,6 +209,30 @@ bool ice_is_e810t(struct ice_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_is_e822 - Check if a device is E822 family device
|
||||
+ * @hw: pointer to the hardware structure
|
||||
+ *
|
||||
+ * Return: true if the device is E822 based, false if not.
|
||||
+ */
|
||||
+bool ice_is_e822(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->device_id) {
|
||||
+ case ICE_DEV_ID_E822C_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822C_QSFP:
|
||||
+ case ICE_DEV_ID_E822C_SFP:
|
||||
+ case ICE_DEV_ID_E822C_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822C_SGMII:
|
||||
+ case ICE_DEV_ID_E822L_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822L_SFP:
|
||||
+ case ICE_DEV_ID_E822L_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822L_SGMII:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_is_e823
|
||||
* @hw: pointer to the hardware structure
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 1c3c29d30815..9d38777310e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -245,6 +245,7 @@ void
|
||||
ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat);
|
||||
bool ice_is_e810t(struct ice_hw *hw);
|
||||
+bool ice_is_e822(struct ice_hw *hw);
|
||||
bool ice_is_e823(struct ice_hw *hw);
|
||||
int
|
||||
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ceb4ba19c511..bb1572a353d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -812,7 +812,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
}
|
||||
mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -1026,7 +1026,7 @@ ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static int
|
||||
ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
{
|
||||
- tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
+ tx->block = ICE_GET_QUAD_NUM(port);
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
tx->has_ready_bitmap = 1;
|
||||
@@ -1248,8 +1248,8 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
*/
|
||||
static int ice_ptp_check_tx_fifo(struct ice_ptp_port *port)
|
||||
{
|
||||
- int quad = port->port_num / ICE_PORTS_PER_QUAD;
|
||||
int offs = port->port_num % ICE_PORTS_PER_QUAD;
|
||||
+ int quad = ICE_GET_QUAD_NUM(port->port_num);
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u32 val, phy_sts;
|
||||
@@ -1448,7 +1448,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
- if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
+ if (WARN_ON_ONCE(port >= hw->ptp.num_lports))
|
||||
return;
|
||||
|
||||
ptp_port = &pf->ptp.port;
|
||||
@@ -1458,7 +1458,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
/* Update cached link status for this port immediately */
|
||||
ptp_port->link_up = linkup;
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
/* Do not reconfigure E810 PHY */
|
||||
return;
|
||||
@@ -1487,7 +1487,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
|
||||
ice_ptp_reset_ts_memory(hw);
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++) {
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) {
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG,
|
||||
&val);
|
||||
if (err)
|
||||
@@ -2038,7 +2038,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
/* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
- if (hw->phy_model == ICE_PHY_E82X)
|
||||
+ if (hw->ptp.phy_model == ICE_PHY_E82X)
|
||||
ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
@@ -2652,7 +2652,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
if (!ice_pf_src_tmr_owned(pf))
|
||||
return;
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -3152,7 +3152,7 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_init(&ptp_port->ps_lock);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3245,7 +3245,7 @@ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
*/
|
||||
static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
{
|
||||
- switch (pf->hw.phy_model) {
|
||||
+ switch (pf->hw.ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
/* E822 based PHY has the clock owner process the interrupt
|
||||
* for all ports.
|
||||
@@ -3281,7 +3281,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ptp->state = ICE_PTP_INITIALIZING;
|
||||
|
||||
- ice_ptp_init_phy_model(hw);
|
||||
+ ice_ptp_init_hw(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 7337e7e710ed..313a72dad813 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -285,18 +285,21 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
|
||||
|
||||
/**
|
||||
* ice_fill_phy_msg_e82x - Fill message data for a PHY register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @port: the port to access
|
||||
* @offset: the register offset
|
||||
*/
|
||||
-static void
|
||||
-ice_fill_phy_msg_e82x(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
+static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 port,
|
||||
+ u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY_E82X;
|
||||
- phy = port / ICE_PORTS_PER_PHY_E82X;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E82X;
|
||||
+ phy_port = port % hw->ptp.ports_per_phy;
|
||||
+ phy = port / hw->ptp.ports_per_phy;
|
||||
+ quadtype = ICE_GET_QUAD_NUM(port) %
|
||||
+ ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -427,7 +430,7 @@ ice_read_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -504,7 +507,7 @@ ice_write_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
@@ -614,24 +617,30 @@ ice_write_64b_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
|
||||
/**
|
||||
* ice_fill_quad_msg_e82x - Fill message data for quad register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @quad: the quad to access
|
||||
* @offset: the register offset
|
||||
*
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * * %0 - OK
|
||||
+ * * %-EINVAL - invalid quad number
|
||||
*/
|
||||
-static int
|
||||
-ice_fill_quad_msg_e82x(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
+static int ice_fill_quad_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 quad,
|
||||
+ u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
+ if (quad >= ICE_GET_QUAD_NUM(hw->ptp.num_lports))
|
||||
return -EINVAL;
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_QUADS_PER_PHY_E82X) == 0)
|
||||
+ if (!(quad % ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy)))
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
@@ -658,7 +667,7 @@ ice_read_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -692,7 +701,7 @@ ice_write_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -813,7 +822,7 @@ static void ice_ptp_reset_ts_memory_e82x(struct ice_hw *hw)
|
||||
{
|
||||
unsigned int quad;
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++)
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++)
|
||||
ice_ptp_reset_ts_memory_quad_e82x(hw, quad);
|
||||
}
|
||||
|
||||
@@ -1110,7 +1119,7 @@ static int ice_ptp_set_vernier_wl(struct ice_hw *hw)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_write_phy_reg_e82x(hw, port, P_REG_WL,
|
||||
@@ -1175,7 +1184,7 @@ ice_ptp_prep_phy_time_e82x(struct ice_hw *hw, u32 time)
|
||||
*/
|
||||
phy_time = (u64)time << 32;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
/* Tx case */
|
||||
err = ice_write_64b_phy_reg_e82x(hw, port,
|
||||
P_REG_TX_TIMER_INC_PRE_L,
|
||||
@@ -1278,7 +1287,7 @@ ice_ptp_prep_phy_adj_e82x(struct ice_hw *hw, s32 adj)
|
||||
else
|
||||
cycles = -(((s64)-adj) << 32);
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_prep_port_adj_e82x(hw, port, cycles);
|
||||
@@ -1304,7 +1313,7 @@ ice_ptp_prep_phy_incval_e82x(struct ice_hw *hw, u64 incval)
|
||||
int err;
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
err = ice_write_40b_phy_reg_e82x(hw, port, P_REG_TIMETUS_L,
|
||||
incval);
|
||||
if (err)
|
||||
@@ -1460,7 +1469,7 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
enum ice_ptp_tmr_cmd cmd;
|
||||
int err;
|
||||
|
||||
@@ -1490,7 +1499,7 @@ ice_ptp_port_cmd_e82x(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_write_port_cmd_e82x(hw, port, cmd);
|
||||
@@ -1603,7 +1612,7 @@ static void ice_phy_cfg_lane_e82x(struct ice_hw *hw, u8 port)
|
||||
return;
|
||||
}
|
||||
|
||||
- quad = port / ICE_PORTS_PER_QUAD;
|
||||
+ quad = ICE_GET_QUAD_NUM(port);
|
||||
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
|
||||
if (err) {
|
||||
@@ -2632,6 +2641,17 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e82x - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e82x(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 8;
|
||||
+}
|
||||
+
|
||||
/* E810 functions
|
||||
*
|
||||
* The following functions operate on the E810 series devices which use
|
||||
@@ -2859,17 +2879,21 @@ static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
|
||||
+ * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
* @hw: pointer to HW struct
|
||||
*
|
||||
- * Enable the timesync PTP functionality for the external PHY connected to
|
||||
- * this function.
|
||||
+ * Perform E810-specific PTP hardware clock initialization steps.
|
||||
+ *
|
||||
+ * Return: 0 on success, other error codes when failed to initialize TimeSync
|
||||
*/
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
+static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
{
|
||||
u8 tmr_idx;
|
||||
int err;
|
||||
|
||||
+ /* Ensure synchronization delay is zero */
|
||||
+ wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
+
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
|
||||
GLTSYN_ENA_TSYN_ENA_M);
|
||||
@@ -2880,21 +2904,6 @@ int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
return err;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
- * @hw: pointer to HW struct
|
||||
- *
|
||||
- * Perform E810-specific PTP hardware clock initialization steps.
|
||||
- */
|
||||
-static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
-{
|
||||
- /* Ensure synchronization delay is zero */
|
||||
- wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
-
|
||||
- /* Initialize the PHY */
|
||||
- return ice_ptp_init_phy_e810(hw);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
|
||||
* @hw: Board private structure
|
||||
@@ -3238,6 +3247,17 @@ int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data)
|
||||
return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e810 - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e810(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E810;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 4;
|
||||
+}
|
||||
+
|
||||
/* Device agnostic functions
|
||||
*
|
||||
* The following functions implement shared behavior common to both E822 and
|
||||
@@ -3295,18 +3315,22 @@ void ice_ptp_unlock(struct ice_hw *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_model - Initialize hw->phy_model based on device type
|
||||
+ * ice_ptp_init_hw - Initialize hw based on device type
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
- * Determine the PHY model for the device, and initialize hw->phy_model
|
||||
+ * Determine the PHY model for the device, and initialize hw
|
||||
* for use by other functions.
|
||||
*/
|
||||
-void ice_ptp_init_phy_model(struct ice_hw *hw)
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
- hw->phy_model = ICE_PHY_E810;
|
||||
+ struct ice_ptp_hw *ptp = &hw->ptp;
|
||||
+
|
||||
+ if (ice_is_e822(hw) || ice_is_e823(hw))
|
||||
+ ice_ptp_init_phy_e82x(ptp);
|
||||
+ else if (ice_is_e810(hw))
|
||||
+ ice_ptp_init_phy_e810(ptp);
|
||||
else
|
||||
- hw->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->phy_model = ICE_PHY_UNSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3327,7 +3351,7 @@ static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
ice_ptp_src_cmd(hw, cmd);
|
||||
|
||||
/* Next, prepare the ports */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_port_cmd_e810(hw, cmd);
|
||||
break;
|
||||
@@ -3379,7 +3403,7 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
|
||||
|
||||
/* PHY timers */
|
||||
/* Fill Rx and Tx ports and send msg to PHY */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
|
||||
break;
|
||||
@@ -3421,7 +3445,7 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_incval_e810(hw, incval);
|
||||
break;
|
||||
@@ -3487,7 +3511,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_adj_e810(hw, adj);
|
||||
break;
|
||||
@@ -3517,7 +3541,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
*/
|
||||
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3545,7 +3569,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_clear_phy_tstamp_e810(hw, block, idx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3606,7 +3630,7 @@ int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
|
||||
*/
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
ice_ptp_reset_ts_memory_e82x(hw);
|
||||
break;
|
||||
@@ -3632,7 +3656,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
/* Clear event err indications for auxiliary pins */
|
||||
(void)rd32(hw, GLTSYN_STAT(src_idx));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_phc_e810(hw);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3655,7 +3679,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
*/
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_get_phy_tx_tstamp_ready_e810(hw, block,
|
||||
tstamp_ready);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 7e8fd369ef7c..d788221eba57 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -211,6 +211,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx);
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw);
|
||||
int ice_ptp_init_phc(struct ice_hw *hw);
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw);
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready);
|
||||
|
||||
/* E822 family functions */
|
||||
@@ -265,7 +266,6 @@ int ice_phy_cfg_tx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
int ice_phy_cfg_rx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
|
||||
/* E810 family functions */
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw);
|
||||
int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
|
||||
int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
|
||||
int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
|
||||
@@ -280,8 +280,6 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
|
||||
u8 *ref_state, u8 *eec_mode, s64 *phase_offset,
|
||||
enum dpll_lock_status *dpll_state);
|
||||
int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
-
|
||||
-void ice_ptp_init_phy_model(struct ice_hw *hw);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 28e47bb78eaf..6fc4cd1030d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -807,6 +807,9 @@ struct ice_mbx_data {
|
||||
u16 async_watermark_val;
|
||||
};
|
||||
|
||||
+#define ICE_PORTS_PER_QUAD 4
|
||||
+#define ICE_GET_QUAD_NUM(port) ((port) / ICE_PORTS_PER_QUAD)
|
||||
+
|
||||
/* PHY model */
|
||||
enum ice_phy_model {
|
||||
ICE_PHY_UNSUP = -1,
|
||||
@@ -814,6 +817,12 @@ enum ice_phy_model {
|
||||
ICE_PHY_E82X,
|
||||
};
|
||||
|
||||
+struct ice_ptp_hw {
|
||||
+ enum ice_phy_model phy_model;
|
||||
+ u8 num_lports;
|
||||
+ u8 ports_per_phy;
|
||||
+};
|
||||
+
|
||||
/* Port hardware description */
|
||||
struct ice_hw {
|
||||
u8 __iomem *hw_addr;
|
||||
@@ -835,7 +844,6 @@ struct ice_hw {
|
||||
u8 revision_id;
|
||||
|
||||
u8 pf_id; /* device profile info */
|
||||
- enum ice_phy_model phy_model;
|
||||
|
||||
u16 max_burst_size; /* driver sets this value */
|
||||
|
||||
@@ -896,12 +904,7 @@ struct ice_hw {
|
||||
/* INTRL granularity in 1 us */
|
||||
u8 intrl_gran;
|
||||
|
||||
-#define ICE_MAX_QUAD 2
|
||||
-#define ICE_QUADS_PER_PHY_E82X 2
|
||||
-#define ICE_PORTS_PER_PHY_E82X 8
|
||||
-#define ICE_PORTS_PER_QUAD 4
|
||||
-#define ICE_PORTS_PER_PHY_E810 4
|
||||
-#define ICE_NUM_EXTERNAL_PORTS (ICE_MAX_QUAD * ICE_PORTS_PER_QUAD)
|
||||
+ struct ice_ptp_hw ptp;
|
||||
|
||||
/* Active package version (currently active) */
|
||||
struct ice_pkg_ver active_pkg_ver;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,80 +0,0 @@
|
||||
From cd12b5c8239993e395436ff9a01b524103aa0641 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:56 -0700
|
||||
Subject: [PATCH] ice: Introduce ice_get_base_incval() helper
|
||||
|
||||
Add a new helper for getting base clock increment value for specific HW.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-6-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 1f374d57c39386520586539641cafc999d0f3ef5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 9 +--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index bb1572a353d0..44b8fc8021cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#define E810_OUT_PROP_DELAY_NS 1
|
||||
|
||||
-#define UNKNOWN_INCVAL_E82X 0x100000000ULL
|
||||
-
|
||||
static const struct ptp_pin_desc ice_pin_desc_e810t[] = {
|
||||
/* name idx func chan */
|
||||
{ "GNSS", GNSS, PTP_PF_EXTTS, 0, { 0, } },
|
||||
@@ -1229,12 +1227,7 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
u64 incval;
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
- incval = ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
- else if (ice_e82x_time_ref(hw) < NUM_ICE_TIME_REF_FREQ)
|
||||
- incval = ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
- else
|
||||
- incval = UNKNOWN_INCVAL_E82X;
|
||||
+ incval = ice_get_base_incval(hw);
|
||||
|
||||
dev_dbg(ice_pf_to_dev(pf), "PTP: using base increment value of 0x%016llx\n",
|
||||
incval);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index d788221eba57..749a3f2d8293 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -283,6 +283,24 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
+/**
|
||||
+ * ice_get_base_incval - Get base clock increment value
|
||||
+ * @hw: pointer to the HW struct
|
||||
+ *
|
||||
+ * Return: base clock increment value for supported PHYs, 0 otherwise
|
||||
+ */
|
||||
+static inline u64 ice_get_base_incval(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
+ return ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
+ case ICE_PHY_E82X:
|
||||
+ return ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
#define ICE_PTP_CLOCK_INDEX_0 0x00
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 437206483113743a4ef40c2f7e14f09705049672 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Mon, 2 Sep 2024 03:18:08 +0000
|
||||
Subject: [PATCH] ice:modify the ice driver version to stx.4
|
||||
|
||||
Change the ice driver min version to stx.4 because we back ported
|
||||
the upstream 36 commits to our code base to support the customer's
|
||||
requirement.
|
||||
|
||||
The ice driver version should be ice-6.6.40-stx.4.
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5807b310bdca..7163d25405f8 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1227,7 +1227,7 @@ uapi-asm-generic:
|
||||
|
||||
# KERNELRELEASE can change from a few different places, meaning version.h
|
||||
# needs to be updated, so this check is forced on all builds
|
||||
-ICE_STX = "-stx.3"
|
||||
+ICE_STX = "-stx.4"
|
||||
I40E_STX = "-stx.0"
|
||||
IAVF_STX = "-stx.0"
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,541 +0,0 @@
|
||||
From cff205e9f2d09efb61ca647dfd01b5a229952e22 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Date: Wed, 13 Sep 2023 21:49:35 +0100
|
||||
Subject: [PATCH 01/46] dpll: documentation on DPLL subsystem interface
|
||||
|
||||
Add documentation explaining common netlink interface to configure DPLL
|
||||
devices and monitoring events. Common way to implement DPLL device in
|
||||
a driver is also covered.
|
||||
|
||||
Co-developed-by: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit dbb291f19393b628a1d15b94a78d471b9d94e532)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/driver-api/dpll.rst | 497 +++++++++++++++++++++++++++++
|
||||
Documentation/driver-api/index.rst | 1 +
|
||||
2 files changed, 498 insertions(+)
|
||||
create mode 100644 Documentation/driver-api/dpll.rst
|
||||
|
||||
diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
|
||||
new file mode 100644
|
||||
index 000000000000..bb52f1b8c0be
|
||||
--- /dev/null
|
||||
+++ b/Documentation/driver-api/dpll.rst
|
||||
@@ -0,0 +1,497 @@
|
||||
+.. SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+===============================
|
||||
+The Linux kernel dpll subsystem
|
||||
+===============================
|
||||
+
|
||||
+DPLL
|
||||
+====
|
||||
+
|
||||
+PLL - Phase Locked Loop is an electronic circuit which syntonizes clock
|
||||
+signal of a device with an external clock signal. Effectively enabling
|
||||
+device to run on the same clock signal beat as provided on a PLL input.
|
||||
+
|
||||
+DPLL - Digital Phase Locked Loop is an integrated circuit which in
|
||||
+addition to plain PLL behavior incorporates a digital phase detector
|
||||
+and may have digital divider in the loop. As a result, the frequency on
|
||||
+DPLL's input and output may be configurable.
|
||||
+
|
||||
+Subsystem
|
||||
+=========
|
||||
+
|
||||
+The main purpose of dpll subsystem is to provide general interface
|
||||
+to configure devices that use any kind of Digital PLL and could use
|
||||
+different sources of input signal to synchronize to, as well as
|
||||
+different types of outputs.
|
||||
+The main interface is NETLINK_GENERIC based protocol with an event
|
||||
+monitoring multicast group defined.
|
||||
+
|
||||
+Device object
|
||||
+=============
|
||||
+
|
||||
+Single dpll device object means single Digital PLL circuit and bunch of
|
||||
+connected pins.
|
||||
+It reports the supported modes of operation and current status to the
|
||||
+user in response to the `do` request of netlink command
|
||||
+``DPLL_CMD_DEVICE_GET`` and list of dplls registered in the subsystem
|
||||
+with `dump` netlink request of the same command.
|
||||
+Changing the configuration of dpll device is done with `do` request of
|
||||
+netlink ``DPLL_CMD_DEVICE_SET`` command.
|
||||
+A device handle is ``DPLL_A_ID``, it shall be provided to get or set
|
||||
+configuration of particular device in the system. It can be obtained
|
||||
+with a ``DPLL_CMD_DEVICE_GET`` `dump` request or
|
||||
+a ``DPLL_CMD_DEVICE_ID_GET`` `do` request, where the one must provide
|
||||
+attributes that result in single device match.
|
||||
+
|
||||
+Pin object
|
||||
+==========
|
||||
+
|
||||
+A pin is amorphic object which represents either input or output, it
|
||||
+could be internal component of the device, as well as externally
|
||||
+connected.
|
||||
+The number of pins per dpll vary, but usually multiple pins shall be
|
||||
+provided for a single dpll device.
|
||||
+Pin's properties, capabilities and status is provided to the user in
|
||||
+response to `do` request of netlink ``DPLL_CMD_PIN_GET`` command.
|
||||
+It is also possible to list all the pins that were registered in the
|
||||
+system with `dump` request of ``DPLL_CMD_PIN_GET`` command.
|
||||
+Configuration of a pin can be changed by `do` request of netlink
|
||||
+``DPLL_CMD_PIN_SET`` command.
|
||||
+Pin handle is a ``DPLL_A_PIN_ID``, it shall be provided to get or set
|
||||
+configuration of particular pin in the system. It can be obtained with
|
||||
+``DPLL_CMD_PIN_GET`` `dump` request or ``DPLL_CMD_PIN_ID_GET`` `do`
|
||||
+request, where user provides attributes that result in single pin match.
|
||||
+
|
||||
+Pin selection
|
||||
+=============
|
||||
+
|
||||
+In general, selected pin (the one which signal is driving the dpll
|
||||
+device) can be obtained from ``DPLL_A_PIN_STATE`` attribute, and only
|
||||
+one pin shall be in ``DPLL_PIN_STATE_CONNECTED`` state for any dpll
|
||||
+device.
|
||||
+
|
||||
+Pin selection can be done either manually or automatically, depending
|
||||
+on hardware capabilities and active dpll device work mode
|
||||
+(``DPLL_A_MODE`` attribute). The consequence is that there are
|
||||
+differences for each mode in terms of available pin states, as well as
|
||||
+for the states the user can request for a dpll device.
|
||||
+
|
||||
+In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive
|
||||
+one of following pin states:
|
||||
+
|
||||
+- ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device
|
||||
+- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll
|
||||
+ device
|
||||
+
|
||||
+In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or
|
||||
+receive one of following pin states:
|
||||
+
|
||||
+- ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid
|
||||
+ input for automatic selection algorithm
|
||||
+- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as
|
||||
+ a valid input for automatic selection algorithm
|
||||
+
|
||||
+In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive
|
||||
+pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection
|
||||
+algorithm locks a dpll device with one of the inputs.
|
||||
+
|
||||
+Shared pins
|
||||
+===========
|
||||
+
|
||||
+A single pin object can be attached to multiple dpll devices.
|
||||
+Then there are two groups of configuration knobs:
|
||||
+
|
||||
+1) Set on a pin - the configuration affects all dpll devices pin is
|
||||
+ registered to (i.e., ``DPLL_A_PIN_FREQUENCY``),
|
||||
+2) Set on a pin-dpll tuple - the configuration affects only selected
|
||||
+ dpll device (i.e., ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE``,
|
||||
+ ``DPLL_A_PIN_DIRECTION``).
|
||||
+
|
||||
+MUX-type pins
|
||||
+=============
|
||||
+
|
||||
+A pin can be MUX-type, it aggregates child pins and serves as a pin
|
||||
+multiplexer. One or more pins are registered with MUX-type instead of
|
||||
+being directly registered to a dpll device.
|
||||
+Pins registered with a MUX-type pin provide user with additional nested
|
||||
+attribute ``DPLL_A_PIN_PARENT_PIN`` for each parent they were registered
|
||||
+with.
|
||||
+If a pin was registered with multiple parent pins, they behave like a
|
||||
+multiple output multiplexer. In this case output of a
|
||||
+``DPLL_CMD_PIN_GET`` would contain multiple pin-parent nested
|
||||
+attributes with current state related to each parent, like:
|
||||
+
|
||||
+'pin': [{{
|
||||
+ 'clock-id': 282574471561216,
|
||||
+ 'module-name': 'ice',
|
||||
+ 'capabilities': 4,
|
||||
+ 'id': 13,
|
||||
+ 'parent-pin': [
|
||||
+ {'parent-id': 2, 'state': 'connected'},
|
||||
+ {'parent-id': 3, 'state': 'disconnected'}
|
||||
+ ],
|
||||
+ 'type': 'synce-eth-port'
|
||||
+ }}]
|
||||
+
|
||||
+Only one child pin can provide its signal to the parent MUX-type pin at
|
||||
+a time, the selection is done by requesting change of a child pin state
|
||||
+on desired parent, with the use of ``DPLL_A_PIN_PARENT`` nested
|
||||
+attribute. Example of netlink `set state on parent pin` message format:
|
||||
+
|
||||
+ ========================== =============================================
|
||||
+ ``DPLL_A_PIN_ID`` child pin id
|
||||
+ ``DPLL_A_PIN_PARENT_PIN`` nested attribute for requesting configuration
|
||||
+ related to parent pin
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` parent pin id
|
||||
+ ``DPLL_A_PIN_STATE`` requested pin state on parent
|
||||
+ ========================== =============================================
|
||||
+
|
||||
+Pin priority
|
||||
+============
|
||||
+
|
||||
+Some devices might offer a capability of automatic pin selection mode
|
||||
+(enum value ``DPLL_MODE_AUTOMATIC`` of ``DPLL_A_MODE`` attribute).
|
||||
+Usually, automatic selection is performed on the hardware level, which
|
||||
+means only pins directly connected to the dpll can be used for automatic
|
||||
+input pin selection.
|
||||
+In automatic selection mode, the user cannot manually select a input
|
||||
+pin for the device, instead the user shall provide all directly
|
||||
+connected pins with a priority ``DPLL_A_PIN_PRIO``, the device would
|
||||
+pick a highest priority valid signal and use it to control the DPLL
|
||||
+device. Example of netlink `set priority on parent pin` message format:
|
||||
+
|
||||
+ ============================ =============================================
|
||||
+ ``DPLL_A_PIN_ID`` configured pin id
|
||||
+ ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting configuration
|
||||
+ related to parent dpll device
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` parent dpll device id
|
||||
+ ``DPLL_A_PIN_PRIO`` requested pin prio on parent dpll
|
||||
+ ============================ =============================================
|
||||
+
|
||||
+Child pin of MUX-type pin is not capable of automatic input pin selection,
|
||||
+in order to configure active input of a MUX-type pin, the user needs to
|
||||
+request desired pin state of the child pin on the parent pin,
|
||||
+as described in the ``MUX-type pins`` chapter.
|
||||
+
|
||||
+Configuration commands group
|
||||
+============================
|
||||
+
|
||||
+Configuration commands are used to get information about registered
|
||||
+dpll devices (and pins), as well as set configuration of device or pins.
|
||||
+As dpll devices must be abstracted and reflect real hardware,
|
||||
+there is no way to add new dpll device via netlink from user space and
|
||||
+each device should be registered by its driver.
|
||||
+
|
||||
+All netlink commands require ``GENL_ADMIN_PERM``. This is to prevent
|
||||
+any spamming/DoS from unauthorized userspace applications.
|
||||
+
|
||||
+List of netlink commands with possible attributes
|
||||
+=================================================
|
||||
+
|
||||
+Constants identifying command types for dpll device uses a
|
||||
+``DPLL_CMD_`` prefix and suffix according to command purpose.
|
||||
+The dpll device related attributes use a ``DPLL_A_`` prefix and
|
||||
+suffix according to attribute purpose.
|
||||
+
|
||||
+ ==================================== =================================
|
||||
+ ``DPLL_CMD_DEVICE_ID_GET`` command to get device ID
|
||||
+ ``DPLL_A_MODULE_NAME`` attr module name of registerer
|
||||
+ ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier
|
||||
+ (EUI-64), as defined by the
|
||||
+ IEEE 1588 standard
|
||||
+ ``DPLL_A_TYPE`` attr type of dpll device
|
||||
+ ==================================== =================================
|
||||
+
|
||||
+ ==================================== =================================
|
||||
+ ``DPLL_CMD_DEVICE_GET`` command to get device info or
|
||||
+ dump list of available devices
|
||||
+ ``DPLL_A_ID`` attr unique dpll device ID
|
||||
+ ``DPLL_A_MODULE_NAME`` attr module name of registerer
|
||||
+ ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier
|
||||
+ (EUI-64), as defined by the
|
||||
+ IEEE 1588 standard
|
||||
+ ``DPLL_A_MODE`` attr selection mode
|
||||
+ ``DPLL_A_MODE_SUPPORTED`` attr available selection modes
|
||||
+ ``DPLL_A_LOCK_STATUS`` attr dpll device lock status
|
||||
+ ``DPLL_A_TEMP`` attr device temperature info
|
||||
+ ``DPLL_A_TYPE`` attr type of dpll device
|
||||
+ ==================================== =================================
|
||||
+
|
||||
+ ==================================== =================================
|
||||
+ ``DPLL_CMD_DEVICE_SET`` command to set dpll device config
|
||||
+ ``DPLL_A_ID`` attr internal dpll device index
|
||||
+ ``DPLL_A_MODE`` attr selection mode to configure
|
||||
+ ==================================== =================================
|
||||
+
|
||||
+Constants identifying command types for pins uses a
|
||||
+``DPLL_CMD_PIN_`` prefix and suffix according to command purpose.
|
||||
+The pin related attributes use a ``DPLL_A_PIN_`` prefix and suffix
|
||||
+according to attribute purpose.
|
||||
+
|
||||
+ ==================================== =================================
|
||||
+ ``DPLL_CMD_PIN_ID_GET`` command to get pin ID
|
||||
+ ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer
|
||||
+ ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier
|
||||
+ (EUI-64), as defined by the
|
||||
+ IEEE 1588 standard
|
||||
+ ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_TYPE`` attr type of a pin
|
||||
+ ==================================== =================================
|
||||
+
|
||||
+ ==================================== ==================================
|
||||
+ ``DPLL_CMD_PIN_GET`` command to get pin info or dump
|
||||
+ list of available pins
|
||||
+ ``DPLL_A_PIN_ID`` attr unique a pin ID
|
||||
+ ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer
|
||||
+ ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier
|
||||
+ (EUI-64), as defined by the
|
||||
+ IEEE 1588 standard
|
||||
+ ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided
|
||||
+ by registerer
|
||||
+ ``DPLL_A_PIN_TYPE`` attr type of a pin
|
||||
+ ``DPLL_A_PIN_FREQUENCY`` attr current frequency of a pin
|
||||
+ ``DPLL_A_PIN_FREQUENCY_SUPPORTED`` nested attr provides supported
|
||||
+ frequencies
|
||||
+ ``DPLL_A_PIN_ANY_FREQUENCY_MIN`` attr minimum value of frequency
|
||||
+ ``DPLL_A_PIN_ANY_FREQUENCY_MAX`` attr maximum value of frequency
|
||||
+ ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent device
|
||||
+ the pin is connected with
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id
|
||||
+ ``DPLL_A_PIN_PRIO`` attr priority of pin on the
|
||||
+ dpll device
|
||||
+ ``DPLL_A_PIN_STATE`` attr state of pin on the parent
|
||||
+ dpll device
|
||||
+ ``DPLL_A_PIN_DIRECTION`` attr direction of a pin on the
|
||||
+ parent dpll device
|
||||
+ ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin
|
||||
+ the pin is connected with
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` attr parent pin id
|
||||
+ ``DPLL_A_PIN_STATE`` attr state of pin on the parent
|
||||
+ pin
|
||||
+ ``DPLL_A_PIN_CAPABILITIES`` attr bitmask of pin capabilities
|
||||
+ ==================================== ==================================
|
||||
+
|
||||
+ ==================================== =================================
|
||||
+ ``DPLL_CMD_PIN_SET`` command to set pins configuration
|
||||
+ ``DPLL_A_PIN_ID`` attr unique a pin ID
|
||||
+ ``DPLL_A_PIN_FREQUENCY`` attr requested frequency of a pin
|
||||
+ ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent dpll
|
||||
+ device configuration request
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id
|
||||
+ ``DPLL_A_PIN_DIRECTION`` attr requested direction of a pin
|
||||
+ ``DPLL_A_PIN_PRIO`` attr requested priority of pin on
|
||||
+ the dpll device
|
||||
+ ``DPLL_A_PIN_STATE`` attr requested state of pin on
|
||||
+ the dpll device
|
||||
+ ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin
|
||||
+ configuration request
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` attr parent pin id
|
||||
+ ``DPLL_A_PIN_STATE`` attr requested state of pin on
|
||||
+ parent pin
|
||||
+ ==================================== =================================
|
||||
+
|
||||
+Netlink dump requests
|
||||
+=====================
|
||||
+
|
||||
+The ``DPLL_CMD_DEVICE_GET`` and ``DPLL_CMD_PIN_GET`` commands are
|
||||
+capable of dump type netlink requests, in which case the response is in
|
||||
+the same format as for their ``do`` request, but every device or pin
|
||||
+registered in the system is returned.
|
||||
+
|
||||
+SET commands format
|
||||
+===================
|
||||
+
|
||||
+``DPLL_CMD_DEVICE_SET`` - to target a dpll device, the user provides
|
||||
+``DPLL_A_ID``, which is unique identifier of dpll device in the system,
|
||||
+as well as parameter being configured (``DPLL_A_MODE``).
|
||||
+
|
||||
+``DPLL_CMD_PIN_SET`` - to target a pin user must provide a
|
||||
+``DPLL_A_PIN_ID``, which is unique identifier of a pin in the system.
|
||||
+Also configured pin parameters must be added.
|
||||
+If ``DPLL_A_PIN_FREQUENCY`` is configured, this affects all the dpll
|
||||
+devices that are connected with the pin, that is why frequency attribute
|
||||
+shall not be enclosed in ``DPLL_A_PIN_PARENT_DEVICE``.
|
||||
+Other attributes: ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE`` or
|
||||
+``DPLL_A_PIN_DIRECTION`` must be enclosed in
|
||||
+``DPLL_A_PIN_PARENT_DEVICE`` as their configuration relates to only one
|
||||
+of parent dplls, targeted by ``DPLL_A_PIN_PARENT_ID`` attribute which is
|
||||
+also required inside that nest.
|
||||
+For MUX-type pins the ``DPLL_A_PIN_STATE`` attribute is configured in
|
||||
+similar way, by enclosing required state in ``DPLL_A_PIN_PARENT_PIN``
|
||||
+nested attribute and targeted parent pin id in ``DPLL_A_PIN_PARENT_ID``.
|
||||
+
|
||||
+In general, it is possible to configure multiple parameters at once, but
|
||||
+internally each parameter change will be invoked separately, where order
|
||||
+of configuration is not guaranteed by any means.
|
||||
+
|
||||
+Configuration pre-defined enums
|
||||
+===============================
|
||||
+
|
||||
+.. kernel-doc:: include/uapi/linux/dpll.h
|
||||
+
|
||||
+Notifications
|
||||
+=============
|
||||
+
|
||||
+dpll device can provide notifications regarding status changes of the
|
||||
+device, i.e. lock status changes, input/output changes or other alarms.
|
||||
+There is one multicast group that is used to notify user-space apps via
|
||||
+netlink socket: ``DPLL_MCGRP_MONITOR``
|
||||
+
|
||||
+Notifications messages:
|
||||
+
|
||||
+ ============================== =====================================
|
||||
+ ``DPLL_CMD_DEVICE_CREATE_NTF`` dpll device was created
|
||||
+ ``DPLL_CMD_DEVICE_DELETE_NTF`` dpll device was deleted
|
||||
+ ``DPLL_CMD_DEVICE_CHANGE_NTF`` dpll device has changed
|
||||
+ ``DPLL_CMD_PIN_CREATE_NTF`` dpll pin was created
|
||||
+ ``DPLL_CMD_PIN_DELETE_NTF`` dpll pin was deleted
|
||||
+ ``DPLL_CMD_PIN_CHANGE_NTF`` dpll pin has changed
|
||||
+ ============================== =====================================
|
||||
+
|
||||
+Events format is the same as for the corresponding get command.
|
||||
+Format of ``DPLL_CMD_DEVICE_`` events is the same as response of
|
||||
+``DPLL_CMD_DEVICE_GET``.
|
||||
+Format of ``DPLL_CMD_PIN_`` events is same as response of
|
||||
+``DPLL_CMD_PIN_GET``.
|
||||
+
|
||||
+Device driver implementation
|
||||
+============================
|
||||
+
|
||||
+Device is allocated by dpll_device_get() call. Second call with the
|
||||
+same arguments will not create new object but provides pointer to
|
||||
+previously created device for given arguments, it also increases
|
||||
+refcount of that object.
|
||||
+Device is deallocated by dpll_device_put() call, which first
|
||||
+decreases the refcount, once refcount is cleared the object is
|
||||
+destroyed.
|
||||
+
|
||||
+Device should implement set of operations and register device via
|
||||
+dpll_device_register() at which point it becomes available to the
|
||||
+users. Multiple driver instances can obtain reference to it with
|
||||
+dpll_device_get(), as well as register dpll device with their own
|
||||
+ops and priv.
|
||||
+
|
||||
+The pins are allocated separately with dpll_pin_get(), it works
|
||||
+similarly to dpll_device_get(). Function first creates object and then
|
||||
+for each call with the same arguments only the object refcount
|
||||
+increases. Also dpll_pin_put() works similarly to dpll_device_put().
|
||||
+
|
||||
+A pin can be registered with parent dpll device or parent pin, depending
|
||||
+on hardware needs. Each registration requires registerer to provide set
|
||||
+of pin callbacks, and private data pointer for calling them:
|
||||
+
|
||||
+- dpll_pin_register() - register pin with a dpll device,
|
||||
+- dpll_pin_on_pin_register() - register pin with another MUX type pin.
|
||||
+
|
||||
+Notifications of adding or removing dpll devices are created within
|
||||
+subsystem itself.
|
||||
+Notifications about registering/deregistering pins are also invoked by
|
||||
+the subsystem.
|
||||
+Notifications about status changes either of dpll device or a pin are
|
||||
+invoked in two ways:
|
||||
+
|
||||
+- after successful change was requested on dpll subsystem, the subsystem
|
||||
+ calls corresponding notification,
|
||||
+- requested by device driver with dpll_device_change_ntf() or
|
||||
+ dpll_pin_change_ntf() when driver informs about the status change.
|
||||
+
|
||||
+The device driver using dpll interface is not required to implement all
|
||||
+the callback operation. Nevertheless, there are few required to be
|
||||
+implemented.
|
||||
+Required dpll device level callback operations:
|
||||
+
|
||||
+- ``.mode_get``,
|
||||
+- ``.lock_status_get``.
|
||||
+
|
||||
+Required pin level callback operations:
|
||||
+
|
||||
+- ``.state_on_dpll_get`` (pins registered with dpll device),
|
||||
+- ``.state_on_pin_get`` (pins registered with parent pin),
|
||||
+- ``.direction_get``.
|
||||
+
|
||||
+Every other operation handler is checked for existence and
|
||||
+``-EOPNOTSUPP`` is returned in case of absence of specific handler.
|
||||
+
|
||||
+The simplest implementation is in the OCP TimeCard driver. The ops
|
||||
+structures are defined like this:
|
||||
+
|
||||
+.. code-block:: c
|
||||
+ static const struct dpll_device_ops dpll_ops = {
|
||||
+ .lock_status_get = ptp_ocp_dpll_lock_status_get,
|
||||
+ .mode_get = ptp_ocp_dpll_mode_get,
|
||||
+ .mode_supported = ptp_ocp_dpll_mode_supported,
|
||||
+ };
|
||||
+
|
||||
+ static const struct dpll_pin_ops dpll_pins_ops = {
|
||||
+ .frequency_get = ptp_ocp_dpll_frequency_get,
|
||||
+ .frequency_set = ptp_ocp_dpll_frequency_set,
|
||||
+ .direction_get = ptp_ocp_dpll_direction_get,
|
||||
+ .direction_set = ptp_ocp_dpll_direction_set,
|
||||
+ .state_on_dpll_get = ptp_ocp_dpll_state_get,
|
||||
+ };
|
||||
+
|
||||
+The registration part is then looks like this part:
|
||||
+
|
||||
+.. code-block:: c
|
||||
+ clkid = pci_get_dsn(pdev);
|
||||
+ bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE);
|
||||
+ if (IS_ERR(bp->dpll)) {
|
||||
+ err = PTR_ERR(bp->dpll);
|
||||
+ dev_err(&pdev->dev, "dpll_device_alloc failed\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
+ bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &bp->sma[i].dpll_prop);
|
||||
+ if (IS_ERR(bp->sma[i].dpll_pin)) {
|
||||
+ err = PTR_ERR(bp->dpll);
|
||||
+ goto out_dpll;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops,
|
||||
+ &bp->sma[i]);
|
||||
+ if (err) {
|
||||
+ dpll_pin_put(bp->sma[i].dpll_pin);
|
||||
+ goto out_dpll;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+In the error path we have to rewind every allocation in the reverse order:
|
||||
+
|
||||
+.. code-block:: c
|
||||
+ while (i) {
|
||||
+ --i;
|
||||
+ dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]);
|
||||
+ dpll_pin_put(bp->sma[i].dpll_pin);
|
||||
+ }
|
||||
+ dpll_device_put(bp->dpll);
|
||||
+
|
||||
+More complex example can be found in Intel's ICE driver or nVidia's mlx5 driver.
|
||||
+
|
||||
+SyncE enablement
|
||||
+================
|
||||
+For SyncE enablement it is required to allow control over dpll device
|
||||
+for a software application which monitors and configures the inputs of
|
||||
+dpll device in response to current state of a dpll device and its
|
||||
+inputs.
|
||||
+In such scenario, dpll device input signal shall be also configurable
|
||||
+to drive dpll with signal recovered from the PHY netdevice.
|
||||
+This is done by exposing a pin to the netdevice - attaching pin to the
|
||||
+netdevice itself with
|
||||
+``netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)``.
|
||||
+Exposed pin id handle ``DPLL_A_PIN_ID`` is then identifiable by the user
|
||||
+as it is attached to rtnetlink respond to get ``RTM_NEWLINK`` command in
|
||||
+nested attribute ``IFLA_DPLL_PIN``.
|
||||
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
|
||||
index 1e16a40da3ba..f549a68951d7 100644
|
||||
--- a/Documentation/driver-api/index.rst
|
||||
+++ b/Documentation/driver-api/index.rst
|
||||
@@ -114,6 +114,7 @@ available subsections can be seen below.
|
||||
zorro
|
||||
hte/index
|
||||
wmi
|
||||
+ dpll
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,956 +0,0 @@
|
||||
From 90b97a5ba43cb28a6b64e8f7e8dc469edca3ad5e Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Date: Wed, 13 Sep 2023 21:49:36 +0100
|
||||
Subject: [PATCH 02/46] dpll: spec: Add Netlink spec in YAML
|
||||
|
||||
Add a protocol spec for DPLL.
|
||||
Add code generated from the spec.
|
||||
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 3badff3a25d815e915d89565a0c82dec608a8d2b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/netlink/specs/dpll.yaml | 488 ++++++++++++++++++++++++++
|
||||
drivers/dpll/dpll_nl.c | 162 +++++++++
|
||||
drivers/dpll/dpll_nl.h | 51 +++
|
||||
include/uapi/linux/dpll.h | 201 +++++++++++
|
||||
4 files changed, 902 insertions(+)
|
||||
create mode 100644 Documentation/netlink/specs/dpll.yaml
|
||||
create mode 100644 drivers/dpll/dpll_nl.c
|
||||
create mode 100644 drivers/dpll/dpll_nl.h
|
||||
create mode 100644 include/uapi/linux/dpll.h
|
||||
|
||||
diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..8b86b28b47a6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/netlink/specs/dpll.yaml
|
||||
@@ -0,0 +1,488 @@
|
||||
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
+
|
||||
+name: dpll
|
||||
+
|
||||
+doc: DPLL subsystem.
|
||||
+
|
||||
+definitions:
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: mode
|
||||
+ doc: |
|
||||
+ working modes a dpll can support, differentiates if and how dpll selects
|
||||
+ one of its inputs to syntonize with it, valid values for DPLL_A_MODE
|
||||
+ attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: manual
|
||||
+ doc: input can be only selected by sending a request to dpll
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: automatic
|
||||
+ doc: highest prio input pin auto selected by dpll
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: lock-status
|
||||
+ doc: |
|
||||
+ provides information of dpll device lock status, valid values for
|
||||
+ DPLL_A_LOCK_STATUS attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: unlocked
|
||||
+ doc: |
|
||||
+ dpll was not yet locked to any valid input (or forced by setting
|
||||
+ DPLL_A_MODE to DPLL_MODE_DETACHED)
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: locked
|
||||
+ doc: |
|
||||
+ dpll is locked to a valid signal, but no holdover available
|
||||
+ -
|
||||
+ name: locked-ho-acq
|
||||
+ doc: |
|
||||
+ dpll is locked and holdover acquired
|
||||
+ -
|
||||
+ name: holdover
|
||||
+ doc: |
|
||||
+ dpll is in holdover state - lost a valid lock or was forced
|
||||
+ by disconnecting all the pins (latter possible only
|
||||
+ when dpll lock-state was already DPLL_LOCK_STATUS_LOCKED_HO_ACQ,
|
||||
+ if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the
|
||||
+ dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED)
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: temp-divider
|
||||
+ value: 1000
|
||||
+ doc: |
|
||||
+ temperature divider allowing userspace to calculate the
|
||||
+ temperature as float with three digit decimal precision.
|
||||
+ Value of (DPLL_A_TEMP / DPLL_TEMP_DIVIDER) is integer part of
|
||||
+ temperature value.
|
||||
+ Value of (DPLL_A_TEMP % DPLL_TEMP_DIVIDER) is fractional part of
|
||||
+ temperature value.
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: type
|
||||
+ doc: type of dpll, valid values for DPLL_A_TYPE attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: pps
|
||||
+ doc: dpll produces Pulse-Per-Second signal
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: eec
|
||||
+ doc: dpll drives the Ethernet Equipment Clock
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: pin-type
|
||||
+ doc: |
|
||||
+ defines possible types of a pin, valid values for DPLL_A_PIN_TYPE
|
||||
+ attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: mux
|
||||
+ doc: aggregates another layer of selectable pins
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: ext
|
||||
+ doc: external input
|
||||
+ -
|
||||
+ name: synce-eth-port
|
||||
+ doc: ethernet port PHY's recovered clock
|
||||
+ -
|
||||
+ name: int-oscillator
|
||||
+ doc: device internal oscillator
|
||||
+ -
|
||||
+ name: gnss
|
||||
+ doc: GNSS recovered clock
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: pin-direction
|
||||
+ doc: |
|
||||
+ defines possible direction of a pin, valid values for
|
||||
+ DPLL_A_PIN_DIRECTION attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: input
|
||||
+ doc: pin used as a input of a signal
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: output
|
||||
+ doc: pin used to output the signal
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: pin-frequency-1-hz
|
||||
+ value: 1
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: pin-frequency-10-khz
|
||||
+ value: 10000
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: pin-frequency-77_5-khz
|
||||
+ value: 77500
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: pin-frequency-10-mhz
|
||||
+ value: 10000000
|
||||
+ -
|
||||
+ type: enum
|
||||
+ name: pin-state
|
||||
+ doc: |
|
||||
+ defines possible states of a pin, valid values for
|
||||
+ DPLL_A_PIN_STATE attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: connected
|
||||
+ doc: pin connected, active input of phase locked loop
|
||||
+ value: 1
|
||||
+ -
|
||||
+ name: disconnected
|
||||
+ doc: pin disconnected, not considered as a valid input
|
||||
+ -
|
||||
+ name: selectable
|
||||
+ doc: pin enabled for automatic input selection
|
||||
+ render-max: true
|
||||
+ -
|
||||
+ type: flags
|
||||
+ name: pin-capabilities
|
||||
+ doc: |
|
||||
+ defines possible capabilities of a pin, valid flags on
|
||||
+ DPLL_A_PIN_CAPABILITIES attribute
|
||||
+ entries:
|
||||
+ -
|
||||
+ name: direction-can-change
|
||||
+ doc: pin direction can be changed
|
||||
+ -
|
||||
+ name: priority-can-change
|
||||
+ doc: pin priority can be changed
|
||||
+ -
|
||||
+ name: state-can-change
|
||||
+ doc: pin state can be changed
|
||||
+
|
||||
+attribute-sets:
|
||||
+ -
|
||||
+ name: dpll
|
||||
+ enum-name: dpll_a
|
||||
+ attributes:
|
||||
+ -
|
||||
+ name: id
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: module-name
|
||||
+ type: string
|
||||
+ -
|
||||
+ name: pad
|
||||
+ type: pad
|
||||
+ -
|
||||
+ name: clock-id
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: mode
|
||||
+ type: u32
|
||||
+ enum: mode
|
||||
+ -
|
||||
+ name: mode-supported
|
||||
+ type: u32
|
||||
+ enum: mode
|
||||
+ multi-attr: true
|
||||
+ -
|
||||
+ name: lock-status
|
||||
+ type: u32
|
||||
+ enum: lock-status
|
||||
+ -
|
||||
+ name: temp
|
||||
+ type: s32
|
||||
+ -
|
||||
+ name: type
|
||||
+ type: u32
|
||||
+ enum: type
|
||||
+ -
|
||||
+ name: pin
|
||||
+ enum-name: dpll_a_pin
|
||||
+ attributes:
|
||||
+ -
|
||||
+ name: id
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: parent-id
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: module-name
|
||||
+ type: string
|
||||
+ -
|
||||
+ name: pad
|
||||
+ type: pad
|
||||
+ -
|
||||
+ name: clock-id
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: board-label
|
||||
+ type: string
|
||||
+ -
|
||||
+ name: panel-label
|
||||
+ type: string
|
||||
+ -
|
||||
+ name: package-label
|
||||
+ type: string
|
||||
+ -
|
||||
+ name: type
|
||||
+ type: u32
|
||||
+ enum: pin-type
|
||||
+ -
|
||||
+ name: direction
|
||||
+ type: u32
|
||||
+ enum: pin-direction
|
||||
+ -
|
||||
+ name: frequency
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: frequency-supported
|
||||
+ type: nest
|
||||
+ multi-attr: true
|
||||
+ nested-attributes: frequency-range
|
||||
+ -
|
||||
+ name: frequency-min
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: frequency-max
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: prio
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: state
|
||||
+ type: u32
|
||||
+ enum: pin-state
|
||||
+ -
|
||||
+ name: capabilities
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: parent-device
|
||||
+ type: nest
|
||||
+ multi-attr: true
|
||||
+ nested-attributes: pin-parent-device
|
||||
+ -
|
||||
+ name: parent-pin
|
||||
+ type: nest
|
||||
+ multi-attr: true
|
||||
+ nested-attributes: pin-parent-pin
|
||||
+ -
|
||||
+ name: pin-parent-device
|
||||
+ subset-of: pin
|
||||
+ attributes:
|
||||
+ -
|
||||
+ name: parent-id
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: direction
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: prio
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: state
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: pin-parent-pin
|
||||
+ subset-of: pin
|
||||
+ attributes:
|
||||
+ -
|
||||
+ name: parent-id
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: state
|
||||
+ type: u32
|
||||
+ -
|
||||
+ name: frequency-range
|
||||
+ subset-of: pin
|
||||
+ attributes:
|
||||
+ -
|
||||
+ name: frequency-min
|
||||
+ type: u64
|
||||
+ -
|
||||
+ name: frequency-max
|
||||
+ type: u64
|
||||
+
|
||||
+operations:
|
||||
+ enum-name: dpll_cmd
|
||||
+ list:
|
||||
+ -
|
||||
+ name: device-id-get
|
||||
+ doc: |
|
||||
+ Get id of dpll device that matches given attributes
|
||||
+ attribute-set: dpll
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-lock-doit
|
||||
+ post: dpll-unlock-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - module-name
|
||||
+ - clock-id
|
||||
+ - type
|
||||
+ reply:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+
|
||||
+ -
|
||||
+ name: device-get
|
||||
+ doc: |
|
||||
+ Get list of DPLL devices (dump) or attributes of a single dpll device
|
||||
+ attribute-set: dpll
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-pre-doit
|
||||
+ post: dpll-post-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ reply: &dev-attrs
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ - module-name
|
||||
+ - mode
|
||||
+ - mode-supported
|
||||
+ - lock-status
|
||||
+ - temp
|
||||
+ - clock-id
|
||||
+ - type
|
||||
+
|
||||
+ dump:
|
||||
+ pre: dpll-lock-dumpit
|
||||
+ post: dpll-unlock-dumpit
|
||||
+ reply: *dev-attrs
|
||||
+
|
||||
+ -
|
||||
+ name: device-set
|
||||
+ doc: Set attributes for a DPLL device
|
||||
+ attribute-set: dpll
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-pre-doit
|
||||
+ post: dpll-post-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ -
|
||||
+ name: device-create-ntf
|
||||
+ doc: Notification about device appearing
|
||||
+ notify: device-get
|
||||
+ mcgrp: monitor
|
||||
+ -
|
||||
+ name: device-delete-ntf
|
||||
+ doc: Notification about device disappearing
|
||||
+ notify: device-get
|
||||
+ mcgrp: monitor
|
||||
+ -
|
||||
+ name: device-change-ntf
|
||||
+ doc: Notification about device configuration being changed
|
||||
+ notify: device-get
|
||||
+ mcgrp: monitor
|
||||
+ -
|
||||
+ name: pin-id-get
|
||||
+ doc: |
|
||||
+ Get id of a pin that matches given attributes
|
||||
+ attribute-set: pin
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-lock-doit
|
||||
+ post: dpll-unlock-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - module-name
|
||||
+ - clock-id
|
||||
+ - board-label
|
||||
+ - panel-label
|
||||
+ - package-label
|
||||
+ - type
|
||||
+ reply:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+
|
||||
+ -
|
||||
+ name: pin-get
|
||||
+ doc: |
|
||||
+ Get list of pins and its attributes.
|
||||
+ - dump request without any attributes given - list all the pins in the
|
||||
+ system
|
||||
+ - dump request with target dpll - list all the pins registered with
|
||||
+ a given dpll device
|
||||
+ - do request with target dpll and target pin - single pin attributes
|
||||
+ attribute-set: pin
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-pin-pre-doit
|
||||
+ post: dpll-pin-post-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ reply: &pin-attrs
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ - board-label
|
||||
+ - panel-label
|
||||
+ - package-label
|
||||
+ - type
|
||||
+ - frequency
|
||||
+ - frequency-supported
|
||||
+ - capabilities
|
||||
+ - parent-device
|
||||
+ - parent-pin
|
||||
+
|
||||
+ dump:
|
||||
+ pre: dpll-lock-dumpit
|
||||
+ post: dpll-unlock-dumpit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ reply: *pin-attrs
|
||||
+
|
||||
+ -
|
||||
+ name: pin-set
|
||||
+ doc: Set attributes of a target pin
|
||||
+ attribute-set: pin
|
||||
+ flags: [ admin-perm ]
|
||||
+
|
||||
+ do:
|
||||
+ pre: dpll-pin-pre-doit
|
||||
+ post: dpll-pin-post-doit
|
||||
+ request:
|
||||
+ attributes:
|
||||
+ - id
|
||||
+ - frequency
|
||||
+ - direction
|
||||
+ - prio
|
||||
+ - state
|
||||
+ - parent-device
|
||||
+ - parent-pin
|
||||
+ -
|
||||
+ name: pin-create-ntf
|
||||
+ doc: Notification about pin appearing
|
||||
+ notify: pin-get
|
||||
+ mcgrp: monitor
|
||||
+ -
|
||||
+ name: pin-delete-ntf
|
||||
+ doc: Notification about pin disappearing
|
||||
+ notify: pin-get
|
||||
+ mcgrp: monitor
|
||||
+ -
|
||||
+ name: pin-change-ntf
|
||||
+ doc: Notification about pin configuration being changed
|
||||
+ notify: pin-get
|
||||
+ mcgrp: monitor
|
||||
+
|
||||
+mcast-groups:
|
||||
+ list:
|
||||
+ -
|
||||
+ name: monitor
|
||||
diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
|
||||
new file mode 100644
|
||||
index 000000000000..14064c8c783b
|
||||
--- /dev/null
|
||||
+++ b/drivers/dpll/dpll_nl.c
|
||||
@@ -0,0 +1,162 @@
|
||||
+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
+/* Do not edit directly, auto-generated from: */
|
||||
+/* Documentation/netlink/specs/dpll.yaml */
|
||||
+/* YNL-GEN kernel source */
|
||||
+
|
||||
+#include <net/netlink.h>
|
||||
+#include <net/genetlink.h>
|
||||
+
|
||||
+#include "dpll_nl.h"
|
||||
+
|
||||
+#include <uapi/linux/dpll.h>
|
||||
+
|
||||
+/* Common nested types */
|
||||
+const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1] = {
|
||||
+ [DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
|
||||
+ [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
+ [DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
|
||||
+ [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
+};
|
||||
+
|
||||
+const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = {
|
||||
+ [DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
|
||||
+ [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_DEVICE_ID_GET - do */
|
||||
+static const struct nla_policy dpll_device_id_get_nl_policy[DPLL_A_TYPE + 1] = {
|
||||
+ [DPLL_A_MODULE_NAME] = { .type = NLA_NUL_STRING, },
|
||||
+ [DPLL_A_CLOCK_ID] = { .type = NLA_U64, },
|
||||
+ [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_DEVICE_GET - do */
|
||||
+static const struct nla_policy dpll_device_get_nl_policy[DPLL_A_ID + 1] = {
|
||||
+ [DPLL_A_ID] = { .type = NLA_U32, },
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_DEVICE_SET - do */
|
||||
+static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_ID + 1] = {
|
||||
+ [DPLL_A_ID] = { .type = NLA_U32, },
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_PIN_ID_GET - do */
|
||||
+static const struct nla_policy dpll_pin_id_get_nl_policy[DPLL_A_PIN_TYPE + 1] = {
|
||||
+ [DPLL_A_PIN_MODULE_NAME] = { .type = NLA_NUL_STRING, },
|
||||
+ [DPLL_A_PIN_CLOCK_ID] = { .type = NLA_U64, },
|
||||
+ [DPLL_A_PIN_BOARD_LABEL] = { .type = NLA_NUL_STRING, },
|
||||
+ [DPLL_A_PIN_PANEL_LABEL] = { .type = NLA_NUL_STRING, },
|
||||
+ [DPLL_A_PIN_PACKAGE_LABEL] = { .type = NLA_NUL_STRING, },
|
||||
+ [DPLL_A_PIN_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 5),
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_PIN_GET - do */
|
||||
+static const struct nla_policy dpll_pin_get_do_nl_policy[DPLL_A_PIN_ID + 1] = {
|
||||
+ [DPLL_A_PIN_ID] = { .type = NLA_U32, },
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_PIN_GET - dump */
|
||||
+static const struct nla_policy dpll_pin_get_dump_nl_policy[DPLL_A_PIN_ID + 1] = {
|
||||
+ [DPLL_A_PIN_ID] = { .type = NLA_U32, },
|
||||
+};
|
||||
+
|
||||
+/* DPLL_CMD_PIN_SET - do */
|
||||
+static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT_PIN + 1] = {
|
||||
+ [DPLL_A_PIN_ID] = { .type = NLA_U32, },
|
||||
+ [DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, },
|
||||
+ [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
+ [DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
|
||||
+ [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
+ [DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy),
|
||||
+ [DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy),
|
||||
+};
|
||||
+
|
||||
+/* Ops table for dpll */
|
||||
+static const struct genl_split_ops dpll_nl_ops[] = {
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_DEVICE_ID_GET,
|
||||
+ .pre_doit = dpll_lock_doit,
|
||||
+ .doit = dpll_nl_device_id_get_doit,
|
||||
+ .post_doit = dpll_unlock_doit,
|
||||
+ .policy = dpll_device_id_get_nl_policy,
|
||||
+ .maxattr = DPLL_A_TYPE,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_DEVICE_GET,
|
||||
+ .pre_doit = dpll_pre_doit,
|
||||
+ .doit = dpll_nl_device_get_doit,
|
||||
+ .post_doit = dpll_post_doit,
|
||||
+ .policy = dpll_device_get_nl_policy,
|
||||
+ .maxattr = DPLL_A_ID,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_DEVICE_GET,
|
||||
+ .start = dpll_lock_dumpit,
|
||||
+ .dumpit = dpll_nl_device_get_dumpit,
|
||||
+ .done = dpll_unlock_dumpit,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_DEVICE_SET,
|
||||
+ .pre_doit = dpll_pre_doit,
|
||||
+ .doit = dpll_nl_device_set_doit,
|
||||
+ .post_doit = dpll_post_doit,
|
||||
+ .policy = dpll_device_set_nl_policy,
|
||||
+ .maxattr = DPLL_A_ID,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_PIN_ID_GET,
|
||||
+ .pre_doit = dpll_lock_doit,
|
||||
+ .doit = dpll_nl_pin_id_get_doit,
|
||||
+ .post_doit = dpll_unlock_doit,
|
||||
+ .policy = dpll_pin_id_get_nl_policy,
|
||||
+ .maxattr = DPLL_A_PIN_TYPE,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_PIN_GET,
|
||||
+ .pre_doit = dpll_pin_pre_doit,
|
||||
+ .doit = dpll_nl_pin_get_doit,
|
||||
+ .post_doit = dpll_pin_post_doit,
|
||||
+ .policy = dpll_pin_get_do_nl_policy,
|
||||
+ .maxattr = DPLL_A_PIN_ID,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_PIN_GET,
|
||||
+ .start = dpll_lock_dumpit,
|
||||
+ .dumpit = dpll_nl_pin_get_dumpit,
|
||||
+ .done = dpll_unlock_dumpit,
|
||||
+ .policy = dpll_pin_get_dump_nl_policy,
|
||||
+ .maxattr = DPLL_A_PIN_ID,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
|
||||
+ },
|
||||
+ {
|
||||
+ .cmd = DPLL_CMD_PIN_SET,
|
||||
+ .pre_doit = dpll_pin_pre_doit,
|
||||
+ .doit = dpll_nl_pin_set_doit,
|
||||
+ .post_doit = dpll_pin_post_doit,
|
||||
+ .policy = dpll_pin_set_nl_policy,
|
||||
+ .maxattr = DPLL_A_PIN_PARENT_PIN,
|
||||
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct genl_multicast_group dpll_nl_mcgrps[] = {
|
||||
+ [DPLL_NLGRP_MONITOR] = { "monitor", },
|
||||
+};
|
||||
+
|
||||
+struct genl_family dpll_nl_family __ro_after_init = {
|
||||
+ .name = DPLL_FAMILY_NAME,
|
||||
+ .version = DPLL_FAMILY_VERSION,
|
||||
+ .netnsok = true,
|
||||
+ .parallel_ops = true,
|
||||
+ .module = THIS_MODULE,
|
||||
+ .split_ops = dpll_nl_ops,
|
||||
+ .n_split_ops = ARRAY_SIZE(dpll_nl_ops),
|
||||
+ .mcgrps = dpll_nl_mcgrps,
|
||||
+ .n_mcgrps = ARRAY_SIZE(dpll_nl_mcgrps),
|
||||
+};
|
||||
diff --git a/drivers/dpll/dpll_nl.h b/drivers/dpll/dpll_nl.h
|
||||
new file mode 100644
|
||||
index 000000000000..1f67aaed4742
|
||||
--- /dev/null
|
||||
+++ b/drivers/dpll/dpll_nl.h
|
||||
@@ -0,0 +1,51 @@
|
||||
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
+/* Do not edit directly, auto-generated from: */
|
||||
+/* Documentation/netlink/specs/dpll.yaml */
|
||||
+/* YNL-GEN kernel header */
|
||||
+
|
||||
+#ifndef _LINUX_DPLL_GEN_H
|
||||
+#define _LINUX_DPLL_GEN_H
|
||||
+
|
||||
+#include <net/netlink.h>
|
||||
+#include <net/genetlink.h>
|
||||
+
|
||||
+#include <uapi/linux/dpll.h>
|
||||
+
|
||||
+/* Common nested types */
|
||||
+extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
+extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
+
|
||||
+int dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+int dpll_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+void
|
||||
+dpll_unlock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+void
|
||||
+dpll_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+void
|
||||
+dpll_pin_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+int dpll_lock_dumpit(struct netlink_callback *cb);
|
||||
+int dpll_unlock_dumpit(struct netlink_callback *cb);
|
||||
+
|
||||
+int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
+int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
+int dpll_nl_pin_set_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
+
|
||||
+enum {
|
||||
+ DPLL_NLGRP_MONITOR,
|
||||
+};
|
||||
+
|
||||
+extern struct genl_family dpll_nl_family;
|
||||
+
|
||||
+#endif /* _LINUX_DPLL_GEN_H */
|
||||
diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
|
||||
new file mode 100644
|
||||
index 000000000000..20ef0718f8dc
|
||||
--- /dev/null
|
||||
+++ b/include/uapi/linux/dpll.h
|
||||
@@ -0,0 +1,201 @@
|
||||
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
+/* Do not edit directly, auto-generated from: */
|
||||
+/* Documentation/netlink/specs/dpll.yaml */
|
||||
+/* YNL-GEN uapi header */
|
||||
+
|
||||
+#ifndef _UAPI_LINUX_DPLL_H
|
||||
+#define _UAPI_LINUX_DPLL_H
|
||||
+
|
||||
+#define DPLL_FAMILY_NAME "dpll"
|
||||
+#define DPLL_FAMILY_VERSION 1
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_mode - working modes a dpll can support, differentiates if and how
|
||||
+ * dpll selects one of its inputs to syntonize with it, valid values for
|
||||
+ * DPLL_A_MODE attribute
|
||||
+ * @DPLL_MODE_MANUAL: input can be only selected by sending a request to dpll
|
||||
+ * @DPLL_MODE_AUTOMATIC: highest prio input pin auto selected by dpll
|
||||
+ */
|
||||
+enum dpll_mode {
|
||||
+ DPLL_MODE_MANUAL = 1,
|
||||
+ DPLL_MODE_AUTOMATIC,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_MODE_MAX,
|
||||
+ DPLL_MODE_MAX = (__DPLL_MODE_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_lock_status - provides information of dpll device lock status,
|
||||
+ * valid values for DPLL_A_LOCK_STATUS attribute
|
||||
+ * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input (or
|
||||
+ * forced by setting DPLL_A_MODE to DPLL_MODE_DETACHED)
|
||||
+ * @DPLL_LOCK_STATUS_LOCKED: dpll is locked to a valid signal, but no holdover
|
||||
+ * available
|
||||
+ * @DPLL_LOCK_STATUS_LOCKED_HO_ACQ: dpll is locked and holdover acquired
|
||||
+ * @DPLL_LOCK_STATUS_HOLDOVER: dpll is in holdover state - lost a valid lock or
|
||||
+ * was forced by disconnecting all the pins (latter possible only when dpll
|
||||
+ * lock-state was already DPLL_LOCK_STATUS_LOCKED_HO_ACQ, if dpll lock-state
|
||||
+ * was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the dpll's lock-state shall remain
|
||||
+ * DPLL_LOCK_STATUS_UNLOCKED)
|
||||
+ */
|
||||
+enum dpll_lock_status {
|
||||
+ DPLL_LOCK_STATUS_UNLOCKED = 1,
|
||||
+ DPLL_LOCK_STATUS_LOCKED,
|
||||
+ DPLL_LOCK_STATUS_LOCKED_HO_ACQ,
|
||||
+ DPLL_LOCK_STATUS_HOLDOVER,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_LOCK_STATUS_MAX,
|
||||
+ DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+#define DPLL_TEMP_DIVIDER 1000
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_type - type of dpll, valid values for DPLL_A_TYPE attribute
|
||||
+ * @DPLL_TYPE_PPS: dpll produces Pulse-Per-Second signal
|
||||
+ * @DPLL_TYPE_EEC: dpll drives the Ethernet Equipment Clock
|
||||
+ */
|
||||
+enum dpll_type {
|
||||
+ DPLL_TYPE_PPS = 1,
|
||||
+ DPLL_TYPE_EEC,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_TYPE_MAX,
|
||||
+ DPLL_TYPE_MAX = (__DPLL_TYPE_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_pin_type - defines possible types of a pin, valid values for
|
||||
+ * DPLL_A_PIN_TYPE attribute
|
||||
+ * @DPLL_PIN_TYPE_MUX: aggregates another layer of selectable pins
|
||||
+ * @DPLL_PIN_TYPE_EXT: external input
|
||||
+ * @DPLL_PIN_TYPE_SYNCE_ETH_PORT: ethernet port PHY's recovered clock
|
||||
+ * @DPLL_PIN_TYPE_INT_OSCILLATOR: device internal oscillator
|
||||
+ * @DPLL_PIN_TYPE_GNSS: GNSS recovered clock
|
||||
+ */
|
||||
+enum dpll_pin_type {
|
||||
+ DPLL_PIN_TYPE_MUX = 1,
|
||||
+ DPLL_PIN_TYPE_EXT,
|
||||
+ DPLL_PIN_TYPE_SYNCE_ETH_PORT,
|
||||
+ DPLL_PIN_TYPE_INT_OSCILLATOR,
|
||||
+ DPLL_PIN_TYPE_GNSS,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_PIN_TYPE_MAX,
|
||||
+ DPLL_PIN_TYPE_MAX = (__DPLL_PIN_TYPE_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_pin_direction - defines possible direction of a pin, valid values
|
||||
+ * for DPLL_A_PIN_DIRECTION attribute
|
||||
+ * @DPLL_PIN_DIRECTION_INPUT: pin used as a input of a signal
|
||||
+ * @DPLL_PIN_DIRECTION_OUTPUT: pin used to output the signal
|
||||
+ */
|
||||
+enum dpll_pin_direction {
|
||||
+ DPLL_PIN_DIRECTION_INPUT = 1,
|
||||
+ DPLL_PIN_DIRECTION_OUTPUT,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_PIN_DIRECTION_MAX,
|
||||
+ DPLL_PIN_DIRECTION_MAX = (__DPLL_PIN_DIRECTION_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+#define DPLL_PIN_FREQUENCY_1_HZ 1
|
||||
+#define DPLL_PIN_FREQUENCY_10_KHZ 10000
|
||||
+#define DPLL_PIN_FREQUENCY_77_5_KHZ 77500
|
||||
+#define DPLL_PIN_FREQUENCY_10_MHZ 10000000
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_pin_state - defines possible states of a pin, valid values for
|
||||
+ * DPLL_A_PIN_STATE attribute
|
||||
+ * @DPLL_PIN_STATE_CONNECTED: pin connected, active input of phase locked loop
|
||||
+ * @DPLL_PIN_STATE_DISCONNECTED: pin disconnected, not considered as a valid
|
||||
+ * input
|
||||
+ * @DPLL_PIN_STATE_SELECTABLE: pin enabled for automatic input selection
|
||||
+ */
|
||||
+enum dpll_pin_state {
|
||||
+ DPLL_PIN_STATE_CONNECTED = 1,
|
||||
+ DPLL_PIN_STATE_DISCONNECTED,
|
||||
+ DPLL_PIN_STATE_SELECTABLE,
|
||||
+
|
||||
+ /* private: */
|
||||
+ __DPLL_PIN_STATE_MAX,
|
||||
+ DPLL_PIN_STATE_MAX = (__DPLL_PIN_STATE_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum dpll_pin_capabilities - defines possible capabilities of a pin, valid
|
||||
+ * flags on DPLL_A_PIN_CAPABILITIES attribute
|
||||
+ * @DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE: pin direction can be changed
|
||||
+ * @DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE: pin priority can be changed
|
||||
+ * @DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE: pin state can be changed
|
||||
+ */
|
||||
+enum dpll_pin_capabilities {
|
||||
+ DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE = 1,
|
||||
+ DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE = 2,
|
||||
+ DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE = 4,
|
||||
+};
|
||||
+
|
||||
+enum dpll_a {
|
||||
+ DPLL_A_ID = 1,
|
||||
+ DPLL_A_MODULE_NAME,
|
||||
+ DPLL_A_PAD,
|
||||
+ DPLL_A_CLOCK_ID,
|
||||
+ DPLL_A_MODE,
|
||||
+ DPLL_A_MODE_SUPPORTED,
|
||||
+ DPLL_A_LOCK_STATUS,
|
||||
+ DPLL_A_TEMP,
|
||||
+ DPLL_A_TYPE,
|
||||
+
|
||||
+ __DPLL_A_MAX,
|
||||
+ DPLL_A_MAX = (__DPLL_A_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+enum dpll_a_pin {
|
||||
+ DPLL_A_PIN_ID = 1,
|
||||
+ DPLL_A_PIN_PARENT_ID,
|
||||
+ DPLL_A_PIN_MODULE_NAME,
|
||||
+ DPLL_A_PIN_PAD,
|
||||
+ DPLL_A_PIN_CLOCK_ID,
|
||||
+ DPLL_A_PIN_BOARD_LABEL,
|
||||
+ DPLL_A_PIN_PANEL_LABEL,
|
||||
+ DPLL_A_PIN_PACKAGE_LABEL,
|
||||
+ DPLL_A_PIN_TYPE,
|
||||
+ DPLL_A_PIN_DIRECTION,
|
||||
+ DPLL_A_PIN_FREQUENCY,
|
||||
+ DPLL_A_PIN_FREQUENCY_SUPPORTED,
|
||||
+ DPLL_A_PIN_FREQUENCY_MIN,
|
||||
+ DPLL_A_PIN_FREQUENCY_MAX,
|
||||
+ DPLL_A_PIN_PRIO,
|
||||
+ DPLL_A_PIN_STATE,
|
||||
+ DPLL_A_PIN_CAPABILITIES,
|
||||
+ DPLL_A_PIN_PARENT_DEVICE,
|
||||
+ DPLL_A_PIN_PARENT_PIN,
|
||||
+
|
||||
+ __DPLL_A_PIN_MAX,
|
||||
+ DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+enum dpll_cmd {
|
||||
+ DPLL_CMD_DEVICE_ID_GET = 1,
|
||||
+ DPLL_CMD_DEVICE_GET,
|
||||
+ DPLL_CMD_DEVICE_SET,
|
||||
+ DPLL_CMD_DEVICE_CREATE_NTF,
|
||||
+ DPLL_CMD_DEVICE_DELETE_NTF,
|
||||
+ DPLL_CMD_DEVICE_CHANGE_NTF,
|
||||
+ DPLL_CMD_PIN_ID_GET,
|
||||
+ DPLL_CMD_PIN_GET,
|
||||
+ DPLL_CMD_PIN_SET,
|
||||
+ DPLL_CMD_PIN_CREATE_NTF,
|
||||
+ DPLL_CMD_PIN_DELETE_NTF,
|
||||
+ DPLL_CMD_PIN_CHANGE_NTF,
|
||||
+
|
||||
+ __DPLL_CMD_MAX,
|
||||
+ DPLL_CMD_MAX = (__DPLL_CMD_MAX - 1)
|
||||
+};
|
||||
+
|
||||
+#define DPLL_MCGRP_MONITOR "monitor"
|
||||
+
|
||||
+#endif /* _UAPI_LINUX_DPLL_H */
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,279 +0,0 @@
|
||||
From 41ef885df68771af53969ce6ce97016bc2fc418b Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Wed, 13 Sep 2023 21:49:39 +0100
|
||||
Subject: [PATCH 05/46] netdev: expose DPLL pin handle for netdevice
|
||||
|
||||
In case netdevice represents a SyncE port, the user needs to understand
|
||||
the connection between netdevice and associated DPLL pin. There might me
|
||||
multiple netdevices pointing to the same pin, in case of VF/SF
|
||||
implementation.
|
||||
|
||||
Add a IFLA Netlink attribute to nest the DPLL pin handle, similar to
|
||||
how it is implemented for devlink port. Add a struct dpll_pin pointer
|
||||
to netdev and protect access to it by RTNL. Expose netdev_dpll_pin_set()
|
||||
and netdev_dpll_pin_clear() helpers to the drivers so they can set/clear
|
||||
the DPLL pin relationship to netdev.
|
||||
|
||||
Note that during the lifetime of struct dpll_pin the pin handle does not
|
||||
change. Therefore it is save to access it lockless. It is drivers
|
||||
responsibility to call netdev_dpll_pin_clear() before dpll_pin_put().
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 5f18426928800c59fb0f9bc8fb0c182bb6f5ee24)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 16 ++++++++++++++--
|
||||
include/linux/dpll.h | 15 +++++++++++++++
|
||||
include/linux/netdevice.h | 21 +++++++++++++++++++++
|
||||
include/uapi/linux/if_link.h | 2 +-
|
||||
net/core/dev.c | 22 ++++++++++++++++++++++
|
||||
net/core/rtnetlink.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 109 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index 9464a6865977..764437a0661b 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -47,6 +47,18 @@ dpll_msg_add_dev_parent_handle(struct sk_buff *msg, u32 id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * dpll_msg_pin_handle_size - get size of pin handle attribute for given pin
|
||||
+ * @pin: pin pointer
|
||||
+ *
|
||||
+ * Return: byte size of pin handle attribute for given pin.
|
||||
+ */
|
||||
+size_t dpll_msg_pin_handle_size(struct dpll_pin *pin)
|
||||
+{
|
||||
+ return pin ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(dpll_msg_pin_handle_size);
|
||||
+
|
||||
/**
|
||||
* dpll_msg_add_pin_handle - attach pin handle attribute to a given message
|
||||
* @msg: pointer to sk_buff message to attach a pin handle
|
||||
@@ -56,8 +68,7 @@ dpll_msg_add_dev_parent_handle(struct sk_buff *msg, u32 id)
|
||||
* * 0 - success
|
||||
* * -EMSGSIZE - no space in message to attach pin handle
|
||||
*/
|
||||
-static int
|
||||
-dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
|
||||
+int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
|
||||
{
|
||||
if (!pin)
|
||||
return 0;
|
||||
@@ -65,6 +76,7 @@ dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
|
||||
return -EMSGSIZE;
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(dpll_msg_add_pin_handle);
|
||||
|
||||
static int
|
||||
dpll_msg_add_mode(struct sk_buff *msg, struct dpll_device *dpll,
|
||||
diff --git a/include/linux/dpll.h b/include/linux/dpll.h
|
||||
index 2202310c10cd..bbc480cd2932 100644
|
||||
--- a/include/linux/dpll.h
|
||||
+++ b/include/linux/dpll.h
|
||||
@@ -101,6 +101,21 @@ struct dpll_pin_properties {
|
||||
struct dpll_pin_frequency *freq_supported;
|
||||
};
|
||||
|
||||
+#if IS_ENABLED(CONFIG_DPLL)
|
||||
+size_t dpll_msg_pin_handle_size(struct dpll_pin *pin);
|
||||
+int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin);
|
||||
+#else
|
||||
+static inline size_t dpll_msg_pin_handle_size(struct dpll_pin *pin)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
struct dpll_device *
|
||||
dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module);
|
||||
|
||||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
|
||||
index b8e60a20416b..272c44030449 100644
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -79,6 +79,8 @@ struct xdp_buff;
|
||||
struct xdp_frame;
|
||||
struct xdp_metadata_ops;
|
||||
struct xdp_md;
|
||||
+/* DPLL specific */
|
||||
+struct dpll_pin;
|
||||
|
||||
typedef u32 xdp_features_t;
|
||||
|
||||
@@ -2060,6 +2062,9 @@ enum netdev_stat_type {
|
||||
* SET_NETDEV_DEVLINK_PORT macro. This pointer is static
|
||||
* during the time netdevice is registered.
|
||||
*
|
||||
+ * @dpll_pin: Pointer to the SyncE source pin of a DPLL subsystem,
|
||||
+ * where the clock is recovered.
|
||||
+ *
|
||||
* FIXME: cleanup struct net_device such that network protocol info
|
||||
* moves out.
|
||||
*/
|
||||
@@ -2417,6 +2422,10 @@ struct net_device {
|
||||
struct rtnl_hw_stats64 *offload_xstats_l3;
|
||||
|
||||
struct devlink_port *devlink_port;
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_DPLL)
|
||||
+ struct dpll_pin *dpll_pin;
|
||||
+#endif
|
||||
};
|
||||
#define to_net_dev(d) container_of(d, struct net_device, dev)
|
||||
|
||||
@@ -3962,6 +3971,18 @@ int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name);
|
||||
int dev_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid, bool recurse);
|
||||
bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b);
|
||||
+void netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin);
|
||||
+void netdev_dpll_pin_clear(struct net_device *dev);
|
||||
+
|
||||
+static inline struct dpll_pin *netdev_dpll_pin(const struct net_device *dev)
|
||||
+{
|
||||
+#if IS_ENABLED(CONFIG_DPLL)
|
||||
+ return dev->dpll_pin;
|
||||
+#else
|
||||
+ return NULL;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again);
|
||||
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
struct netdev_queue *txq, int *ret);
|
||||
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
|
||||
index ce3117df9cec..fac351a93aed 100644
|
||||
--- a/include/uapi/linux/if_link.h
|
||||
+++ b/include/uapi/linux/if_link.h
|
||||
@@ -376,7 +376,7 @@ enum {
|
||||
|
||||
IFLA_GSO_IPV4_MAX_SIZE,
|
||||
IFLA_GRO_IPV4_MAX_SIZE,
|
||||
-
|
||||
+ IFLA_DPLL_PIN,
|
||||
__IFLA_MAX
|
||||
};
|
||||
|
||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
index 890b3b758d3f..5895bf5fab4b 100644
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -9064,6 +9064,28 @@ bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b)
|
||||
}
|
||||
EXPORT_SYMBOL(netdev_port_same_parent_id);
|
||||
|
||||
+static void netdev_dpll_pin_assign(struct net_device *dev, struct dpll_pin *dpll_pin)
|
||||
+{
|
||||
+#if IS_ENABLED(CONFIG_DPLL)
|
||||
+ rtnl_lock();
|
||||
+ dev->dpll_pin = dpll_pin;
|
||||
+ rtnl_unlock();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)
|
||||
+{
|
||||
+ WARN_ON(!dpll_pin);
|
||||
+ netdev_dpll_pin_assign(dev, dpll_pin);
|
||||
+}
|
||||
+EXPORT_SYMBOL(netdev_dpll_pin_set);
|
||||
+
|
||||
+void netdev_dpll_pin_clear(struct net_device *dev)
|
||||
+{
|
||||
+ netdev_dpll_pin_assign(dev, NULL);
|
||||
+}
|
||||
+EXPORT_SYMBOL(netdev_dpll_pin_clear);
|
||||
+
|
||||
/**
|
||||
* dev_change_proto_down - set carrier according to proto_down.
|
||||
*
|
||||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
|
||||
index 7ea66de1442c..bb004419d318 100644
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/addrconf.h>
|
||||
#endif
|
||||
+#include <linux/dpll.h>
|
||||
|
||||
#include "dev.h"
|
||||
|
||||
@@ -1055,6 +1056,15 @@ static size_t rtnl_devlink_port_size(const struct net_device *dev)
|
||||
return size;
|
||||
}
|
||||
|
||||
+static size_t rtnl_dpll_pin_size(const struct net_device *dev)
|
||||
+{
|
||||
+ size_t size = nla_total_size(0); /* nest IFLA_DPLL_PIN */
|
||||
+
|
||||
+ size += dpll_msg_pin_handle_size(netdev_dpll_pin(dev));
|
||||
+
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
static noinline size_t if_nlmsg_size(const struct net_device *dev,
|
||||
u32 ext_filter_mask)
|
||||
{
|
||||
@@ -1111,6 +1121,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
|
||||
+ rtnl_prop_list_size(dev)
|
||||
+ nla_total_size(MAX_ADDR_LEN) /* IFLA_PERM_ADDRESS */
|
||||
+ rtnl_devlink_port_size(dev)
|
||||
+ + rtnl_dpll_pin_size(dev)
|
||||
+ 0;
|
||||
}
|
||||
|
||||
@@ -1774,6 +1785,28 @@ static int rtnl_fill_devlink_port(struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int rtnl_fill_dpll_pin(struct sk_buff *skb,
|
||||
+ const struct net_device *dev)
|
||||
+{
|
||||
+ struct nlattr *dpll_pin_nest;
|
||||
+ int ret;
|
||||
+
|
||||
+ dpll_pin_nest = nla_nest_start(skb, IFLA_DPLL_PIN);
|
||||
+ if (!dpll_pin_nest)
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ ret = dpll_msg_add_pin_handle(skb, netdev_dpll_pin(dev));
|
||||
+ if (ret < 0)
|
||||
+ goto nest_cancel;
|
||||
+
|
||||
+ nla_nest_end(skb, dpll_pin_nest);
|
||||
+ return 0;
|
||||
+
|
||||
+nest_cancel:
|
||||
+ nla_nest_cancel(skb, dpll_pin_nest);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtnl_fill_ifinfo(struct sk_buff *skb,
|
||||
struct net_device *dev, struct net *src_net,
|
||||
int type, u32 pid, u32 seq, u32 change,
|
||||
@@ -1916,6 +1949,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
|
||||
if (rtnl_fill_devlink_port(skb, dev))
|
||||
goto nla_put_failure;
|
||||
|
||||
+ if (rtnl_fill_dpll_pin(skb, dev))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
nlmsg_end(skb, nlh);
|
||||
return 0;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,651 +0,0 @@
|
||||
From b0564f1f3105dde3373d0c68a17c8016c23b0aae Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Date: Wed, 13 Sep 2023 21:49:42 +0100
|
||||
Subject: [PATCH 08/46] ptp_ocp: implement DPLL ops
|
||||
|
||||
Implement basic DPLL operations in ptp_ocp driver as the
|
||||
simplest example of using new subsystem.
|
||||
|
||||
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 09eeb3aecc6c74c9a911396f9ab46b1a41fcd7b8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/ptp/Kconfig | 1 +
|
||||
drivers/ptp/ptp_ocp.c | 369 +++++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 310 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
|
||||
index ed9d97a032f1..5dd5f188e14f 100644
|
||||
--- a/drivers/ptp/Kconfig
|
||||
+++ b/drivers/ptp/Kconfig
|
||||
@@ -188,6 +188,7 @@ config PTP_1588_CLOCK_OCP
|
||||
depends on COMMON_CLK
|
||||
select NET_DEVLINK
|
||||
select CRC16
|
||||
+ select DPLL
|
||||
help
|
||||
This driver adds support for an OpenCompute time card.
|
||||
|
||||
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
|
||||
index a7a6947ab4bc..41eaffcae462 100644
|
||||
--- a/drivers/ptp/ptp_ocp.c
|
||||
+++ b/drivers/ptp/ptp_ocp.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/crc16.h>
|
||||
+#include <linux/dpll.h>
|
||||
|
||||
#define PCI_VENDOR_ID_FACEBOOK 0x1d9b
|
||||
#define PCI_DEVICE_ID_FACEBOOK_TIMECARD 0x0400
|
||||
@@ -260,12 +261,21 @@ enum ptp_ocp_sma_mode {
|
||||
SMA_MODE_OUT,
|
||||
};
|
||||
|
||||
+static struct dpll_pin_frequency ptp_ocp_sma_freq[] = {
|
||||
+ DPLL_PIN_FREQUENCY_1PPS,
|
||||
+ DPLL_PIN_FREQUENCY_10MHZ,
|
||||
+ DPLL_PIN_FREQUENCY_IRIG_B,
|
||||
+ DPLL_PIN_FREQUENCY_DCF77,
|
||||
+};
|
||||
+
|
||||
struct ptp_ocp_sma_connector {
|
||||
enum ptp_ocp_sma_mode mode;
|
||||
bool fixed_fcn;
|
||||
bool fixed_dir;
|
||||
bool disabled;
|
||||
u8 default_fcn;
|
||||
+ struct dpll_pin *dpll_pin;
|
||||
+ struct dpll_pin_properties dpll_prop;
|
||||
};
|
||||
|
||||
struct ocp_attr_group {
|
||||
@@ -294,6 +304,7 @@ struct ptp_ocp_serial_port {
|
||||
|
||||
#define OCP_BOARD_ID_LEN 13
|
||||
#define OCP_SERIAL_LEN 6
|
||||
+#define OCP_SMA_NUM 4
|
||||
|
||||
struct ptp_ocp {
|
||||
struct pci_dev *pdev;
|
||||
@@ -331,7 +342,9 @@ struct ptp_ocp {
|
||||
const struct attribute_group **attr_group;
|
||||
const struct ptp_ocp_eeprom_map *eeprom_map;
|
||||
struct dentry *debug_root;
|
||||
+ bool sync;
|
||||
time64_t gnss_lost;
|
||||
+ struct delayed_work sync_work;
|
||||
int id;
|
||||
int n_irqs;
|
||||
struct ptp_ocp_serial_port gnss_port;
|
||||
@@ -350,8 +363,9 @@ struct ptp_ocp {
|
||||
u32 ts_window_adjust;
|
||||
u64 fw_cap;
|
||||
struct ptp_ocp_signal signal[4];
|
||||
- struct ptp_ocp_sma_connector sma[4];
|
||||
+ struct ptp_ocp_sma_connector sma[OCP_SMA_NUM];
|
||||
const struct ocp_sma_op *sma_op;
|
||||
+ struct dpll_device *dpll;
|
||||
};
|
||||
|
||||
#define OCP_REQ_TIMESTAMP BIT(0)
|
||||
@@ -835,6 +849,7 @@ static DEFINE_IDR(ptp_ocp_idr);
|
||||
struct ocp_selector {
|
||||
const char *name;
|
||||
int value;
|
||||
+ u64 frequency;
|
||||
};
|
||||
|
||||
static const struct ocp_selector ptp_ocp_clock[] = {
|
||||
@@ -855,31 +870,31 @@ static const struct ocp_selector ptp_ocp_clock[] = {
|
||||
#define SMA_SELECT_MASK GENMASK(14, 0)
|
||||
|
||||
static const struct ocp_selector ptp_ocp_sma_in[] = {
|
||||
- { .name = "10Mhz", .value = 0x0000 },
|
||||
- { .name = "PPS1", .value = 0x0001 },
|
||||
- { .name = "PPS2", .value = 0x0002 },
|
||||
- { .name = "TS1", .value = 0x0004 },
|
||||
- { .name = "TS2", .value = 0x0008 },
|
||||
- { .name = "IRIG", .value = 0x0010 },
|
||||
- { .name = "DCF", .value = 0x0020 },
|
||||
- { .name = "TS3", .value = 0x0040 },
|
||||
- { .name = "TS4", .value = 0x0080 },
|
||||
- { .name = "FREQ1", .value = 0x0100 },
|
||||
- { .name = "FREQ2", .value = 0x0200 },
|
||||
- { .name = "FREQ3", .value = 0x0400 },
|
||||
- { .name = "FREQ4", .value = 0x0800 },
|
||||
- { .name = "None", .value = SMA_DISABLE },
|
||||
+ { .name = "10Mhz", .value = 0x0000, .frequency = 10000000 },
|
||||
+ { .name = "PPS1", .value = 0x0001, .frequency = 1 },
|
||||
+ { .name = "PPS2", .value = 0x0002, .frequency = 1 },
|
||||
+ { .name = "TS1", .value = 0x0004, .frequency = 0 },
|
||||
+ { .name = "TS2", .value = 0x0008, .frequency = 0 },
|
||||
+ { .name = "IRIG", .value = 0x0010, .frequency = 10000 },
|
||||
+ { .name = "DCF", .value = 0x0020, .frequency = 77500 },
|
||||
+ { .name = "TS3", .value = 0x0040, .frequency = 0 },
|
||||
+ { .name = "TS4", .value = 0x0080, .frequency = 0 },
|
||||
+ { .name = "FREQ1", .value = 0x0100, .frequency = 0 },
|
||||
+ { .name = "FREQ2", .value = 0x0200, .frequency = 0 },
|
||||
+ { .name = "FREQ3", .value = 0x0400, .frequency = 0 },
|
||||
+ { .name = "FREQ4", .value = 0x0800, .frequency = 0 },
|
||||
+ { .name = "None", .value = SMA_DISABLE, .frequency = 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct ocp_selector ptp_ocp_sma_out[] = {
|
||||
- { .name = "10Mhz", .value = 0x0000 },
|
||||
- { .name = "PHC", .value = 0x0001 },
|
||||
- { .name = "MAC", .value = 0x0002 },
|
||||
- { .name = "GNSS1", .value = 0x0004 },
|
||||
- { .name = "GNSS2", .value = 0x0008 },
|
||||
- { .name = "IRIG", .value = 0x0010 },
|
||||
- { .name = "DCF", .value = 0x0020 },
|
||||
+ { .name = "10Mhz", .value = 0x0000, .frequency = 10000000 },
|
||||
+ { .name = "PHC", .value = 0x0001, .frequency = 1 },
|
||||
+ { .name = "MAC", .value = 0x0002, .frequency = 1 },
|
||||
+ { .name = "GNSS1", .value = 0x0004, .frequency = 1 },
|
||||
+ { .name = "GNSS2", .value = 0x0008, .frequency = 1 },
|
||||
+ { .name = "IRIG", .value = 0x0010, .frequency = 10000 },
|
||||
+ { .name = "DCF", .value = 0x0020, .frequency = 77000 },
|
||||
{ .name = "GEN1", .value = 0x0040 },
|
||||
{ .name = "GEN2", .value = 0x0080 },
|
||||
{ .name = "GEN3", .value = 0x0100 },
|
||||
@@ -890,15 +905,15 @@ static const struct ocp_selector ptp_ocp_sma_out[] = {
|
||||
};
|
||||
|
||||
static const struct ocp_selector ptp_ocp_art_sma_in[] = {
|
||||
- { .name = "PPS1", .value = 0x0001 },
|
||||
- { .name = "10Mhz", .value = 0x0008 },
|
||||
+ { .name = "PPS1", .value = 0x0001, .frequency = 1 },
|
||||
+ { .name = "10Mhz", .value = 0x0008, .frequency = 1000000 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct ocp_selector ptp_ocp_art_sma_out[] = {
|
||||
- { .name = "PHC", .value = 0x0002 },
|
||||
- { .name = "GNSS", .value = 0x0004 },
|
||||
- { .name = "10Mhz", .value = 0x0010 },
|
||||
+ { .name = "PHC", .value = 0x0002, .frequency = 1 },
|
||||
+ { .name = "GNSS", .value = 0x0004, .frequency = 1 },
|
||||
+ { .name = "10Mhz", .value = 0x0010, .frequency = 10000000 },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1351,7 +1366,6 @@ static int
|
||||
ptp_ocp_init_clock(struct ptp_ocp *bp)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
- bool sync;
|
||||
u32 ctrl;
|
||||
|
||||
ctrl = OCP_CTRL_ENABLE;
|
||||
@@ -1375,8 +1389,8 @@ ptp_ocp_init_clock(struct ptp_ocp *bp)
|
||||
|
||||
ptp_ocp_estimate_pci_timing(bp);
|
||||
|
||||
- sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC;
|
||||
- if (!sync) {
|
||||
+ bp->sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC;
|
||||
+ if (!bp->sync) {
|
||||
ktime_get_clocktai_ts64(&ts);
|
||||
ptp_ocp_settime(&bp->ptp_info, &ts);
|
||||
}
|
||||
@@ -2289,22 +2303,35 @@ ptp_ocp_sma_fb_set_inputs(struct ptp_ocp *bp, int sma_nr, u32 val)
|
||||
static void
|
||||
ptp_ocp_sma_fb_init(struct ptp_ocp *bp)
|
||||
{
|
||||
+ struct dpll_pin_properties prop = {
|
||||
+ .board_label = NULL,
|
||||
+ .type = DPLL_PIN_TYPE_EXT,
|
||||
+ .capabilities = DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE,
|
||||
+ .freq_supported_num = ARRAY_SIZE(ptp_ocp_sma_freq),
|
||||
+ .freq_supported = ptp_ocp_sma_freq,
|
||||
+
|
||||
+ };
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
/* defaults */
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
+ bp->sma[i].default_fcn = i & 1;
|
||||
+ bp->sma[i].dpll_prop = prop;
|
||||
+ bp->sma[i].dpll_prop.board_label =
|
||||
+ bp->ptp_info.pin_config[i].name;
|
||||
+ }
|
||||
bp->sma[0].mode = SMA_MODE_IN;
|
||||
bp->sma[1].mode = SMA_MODE_IN;
|
||||
bp->sma[2].mode = SMA_MODE_OUT;
|
||||
bp->sma[3].mode = SMA_MODE_OUT;
|
||||
- for (i = 0; i < 4; i++)
|
||||
- bp->sma[i].default_fcn = i & 1;
|
||||
-
|
||||
/* If no SMA1 map, the pin functions and directions are fixed. */
|
||||
if (!bp->sma_map1) {
|
||||
- for (i = 0; i < 4; i++) {
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
bp->sma[i].fixed_fcn = true;
|
||||
bp->sma[i].fixed_dir = true;
|
||||
+ bp->sma[1].dpll_prop.capabilities &=
|
||||
+ ~DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2314,7 +2341,7 @@ ptp_ocp_sma_fb_init(struct ptp_ocp *bp)
|
||||
*/
|
||||
reg = ioread32(&bp->sma_map2->gpio2);
|
||||
if (reg == 0xffffffff) {
|
||||
- for (i = 0; i < 4; i++)
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++)
|
||||
bp->sma[i].fixed_dir = true;
|
||||
} else {
|
||||
reg = ioread32(&bp->sma_map1->gpio1);
|
||||
@@ -2336,7 +2363,7 @@ static const struct ocp_sma_op ocp_fb_sma_op = {
|
||||
};
|
||||
|
||||
static int
|
||||
-ptp_ocp_fb_set_pins(struct ptp_ocp *bp)
|
||||
+ptp_ocp_set_pins(struct ptp_ocp *bp)
|
||||
{
|
||||
struct ptp_pin_desc *config;
|
||||
int i;
|
||||
@@ -2403,16 +2430,16 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
|
||||
|
||||
ptp_ocp_tod_init(bp);
|
||||
ptp_ocp_nmea_out_init(bp);
|
||||
- ptp_ocp_sma_init(bp);
|
||||
ptp_ocp_signal_init(bp);
|
||||
|
||||
err = ptp_ocp_attr_group_add(bp, fb_timecard_groups);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- err = ptp_ocp_fb_set_pins(bp);
|
||||
+ err = ptp_ocp_set_pins(bp);
|
||||
if (err)
|
||||
return err;
|
||||
+ ptp_ocp_sma_init(bp);
|
||||
|
||||
return ptp_ocp_init_clock(bp);
|
||||
}
|
||||
@@ -2452,6 +2479,14 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data)
|
||||
static void
|
||||
ptp_ocp_art_sma_init(struct ptp_ocp *bp)
|
||||
{
|
||||
+ struct dpll_pin_properties prop = {
|
||||
+ .board_label = NULL,
|
||||
+ .type = DPLL_PIN_TYPE_EXT,
|
||||
+ .capabilities = 0,
|
||||
+ .freq_supported_num = ARRAY_SIZE(ptp_ocp_sma_freq),
|
||||
+ .freq_supported = ptp_ocp_sma_freq,
|
||||
+
|
||||
+ };
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
@@ -2466,16 +2501,16 @@ ptp_ocp_art_sma_init(struct ptp_ocp *bp)
|
||||
bp->sma[2].default_fcn = 0x10; /* OUT: 10Mhz */
|
||||
bp->sma[3].default_fcn = 0x02; /* OUT: PHC */
|
||||
|
||||
- /* If no SMA map, the pin functions and directions are fixed. */
|
||||
- if (!bp->art_sma) {
|
||||
- for (i = 0; i < 4; i++) {
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
+ /* If no SMA map, the pin functions and directions are fixed. */
|
||||
+ bp->sma[i].dpll_prop = prop;
|
||||
+ bp->sma[i].dpll_prop.board_label =
|
||||
+ bp->ptp_info.pin_config[i].name;
|
||||
+ if (!bp->art_sma) {
|
||||
bp->sma[i].fixed_fcn = true;
|
||||
bp->sma[i].fixed_dir = true;
|
||||
+ continue;
|
||||
}
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (i = 0; i < 4; i++) {
|
||||
reg = ioread32(&bp->art_sma->map[i].gpio);
|
||||
|
||||
switch (reg & 0xff) {
|
||||
@@ -2486,9 +2521,13 @@ ptp_ocp_art_sma_init(struct ptp_ocp *bp)
|
||||
case 1:
|
||||
case 8:
|
||||
bp->sma[i].mode = SMA_MODE_IN;
|
||||
+ bp->sma[i].dpll_prop.capabilities =
|
||||
+ DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE;
|
||||
break;
|
||||
default:
|
||||
bp->sma[i].mode = SMA_MODE_OUT;
|
||||
+ bp->sma[i].dpll_prop.capabilities =
|
||||
+ DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2555,6 +2594,9 @@ ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
|
||||
/* Enable MAC serial port during initialisation */
|
||||
iowrite32(1, &bp->board_config->mro50_serial_activate);
|
||||
|
||||
+ err = ptp_ocp_set_pins(bp);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
ptp_ocp_sma_init(bp);
|
||||
|
||||
err = ptp_ocp_attr_group_add(bp, art_timecard_groups);
|
||||
@@ -2696,16 +2738,9 @@ sma4_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
}
|
||||
|
||||
static int
|
||||
-ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
|
||||
+ptp_ocp_sma_store_val(struct ptp_ocp *bp, int val, enum ptp_ocp_sma_mode mode, int sma_nr)
|
||||
{
|
||||
struct ptp_ocp_sma_connector *sma = &bp->sma[sma_nr - 1];
|
||||
- enum ptp_ocp_sma_mode mode;
|
||||
- int val;
|
||||
-
|
||||
- mode = sma->mode;
|
||||
- val = sma_parse_inputs(bp->sma_op->tbl, buf, &mode);
|
||||
- if (val < 0)
|
||||
- return val;
|
||||
|
||||
if (sma->fixed_dir && (mode != sma->mode || val & SMA_DISABLE))
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2740,6 +2775,20 @@ ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
|
||||
return val;
|
||||
}
|
||||
|
||||
+static int
|
||||
+ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
|
||||
+{
|
||||
+ struct ptp_ocp_sma_connector *sma = &bp->sma[sma_nr - 1];
|
||||
+ enum ptp_ocp_sma_mode mode;
|
||||
+ int val;
|
||||
+
|
||||
+ mode = sma->mode;
|
||||
+ val = sma_parse_inputs(bp->sma_op->tbl, buf, &mode);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+ return ptp_ocp_sma_store_val(bp, val, mode, sma_nr);
|
||||
+}
|
||||
+
|
||||
static ssize_t
|
||||
sma1_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@@ -3834,9 +3883,8 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
|
||||
strcpy(buf, "unknown");
|
||||
break;
|
||||
}
|
||||
- val = ioread32(&bp->reg->status);
|
||||
seq_printf(s, "%7s: %s, state: %s\n", "PHC src", buf,
|
||||
- val & OCP_STATUS_IN_SYNC ? "sync" : "unsynced");
|
||||
+ bp->sync ? "sync" : "unsynced");
|
||||
|
||||
if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, &sts)) {
|
||||
struct timespec64 sys_ts;
|
||||
@@ -4067,7 +4115,6 @@ ptp_ocp_phc_info(struct ptp_ocp *bp)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
u32 version, select;
|
||||
- bool sync;
|
||||
|
||||
version = ioread32(&bp->reg->version);
|
||||
select = ioread32(&bp->reg->select);
|
||||
@@ -4076,11 +4123,10 @@ ptp_ocp_phc_info(struct ptp_ocp *bp)
|
||||
ptp_ocp_select_name_from_val(ptp_ocp_clock, select >> 16),
|
||||
ptp_clock_index(bp->ptp));
|
||||
|
||||
- sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC;
|
||||
if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, NULL))
|
||||
dev_info(&bp->pdev->dev, "Time: %lld.%ld, %s\n",
|
||||
ts.tv_sec, ts.tv_nsec,
|
||||
- sync ? "in-sync" : "UNSYNCED");
|
||||
+ bp->sync ? "in-sync" : "UNSYNCED");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4177,12 +4223,168 @@ ptp_ocp_detach(struct ptp_ocp *bp)
|
||||
device_unregister(&bp->dev);
|
||||
}
|
||||
|
||||
+static int ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll,
|
||||
+ void *priv,
|
||||
+ enum dpll_lock_status *status,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp *bp = priv;
|
||||
+
|
||||
+ *status = bp->sync ? DPLL_LOCK_STATUS_LOCKED : DPLL_LOCK_STATUS_UNLOCKED;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_state_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *priv,
|
||||
+ enum dpll_pin_state *state,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp *bp = priv;
|
||||
+ int idx;
|
||||
+
|
||||
+ if (bp->pps_select) {
|
||||
+ idx = ioread32(&bp->pps_select->gpio1);
|
||||
+ *state = (&bp->sma[idx] == pin_priv) ? DPLL_PIN_STATE_CONNECTED :
|
||||
+ DPLL_PIN_STATE_SELECTABLE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ NL_SET_ERR_MSG(extack, "pin selection is not supported on current HW");
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_mode_get(const struct dpll_device *dpll, void *priv,
|
||||
+ u32 *mode, struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ *mode = DPLL_MODE_AUTOMATIC;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static bool ptp_ocp_dpll_mode_supported(const struct dpll_device *dpll,
|
||||
+ void *priv, const enum dpll_mode mode,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ return mode == DPLL_MODE_AUTOMATIC;
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_direction_get(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *priv,
|
||||
+ enum dpll_pin_direction *direction,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp_sma_connector *sma = pin_priv;
|
||||
+
|
||||
+ *direction = sma->mode == SMA_MODE_IN ?
|
||||
+ DPLL_PIN_DIRECTION_INPUT :
|
||||
+ DPLL_PIN_DIRECTION_OUTPUT;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_direction_set(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv,
|
||||
+ enum dpll_pin_direction direction,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp_sma_connector *sma = pin_priv;
|
||||
+ struct ptp_ocp *bp = dpll_priv;
|
||||
+ enum ptp_ocp_sma_mode mode;
|
||||
+ int sma_nr = (sma - bp->sma);
|
||||
+
|
||||
+ if (sma->fixed_dir)
|
||||
+ return -EOPNOTSUPP;
|
||||
+ mode = direction == DPLL_PIN_DIRECTION_INPUT ?
|
||||
+ SMA_MODE_IN : SMA_MODE_OUT;
|
||||
+ return ptp_ocp_sma_store_val(bp, 0, mode, sma_nr);
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_frequency_set(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv, u64 frequency,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp_sma_connector *sma = pin_priv;
|
||||
+ struct ptp_ocp *bp = dpll_priv;
|
||||
+ const struct ocp_selector *tbl;
|
||||
+ int sma_nr = (sma - bp->sma);
|
||||
+ int i;
|
||||
+
|
||||
+ if (sma->fixed_fcn)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ tbl = bp->sma_op->tbl[sma->mode];
|
||||
+ for (i = 0; tbl[i].name; i++)
|
||||
+ if (tbl[i].frequency == frequency)
|
||||
+ return ptp_ocp_sma_store_val(bp, i, sma->mode, sma_nr);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int ptp_ocp_dpll_frequency_get(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv, u64 *frequency,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ptp_ocp_sma_connector *sma = pin_priv;
|
||||
+ struct ptp_ocp *bp = dpll_priv;
|
||||
+ const struct ocp_selector *tbl;
|
||||
+ int sma_nr = (sma - bp->sma);
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ val = bp->sma_op->get(bp, sma_nr);
|
||||
+ tbl = bp->sma_op->tbl[sma->mode];
|
||||
+ for (i = 0; tbl[i].name; i++)
|
||||
+ if (val == tbl[i].value) {
|
||||
+ *frequency = tbl[i].frequency;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static const struct dpll_device_ops dpll_ops = {
|
||||
+ .lock_status_get = ptp_ocp_dpll_lock_status_get,
|
||||
+ .mode_get = ptp_ocp_dpll_mode_get,
|
||||
+ .mode_supported = ptp_ocp_dpll_mode_supported,
|
||||
+};
|
||||
+
|
||||
+static const struct dpll_pin_ops dpll_pins_ops = {
|
||||
+ .frequency_get = ptp_ocp_dpll_frequency_get,
|
||||
+ .frequency_set = ptp_ocp_dpll_frequency_set,
|
||||
+ .direction_get = ptp_ocp_dpll_direction_get,
|
||||
+ .direction_set = ptp_ocp_dpll_direction_set,
|
||||
+ .state_on_dpll_get = ptp_ocp_dpll_state_get,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+ptp_ocp_sync_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ptp_ocp *bp;
|
||||
+ bool sync;
|
||||
+
|
||||
+ bp = container_of(work, struct ptp_ocp, sync_work.work);
|
||||
+ sync = !!(ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC);
|
||||
+
|
||||
+ if (bp->sync != sync)
|
||||
+ dpll_device_change_ntf(bp->dpll);
|
||||
+
|
||||
+ bp->sync = sync;
|
||||
+
|
||||
+ queue_delayed_work(system_power_efficient_wq, &bp->sync_work, HZ);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct devlink *devlink;
|
||||
struct ptp_ocp *bp;
|
||||
- int err;
|
||||
+ int err, i;
|
||||
+ u64 clkid;
|
||||
|
||||
devlink = devlink_alloc(&ptp_ocp_devlink_ops, sizeof(*bp), &pdev->dev);
|
||||
if (!devlink) {
|
||||
@@ -4201,6 +4403,8 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (err)
|
||||
goto out_disable;
|
||||
|
||||
+ INIT_DELAYED_WORK(&bp->sync_work, ptp_ocp_sync_work);
|
||||
+
|
||||
/* compat mode.
|
||||
* Older FPGA firmware only returns 2 irq's.
|
||||
* allow this - if not all of the IRQ's are returned, skip the
|
||||
@@ -4232,8 +4436,43 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
ptp_ocp_info(bp);
|
||||
devlink_register(devlink);
|
||||
- return 0;
|
||||
|
||||
+ clkid = pci_get_dsn(pdev);
|
||||
+ bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE);
|
||||
+ if (IS_ERR(bp->dpll)) {
|
||||
+ err = PTR_ERR(bp->dpll);
|
||||
+ dev_err(&pdev->dev, "dpll_device_alloc failed\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
+ bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &bp->sma[i].dpll_prop);
|
||||
+ if (IS_ERR(bp->sma[i].dpll_pin)) {
|
||||
+ err = PTR_ERR(bp->dpll);
|
||||
+ goto out_dpll;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops,
|
||||
+ &bp->sma[i]);
|
||||
+ if (err) {
|
||||
+ dpll_pin_put(bp->sma[i].dpll_pin);
|
||||
+ goto out_dpll;
|
||||
+ }
|
||||
+ }
|
||||
+ queue_delayed_work(system_power_efficient_wq, &bp->sync_work, HZ);
|
||||
+
|
||||
+ return 0;
|
||||
+out_dpll:
|
||||
+ while (i) {
|
||||
+ --i;
|
||||
+ dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]);
|
||||
+ dpll_pin_put(bp->sma[i].dpll_pin);
|
||||
+ }
|
||||
+ dpll_device_put(bp->dpll);
|
||||
out:
|
||||
ptp_ocp_detach(bp);
|
||||
out_disable:
|
||||
@@ -4248,7 +4487,17 @@ ptp_ocp_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ptp_ocp *bp = pci_get_drvdata(pdev);
|
||||
struct devlink *devlink = priv_to_devlink(bp);
|
||||
+ int i;
|
||||
|
||||
+ cancel_delayed_work_sync(&bp->sync_work);
|
||||
+ for (i = 0; i < OCP_SMA_NUM; i++) {
|
||||
+ if (bp->sma[i].dpll_pin) {
|
||||
+ dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, bp);
|
||||
+ dpll_pin_put(bp->sma[i].dpll_pin);
|
||||
+ }
|
||||
+ }
|
||||
+ dpll_device_unregister(bp->dpll, &dpll_ops, bp);
|
||||
+ dpll_device_put(bp->dpll);
|
||||
devlink_unregister(devlink);
|
||||
ptp_ocp_detach(bp);
|
||||
pci_disable_device(pdev);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,624 +0,0 @@
|
||||
From 5f8d07324a98db8f49c8ff40b71c62eba801b0eb Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Wed, 13 Sep 2023 21:49:43 +0100
|
||||
Subject: [PATCH 09/46] mlx5: Implement SyncE support using DPLL infrastructure
|
||||
|
||||
Implement SyncE support using newly introduced DPLL support.
|
||||
Make sure that each PFs/VFs/SFs probed with appropriate capability
|
||||
will spawn a dpll auxiliary device and register appropriate dpll device
|
||||
and pin instances.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 496fd0a26bbf73b6b12407ee4fbe5ff49d659a6d)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlx5/core/Kconfig | 8 +
|
||||
.../net/ethernet/mellanox/mlx5/core/Makefile | 3 +
|
||||
drivers/net/ethernet/mellanox/mlx5/core/dev.c | 17 +
|
||||
.../net/ethernet/mellanox/mlx5/core/dpll.c | 432 ++++++++++++++++++
|
||||
include/linux/mlx5/driver.h | 2 +
|
||||
include/linux/mlx5/mlx5_ifc.h | 59 ++-
|
||||
6 files changed, 520 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
|
||||
index c4f4de82e29e..685335832a93 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
|
||||
@@ -189,3 +189,11 @@ config MLX5_SF_MANAGER
|
||||
port is managed through devlink. A subfunction supports RDMA, netdevice
|
||||
and vdpa device. It is similar to a SRIOV VF but it doesn't require
|
||||
SRIOV support.
|
||||
+
|
||||
+config MLX5_DPLL
|
||||
+ tristate "Mellanox 5th generation network adapters (ConnectX series) DPLL support"
|
||||
+ depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE
|
||||
+ select DPLL
|
||||
+ help
|
||||
+ DPLL support in Mellanox Technologies ConnectX NICs.
|
||||
+
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
|
||||
index 7e94caca4888..c44870b175f9 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
|
||||
@@ -128,3 +128,6 @@ mlx5_core-$(CONFIG_MLX5_SF) += sf/vhca_event.o sf/dev/dev.o sf/dev/driver.o irq_
|
||||
# SF manager
|
||||
#
|
||||
mlx5_core-$(CONFIG_MLX5_SF_MANAGER) += sf/cmd.o sf/hw_table.o sf/devlink.o
|
||||
+
|
||||
+obj-$(CONFIG_MLX5_DPLL) += mlx5_dpll.o
|
||||
+mlx5_dpll-y := dpll.o
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
|
||||
index 7909f378dc93..1fc03480c2ff 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
|
||||
@@ -206,6 +206,19 @@ static bool is_ib_enabled(struct mlx5_core_dev *dev)
|
||||
return err ? false : val.vbool;
|
||||
}
|
||||
|
||||
+static bool is_dpll_supported(struct mlx5_core_dev *dev)
|
||||
+{
|
||||
+ if (!IS_ENABLED(CONFIG_MLX5_DPLL))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!MLX5_CAP_MCAM_REG2(dev, synce_registers)) {
|
||||
+ mlx5_core_warn(dev, "Missing SyncE capability\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
enum {
|
||||
MLX5_INTERFACE_PROTOCOL_ETH,
|
||||
MLX5_INTERFACE_PROTOCOL_ETH_REP,
|
||||
@@ -215,6 +228,8 @@ enum {
|
||||
MLX5_INTERFACE_PROTOCOL_MPIB,
|
||||
|
||||
MLX5_INTERFACE_PROTOCOL_VNET,
|
||||
+
|
||||
+ MLX5_INTERFACE_PROTOCOL_DPLL,
|
||||
};
|
||||
|
||||
static const struct mlx5_adev_device {
|
||||
@@ -237,6 +252,8 @@ static const struct mlx5_adev_device {
|
||||
.is_supported = &is_ib_rep_supported },
|
||||
[MLX5_INTERFACE_PROTOCOL_MPIB] = { .suffix = "multiport",
|
||||
.is_supported = &is_mp_supported },
|
||||
+ [MLX5_INTERFACE_PROTOCOL_DPLL] = { .suffix = "dpll",
|
||||
+ .is_supported = &is_dpll_supported },
|
||||
};
|
||||
|
||||
int mlx5_adev_idx_alloc(void)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
new file mode 100644
|
||||
index 000000000000..74f0c7867120
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
@@ -0,0 +1,432 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
+/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
+
|
||||
+#include <linux/dpll.h>
|
||||
+#include <linux/mlx5/driver.h>
|
||||
+
|
||||
+/* This structure represents a reference to DPLL, one is created
|
||||
+ * per mdev instance.
|
||||
+ */
|
||||
+struct mlx5_dpll {
|
||||
+ struct dpll_device *dpll;
|
||||
+ struct dpll_pin *dpll_pin;
|
||||
+ struct mlx5_core_dev *mdev;
|
||||
+ struct workqueue_struct *wq;
|
||||
+ struct delayed_work work;
|
||||
+ struct {
|
||||
+ bool valid;
|
||||
+ enum dpll_lock_status lock_status;
|
||||
+ enum dpll_pin_state pin_state;
|
||||
+ } last;
|
||||
+ struct notifier_block mdev_nb;
|
||||
+ struct net_device *tracking_netdev;
|
||||
+};
|
||||
+
|
||||
+static int mlx5_dpll_clock_id_get(struct mlx5_core_dev *mdev, u64 *clock_id)
|
||||
+{
|
||||
+ u32 out[MLX5_ST_SZ_DW(msecq_reg)] = {};
|
||||
+ u32 in[MLX5_ST_SZ_DW(msecq_reg)] = {};
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out),
|
||||
+ MLX5_REG_MSECQ, 0, 0);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ *clock_id = MLX5_GET64(msecq_reg, out, local_clock_identity);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlx5_dpll_synce_status_get(struct mlx5_core_dev *mdev,
|
||||
+ enum mlx5_msees_admin_status *admin_status,
|
||||
+ enum mlx5_msees_oper_status *oper_status,
|
||||
+ bool *ho_acq)
|
||||
+{
|
||||
+ u32 out[MLX5_ST_SZ_DW(msees_reg)] = {};
|
||||
+ u32 in[MLX5_ST_SZ_DW(msees_reg)] = {};
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out),
|
||||
+ MLX5_REG_MSEES, 0, 0);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ if (admin_status)
|
||||
+ *admin_status = MLX5_GET(msees_reg, out, admin_status);
|
||||
+ *oper_status = MLX5_GET(msees_reg, out, oper_status);
|
||||
+ if (ho_acq)
|
||||
+ *ho_acq = MLX5_GET(msees_reg, out, ho_acq);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlx5_dpll_synce_status_set(struct mlx5_core_dev *mdev,
|
||||
+ enum mlx5_msees_admin_status admin_status)
|
||||
+{
|
||||
+ u32 out[MLX5_ST_SZ_DW(msees_reg)] = {};
|
||||
+ u32 in[MLX5_ST_SZ_DW(msees_reg)] = {};
|
||||
+
|
||||
+ MLX5_SET(msees_reg, in, field_select,
|
||||
+ MLX5_MSEES_FIELD_SELECT_ENABLE |
|
||||
+ MLX5_MSEES_FIELD_SELECT_ADMIN_STATUS);
|
||||
+ MLX5_SET(msees_reg, in, admin_status, admin_status);
|
||||
+ return mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out),
|
||||
+ MLX5_REG_MSEES, 0, 1);
|
||||
+}
|
||||
+
|
||||
+static enum dpll_lock_status
|
||||
+mlx5_dpll_lock_status_get(enum mlx5_msees_oper_status oper_status, bool ho_acq)
|
||||
+{
|
||||
+ switch (oper_status) {
|
||||
+ case MLX5_MSEES_OPER_STATUS_SELF_TRACK:
|
||||
+ fallthrough;
|
||||
+ case MLX5_MSEES_OPER_STATUS_OTHER_TRACK:
|
||||
+ return ho_acq ? DPLL_LOCK_STATUS_LOCKED_HO_ACQ :
|
||||
+ DPLL_LOCK_STATUS_LOCKED;
|
||||
+ case MLX5_MSEES_OPER_STATUS_HOLDOVER:
|
||||
+ fallthrough;
|
||||
+ case MLX5_MSEES_OPER_STATUS_FAIL_HOLDOVER:
|
||||
+ return DPLL_LOCK_STATUS_HOLDOVER;
|
||||
+ default:
|
||||
+ return DPLL_LOCK_STATUS_UNLOCKED;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static enum dpll_pin_state
|
||||
+mlx5_dpll_pin_state_get(enum mlx5_msees_admin_status admin_status,
|
||||
+ enum mlx5_msees_oper_status oper_status)
|
||||
+{
|
||||
+ return (admin_status == MLX5_MSEES_ADMIN_STATUS_TRACK &&
|
||||
+ (oper_status == MLX5_MSEES_OPER_STATUS_SELF_TRACK ||
|
||||
+ oper_status == MLX5_MSEES_OPER_STATUS_OTHER_TRACK)) ?
|
||||
+ DPLL_PIN_STATE_CONNECTED : DPLL_PIN_STATE_DISCONNECTED;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll,
|
||||
+ void *priv,
|
||||
+ enum dpll_lock_status *status,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ enum mlx5_msees_oper_status oper_status;
|
||||
+ struct mlx5_dpll *mdpll = priv;
|
||||
+ bool ho_acq;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_dpll_synce_status_get(mdpll->mdev, NULL,
|
||||
+ &oper_status, &ho_acq);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ *status = mlx5_dpll_lock_status_get(oper_status, ho_acq);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_device_mode_get(const struct dpll_device *dpll,
|
||||
+ void *priv,
|
||||
+ u32 *mode, struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ *mode = DPLL_MODE_MANUAL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static bool mlx5_dpll_device_mode_supported(const struct dpll_device *dpll,
|
||||
+ void *priv,
|
||||
+ enum dpll_mode mode,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ return mode == DPLL_MODE_MANUAL;
|
||||
+}
|
||||
+
|
||||
+static const struct dpll_device_ops mlx5_dpll_device_ops = {
|
||||
+ .lock_status_get = mlx5_dpll_device_lock_status_get,
|
||||
+ .mode_get = mlx5_dpll_device_mode_get,
|
||||
+ .mode_supported = mlx5_dpll_device_mode_supported,
|
||||
+};
|
||||
+
|
||||
+static int mlx5_dpll_pin_direction_get(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv,
|
||||
+ enum dpll_pin_direction *direction,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ *direction = DPLL_PIN_DIRECTION_INPUT;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_state_on_dpll_get(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv,
|
||||
+ enum dpll_pin_state *state,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ enum mlx5_msees_admin_status admin_status;
|
||||
+ enum mlx5_msees_oper_status oper_status;
|
||||
+ struct mlx5_dpll *mdpll = pin_priv;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_dpll_synce_status_get(mdpll->mdev, &admin_status,
|
||||
+ &oper_status, NULL);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ *state = mlx5_dpll_pin_state_get(admin_status, oper_status);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_state_on_dpll_set(const struct dpll_pin *pin,
|
||||
+ void *pin_priv,
|
||||
+ const struct dpll_device *dpll,
|
||||
+ void *dpll_priv,
|
||||
+ enum dpll_pin_state state,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct mlx5_dpll *mdpll = pin_priv;
|
||||
+
|
||||
+ return mlx5_dpll_synce_status_set(mdpll->mdev,
|
||||
+ state == DPLL_PIN_STATE_CONNECTED ?
|
||||
+ MLX5_MSEES_ADMIN_STATUS_TRACK :
|
||||
+ MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING);
|
||||
+}
|
||||
+
|
||||
+static const struct dpll_pin_ops mlx5_dpll_pins_ops = {
|
||||
+ .direction_get = mlx5_dpll_pin_direction_get,
|
||||
+ .state_on_dpll_get = mlx5_dpll_state_on_dpll_get,
|
||||
+ .state_on_dpll_set = mlx5_dpll_state_on_dpll_set,
|
||||
+};
|
||||
+
|
||||
+static const struct dpll_pin_properties mlx5_dpll_pin_properties = {
|
||||
+ .type = DPLL_PIN_TYPE_SYNCE_ETH_PORT,
|
||||
+ .capabilities = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE,
|
||||
+};
|
||||
+
|
||||
+#define MLX5_DPLL_PERIODIC_WORK_INTERVAL 500 /* ms */
|
||||
+
|
||||
+static void mlx5_dpll_periodic_work_queue(struct mlx5_dpll *mdpll)
|
||||
+{
|
||||
+ queue_delayed_work(mdpll->wq, &mdpll->work,
|
||||
+ msecs_to_jiffies(MLX5_DPLL_PERIODIC_WORK_INTERVAL));
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_periodic_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct mlx5_dpll *mdpll = container_of(work, struct mlx5_dpll,
|
||||
+ work.work);
|
||||
+ enum mlx5_msees_admin_status admin_status;
|
||||
+ enum mlx5_msees_oper_status oper_status;
|
||||
+ enum dpll_lock_status lock_status;
|
||||
+ enum dpll_pin_state pin_state;
|
||||
+ bool ho_acq;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_dpll_synce_status_get(mdpll->mdev, &admin_status,
|
||||
+ &oper_status, &ho_acq);
|
||||
+ if (err)
|
||||
+ goto err_out;
|
||||
+ lock_status = mlx5_dpll_lock_status_get(oper_status, ho_acq);
|
||||
+ pin_state = mlx5_dpll_pin_state_get(admin_status, oper_status);
|
||||
+
|
||||
+ if (!mdpll->last.valid)
|
||||
+ goto invalid_out;
|
||||
+
|
||||
+ if (mdpll->last.lock_status != lock_status)
|
||||
+ dpll_device_change_ntf(mdpll->dpll);
|
||||
+ if (mdpll->last.pin_state != pin_state)
|
||||
+ dpll_pin_change_ntf(mdpll->dpll_pin);
|
||||
+
|
||||
+invalid_out:
|
||||
+ mdpll->last.lock_status = lock_status;
|
||||
+ mdpll->last.pin_state = pin_state;
|
||||
+ mdpll->last.valid = true;
|
||||
+err_out:
|
||||
+ mlx5_dpll_periodic_work_queue(mdpll);
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_netdev_dpll_pin_set(struct mlx5_dpll *mdpll,
|
||||
+ struct net_device *netdev)
|
||||
+{
|
||||
+ if (mdpll->tracking_netdev)
|
||||
+ return;
|
||||
+ netdev_dpll_pin_set(netdev, mdpll->dpll_pin);
|
||||
+ mdpll->tracking_netdev = netdev;
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_netdev_dpll_pin_clear(struct mlx5_dpll *mdpll)
|
||||
+{
|
||||
+ if (!mdpll->tracking_netdev)
|
||||
+ return;
|
||||
+ netdev_dpll_pin_clear(mdpll->tracking_netdev);
|
||||
+ mdpll->tracking_netdev = NULL;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_mdev_notifier_event(struct notifier_block *nb,
|
||||
+ unsigned long event, void *data)
|
||||
+{
|
||||
+ struct mlx5_dpll *mdpll = container_of(nb, struct mlx5_dpll, mdev_nb);
|
||||
+ struct net_device *netdev = data;
|
||||
+
|
||||
+ switch (event) {
|
||||
+ case MLX5_DRIVER_EVENT_UPLINK_NETDEV:
|
||||
+ if (netdev)
|
||||
+ mlx5_dpll_netdev_dpll_pin_set(mdpll, netdev);
|
||||
+ else
|
||||
+ mlx5_dpll_netdev_dpll_pin_clear(mdpll);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return NOTIFY_DONE;
|
||||
+ }
|
||||
+
|
||||
+ return NOTIFY_OK;
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_mdev_netdev_track(struct mlx5_dpll *mdpll,
|
||||
+ struct mlx5_core_dev *mdev)
|
||||
+{
|
||||
+ mdpll->mdev_nb.notifier_call = mlx5_dpll_mdev_notifier_event;
|
||||
+ mlx5_blocking_notifier_register(mdev, &mdpll->mdev_nb);
|
||||
+ mlx5_core_uplink_netdev_event_replay(mdev);
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_mdev_netdev_untrack(struct mlx5_dpll *mdpll,
|
||||
+ struct mlx5_core_dev *mdev)
|
||||
+{
|
||||
+ mlx5_blocking_notifier_unregister(mdev, &mdpll->mdev_nb);
|
||||
+ mlx5_dpll_netdev_dpll_pin_clear(mdpll);
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_probe(struct auxiliary_device *adev,
|
||||
+ const struct auxiliary_device_id *id)
|
||||
+{
|
||||
+ struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
|
||||
+ struct mlx5_core_dev *mdev = edev->mdev;
|
||||
+ struct mlx5_dpll *mdpll;
|
||||
+ u64 clock_id;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlx5_dpll_synce_status_set(mdev,
|
||||
+ MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mlx5_dpll_clock_id_get(mdev, &clock_id);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mdpll = kzalloc(sizeof(*mdpll), GFP_KERNEL);
|
||||
+ if (!mdpll)
|
||||
+ return -ENOMEM;
|
||||
+ mdpll->mdev = mdev;
|
||||
+ auxiliary_set_drvdata(adev, mdpll);
|
||||
+
|
||||
+ /* Multiple mdev instances might share one DPLL device. */
|
||||
+ mdpll->dpll = dpll_device_get(clock_id, 0, THIS_MODULE);
|
||||
+ if (IS_ERR(mdpll->dpll)) {
|
||||
+ err = PTR_ERR(mdpll->dpll);
|
||||
+ goto err_free_mdpll;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_device_register(mdpll->dpll, DPLL_TYPE_EEC,
|
||||
+ &mlx5_dpll_device_ops, mdpll);
|
||||
+ if (err)
|
||||
+ goto err_put_dpll_device;
|
||||
+
|
||||
+ /* Multiple mdev instances might share one DPLL pin. */
|
||||
+ mdpll->dpll_pin = dpll_pin_get(clock_id, mlx5_get_dev_index(mdev),
|
||||
+ THIS_MODULE, &mlx5_dpll_pin_properties);
|
||||
+ if (IS_ERR(mdpll->dpll_pin)) {
|
||||
+ err = PTR_ERR(mdpll->dpll_pin);
|
||||
+ goto err_unregister_dpll_device;
|
||||
+ }
|
||||
+
|
||||
+ err = dpll_pin_register(mdpll->dpll, mdpll->dpll_pin,
|
||||
+ &mlx5_dpll_pins_ops, mdpll);
|
||||
+ if (err)
|
||||
+ goto err_put_dpll_pin;
|
||||
+
|
||||
+ mdpll->wq = create_singlethread_workqueue("mlx5_dpll");
|
||||
+ if (!mdpll->wq) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_unregister_dpll_pin;
|
||||
+ }
|
||||
+
|
||||
+ mlx5_dpll_mdev_netdev_track(mdpll, mdev);
|
||||
+
|
||||
+ INIT_DELAYED_WORK(&mdpll->work, &mlx5_dpll_periodic_work);
|
||||
+ mlx5_dpll_periodic_work_queue(mdpll);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_unregister_dpll_pin:
|
||||
+ dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin,
|
||||
+ &mlx5_dpll_pins_ops, mdpll);
|
||||
+err_put_dpll_pin:
|
||||
+ dpll_pin_put(mdpll->dpll_pin);
|
||||
+err_unregister_dpll_device:
|
||||
+ dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll);
|
||||
+err_put_dpll_device:
|
||||
+ dpll_device_put(mdpll->dpll);
|
||||
+err_free_mdpll:
|
||||
+ kfree(mdpll);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void mlx5_dpll_remove(struct auxiliary_device *adev)
|
||||
+{
|
||||
+ struct mlx5_dpll *mdpll = auxiliary_get_drvdata(adev);
|
||||
+ struct mlx5_core_dev *mdev = mdpll->mdev;
|
||||
+
|
||||
+ cancel_delayed_work(&mdpll->work);
|
||||
+ mlx5_dpll_mdev_netdev_untrack(mdpll, mdev);
|
||||
+ destroy_workqueue(mdpll->wq);
|
||||
+ dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin,
|
||||
+ &mlx5_dpll_pins_ops, mdpll);
|
||||
+ dpll_pin_put(mdpll->dpll_pin);
|
||||
+ dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll);
|
||||
+ dpll_device_put(mdpll->dpll);
|
||||
+ kfree(mdpll);
|
||||
+
|
||||
+ mlx5_dpll_synce_status_set(mdev,
|
||||
+ MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING);
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_suspend(struct auxiliary_device *adev, pm_message_t state)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlx5_dpll_resume(struct auxiliary_device *adev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct auxiliary_device_id mlx5_dpll_id_table[] = {
|
||||
+ { .name = MLX5_ADEV_NAME ".dpll", },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(auxiliary, mlx5_dpll_id_table);
|
||||
+
|
||||
+static struct auxiliary_driver mlx5_dpll_driver = {
|
||||
+ .name = "dpll",
|
||||
+ .probe = mlx5_dpll_probe,
|
||||
+ .remove = mlx5_dpll_remove,
|
||||
+ .suspend = mlx5_dpll_suspend,
|
||||
+ .resume = mlx5_dpll_resume,
|
||||
+ .id_table = mlx5_dpll_id_table,
|
||||
+};
|
||||
+
|
||||
+static int __init mlx5_dpll_init(void)
|
||||
+{
|
||||
+ return auxiliary_driver_register(&mlx5_dpll_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit mlx5_dpll_exit(void)
|
||||
+{
|
||||
+ auxiliary_driver_unregister(&mlx5_dpll_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(mlx5_dpll_init);
|
||||
+module_exit(mlx5_dpll_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Jiri Pirko <jiri@nvidia.com>");
|
||||
+MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) DPLL driver");
|
||||
+MODULE_LICENSE("Dual BSD/GPL");
|
||||
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
|
||||
index ffb98bc43b2d..8829fc8646e0 100644
|
||||
--- a/include/linux/mlx5/driver.h
|
||||
+++ b/include/linux/mlx5/driver.h
|
||||
@@ -155,6 +155,8 @@ enum {
|
||||
MLX5_REG_MCC = 0x9062,
|
||||
MLX5_REG_MCDA = 0x9063,
|
||||
MLX5_REG_MCAM = 0x907f,
|
||||
+ MLX5_REG_MSECQ = 0x9155,
|
||||
+ MLX5_REG_MSEES = 0x9156,
|
||||
MLX5_REG_MIRC = 0x9162,
|
||||
MLX5_REG_SBCAM = 0xB01F,
|
||||
MLX5_REG_RESOURCE_DUMP = 0xC000,
|
||||
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
|
||||
index 3d1cd726df34..c959a2a654df 100644
|
||||
--- a/include/linux/mlx5/mlx5_ifc.h
|
||||
+++ b/include/linux/mlx5/mlx5_ifc.h
|
||||
@@ -10178,7 +10178,9 @@ struct mlx5_ifc_mcam_access_reg_bits2 {
|
||||
u8 mirc[0x1];
|
||||
u8 regs_97_to_96[0x2];
|
||||
|
||||
- u8 regs_95_to_64[0x20];
|
||||
+ u8 regs_95_to_87[0x09];
|
||||
+ u8 synce_registers[0x2];
|
||||
+ u8 regs_84_to_64[0x15];
|
||||
|
||||
u8 regs_63_to_32[0x20];
|
||||
|
||||
@@ -12558,4 +12560,59 @@ struct mlx5_ifc_modify_page_track_obj_in_bits {
|
||||
struct mlx5_ifc_page_track_bits obj_context;
|
||||
};
|
||||
|
||||
+struct mlx5_ifc_msecq_reg_bits {
|
||||
+ u8 reserved_at_0[0x20];
|
||||
+
|
||||
+ u8 reserved_at_20[0x12];
|
||||
+ u8 network_option[0x2];
|
||||
+ u8 local_ssm_code[0x4];
|
||||
+ u8 local_enhanced_ssm_code[0x8];
|
||||
+
|
||||
+ u8 local_clock_identity[0x40];
|
||||
+
|
||||
+ u8 reserved_at_80[0x180];
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MLX5_MSEES_FIELD_SELECT_ENABLE = BIT(0),
|
||||
+ MLX5_MSEES_FIELD_SELECT_ADMIN_STATUS = BIT(1),
|
||||
+ MLX5_MSEES_FIELD_SELECT_ADMIN_FREQ_MEASURE = BIT(2),
|
||||
+};
|
||||
+
|
||||
+enum mlx5_msees_admin_status {
|
||||
+ MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING = 0x0,
|
||||
+ MLX5_MSEES_ADMIN_STATUS_TRACK = 0x1,
|
||||
+};
|
||||
+
|
||||
+enum mlx5_msees_oper_status {
|
||||
+ MLX5_MSEES_OPER_STATUS_FREE_RUNNING = 0x0,
|
||||
+ MLX5_MSEES_OPER_STATUS_SELF_TRACK = 0x1,
|
||||
+ MLX5_MSEES_OPER_STATUS_OTHER_TRACK = 0x2,
|
||||
+ MLX5_MSEES_OPER_STATUS_HOLDOVER = 0x3,
|
||||
+ MLX5_MSEES_OPER_STATUS_FAIL_HOLDOVER = 0x4,
|
||||
+ MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING = 0x5,
|
||||
+};
|
||||
+
|
||||
+struct mlx5_ifc_msees_reg_bits {
|
||||
+ u8 reserved_at_0[0x8];
|
||||
+ u8 local_port[0x8];
|
||||
+ u8 pnat[0x2];
|
||||
+ u8 lp_msb[0x2];
|
||||
+ u8 reserved_at_14[0xc];
|
||||
+
|
||||
+ u8 field_select[0x20];
|
||||
+
|
||||
+ u8 admin_status[0x4];
|
||||
+ u8 oper_status[0x4];
|
||||
+ u8 ho_acq[0x1];
|
||||
+ u8 reserved_at_49[0xc];
|
||||
+ u8 admin_freq_measure[0x1];
|
||||
+ u8 oper_freq_measure[0x1];
|
||||
+ u8 failure_reason[0x9];
|
||||
+
|
||||
+ u8 frequency_diff[0x20];
|
||||
+
|
||||
+ u8 reserved_at_80[0x180];
|
||||
+};
|
||||
+
|
||||
#endif /* MLX5_IFC_H */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 3d465acb6c1390963cef5bfc5d6fc6c957294104 Mon Sep 17 00:00:00 2001
|
||||
From: Yang Li <yang.lee@linux.alibaba.com>
|
||||
Date: Tue, 19 Sep 2023 09:03:05 +0800
|
||||
Subject: [PATCH 10/46] netdev: Remove unneeded semicolon
|
||||
|
||||
./drivers/dpll/dpll_netlink.c:847:3-4: Unneeded semicolon
|
||||
|
||||
Reported-by: Abaci Robot <abaci@linux.alibaba.com>
|
||||
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6605
|
||||
Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202309190540.RFwfIgO7-lkp@intel.com/
|
||||
Link: https://lore.kernel.org/r/20230919010305.120991-1-yang.lee@linux.alibaba.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit f20161cf51657bf4c85380c0c1c80188a74f168d)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index 764437a0661b..e20daba6896a 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -844,7 +844,7 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
pin_match = pin;
|
||||
- };
|
||||
+ }
|
||||
}
|
||||
if (!pin_match) {
|
||||
NL_SET_ERR_MSG(extack, "not found");
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 44ad8b2bd48e3a01f46e10aebb59e8e0a52dc9b1 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Bulwahn <lukas.bulwahn@gmail.com>
|
||||
Date: Mon, 25 Sep 2023 07:43:05 +0200
|
||||
Subject: [PATCH 11/46] MAINTAINERS: adjust header file entry in DPLL SUBSYSTEM
|
||||
|
||||
Commit 9431063ad323 ("dpll: core: Add DPLL framework base functions") adds
|
||||
the section DPLL SUBSYSTEM in MAINTAINERS and includes a file entry to the
|
||||
non-existing file 'include/net/dpll.h'.
|
||||
|
||||
Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a
|
||||
broken reference. Looking at the file stat of the commit above, this entry
|
||||
clearly intended to refer to 'include/linux/dpll.h'.
|
||||
|
||||
Adjust this header file entry in DPLL SUBSYSTEM.
|
||||
|
||||
Signed-off-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 20f7cce7cf18020cd2b052a6441a7d1623f0e352)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
MAINTAINERS | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 531d44ed1e7b..ba98a1973524 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -6373,7 +6373,7 @@ L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/driver-api/dpll.rst
|
||||
F: drivers/dpll/*
|
||||
-F: include/net/dpll.h
|
||||
+F: include/linux/dpll.h
|
||||
F: include/uapi/linux/dpll.h
|
||||
|
||||
DRBD DRIVER
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,74 +0,0 @@
|
||||
From 28fb3199a16a20f9939236fb7cbd5821046de923 Mon Sep 17 00:00:00 2001
|
||||
From: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Date: Thu, 28 Sep 2023 12:27:07 +0700
|
||||
Subject: [PATCH 12/46] Documentation: dpll: Fix code blocks
|
||||
|
||||
kernel test robot and Stephen Rothwell report htmldocs warnings:
|
||||
|
||||
Documentation/driver-api/dpll.rst:427: WARNING: Error in "code-block" directive:
|
||||
maximum 1 argument(s) allowed, 18 supplied.
|
||||
|
||||
.. code-block:: c
|
||||
<snipped>...
|
||||
Documentation/driver-api/dpll.rst:444: WARNING: Error in "code-block" directive:
|
||||
maximum 1 argument(s) allowed, 21 supplied.
|
||||
|
||||
.. code-block:: c
|
||||
<snipped>...
|
||||
Documentation/driver-api/dpll.rst:474: WARNING: Error in "code-block" directive:
|
||||
maximum 1 argument(s) allowed, 12 supplied.
|
||||
|
||||
.. code-block:: c
|
||||
<snipped>...
|
||||
|
||||
Fix these above by adding missing blank line separator after code-block
|
||||
directive.
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202309180456.lOhxy9gS-lkp@intel.com/
|
||||
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Closes: https://lore.kernel.org/linux-next/20230918131521.155e9e63@canb.auug.org.au/
|
||||
Fixes: dbb291f19393b6 ("dpll: documentation on DPLL subsystem interface")
|
||||
Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Acked-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Tested-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Link: https://lore.kernel.org/r/20230928052708.44820-2-bagasdotme@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 92425d08a60814b4a2e91626f1e24e4fd5fd5c7e)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/driver-api/dpll.rst | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
|
||||
index bb52f1b8c0be..01eb4de86703 100644
|
||||
--- a/Documentation/driver-api/dpll.rst
|
||||
+++ b/Documentation/driver-api/dpll.rst
|
||||
@@ -425,6 +425,7 @@ The simplest implementation is in the OCP TimeCard driver. The ops
|
||||
structures are defined like this:
|
||||
|
||||
.. code-block:: c
|
||||
+
|
||||
static const struct dpll_device_ops dpll_ops = {
|
||||
.lock_status_get = ptp_ocp_dpll_lock_status_get,
|
||||
.mode_get = ptp_ocp_dpll_mode_get,
|
||||
@@ -442,6 +443,7 @@ structures are defined like this:
|
||||
The registration part is then looks like this part:
|
||||
|
||||
.. code-block:: c
|
||||
+
|
||||
clkid = pci_get_dsn(pdev);
|
||||
bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE);
|
||||
if (IS_ERR(bp->dpll)) {
|
||||
@@ -472,6 +474,7 @@ The registration part is then looks like this part:
|
||||
In the error path we have to rewind every allocation in the reverse order:
|
||||
|
||||
.. code-block:: c
|
||||
+
|
||||
while (i) {
|
||||
--i;
|
||||
dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,61 +0,0 @@
|
||||
From d77ae1b7c63966150bf19653579623f532e8cafb Mon Sep 17 00:00:00 2001
|
||||
From: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Date: Thu, 28 Sep 2023 12:27:08 +0700
|
||||
Subject: [PATCH 13/46] Documentation: dpll: wrap DPLL_CMD_PIN_GET output in a
|
||||
code block
|
||||
|
||||
DPLL_CMD_PIN_GET netlink command output for mux-type pins looks ugly
|
||||
with normal paragraph formatting. Format it as a code block instead.
|
||||
|
||||
Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
|
||||
Acked-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Tested-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Link: https://lore.kernel.org/r/20230928052708.44820-3-bagasdotme@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit c8afdc01832943fab030103bd027ce021d26ddcf)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/driver-api/dpll.rst | 26 +++++++++++++-------------
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
|
||||
index 01eb4de86703..69670deb8c4e 100644
|
||||
--- a/Documentation/driver-api/dpll.rst
|
||||
+++ b/Documentation/driver-api/dpll.rst
|
||||
@@ -119,19 +119,19 @@ with.
|
||||
If a pin was registered with multiple parent pins, they behave like a
|
||||
multiple output multiplexer. In this case output of a
|
||||
``DPLL_CMD_PIN_GET`` would contain multiple pin-parent nested
|
||||
-attributes with current state related to each parent, like:
|
||||
-
|
||||
-'pin': [{{
|
||||
- 'clock-id': 282574471561216,
|
||||
- 'module-name': 'ice',
|
||||
- 'capabilities': 4,
|
||||
- 'id': 13,
|
||||
- 'parent-pin': [
|
||||
- {'parent-id': 2, 'state': 'connected'},
|
||||
- {'parent-id': 3, 'state': 'disconnected'}
|
||||
- ],
|
||||
- 'type': 'synce-eth-port'
|
||||
- }}]
|
||||
+attributes with current state related to each parent, like::
|
||||
+
|
||||
+ 'pin': [{{
|
||||
+ 'clock-id': 282574471561216,
|
||||
+ 'module-name': 'ice',
|
||||
+ 'capabilities': 4,
|
||||
+ 'id': 13,
|
||||
+ 'parent-pin': [
|
||||
+ {'parent-id': 2, 'state': 'connected'},
|
||||
+ {'parent-id': 3, 'state': 'disconnected'}
|
||||
+ ],
|
||||
+ 'type': 'synce-eth-port'
|
||||
+ }}]
|
||||
|
||||
Only one child pin can provide its signal to the parent MUX-type pin at
|
||||
a time, the selection is done by requesting change of a child pin state
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,54 +0,0 @@
|
||||
From a04c89a000d99aef7d7e9ba9180cd70789250dee Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Wed, 16 Aug 2023 17:00:54 -0700
|
||||
Subject: [PATCH 14/46] ice: remove ICE_F_PTP_EXTTS feature flag
|
||||
|
||||
The ICE_F_PTP_EXTTS feature flag is ostensibly intended to support checking
|
||||
whether the device supports external timestamp pins. It is only checked in
|
||||
E810-specific code flows, and is enabled for all E810-based devices. E822
|
||||
and E823 flows unconditionally enable external timestamp support.
|
||||
|
||||
This makes the feature flag meaningless, as it is always enabled. Just
|
||||
unconditionally enable support for external timestamp pins and remove this
|
||||
unnecessary flag.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 12a5a28b565bfb5abab7ab17fe3c6a3c02a2affe)
|
||||
[jma: Adjust the code for context changes, because https://git.yoctoproject.org/
|
||||
linux-yocto/commit/?h=v6.6.40&id=0d1b22367ec2 already included the part
|
||||
of code.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 1 -
|
||||
2 files changed, 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 537d5939c28e..b9cd0113b859 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -199,7 +199,6 @@ extern const char ice_drv_ver[];
|
||||
|
||||
enum ice_feature {
|
||||
ICE_F_DSCP,
|
||||
- ICE_F_PTP_EXTTS,
|
||||
ICE_F_PHY_RCLK,
|
||||
ICE_F_SMA_CTRL,
|
||||
ICE_F_CGU,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 2847fc17d224..f7a0dd570b34 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -4007,7 +4007,6 @@ void ice_init_feature_support(struct ice_pf *pf)
|
||||
case ICE_DEV_ID_E810_XXV_QSFP:
|
||||
case ICE_DEV_ID_E810_XXV_SFP:
|
||||
ice_set_feature_support(pf, ICE_F_DSCP);
|
||||
- ice_set_feature_support(pf, ICE_F_PTP_EXTTS);
|
||||
if (ice_is_phy_rclk_present(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_PHY_RCLK);
|
||||
/* If we don't own the timer - don't enable other caps */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 24aee90e5bf889b197efdd2b0bdb3676d68c7ded Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Wed, 16 Aug 2023 17:00:58 -0700
|
||||
Subject: [PATCH 15/46] ice: check netlist before enabling ICE_F_GNSS
|
||||
|
||||
Similar to the change made for ICE_F_SMA_CTRL, check the netlist before
|
||||
enabling support for ICE_F_GNSS. This ensures that the driver only enables
|
||||
the GNSS feature on devices which actually have the feature enabled in the
|
||||
firmware device configuration.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 89776a6a702e9b7bf9ae1691621f9699b2c18cc1)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 15 +++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_gnss.c | 3 +++
|
||||
4 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index aa532bfa1957..353ac55bdb9d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -1394,6 +1394,7 @@ struct ice_aqc_link_topo_params {
|
||||
#define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM 8
|
||||
#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL 9
|
||||
#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX 10
|
||||
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_GPS 11
|
||||
#define ICE_AQC_LINK_TOPO_NODE_CTX_S 4
|
||||
#define ICE_AQC_LINK_TOPO_NODE_CTX_M \
|
||||
(0xF << ICE_AQC_LINK_TOPO_NODE_CTX_S)
|
||||
@@ -1436,6 +1437,7 @@ struct ice_aqc_get_link_topo {
|
||||
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY 0x30
|
||||
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_C827 0x31
|
||||
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX 0x47
|
||||
+#define ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS 0x48
|
||||
u8 rsvd[9];
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 089558b3b1ae..8f31ae449948 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -2764,6 +2764,21 @@ bool ice_is_pf_c827(struct ice_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_is_gps_in_netlist
|
||||
+ * @hw: pointer to the hw struct
|
||||
+ *
|
||||
+ * Check if the GPS generic device is present in the netlist
|
||||
+ */
|
||||
+bool ice_is_gps_in_netlist(struct ice_hw *hw)
|
||||
+{
|
||||
+ if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_aq_list_caps - query function/device capabilities
|
||||
* @hw: pointer to the HW struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 74e44b450de4..47a75651ca38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -93,6 +93,7 @@ ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
|
||||
struct ice_aqc_get_phy_caps_data *caps,
|
||||
struct ice_sq_cd *cd);
|
||||
bool ice_is_pf_c827(struct ice_hw *hw);
|
||||
+bool ice_is_gps_in_netlist(struct ice_hw *hw);
|
||||
int
|
||||
ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
|
||||
u16 *node_handle);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c
|
||||
index 75c9de675f20..c8ea1af51ad3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_gnss.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_gnss.c
|
||||
@@ -389,6 +389,9 @@ bool ice_gnss_is_gps_present(struct ice_hw *hw)
|
||||
if (!hw->func_caps.ts_func_info.src_tmr_owned)
|
||||
return false;
|
||||
|
||||
+ if (!ice_is_gps_in_netlist(hw))
|
||||
+ return false;
|
||||
+
|
||||
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
||||
if (ice_is_e810t(hw)) {
|
||||
int err;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,347 +0,0 @@
|
||||
From 97de9017c0311e01f354af4f70edb94d7dc58f80 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 2 Oct 2023 11:51:32 -0700
|
||||
Subject: [PATCH 16/46] ice: fix linking when CONFIG_PTP_1588_CLOCK=n
|
||||
|
||||
The recent support for DPLL introduced by commit 8a3a565ff210 ("ice: add
|
||||
admin commands to access cgu configuration") and commit d7999f5ea64b ("ice:
|
||||
implement dpll interface to control cgu") broke linking the ice driver if
|
||||
CONFIG_PTP_1588_CLOCK=n:
|
||||
|
||||
ld: vmlinux.o: in function `ice_init_feature_support':
|
||||
(.text+0x8702b8): undefined reference to `ice_is_phy_rclk_present'
|
||||
ld: (.text+0x8702cd): undefined reference to `ice_is_cgu_present'
|
||||
ld: (.text+0x8702d9): undefined reference to `ice_is_clock_mux_present_e810t'
|
||||
ld: vmlinux.o: in function `ice_dpll_init_info_direct_pins':
|
||||
ice_dpll.c:(.text+0x894167): undefined reference to `ice_cgu_get_pin_freq_supp'
|
||||
ld: ice_dpll.c:(.text+0x894197): undefined reference to `ice_cgu_get_pin_name'
|
||||
ld: ice_dpll.c:(.text+0x8941a8): undefined reference to `ice_cgu_get_pin_type'
|
||||
ld: vmlinux.o: in function `ice_dpll_update_state':
|
||||
ice_dpll.c:(.text+0x894494): undefined reference to `ice_get_cgu_state'
|
||||
ld: vmlinux.o: in function `ice_dpll_init':
|
||||
(.text+0x8953d5): undefined reference to `ice_get_cgu_rclk_pin_info'
|
||||
|
||||
The first commit broke things by calling functions in
|
||||
ice_init_feature_support that are compiled as part of ice_ptp_hw.o,
|
||||
including:
|
||||
|
||||
* ice_is_phy_rclk_present
|
||||
* ice_is_clock_mux_present_e810t
|
||||
* ice_is_cgU_present
|
||||
|
||||
The second commit continued the break by calling several CGU functions
|
||||
defined in ice_ptp_hw.c in the DPLL code.
|
||||
Because the ice_dpll.c file is compiled unconditionally, it will not
|
||||
link when CONFIG_PTP_1588_CLOCK=n.
|
||||
|
||||
It might be possible to break this dependency and expose those functions
|
||||
without CONFIG_PTP_1588_CLOCK, but that is not clear to me.
|
||||
|
||||
For the DPLL case, simply compile ice_dpll.o only when we have
|
||||
CONFIG_PTP_1588_CLOCK. Add stub no-op implementation of ice_dpll_init() and
|
||||
ice_dpll_uninit() when CONFIG_PTP_1588_CLOCK=n into ice_dpll.h
|
||||
|
||||
The other functions are part of checking the netlist to see if hardware
|
||||
features are enabled. These checks don't really belong in ice_ptp_hw.c, and
|
||||
make more sense as part of the ice_common.c file. We already have
|
||||
ice_is_gps_in_netlist() in ice_common.c which is doing a similar check.
|
||||
|
||||
Move the functions into ice_common.c and rename them to have the similar
|
||||
postfix of "in_netlist()" to be more expressive of what they are actually
|
||||
checking.
|
||||
|
||||
This also makes the ice_find_netlist_node only called from within
|
||||
ice_common.c, so its safe to mark it static and stop declaring it in the
|
||||
ice_common.h header as well.
|
||||
|
||||
Fixes: 8a3a565ff210 ("ice: add admin commands to access cgu configuration")
|
||||
Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202309191214.TaYEct4H-lkp@intel.com
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Simon Horman <horms@kernel.org> # build-tested
|
||||
Link: https://lore.kernel.org/r/20231002185132.1575271-1-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 91e43ca0090b5fd59302c3d150835299785f30ea)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/Makefile | 5 +-
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 66 ++++++++++++++++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 6 +-
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.h | 6 +-
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 6 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 66 ---------------------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 3 -
|
||||
7 files changed, 76 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile
|
||||
index 00806ddf5bf0..0679907980f7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/Makefile
|
||||
+++ b/drivers/net/ethernet/intel/ice/Makefile
|
||||
@@ -34,8 +34,7 @@ ice-y := ice_main.o \
|
||||
ice_lag.o \
|
||||
ice_ethtool.o \
|
||||
ice_repr.o \
|
||||
- ice_tc_lib.o \
|
||||
- ice_dpll.o
|
||||
+ ice_tc_lib.o
|
||||
ice-$(CONFIG_PCI_IOV) += \
|
||||
ice_sriov.o \
|
||||
ice_virtchnl.o \
|
||||
@@ -44,7 +43,7 @@ ice-$(CONFIG_PCI_IOV) += \
|
||||
ice_vf_mbx.o \
|
||||
ice_vf_vsi_vlan_ops.o \
|
||||
ice_vf_lib.o
|
||||
-ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o
|
||||
+ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o
|
||||
ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
|
||||
ice-$(CONFIG_RFS_ACCEL) += ice_arfs.o
|
||||
ice-$(CONFIG_XDP_SOCKETS) += ice_xsk.o
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 8f31ae449948..a1f1f037f327 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -477,9 +477,8 @@ ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
|
||||
* netlist. When found ICE_SUCCESS is returned, ICE_ERR_DOES_NOT_EXIST
|
||||
* otherwise. If node_handle provided, it would be set to found node handle.
|
||||
*/
|
||||
-int
|
||||
-ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
|
||||
- u16 *node_handle)
|
||||
+static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx,
|
||||
+ u8 node_part_number, u16 *node_handle)
|
||||
{
|
||||
struct ice_aqc_get_link_topo cmd;
|
||||
u8 rec_node_part_number;
|
||||
@@ -2764,6 +2763,67 @@ bool ice_is_pf_c827(struct ice_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_is_phy_rclk_in_netlist
|
||||
+ * @hw: pointer to the hw struct
|
||||
+ *
|
||||
+ * Check if the PHY Recovered Clock device is present in the netlist
|
||||
+ */
|
||||
+bool ice_is_phy_rclk_in_netlist(struct ice_hw *hw)
|
||||
+{
|
||||
+ if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_C827, NULL) &&
|
||||
+ ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY, NULL))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_is_clock_mux_in_netlist
|
||||
+ * @hw: pointer to the hw struct
|
||||
+ *
|
||||
+ * Check if the Clock Multiplexer device is present in the netlist
|
||||
+ */
|
||||
+bool ice_is_clock_mux_in_netlist(struct ice_hw *hw)
|
||||
+{
|
||||
+ if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX,
|
||||
+ NULL))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_is_cgu_in_netlist - check for CGU presence
|
||||
+ * @hw: pointer to the hw struct
|
||||
+ *
|
||||
+ * Check if the Clock Generation Unit (CGU) device is present in the netlist.
|
||||
+ * Save the CGU part number in the hw structure for later use.
|
||||
+ * Return:
|
||||
+ * * true - cgu is present
|
||||
+ * * false - cgu is not present
|
||||
+ */
|
||||
+bool ice_is_cgu_in_netlist(struct ice_hw *hw)
|
||||
+{
|
||||
+ if (!ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032,
|
||||
+ NULL)) {
|
||||
+ hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032;
|
||||
+ return true;
|
||||
+ } else if (!ice_find_netlist_node(hw,
|
||||
+ ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384,
|
||||
+ NULL)) {
|
||||
+ hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_is_gps_in_netlist
|
||||
* @hw: pointer to the hw struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 47a75651ca38..7a966a0c224f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -93,11 +93,11 @@ ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
|
||||
struct ice_aqc_get_phy_caps_data *caps,
|
||||
struct ice_sq_cd *cd);
|
||||
bool ice_is_pf_c827(struct ice_hw *hw);
|
||||
+bool ice_is_phy_rclk_in_netlist(struct ice_hw *hw);
|
||||
+bool ice_is_clock_mux_in_netlist(struct ice_hw *hw);
|
||||
+bool ice_is_cgu_in_netlist(struct ice_hw *hw);
|
||||
bool ice_is_gps_in_netlist(struct ice_hw *hw);
|
||||
int
|
||||
-ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
|
||||
- u16 *node_handle);
|
||||
-int
|
||||
ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
|
||||
u8 *node_part_number, u16 *node_handle);
|
||||
int
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
index 9c524c4bdfd7..2dfe764b81e1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
@@ -97,8 +97,12 @@ struct ice_dplls {
|
||||
s32 output_phase_adj_max;
|
||||
};
|
||||
|
||||
+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
||||
void ice_dpll_init(struct ice_pf *pf);
|
||||
-
|
||||
void ice_dpll_deinit(struct ice_pf *pf);
|
||||
+#else
|
||||
+static inline void ice_dpll_init(struct ice_pf *pf) { }
|
||||
+static inline void ice_dpll_deinit(struct ice_pf *pf) { }
|
||||
+#endif
|
||||
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index f7a0dd570b34..632091487413 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -4007,14 +4007,14 @@ void ice_init_feature_support(struct ice_pf *pf)
|
||||
case ICE_DEV_ID_E810_XXV_QSFP:
|
||||
case ICE_DEV_ID_E810_XXV_SFP:
|
||||
ice_set_feature_support(pf, ICE_F_DSCP);
|
||||
- if (ice_is_phy_rclk_present(&pf->hw))
|
||||
+ if (ice_is_phy_rclk_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_PHY_RCLK);
|
||||
/* If we don't own the timer - don't enable other caps */
|
||||
if (!pf->hw.func_caps.ts_func_info.src_tmr_owned)
|
||||
break;
|
||||
- if (ice_is_cgu_present(&pf->hw))
|
||||
+ if (ice_is_cgu_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_CGU);
|
||||
- if (ice_is_clock_mux_present_e810t(&pf->hw))
|
||||
+ if (ice_is_clock_mux_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_SMA_CTRL);
|
||||
if (ice_gnss_is_gps_present(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_GNSS);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 00ddf37296cc..8ccd633d9c2e 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -3479,45 +3479,6 @@ int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
return ice_clear_phy_tstamp_e822(hw, block, idx);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_is_phy_rclk_present - check recovered clk presence
|
||||
- * @hw: pointer to the hw struct
|
||||
- *
|
||||
- * Check if the PHY Recovered Clock device is present in the netlist
|
||||
- * Return:
|
||||
- * * true - device found in netlist
|
||||
- * * false - device not found
|
||||
- */
|
||||
-bool ice_is_phy_rclk_present(struct ice_hw *hw)
|
||||
-{
|
||||
- if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
- ICE_AQC_GET_LINK_TOPO_NODE_NR_C827, NULL) &&
|
||||
- ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
- ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY, NULL))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_is_clock_mux_present_e810t
|
||||
- * @hw: pointer to the hw struct
|
||||
- *
|
||||
- * Check if the Clock Multiplexer device is present in the netlist
|
||||
- * Return:
|
||||
- * * true - device found in netlist
|
||||
- * * false - device not found
|
||||
- */
|
||||
-bool ice_is_clock_mux_present_e810t(struct ice_hw *hw)
|
||||
-{
|
||||
- if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX,
|
||||
- ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX,
|
||||
- NULL))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_get_pf_c827_idx - find and return the C827 index for the current pf
|
||||
* @hw: pointer to the hw struct
|
||||
@@ -3618,33 +3579,6 @@ int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
tstamp_ready);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_is_cgu_present - check for CGU presence
|
||||
- * @hw: pointer to the hw struct
|
||||
- *
|
||||
- * Check if the Clock Generation Unit (CGU) device is present in the netlist
|
||||
- * Return:
|
||||
- * * true - cgu is present
|
||||
- * * false - cgu is not present
|
||||
- */
|
||||
-bool ice_is_cgu_present(struct ice_hw *hw)
|
||||
-{
|
||||
- if (!ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
- ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032,
|
||||
- NULL)) {
|
||||
- hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032;
|
||||
- return true;
|
||||
- } else if (!ice_find_netlist_node(hw,
|
||||
- ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
|
||||
- ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384,
|
||||
- NULL)) {
|
||||
- hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384;
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_cgu_get_pin_desc_e823 - get pin description array
|
||||
* @hw: pointer to the hw struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 594cc6875a95..d81e77386b54 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -270,10 +270,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
|
||||
int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
|
||||
int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
|
||||
bool ice_is_pca9575_present(struct ice_hw *hw);
|
||||
-bool ice_is_phy_rclk_present(struct ice_hw *hw);
|
||||
-bool ice_is_clock_mux_present_e810t(struct ice_hw *hw);
|
||||
int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx);
|
||||
-bool ice_is_cgu_present(struct ice_hw *hw);
|
||||
enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
|
||||
struct dpll_pin_frequency *
|
||||
ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,48 +0,0 @@
|
||||
From c5af08d5854c37d5c12bc048e83024e552a3c438 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Chancellor <nathan@kernel.org>
|
||||
Date: Mon, 2 Oct 2023 13:55:20 -0700
|
||||
Subject: [PATCH 17/46] ptp: Fix type of mode parameter in
|
||||
ptp_ocp_dpll_mode_get()
|
||||
|
||||
When building with -Wincompatible-function-pointer-types-strict, a
|
||||
warning designed to catch potential kCFI failures at build time rather
|
||||
than run time due to incorrect function pointer types, there is a
|
||||
warning due to a mismatch between the type of the mode parameter in
|
||||
ptp_ocp_dpll_mode_get() vs. what the function pointer prototype for
|
||||
->mode_get() in 'struct dpll_device_ops' expects.
|
||||
|
||||
drivers/ptp/ptp_ocp.c:4353:14: error: incompatible function pointer types initializing 'int (*)(const struct dpll_device *, void *, enum dpll_mode *, struct netlink_ext_ack *)' with an expression of type 'int (const struct dpll_device *, void *, u32 *, struct netlink_ext_ack *)' (aka 'int (const struct dpll_device *, void *, unsigned int *, struct netlink_ext_ack *)') [-Werror,-Wincompatible-function-pointer-types-strict]
|
||||
4353 | .mode_get = ptp_ocp_dpll_mode_get,
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
1 error generated.
|
||||
|
||||
Change the type of the mode parameter in ptp_ocp_dpll_mode_get() to
|
||||
clear up the warning and avoid kCFI failures at run time.
|
||||
|
||||
Fixes: 09eeb3aecc6c ("ptp_ocp: implement DPLL ops")
|
||||
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231002-net-wifpts-dpll_mode_get-v1-1-a356a16413cf@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 26cc115d590c70e66d8399f39e4d9973d26439bc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/ptp/ptp_ocp.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
|
||||
index 41eaffcae462..30a7d08ef912 100644
|
||||
--- a/drivers/ptp/ptp_ocp.c
|
||||
+++ b/drivers/ptp/ptp_ocp.c
|
||||
@@ -4254,7 +4254,7 @@ static int ptp_ocp_dpll_state_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
}
|
||||
|
||||
static int ptp_ocp_dpll_mode_get(const struct dpll_device *dpll, void *priv,
|
||||
- u32 *mode, struct netlink_ext_ack *extack)
|
||||
+ enum dpll_mode *mode, struct netlink_ext_ack *extack)
|
||||
{
|
||||
*mode = DPLL_MODE_AUTOMATIC;
|
||||
return 0;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 3455575d5b1777e520c1b7157d5d6cca3b5bb30b Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Chancellor <nathan@kernel.org>
|
||||
Date: Mon, 2 Oct 2023 13:55:21 -0700
|
||||
Subject: [PATCH 18/46] mlx5: Fix type of mode parameter in
|
||||
mlx5_dpll_device_mode_get()
|
||||
|
||||
When building with -Wincompatible-function-pointer-types-strict, a
|
||||
warning designed to catch potential kCFI failures at build time rather
|
||||
than run time due to incorrect function pointer types, there is a
|
||||
warning due to a mismatch between the type of the mode parameter in
|
||||
mlx5_dpll_device_mode_get() vs. what the function pointer prototype for
|
||||
->mode_get() in 'struct dpll_device_ops' expects.
|
||||
|
||||
drivers/net/ethernet/mellanox/mlx5/core/dpll.c:141:14: error: incompatible function pointer types initializing 'int (*)(const struct dpll_device *, void *, enum dpll_mode *, struct netlink_ext_ack *)' with an expression of type 'int (const struct dpll_device *, void *, u32 *, struct netlink_ext_ack *)' (aka 'int (const struct dpll_device *, void *, unsigned int *, struct netlink_ext_ack *)') [-Werror,-Wincompatible-function-pointer-types-strict]
|
||||
141 | .mode_get = mlx5_dpll_device_mode_get,
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
1 error generated.
|
||||
|
||||
Change the type of the mode parameter in mlx5_dpll_device_mode_get() to
|
||||
clear up the warning and avoid kCFI failures at run time.
|
||||
|
||||
Fixes: 496fd0a26bbf ("mlx5: Implement SyncE support using DPLL infrastructure")
|
||||
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231002-net-wifpts-dpll_mode_get-v1-2-a356a16413cf@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit f4ecb3d44a117b16029485325bda1bc98c26de36)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/dpll.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
index 74f0c7867120..2cd81bb32c66 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
|
||||
@@ -121,8 +121,8 @@ static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll,
|
||||
}
|
||||
|
||||
static int mlx5_dpll_device_mode_get(const struct dpll_device *dpll,
|
||||
- void *priv,
|
||||
- u32 *mode, struct netlink_ext_ack *extack)
|
||||
+ void *priv, enum dpll_mode *mode,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
{
|
||||
*mode = DPLL_MODE_MANUAL;
|
||||
return 0;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,177 +0,0 @@
|
||||
From a90e48a7c15fd31fe0a74ef674d3c483e4138e64 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 6 Oct 2023 13:44:35 +0200
|
||||
Subject: [PATCH 19/46] tools: ynl-gen: lift type requirement for attribute
|
||||
subsets
|
||||
|
||||
In case an attribute is used in a subset, the type has to be currently
|
||||
specified. As the attribute is already defined in the original set, this
|
||||
is a redundant information in yaml file, moreover, may lead to
|
||||
inconsistencies.
|
||||
|
||||
Example:
|
||||
attribute-sets:
|
||||
...
|
||||
name: pin
|
||||
enum-name: dpll_a_pin
|
||||
attributes:
|
||||
...
|
||||
-
|
||||
name: parent-id
|
||||
type: u32
|
||||
...
|
||||
-
|
||||
name: pin-parent-device
|
||||
subset-of: pin
|
||||
attributes:
|
||||
-
|
||||
name: parent-id
|
||||
type: u32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
Remove the requirement from schema files to specify the "type" for
|
||||
attribute subsets.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231006114436.1725425-2-jiri@resnulli.us
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit e18f3dc2beaa5055e27334cd2d8b492bc3e9b3a4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/netlink/genetlink-c.yaml | 14 +++++++++++++-
|
||||
Documentation/netlink/genetlink-legacy.yaml | 14 +++++++++++++-
|
||||
Documentation/netlink/genetlink.yaml | 14 +++++++++++++-
|
||||
Documentation/netlink/netlink-raw.yaml | 14 +++++++++++++-
|
||||
4 files changed, 52 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
|
||||
index 9806c44f604c..32736b2d8ae8 100644
|
||||
--- a/Documentation/netlink/genetlink-c.yaml
|
||||
+++ b/Documentation/netlink/genetlink-c.yaml
|
||||
@@ -142,7 +142,7 @@ properties:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
- required: [ name, type ]
|
||||
+ required: [ name ]
|
||||
additionalProperties: False
|
||||
properties:
|
||||
name:
|
||||
@@ -215,6 +215,18 @@ properties:
|
||||
not:
|
||||
required: [ name-prefix ]
|
||||
|
||||
+ # type property is only required if not in subset definition
|
||||
+ if:
|
||||
+ properties:
|
||||
+ subset-of:
|
||||
+ not:
|
||||
+ type: string
|
||||
+ then:
|
||||
+ properties:
|
||||
+ attributes:
|
||||
+ items:
|
||||
+ required: [ type ]
|
||||
+
|
||||
operations:
|
||||
description: Operations supported by the protocol.
|
||||
type: object
|
||||
diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml
|
||||
index 12a0a045605d..25fe1379b180 100644
|
||||
--- a/Documentation/netlink/genetlink-legacy.yaml
|
||||
+++ b/Documentation/netlink/genetlink-legacy.yaml
|
||||
@@ -180,7 +180,7 @@ properties:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
- required: [ name, type ]
|
||||
+ required: [ name ]
|
||||
additionalProperties: False
|
||||
properties:
|
||||
name:
|
||||
@@ -254,6 +254,18 @@ properties:
|
||||
not:
|
||||
required: [ name-prefix ]
|
||||
|
||||
+ # type property is only required if not in subset definition
|
||||
+ if:
|
||||
+ properties:
|
||||
+ subset-of:
|
||||
+ not:
|
||||
+ type: string
|
||||
+ then:
|
||||
+ properties:
|
||||
+ attributes:
|
||||
+ items:
|
||||
+ required: [ type ]
|
||||
+
|
||||
operations:
|
||||
description: Operations supported by the protocol.
|
||||
type: object
|
||||
diff --git a/Documentation/netlink/genetlink.yaml b/Documentation/netlink/genetlink.yaml
|
||||
index 3d338c48bf21..6ea1c947ce51 100644
|
||||
--- a/Documentation/netlink/genetlink.yaml
|
||||
+++ b/Documentation/netlink/genetlink.yaml
|
||||
@@ -115,7 +115,7 @@ properties:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
- required: [ name, type ]
|
||||
+ required: [ name ]
|
||||
additionalProperties: False
|
||||
properties:
|
||||
name:
|
||||
@@ -184,6 +184,18 @@ properties:
|
||||
not:
|
||||
required: [ name-prefix ]
|
||||
|
||||
+ # type property is only required if not in subset definition
|
||||
+ if:
|
||||
+ properties:
|
||||
+ subset-of:
|
||||
+ not:
|
||||
+ type: string
|
||||
+ then:
|
||||
+ properties:
|
||||
+ attributes:
|
||||
+ items:
|
||||
+ required: [ type ]
|
||||
+
|
||||
operations:
|
||||
description: Operations supported by the protocol.
|
||||
type: object
|
||||
diff --git a/Documentation/netlink/netlink-raw.yaml b/Documentation/netlink/netlink-raw.yaml
|
||||
index 896797876414..d976851b80f8 100644
|
||||
--- a/Documentation/netlink/netlink-raw.yaml
|
||||
+++ b/Documentation/netlink/netlink-raw.yaml
|
||||
@@ -187,7 +187,7 @@ properties:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
- required: [ name, type ]
|
||||
+ required: [ name ]
|
||||
additionalProperties: False
|
||||
properties:
|
||||
name:
|
||||
@@ -261,6 +261,18 @@ properties:
|
||||
not:
|
||||
required: [ name-prefix ]
|
||||
|
||||
+ # type property is only required if not in subset definition
|
||||
+ if:
|
||||
+ properties:
|
||||
+ subset-of:
|
||||
+ not:
|
||||
+ type: string
|
||||
+ then:
|
||||
+ properties:
|
||||
+ attributes:
|
||||
+ items:
|
||||
+ required: [ type ]
|
||||
+
|
||||
operations:
|
||||
description: Operations supported by the protocol.
|
||||
type: object
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,107 +0,0 @@
|
||||
From c6f3d22b1cdb4abcf53e2901974361bac7310635 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Wed, 11 Oct 2023 12:12:32 +0200
|
||||
Subject: [PATCH 20/46] dpll: docs: add support for pin signal phase
|
||||
offset/adjust
|
||||
|
||||
Add documentation on:
|
||||
- measurement of phase of signal between pin and dpll
|
||||
- adjustment of pin signal phase
|
||||
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 27ed30d1f861315719bd8c2b2e81576d71750331)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/driver-api/dpll.rst | 53 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 52 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
|
||||
index 69670deb8c4e..e3d593841aa7 100644
|
||||
--- a/Documentation/driver-api/dpll.rst
|
||||
+++ b/Documentation/driver-api/dpll.rst
|
||||
@@ -173,6 +173,47 @@ in order to configure active input of a MUX-type pin, the user needs to
|
||||
request desired pin state of the child pin on the parent pin,
|
||||
as described in the ``MUX-type pins`` chapter.
|
||||
|
||||
+Phase offset measurement and adjustment
|
||||
+========================================
|
||||
+
|
||||
+Device may provide ability to measure a phase difference between signals
|
||||
+on a pin and its parent dpll device. If pin-dpll phase offset measurement
|
||||
+is supported, it shall be provided with ``DPLL_A_PIN_PHASE_OFFSET``
|
||||
+attribute for each parent dpll device.
|
||||
+
|
||||
+Device may also provide ability to adjust a signal phase on a pin.
|
||||
+If pin phase adjustment is supported, minimal and maximal values that pin
|
||||
+handle shall be provide to the user on ``DPLL_CMD_PIN_GET`` respond
|
||||
+with ``DPLL_A_PIN_PHASE_ADJUST_MIN`` and ``DPLL_A_PIN_PHASE_ADJUST_MAX``
|
||||
+attributes. Configured phase adjust value is provided with
|
||||
+``DPLL_A_PIN_PHASE_ADJUST`` attribute of a pin, and value change can be
|
||||
+requested with the same attribute with ``DPLL_CMD_PIN_SET`` command.
|
||||
+
|
||||
+ =============================== ======================================
|
||||
+ ``DPLL_A_PIN_ID`` configured pin id
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase adjustment
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase adjustment
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase
|
||||
+ adjustment on parent dpll device
|
||||
+ ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting
|
||||
+ configuration on given parent dpll
|
||||
+ device
|
||||
+ ``DPLL_A_PIN_PARENT_ID`` parent dpll device id
|
||||
+ ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference
|
||||
+ between a pin and parent dpll device
|
||||
+ =============================== ======================================
|
||||
+
|
||||
+All phase related values are provided in pico seconds, which represents
|
||||
+time difference between signals phase. The negative value means that
|
||||
+phase of signal on pin is earlier in time than dpll's signal. Positive
|
||||
+value means that phase of signal on pin is later in time than signal of
|
||||
+a dpll.
|
||||
+
|
||||
+Phase adjust (also min and max) values are integers, but measured phase
|
||||
+offset values are fractional with 3-digit decimal places and shell be
|
||||
+divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and
|
||||
+modulo divided to get fractional part.
|
||||
+
|
||||
Configuration commands group
|
||||
============================
|
||||
|
||||
@@ -263,6 +304,12 @@ according to attribute purpose.
|
||||
frequencies
|
||||
``DPLL_A_PIN_ANY_FREQUENCY_MIN`` attr minimum value of frequency
|
||||
``DPLL_A_PIN_ANY_FREQUENCY_MAX`` attr maximum value of frequency
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase
|
||||
+ adjustment
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase
|
||||
+ adjustment
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase
|
||||
+ adjustment on parent device
|
||||
``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent device
|
||||
the pin is connected with
|
||||
``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id
|
||||
@@ -270,8 +317,10 @@ according to attribute purpose.
|
||||
dpll device
|
||||
``DPLL_A_PIN_STATE`` attr state of pin on the parent
|
||||
dpll device
|
||||
- ``DPLL_A_PIN_DIRECTION`` attr direction of a pin on the
|
||||
+ ``DPLL_A_PIN_DIRECTION`` attr direction of a pin on the
|
||||
parent dpll device
|
||||
+ ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference
|
||||
+ between a pin and parent dpll
|
||||
``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin
|
||||
the pin is connected with
|
||||
``DPLL_A_PIN_PARENT_ID`` attr parent pin id
|
||||
@@ -284,6 +333,8 @@ according to attribute purpose.
|
||||
``DPLL_CMD_PIN_SET`` command to set pins configuration
|
||||
``DPLL_A_PIN_ID`` attr unique a pin ID
|
||||
``DPLL_A_PIN_FREQUENCY`` attr requested frequency of a pin
|
||||
+ ``DPLL_A_PIN_PHASE_ADJUST`` attr requested value of phase
|
||||
+ adjustment on parent device
|
||||
``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent dpll
|
||||
device configuration request
|
||||
``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,141 +0,0 @@
|
||||
From 99c6ac37b209ab9c87c25d5b81318faa96eb47fb Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 6 Oct 2023 13:44:36 +0200
|
||||
Subject: [PATCH 21/46] netlink: specs: remove redundant type keys from
|
||||
attributes in subsets
|
||||
|
||||
No longer needed to define type for subset attributes. Remove those.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231006114436.1725425-3-jiri@resnulli.us
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 7049fd5df78cf0e7463d8e8bb41db60b6762df6c)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/netlink/specs/devlink.yaml | 10 ----------
|
||||
Documentation/netlink/specs/dpll.yaml | 8 --------
|
||||
Documentation/netlink/specs/ethtool.yaml | 3 ---
|
||||
3 files changed, 21 deletions(-)
|
||||
|
||||
diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
|
||||
index 065661acb878..dec130d2507c 100644
|
||||
--- a/Documentation/netlink/specs/devlink.yaml
|
||||
+++ b/Documentation/netlink/specs/devlink.yaml
|
||||
@@ -199,54 +199,44 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: reload-stats
|
||||
- type: nest
|
||||
-
|
||||
name: remote-reload-stats
|
||||
- type: nest
|
||||
-
|
||||
name: dl-reload-stats
|
||||
subset-of: devlink
|
||||
attributes:
|
||||
-
|
||||
name: reload-action-info
|
||||
- type: nest
|
||||
-
|
||||
name: dl-reload-act-info
|
||||
subset-of: devlink
|
||||
attributes:
|
||||
-
|
||||
name: reload-action
|
||||
- type: u8
|
||||
-
|
||||
name: reload-action-stats
|
||||
- type: nest
|
||||
-
|
||||
name: dl-reload-act-stats
|
||||
subset-of: devlink
|
||||
attributes:
|
||||
-
|
||||
name: reload-stats-entry
|
||||
- type: nest
|
||||
-
|
||||
name: dl-reload-stats-entry
|
||||
subset-of: devlink
|
||||
attributes:
|
||||
-
|
||||
name: reload-stats-limit
|
||||
- type: u8
|
||||
-
|
||||
name: reload-stats-value
|
||||
- type: u32
|
||||
-
|
||||
name: dl-info-version
|
||||
subset-of: devlink
|
||||
attributes:
|
||||
-
|
||||
name: info-version-name
|
||||
- type: string
|
||||
-
|
||||
name: info-version-value
|
||||
- type: string
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
|
||||
index 8b86b28b47a6..1c1b53136c7b 100644
|
||||
--- a/Documentation/netlink/specs/dpll.yaml
|
||||
+++ b/Documentation/netlink/specs/dpll.yaml
|
||||
@@ -278,36 +278,28 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: parent-id
|
||||
- type: u32
|
||||
-
|
||||
name: direction
|
||||
- type: u32
|
||||
-
|
||||
name: prio
|
||||
- type: u32
|
||||
-
|
||||
name: state
|
||||
- type: u32
|
||||
-
|
||||
name: pin-parent-pin
|
||||
subset-of: pin
|
||||
attributes:
|
||||
-
|
||||
name: parent-id
|
||||
- type: u32
|
||||
-
|
||||
name: state
|
||||
- type: u32
|
||||
-
|
||||
name: frequency-range
|
||||
subset-of: pin
|
||||
attributes:
|
||||
-
|
||||
name: frequency-min
|
||||
- type: u64
|
||||
-
|
||||
name: frequency-max
|
||||
- type: u64
|
||||
|
||||
operations:
|
||||
enum-name: dpll_cmd
|
||||
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
|
||||
index 837b565577ca..5c7a65b009b4 100644
|
||||
--- a/Documentation/netlink/specs/ethtool.yaml
|
||||
+++ b/Documentation/netlink/specs/ethtool.yaml
|
||||
@@ -818,13 +818,10 @@ attribute-sets:
|
||||
attributes:
|
||||
-
|
||||
name: hist-bkt-low
|
||||
- type: u32
|
||||
-
|
||||
name: hist-bkt-hi
|
||||
- type: u32
|
||||
-
|
||||
name: hist-val
|
||||
- type: u64
|
||||
-
|
||||
name: stats
|
||||
attributes:
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,174 +0,0 @@
|
||||
From 304d5b650378394e20c1f65af6a4898c49f95e12 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Wed, 11 Oct 2023 12:12:33 +0200
|
||||
Subject: [PATCH 22/46] dpll: spec: add support for pin-dpll signal phase
|
||||
offset/adjust
|
||||
|
||||
Add attributes for providing the user with:
|
||||
- measurement of signals phase offset between pin and dpll
|
||||
- ability to adjust the phase of pin signal
|
||||
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit c3c6ab95c397134bf5948f18743b3ba8008e7c47)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/netlink/specs/dpll.yaml | 30 +++++++++++++++++++++++++++
|
||||
drivers/dpll/dpll_nl.c | 8 ++++---
|
||||
drivers/dpll/dpll_nl.h | 2 +-
|
||||
include/uapi/linux/dpll.h | 6 ++++++
|
||||
4 files changed, 42 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
|
||||
index 1c1b53136c7b..cf8abe1c0550 100644
|
||||
--- a/Documentation/netlink/specs/dpll.yaml
|
||||
+++ b/Documentation/netlink/specs/dpll.yaml
|
||||
@@ -164,6 +164,18 @@ definitions:
|
||||
-
|
||||
name: state-can-change
|
||||
doc: pin state can be changed
|
||||
+ -
|
||||
+ type: const
|
||||
+ name: phase-offset-divider
|
||||
+ value: 1000
|
||||
+ doc: |
|
||||
+ phase offset divider allows userspace to calculate a value of
|
||||
+ measured signal phase difference between a pin and dpll device
|
||||
+ as a fractional value with three digit decimal precision.
|
||||
+ Value of (DPLL_A_PHASE_OFFSET / DPLL_PHASE_OFFSET_DIVIDER) is an
|
||||
+ integer part of a measured phase offset value.
|
||||
+ Value of (DPLL_A_PHASE_OFFSET % DPLL_PHASE_OFFSET_DIVIDER) is a
|
||||
+ fractional part of a measured phase offset value.
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
@@ -272,6 +284,18 @@ attribute-sets:
|
||||
type: nest
|
||||
multi-attr: true
|
||||
nested-attributes: pin-parent-pin
|
||||
+ -
|
||||
+ name: phase-adjust-min
|
||||
+ type: s32
|
||||
+ -
|
||||
+ name: phase-adjust-max
|
||||
+ type: s32
|
||||
+ -
|
||||
+ name: phase-adjust
|
||||
+ type: s32
|
||||
+ -
|
||||
+ name: phase-offset
|
||||
+ type: s64
|
||||
-
|
||||
name: pin-parent-device
|
||||
subset-of: pin
|
||||
@@ -284,6 +308,8 @@ attribute-sets:
|
||||
name: prio
|
||||
-
|
||||
name: state
|
||||
+ -
|
||||
+ name: phase-offset
|
||||
-
|
||||
name: pin-parent-pin
|
||||
subset-of: pin
|
||||
@@ -431,6 +457,9 @@ operations:
|
||||
- capabilities
|
||||
- parent-device
|
||||
- parent-pin
|
||||
+ - phase-adjust-min
|
||||
+ - phase-adjust-max
|
||||
+ - phase-adjust
|
||||
|
||||
dump:
|
||||
pre: dpll-lock-dumpit
|
||||
@@ -458,6 +487,7 @@ operations:
|
||||
- state
|
||||
- parent-device
|
||||
- parent-pin
|
||||
+ - phase-adjust
|
||||
-
|
||||
name: pin-create-ntf
|
||||
doc: Notification about pin appearing
|
||||
diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
|
||||
index 14064c8c783b..eaee5be7aa64 100644
|
||||
--- a/drivers/dpll/dpll_nl.c
|
||||
+++ b/drivers/dpll/dpll_nl.c
|
||||
@@ -11,11 +11,12 @@
|
||||
#include <uapi/linux/dpll.h>
|
||||
|
||||
/* Common nested types */
|
||||
-const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1] = {
|
||||
+const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1] = {
|
||||
[DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
[DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
+ [DPLL_A_PIN_PHASE_OFFSET] = { .type = NLA_S64, },
|
||||
};
|
||||
|
||||
const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = {
|
||||
@@ -61,7 +62,7 @@ static const struct nla_policy dpll_pin_get_dump_nl_policy[DPLL_A_PIN_ID + 1] =
|
||||
};
|
||||
|
||||
/* DPLL_CMD_PIN_SET - do */
|
||||
-static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT_PIN + 1] = {
|
||||
+static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST + 1] = {
|
||||
[DPLL_A_PIN_ID] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, },
|
||||
[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
@@ -69,6 +70,7 @@ static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PARENT_PIN + 1]
|
||||
[DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
[DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy),
|
||||
[DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy),
|
||||
+ [DPLL_A_PIN_PHASE_ADJUST] = { .type = NLA_S32, },
|
||||
};
|
||||
|
||||
/* Ops table for dpll */
|
||||
@@ -140,7 +142,7 @@ static const struct genl_split_ops dpll_nl_ops[] = {
|
||||
.doit = dpll_nl_pin_set_doit,
|
||||
.post_doit = dpll_pin_post_doit,
|
||||
.policy = dpll_pin_set_nl_policy,
|
||||
- .maxattr = DPLL_A_PIN_PARENT_PIN,
|
||||
+ .maxattr = DPLL_A_PIN_PHASE_ADJUST,
|
||||
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
},
|
||||
};
|
||||
diff --git a/drivers/dpll/dpll_nl.h b/drivers/dpll/dpll_nl.h
|
||||
index 1f67aaed4742..92d4c9c4f788 100644
|
||||
--- a/drivers/dpll/dpll_nl.h
|
||||
+++ b/drivers/dpll/dpll_nl.h
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <uapi/linux/dpll.h>
|
||||
|
||||
/* Common nested types */
|
||||
-extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
+extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1];
|
||||
extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
|
||||
int dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
|
||||
index 20ef0718f8dc..715a491d2727 100644
|
||||
--- a/include/uapi/linux/dpll.h
|
||||
+++ b/include/uapi/linux/dpll.h
|
||||
@@ -138,6 +138,8 @@ enum dpll_pin_capabilities {
|
||||
DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE = 4,
|
||||
};
|
||||
|
||||
+#define DPLL_PHASE_OFFSET_DIVIDER 1000
|
||||
+
|
||||
enum dpll_a {
|
||||
DPLL_A_ID = 1,
|
||||
DPLL_A_MODULE_NAME,
|
||||
@@ -173,6 +175,10 @@ enum dpll_a_pin {
|
||||
DPLL_A_PIN_CAPABILITIES,
|
||||
DPLL_A_PIN_PARENT_DEVICE,
|
||||
DPLL_A_PIN_PARENT_PIN,
|
||||
+ DPLL_A_PIN_PHASE_ADJUST_MIN,
|
||||
+ DPLL_A_PIN_PHASE_ADJUST_MAX,
|
||||
+ DPLL_A_PIN_PHASE_ADJUST,
|
||||
+ DPLL_A_PIN_PHASE_OFFSET,
|
||||
|
||||
__DPLL_A_PIN_MAX,
|
||||
DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,251 +0,0 @@
|
||||
From 39f2322307b6cacde3f44d6ea8f64cc62d35ec79 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Wed, 11 Oct 2023 12:12:34 +0200
|
||||
Subject: [PATCH 23/46] dpll: netlink/core: add support for pin-dpll signal
|
||||
phase offset/adjust
|
||||
|
||||
Add callback ops for pin-dpll phase measurement.
|
||||
Add callback for pin signal phase adjustment.
|
||||
Add min and max phase adjustment values to pin proprties.
|
||||
Invoke callbacks in dpll_netlink.c when filling the pin details to
|
||||
provide user with phase related attribute values.
|
||||
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit d7fbc0b7e846e9e0e70ae766d274b8720fbab412)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 138 +++++++++++++++++++++++++++++++++++-
|
||||
include/linux/dpll.h | 18 +++++
|
||||
2 files changed, 155 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index e20daba6896a..09a6c2a1ea92 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -212,6 +212,53 @@ dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+dpll_msg_add_pin_phase_adjust(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
+ struct dpll_pin_ref *ref,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
+ struct dpll_device *dpll = ref->dpll;
|
||||
+ s32 phase_adjust;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!ops->phase_adjust_get)
|
||||
+ return 0;
|
||||
+ ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll),
|
||||
+ &phase_adjust, extack);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST, phase_adjust))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
+ struct dpll_pin_ref *ref,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
+ struct dpll_device *dpll = ref->dpll;
|
||||
+ s64 phase_offset;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!ops->phase_offset_get)
|
||||
+ return 0;
|
||||
+ ret = ops->phase_offset_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll), &phase_offset,
|
||||
+ extack);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (nla_put_64bit(msg, DPLL_A_PIN_PHASE_OFFSET, sizeof(phase_offset),
|
||||
+ &phase_offset, DPLL_A_PIN_PAD))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
|
||||
@@ -330,6 +377,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
|
||||
+ if (ret)
|
||||
+ goto nest_cancel;
|
||||
+ ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
nla_nest_end(msg, attr);
|
||||
@@ -377,6 +427,15 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (nla_put_u32(msg, DPLL_A_PIN_CAPABILITIES, prop->capabilities))
|
||||
return -EMSGSIZE;
|
||||
ret = dpll_msg_add_pin_freq(msg, pin, ref, extack);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MIN,
|
||||
+ prop->phase_range.min))
|
||||
+ return -EMSGSIZE;
|
||||
+ if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MAX,
|
||||
+ prop->phase_range.max))
|
||||
+ return -EMSGSIZE;
|
||||
+ ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (xa_empty(&pin->parent_refs))
|
||||
@@ -416,7 +475,7 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
|
||||
if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
|
||||
return -EMSGSIZE;
|
||||
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -705,6 +764,78 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct dpll_pin_ref *ref, *failed;
|
||||
+ const struct dpll_pin_ops *ops;
|
||||
+ s32 phase_adj, old_phase_adj;
|
||||
+ struct dpll_device *dpll;
|
||||
+ unsigned long i;
|
||||
+ int ret;
|
||||
+
|
||||
+ phase_adj = nla_get_s32(phase_adj_attr);
|
||||
+ if (phase_adj > pin->prop->phase_range.max ||
|
||||
+ phase_adj < pin->prop->phase_range.min) {
|
||||
+ NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
|
||||
+ "phase adjust value not supported");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ if (!ops->phase_adjust_set || !ops->phase_adjust_get) {
|
||||
+ NL_SET_ERR_MSG(extack, "phase adjust not supported");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+ ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
+ ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll), &old_phase_adj,
|
||||
+ extack);
|
||||
+ if (ret) {
|
||||
+ NL_SET_ERR_MSG(extack, "unable to get old phase adjust value");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (phase_adj == old_phase_adj)
|
||||
+ return 0;
|
||||
+
|
||||
+ xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
+ ret = ops->phase_adjust_set(pin,
|
||||
+ dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll), phase_adj,
|
||||
+ extack);
|
||||
+ if (ret) {
|
||||
+ failed = ref;
|
||||
+ NL_SET_ERR_MSG_FMT(extack,
|
||||
+ "phase adjust set failed for dpll_id:%u",
|
||||
+ dpll->id);
|
||||
+ goto rollback;
|
||||
+ }
|
||||
+ }
|
||||
+ __dpll_pin_change_ntf(pin);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+rollback:
|
||||
+ xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
+ if (ref == failed)
|
||||
+ break;
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
+ if (ops->phase_adjust_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll), old_phase_adj,
|
||||
+ extack))
|
||||
+ NL_SET_ERR_MSG(extack, "set phase adjust rollback failed");
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -793,6 +924,11 @@ dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
+ case DPLL_A_PIN_PHASE_ADJUST:
|
||||
+ ret = dpll_pin_phase_adj_set(pin, a, info->extack);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ break;
|
||||
case DPLL_A_PIN_PARENT_DEVICE:
|
||||
ret = dpll_pin_parent_device_set(pin, a, info->extack);
|
||||
if (ret)
|
||||
diff --git a/include/linux/dpll.h b/include/linux/dpll.h
|
||||
index bbc480cd2932..578fc5fa3750 100644
|
||||
--- a/include/linux/dpll.h
|
||||
+++ b/include/linux/dpll.h
|
||||
@@ -68,6 +68,18 @@ struct dpll_pin_ops {
|
||||
int (*prio_set)(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
const u32 prio, struct netlink_ext_ack *extack);
|
||||
+ int (*phase_offset_get)(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s64 *phase_offset,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+ int (*phase_adjust_get)(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s32 *phase_adjust,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+ int (*phase_adjust_set)(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ const s32 phase_adjust,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
};
|
||||
|
||||
struct dpll_pin_frequency {
|
||||
@@ -91,6 +103,11 @@ struct dpll_pin_frequency {
|
||||
#define DPLL_PIN_FREQUENCY_DCF77 \
|
||||
DPLL_PIN_FREQUENCY(DPLL_PIN_FREQUENCY_77_5_KHZ)
|
||||
|
||||
+struct dpll_pin_phase_adjust_range {
|
||||
+ s32 min;
|
||||
+ s32 max;
|
||||
+};
|
||||
+
|
||||
struct dpll_pin_properties {
|
||||
const char *board_label;
|
||||
const char *panel_label;
|
||||
@@ -99,6 +116,7 @@ struct dpll_pin_properties {
|
||||
unsigned long capabilities;
|
||||
u32 freq_supported_num;
|
||||
struct dpll_pin_frequency *freq_supported;
|
||||
+ struct dpll_pin_phase_adjust_range phase_range;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DPLL)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,342 +0,0 @@
|
||||
From 2cad1ea959a38a58726855eeda1d618d99226774 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Wed, 11 Oct 2023 12:12:35 +0200
|
||||
Subject: [PATCH 24/46] ice: dpll: implement phase related callbacks
|
||||
|
||||
Implement new callback ops related to measurement and adjustment of
|
||||
signal phase for pin-dpll in ice driver.
|
||||
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 90e1c90750d773fc991833f317b439236e13fc25)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.c | 220 +++++++++++++++++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.h | 10 +-
|
||||
2 files changed, 226 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
index 1faee9cb944d..835c419ccc74 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
@@ -878,6 +878,199 @@ ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
|
||||
+ * @pin: pointer to a pin
|
||||
+ * @pin_priv: private data pointer passed on pin registration
|
||||
+ * @dpll: registered dpll pointer
|
||||
+ * @dpll_priv: private data pointer passed on dpll registration
|
||||
+ * @phase_adjust: on success holds pin phase_adjust value
|
||||
+ * @extack: error reporting
|
||||
+ *
|
||||
+ * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
|
||||
+ *
|
||||
+ * Context: Acquires pf->dplls.lock
|
||||
+ * Return:
|
||||
+ * * 0 - success
|
||||
+ * * negative - error
|
||||
+ */
|
||||
+static int
|
||||
+ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s32 *phase_adjust,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ice_dpll_pin *p = pin_priv;
|
||||
+ struct ice_pf *pf = p->pf;
|
||||
+
|
||||
+ mutex_lock(&pf->dplls.lock);
|
||||
+ *phase_adjust = p->phase_adjust;
|
||||
+ mutex_unlock(&pf->dplls.lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
|
||||
+ * @pin: pointer to a pin
|
||||
+ * @pin_priv: private data pointer passed on pin registration
|
||||
+ * @dpll: registered dpll pointer
|
||||
+ * @dpll_priv: private data pointer passed on dpll registration
|
||||
+ * @phase_adjust: phase_adjust to be set
|
||||
+ * @extack: error reporting
|
||||
+ * @type: type of a pin
|
||||
+ *
|
||||
+ * Helper for dpll subsystem callback. Handler for setting phase adjust value
|
||||
+ * of a pin.
|
||||
+ *
|
||||
+ * Context: Acquires pf->dplls.lock
|
||||
+ * Return:
|
||||
+ * * 0 - success
|
||||
+ * * negative - error
|
||||
+ */
|
||||
+static int
|
||||
+ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s32 phase_adjust,
|
||||
+ struct netlink_ext_ack *extack,
|
||||
+ enum ice_dpll_pin_type type)
|
||||
+{
|
||||
+ struct ice_dpll_pin *p = pin_priv;
|
||||
+ struct ice_dpll *d = dpll_priv;
|
||||
+ struct ice_pf *pf = d->pf;
|
||||
+ u8 flag, flags_en = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ mutex_lock(&pf->dplls.lock);
|
||||
+ switch (type) {
|
||||
+ case ICE_DPLL_PIN_TYPE_INPUT:
|
||||
+ flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
|
||||
+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
|
||||
+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
|
||||
+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
|
||||
+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
|
||||
+ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
|
||||
+ 0, phase_adjust);
|
||||
+ break;
|
||||
+ case ICE_DPLL_PIN_TYPE_OUTPUT:
|
||||
+ flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
|
||||
+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
|
||||
+ flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
|
||||
+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
|
||||
+ flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
|
||||
+ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
|
||||
+ phase_adjust);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+ if (!ret)
|
||||
+ p->phase_adjust = phase_adjust;
|
||||
+ mutex_unlock(&pf->dplls.lock);
|
||||
+ if (ret)
|
||||
+ NL_SET_ERR_MSG_FMT(extack,
|
||||
+ "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n",
|
||||
+ ret,
|
||||
+ ice_aq_str(pf->hw.adminq.sq_last_status),
|
||||
+ phase_adjust, p->idx, d->dpll_idx);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
|
||||
+ * @pin: pointer to a pin
|
||||
+ * @pin_priv: private data pointer passed on pin registration
|
||||
+ * @dpll: registered dpll pointer
|
||||
+ * @dpll_priv: private data pointer passed on dpll registration
|
||||
+ * @phase_adjust: phase_adjust to be set
|
||||
+ * @extack: error reporting
|
||||
+ *
|
||||
+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
|
||||
+ * pin.
|
||||
+ *
|
||||
+ * Context: Calls a function which acquires pf->dplls.lock
|
||||
+ * Return:
|
||||
+ * * 0 - success
|
||||
+ * * negative - error
|
||||
+ */
|
||||
+static int
|
||||
+ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s32 phase_adjust,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
|
||||
+ phase_adjust, extack,
|
||||
+ ICE_DPLL_PIN_TYPE_INPUT);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
|
||||
+ * @pin: pointer to a pin
|
||||
+ * @pin_priv: private data pointer passed on pin registration
|
||||
+ * @dpll: registered dpll pointer
|
||||
+ * @dpll_priv: private data pointer passed on dpll registration
|
||||
+ * @phase_adjust: phase_adjust to be set
|
||||
+ * @extack: error reporting
|
||||
+ *
|
||||
+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
|
||||
+ * pin.
|
||||
+ *
|
||||
+ * Context: Calls a function which acquires pf->dplls.lock
|
||||
+ * Return:
|
||||
+ * * 0 - success
|
||||
+ * * negative - error
|
||||
+ */
|
||||
+static int
|
||||
+ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s32 phase_adjust,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
|
||||
+ phase_adjust, extack,
|
||||
+ ICE_DPLL_PIN_TYPE_OUTPUT);
|
||||
+}
|
||||
+
|
||||
+#define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
|
||||
+#define ICE_DPLL_PHASE_OFFSET_FACTOR \
|
||||
+ (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
|
||||
+/**
|
||||
+ * ice_dpll_phase_offset_get - callback for get dpll phase shift value
|
||||
+ * @pin: pointer to a pin
|
||||
+ * @pin_priv: private data pointer passed on pin registration
|
||||
+ * @dpll: registered dpll pointer
|
||||
+ * @dpll_priv: private data pointer passed on dpll registration
|
||||
+ * @phase_offset: on success holds pin phase_offset value
|
||||
+ * @extack: error reporting
|
||||
+ *
|
||||
+ * Dpll subsystem callback. Handler for getting phase shift value between
|
||||
+ * dpll's input and output.
|
||||
+ *
|
||||
+ * Context: Acquires pf->dplls.lock
|
||||
+ * Return:
|
||||
+ * * 0 - success
|
||||
+ * * negative - error
|
||||
+ */
|
||||
+static int
|
||||
+ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
+ const struct dpll_device *dpll, void *dpll_priv,
|
||||
+ s64 *phase_offset, struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct ice_dpll *d = dpll_priv;
|
||||
+ struct ice_pf *pf = d->pf;
|
||||
+
|
||||
+ mutex_lock(&pf->dplls.lock);
|
||||
+ if (d->active_input == pin)
|
||||
+ *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
|
||||
+ else
|
||||
+ *phase_offset = 0;
|
||||
+ mutex_unlock(&pf->dplls.lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
|
||||
* @pin: pointer to a pin
|
||||
@@ -993,6 +1186,9 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
|
||||
.prio_get = ice_dpll_input_prio_get,
|
||||
.prio_set = ice_dpll_input_prio_set,
|
||||
.direction_get = ice_dpll_input_direction,
|
||||
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
||||
+ .phase_adjust_set = ice_dpll_input_phase_adjust_set,
|
||||
+ .phase_offset_get = ice_dpll_phase_offset_get,
|
||||
};
|
||||
|
||||
static const struct dpll_pin_ops ice_dpll_output_ops = {
|
||||
@@ -1001,6 +1197,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
|
||||
.state_on_dpll_get = ice_dpll_output_state_get,
|
||||
.state_on_dpll_set = ice_dpll_output_state_set,
|
||||
.direction_get = ice_dpll_output_direction,
|
||||
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
||||
+ .phase_adjust_set = ice_dpll_output_phase_adjust_set,
|
||||
};
|
||||
|
||||
static const struct dpll_device_ops ice_dpll_ops = {
|
||||
@@ -1031,6 +1229,8 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
|
||||
*/
|
||||
static void ice_dpll_notify_changes(struct ice_dpll *d)
|
||||
{
|
||||
+ bool pin_notified = false;
|
||||
+
|
||||
if (d->prev_dpll_state != d->dpll_state) {
|
||||
d->prev_dpll_state = d->dpll_state;
|
||||
dpll_device_change_ntf(d->dpll);
|
||||
@@ -1039,7 +1239,14 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
|
||||
if (d->prev_input)
|
||||
dpll_pin_change_ntf(d->prev_input);
|
||||
d->prev_input = d->active_input;
|
||||
- if (d->active_input)
|
||||
+ if (d->active_input) {
|
||||
+ dpll_pin_change_ntf(d->active_input);
|
||||
+ pin_notified = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (d->prev_phase_offset != d->phase_offset) {
|
||||
+ d->prev_phase_offset = d->phase_offset;
|
||||
+ if (!pin_notified && d->active_input)
|
||||
dpll_pin_change_ntf(d->active_input);
|
||||
}
|
||||
}
|
||||
@@ -1065,7 +1272,7 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
|
||||
|
||||
ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
|
||||
&d->input_idx, &d->ref_state, &d->eec_mode,
|
||||
- &d->phase_shift, &d->dpll_state);
|
||||
+ &d->phase_offset, &d->dpll_state);
|
||||
|
||||
dev_dbg(ice_pf_to_dev(pf),
|
||||
"update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
|
||||
@@ -1656,6 +1863,15 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
return ret;
|
||||
pins[i].prop.capabilities |=
|
||||
DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
|
||||
+ pins[i].prop.phase_range.min =
|
||||
+ pf->dplls.input_phase_adj_max;
|
||||
+ pins[i].prop.phase_range.max =
|
||||
+ -pf->dplls.input_phase_adj_max;
|
||||
+ } else {
|
||||
+ pins[i].prop.phase_range.min =
|
||||
+ pf->dplls.output_phase_adj_max;
|
||||
+ pins[i].prop.phase_range.max =
|
||||
+ -pf->dplls.output_phase_adj_max;
|
||||
}
|
||||
pins[i].prop.capabilities |=
|
||||
DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
index 2dfe764b81e1..bb32b6d88373 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
@@ -19,6 +19,7 @@
|
||||
* @state: state of a pin
|
||||
* @prop: pin properties
|
||||
* @freq: current frequency of a pin
|
||||
+ * @phase_adjust: current phase adjust value
|
||||
*/
|
||||
struct ice_dpll_pin {
|
||||
struct dpll_pin *pin;
|
||||
@@ -30,6 +31,7 @@ struct ice_dpll_pin {
|
||||
u8 state[ICE_DPLL_RCLK_NUM_MAX];
|
||||
struct dpll_pin_properties prop;
|
||||
u32 freq;
|
||||
+ s32 phase_adjust;
|
||||
};
|
||||
|
||||
/** ice_dpll - store info required for DPLL control
|
||||
@@ -40,7 +42,8 @@ struct ice_dpll_pin {
|
||||
* @prev_input_idx: previously selected input index
|
||||
* @ref_state: state of dpll reference signals
|
||||
* @eec_mode: eec_mode dpll is configured for
|
||||
- * @phase_shift: phase shift delay of a dpll
|
||||
+ * @phase_offset: phase offset of active pin vs dpll signal
|
||||
+ * @prev_phase_offset: previous phase offset of active pin vs dpll signal
|
||||
* @input_prio: priorities of each input
|
||||
* @dpll_state: current dpll sync state
|
||||
* @prev_dpll_state: last dpll sync state
|
||||
@@ -55,7 +58,8 @@ struct ice_dpll {
|
||||
u8 prev_input_idx;
|
||||
u8 ref_state;
|
||||
u8 eec_mode;
|
||||
- s64 phase_shift;
|
||||
+ s64 phase_offset;
|
||||
+ s64 prev_phase_offset;
|
||||
u8 *input_prio;
|
||||
enum dpll_lock_status dpll_state;
|
||||
enum dpll_lock_status prev_dpll_state;
|
||||
@@ -78,6 +82,8 @@ struct ice_dpll {
|
||||
* @cgu_state_acq_err_num: number of errors returned during periodic work
|
||||
* @base_rclk_idx: idx of first pin used for clock revocery pins
|
||||
* @clock_id: clock_id of dplls
|
||||
+ * @input_phase_adj_max: max phase adjust value for an input pins
|
||||
+ * @output_phase_adj_max: max phase adjust value for an output pins
|
||||
*/
|
||||
struct ice_dplls {
|
||||
struct kthread_worker *kworker;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 48ea8a9833e381a05157086ab0dd8ee56246b7d5 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Wed, 11 Oct 2023 12:12:36 +0200
|
||||
Subject: [PATCH 25/46] dpll: netlink/core: change pin frequency set behavior
|
||||
|
||||
Align the approach of pin frequency set behavior with the approach
|
||||
introduced with pin phase adjust set.
|
||||
Fail the request if any of devices did not registered the callback ops.
|
||||
If callback op on any pin's registered device fails, return error and
|
||||
rollback the value to previous one.
|
||||
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 20f6677234d8105e55beca355135e94bb10fbf74)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 50 +++++++++++++++++++++++++++++++------
|
||||
1 file changed, 42 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index 09a6c2a1ea92..a6dc3997bf5c 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -615,8 +615,10 @@ static int
|
||||
dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
- u64 freq = nla_get_u64(a);
|
||||
- struct dpll_pin_ref *ref;
|
||||
+ u64 freq = nla_get_u64(a), old_freq;
|
||||
+ struct dpll_pin_ref *ref, *failed;
|
||||
+ const struct dpll_pin_ops *ops;
|
||||
+ struct dpll_device *dpll;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
|
||||
@@ -626,19 +628,51 @@ dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
|
||||
}
|
||||
|
||||
xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
- const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
- struct dpll_device *dpll = ref->dpll;
|
||||
-
|
||||
- if (!ops->frequency_set)
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ if (!ops->frequency_set || !ops->frequency_get) {
|
||||
+ NL_SET_ERR_MSG(extack, "frequency set not supported by the device");
|
||||
return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+ ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
+ ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
|
||||
+ dpll_priv(dpll), &old_freq, extack);
|
||||
+ if (ret) {
|
||||
+ NL_SET_ERR_MSG(extack, "unable to get old frequency value");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (freq == old_freq)
|
||||
+ return 0;
|
||||
+
|
||||
+ xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
ret = ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
dpll, dpll_priv(dpll), freq, extack);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ if (ret) {
|
||||
+ failed = ref;
|
||||
+ NL_SET_ERR_MSG_FMT(extack, "frequency set failed for dpll_id:%u",
|
||||
+ dpll->id);
|
||||
+ goto rollback;
|
||||
+ }
|
||||
}
|
||||
__dpll_pin_change_ntf(pin);
|
||||
|
||||
return 0;
|
||||
+
|
||||
+rollback:
|
||||
+ xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
+ if (ref == failed)
|
||||
+ break;
|
||||
+ ops = dpll_pin_ops(ref);
|
||||
+ dpll = ref->dpll;
|
||||
+ if (ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
+ dpll, dpll_priv(dpll), old_freq, extack))
|
||||
+ NL_SET_ERR_MSG(extack, "set frequency rollback failed");
|
||||
+ }
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 1db547235552584bc7a2f1bacc43cc55c4db50aa Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Fri, 13 Oct 2023 12:25:10 +0200
|
||||
Subject: [PATCH 26/46] ice: dpll: fix initial lock status of dpll
|
||||
|
||||
When dpll device is registered and dpll subsystem performs notify of a
|
||||
new device, the lock state value provided to dpll subsystem equals 0
|
||||
which is invalid value for the `enum dpll_lock_status`.
|
||||
Provide correct value by obtaining it from firmware before registering
|
||||
the dpll device.
|
||||
|
||||
Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
|
||||
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 7a1aba89ac54ccf6cad23a91a34c0ab24b1d7997)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
index 835c419ccc74..607f534055b6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
@@ -1756,6 +1756,7 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
|
||||
}
|
||||
d->pf = pf;
|
||||
if (cgu) {
|
||||
+ ice_dpll_update_state(pf, d, true);
|
||||
ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d);
|
||||
if (ret) {
|
||||
dpll_device_put(d->dpll);
|
||||
@@ -1796,8 +1797,6 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
|
||||
struct ice_dplls *d = &pf->dplls;
|
||||
struct kthread_worker *kworker;
|
||||
|
||||
- ice_dpll_update_state(pf, &d->eec, true);
|
||||
- ice_dpll_update_state(pf, &d->pps, true);
|
||||
kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
|
||||
kworker = kthread_create_worker(0, "ice-dplls-%s",
|
||||
dev_name(ice_pf_to_dev(pf)));
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 2f2ca7f272758284fb9c15ed5f513cdeaefee46c Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Tue, 31 Oct 2023 18:06:54 +0100
|
||||
Subject: [PATCH 27/46] ice: dpll: fix check for dpll input priority range
|
||||
|
||||
Supported priority value for input pins may differ with regard of NIC
|
||||
firmware version. E810T NICs with 3.20/4.00 FW versions would accept
|
||||
priority range 0-31, where firmware 4.10+ would support the range 0-9
|
||||
and extra value of 255.
|
||||
Remove the in-range check as the driver has no information on supported
|
||||
values from the running firmware, let firmware decide if given value is
|
||||
correct and return extack error if the value is not supported.
|
||||
|
||||
Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 4a4027f25dc3f39c2aafb3bf8926125c5378c9dc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.c | 6 ------
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.h | 1 -
|
||||
2 files changed, 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
index 607f534055b6..831ba6683962 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
@@ -815,12 +815,6 @@ ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
|
||||
struct ice_pf *pf = d->pf;
|
||||
int ret;
|
||||
|
||||
- if (prio > ICE_DPLL_PRIO_MAX) {
|
||||
- NL_SET_ERR_MSG_FMT(extack, "prio out of supported range 0-%d",
|
||||
- ICE_DPLL_PRIO_MAX);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
mutex_lock(&pf->dplls.lock);
|
||||
ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
|
||||
mutex_unlock(&pf->dplls.lock);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
index bb32b6d88373..93172e93995b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "ice.h"
|
||||
|
||||
-#define ICE_DPLL_PRIO_MAX 0xF
|
||||
#define ICE_DPLL_RCLK_NUM_MAX 4
|
||||
|
||||
/** ice_dpll_pin - store info about pins
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,346 +0,0 @@
|
||||
From 6add02878183b5256a0b01ee820f3e0cc878e15d Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 17 Jul 2023 15:17:13 -0700
|
||||
Subject: [PATCH 28/46] ice: introduce hw->phy_model for handling PTP PHY
|
||||
differences
|
||||
|
||||
The ice driver has PTP support which works across a couple of different
|
||||
device families. The device families each have different PHY hardware which
|
||||
have unique requirements for programming.
|
||||
|
||||
Today, there is E810-based hardware, and E822-based hardware. To handle
|
||||
this, the driver checks the ice_is_e810() function to separate between the
|
||||
two existing families of hardware.
|
||||
|
||||
Future development is going to add new hardware designs which have further
|
||||
unique requirements. To make this easier, introduce a phy_model field to
|
||||
the HW structure. This field represents what PHY model the current device
|
||||
has, and is used to allow distinguishing which logic a particular device
|
||||
needs.
|
||||
|
||||
This will make supporting future upcoming hardware easier, by providing an
|
||||
obvious place to initialize the PHY model, and by already using switch/case
|
||||
statements instead of the previous if statements.
|
||||
|
||||
Astute reviewers may notice that there are a handful of remaining checks
|
||||
for ice_is_e810() left in ice_ptp.c These conflict with some other
|
||||
cleanup patches in development, and will be fixed in the near future.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit be16574609f14c67efd89d5d8f9f19ab7724bfc9)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 32 ++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 102 ++++++++++++++++----
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 8 ++
|
||||
4 files changed, 117 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c4270708a769..3648d3cccacc 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1366,6 +1366,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
{
|
||||
struct ice_ptp_port *ptp_port;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
|
||||
if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
return;
|
||||
@@ -1380,11 +1381,16 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
/* Update cached link status for this port immediately */
|
||||
ptp_port->link_up = linkup;
|
||||
|
||||
- /* E810 devices do not need to reconfigure the PHY */
|
||||
- if (ice_is_e810(&pf->hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
+ /* Do not reconfigure E810 PHY */
|
||||
return;
|
||||
-
|
||||
- ice_ptp_port_phy_restart(ptp_port);
|
||||
+ case ICE_PHY_E822:
|
||||
+ ice_ptp_port_phy_restart(ptp_port);
|
||||
+ return;
|
||||
+ default:
|
||||
+ dev_warn(ice_pf_to_dev(pf), "%s: Unknown PHY type\n", __func__);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2687,14 +2693,22 @@ static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp)
|
||||
*/
|
||||
static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+
|
||||
mutex_init(&ptp_port->ps_lock);
|
||||
|
||||
- if (ice_is_e810(&pf->hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
+ case ICE_PHY_E822:
|
||||
+ kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
+ ice_ptp_wait_for_offsets);
|
||||
|
||||
- kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
- ice_ptp_wait_for_offsets);
|
||||
- return ice_ptp_init_tx_e822(pf, &ptp_port->tx, ptp_port->port_num);
|
||||
+ return ice_ptp_init_tx_e822(pf, &ptp_port->tx,
|
||||
+ ptp_port->port_num);
|
||||
+ default:
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2715,6 +2729,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err;
|
||||
|
||||
+ ice_ptp_init_phy_model(hw);
|
||||
+
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 8ccd633d9c2e..9aef80ad5100 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -3275,6 +3275,21 @@ void ice_ptp_unlock(struct ice_hw *hw)
|
||||
wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_model - Initialize hw->phy_model based on device type
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * Determine the PHY model for the device, and initialize hw->phy_model
|
||||
+ * for use by other functions.
|
||||
+ */
|
||||
+void ice_ptp_init_phy_model(struct ice_hw *hw)
|
||||
+{
|
||||
+ if (ice_is_e810(hw))
|
||||
+ hw->phy_model = ICE_PHY_E810;
|
||||
+ else
|
||||
+ hw->phy_model = ICE_PHY_E822;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_tmr_cmd - Prepare and trigger a timer sync command
|
||||
* @hw: pointer to HW struct
|
||||
@@ -3293,10 +3308,17 @@ static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
ice_ptp_src_cmd(hw, cmd);
|
||||
|
||||
/* Next, prepare the ports */
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
err = ice_ptp_port_cmd_e810(hw, cmd);
|
||||
- else
|
||||
+ break;
|
||||
+ case ICE_PHY_E822:
|
||||
err = ice_ptp_port_cmd_e822(hw, cmd);
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, err %d\n",
|
||||
cmd, err);
|
||||
@@ -3338,10 +3360,17 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
|
||||
|
||||
/* PHY timers */
|
||||
/* Fill Rx and Tx ports and send msg to PHY */
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
|
||||
- else
|
||||
+ break;
|
||||
+ case ICE_PHY_E822:
|
||||
err = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -3373,10 +3402,17 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_incval_e810(hw, incval);
|
||||
- else
|
||||
+ break;
|
||||
+ case ICE_PHY_E822:
|
||||
err = ice_ptp_prep_phy_incval_e822(hw, incval);
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -3432,10 +3468,17 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_adj_e810(hw, adj);
|
||||
- else
|
||||
+ break;
|
||||
+ case ICE_PHY_E822:
|
||||
err = ice_ptp_prep_phy_adj_e822(hw, adj);
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -3455,10 +3498,14 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
*/
|
||||
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
|
||||
- else
|
||||
+ case ICE_PHY_E822:
|
||||
return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3473,10 +3520,14 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
return ice_clear_phy_tstamp_e810(hw, block, idx);
|
||||
- else
|
||||
+ case ICE_PHY_E822:
|
||||
return ice_clear_phy_tstamp_e822(hw, block, idx);
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3530,10 +3581,14 @@ int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
|
||||
*/
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E822:
|
||||
+ ice_ptp_reset_ts_memory_e822(hw);
|
||||
+ break;
|
||||
+ case ICE_PHY_E810:
|
||||
+ default:
|
||||
return;
|
||||
-
|
||||
- ice_ptp_reset_ts_memory_e822(hw);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3552,10 +3607,14 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
/* Clear event err indications for auxiliary pins */
|
||||
(void)rd32(hw, GLTSYN_STAT(src_idx));
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
return ice_ptp_init_phc_e810(hw);
|
||||
- else
|
||||
+ case ICE_PHY_E822:
|
||||
return ice_ptp_init_phc_e822(hw);
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3571,12 +3630,17 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
*/
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
+ switch (hw->phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
return ice_get_phy_tx_tstamp_ready_e810(hw, block,
|
||||
tstamp_ready);
|
||||
- else
|
||||
+ case ICE_PHY_E822:
|
||||
return ice_get_phy_tx_tstamp_ready_e822(hw, block,
|
||||
tstamp_ready);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index d81e77386b54..4f71d4bfeadf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -281,6 +281,8 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
|
||||
enum dpll_lock_status *dpll_state);
|
||||
int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
|
||||
+void ice_ptp_init_phy_model(struct ice_hw *hw);
|
||||
+
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
#define ICE_PTP_CLOCK_INDEX_0 0x00
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 5eb778d9ae64..4cd131546aa9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -822,6 +822,13 @@ struct ice_mbx_data {
|
||||
u16 async_watermark_val;
|
||||
};
|
||||
|
||||
+/* PHY model */
|
||||
+enum ice_phy_model {
|
||||
+ ICE_PHY_UNSUP = -1,
|
||||
+ ICE_PHY_E810 = 1,
|
||||
+ ICE_PHY_E822,
|
||||
+};
|
||||
+
|
||||
/* Port hardware description */
|
||||
struct ice_hw {
|
||||
u8 __iomem *hw_addr;
|
||||
@@ -843,6 +850,7 @@ struct ice_hw {
|
||||
u8 revision_id;
|
||||
|
||||
u8 pf_id; /* device profile info */
|
||||
+ enum ice_phy_model phy_model;
|
||||
|
||||
u16 max_burst_size; /* driver sets this value */
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,150 +0,0 @@
|
||||
From 4014377612cd199b2488074dbd6865cd1a1a835e Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Tue, 31 Oct 2023 18:08:00 +0100
|
||||
Subject: [PATCH 29/46] ice: dpll: fix output pin capabilities
|
||||
|
||||
The dpll output pins which are used to feed clock signal of PHY and MAC
|
||||
circuits cannot be disconnected, those integrated circuits require clock
|
||||
signal for operation.
|
||||
By stopping assignment of DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE pin
|
||||
capability, prevent the user from invoking the state set callback on
|
||||
those pins, setting the state on those pins already returns error, as
|
||||
firmware doesn't allow the change of their state.
|
||||
|
||||
Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
|
||||
Fixes: 8a3a565ff210 ("ice: add admin commands to access cgu configuration")
|
||||
Reviewed-by: Andrii Staikov <andrii.staikov@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 6db5f2cd9ebb12e930a82c01714a6589576cd50f)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_dpll.c | 12 +++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 54 +++++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 2 +
|
||||
3 files changed, 64 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
index 831ba6683962..86b180cb32a0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
||||
@@ -1823,6 +1823,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
int num_pins, i, ret = -EINVAL;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct ice_dpll_pin *pins;
|
||||
+ unsigned long caps;
|
||||
u8 freq_supp_num;
|
||||
bool input;
|
||||
|
||||
@@ -1842,6 +1843,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
}
|
||||
|
||||
for (i = 0; i < num_pins; i++) {
|
||||
+ caps = 0;
|
||||
pins[i].idx = i;
|
||||
pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
|
||||
pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
|
||||
@@ -1854,8 +1856,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
&dp->input_prio[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
- pins[i].prop.capabilities |=
|
||||
- DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
|
||||
+ caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
|
||||
+ DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
|
||||
pins[i].prop.phase_range.min =
|
||||
pf->dplls.input_phase_adj_max;
|
||||
pins[i].prop.phase_range.max =
|
||||
@@ -1865,9 +1867,11 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
pf->dplls.output_phase_adj_max;
|
||||
pins[i].prop.phase_range.max =
|
||||
-pf->dplls.output_phase_adj_max;
|
||||
+ ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
}
|
||||
- pins[i].prop.capabilities |=
|
||||
- DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
||||
+ pins[i].prop.capabilities = caps;
|
||||
ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 9aef80ad5100..a299af39a7c4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -3935,3 +3935,57 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num)
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * ice_cgu_get_output_pin_state_caps - get output pin state capabilities
|
||||
+ * @hw: pointer to the hw struct
|
||||
+ * @pin_id: id of a pin
|
||||
+ * @caps: capabilities to modify
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * * 0 - success, state capabilities were modified
|
||||
+ * * negative - failure, capabilities were not modified
|
||||
+ */
|
||||
+int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
+ unsigned long *caps)
|
||||
+{
|
||||
+ bool can_change = true;
|
||||
+
|
||||
+ switch (hw->device_id) {
|
||||
+ case ICE_DEV_ID_E810C_SFP:
|
||||
+ if (pin_id == ZL_OUT2 || pin_id == ZL_OUT3)
|
||||
+ can_change = false;
|
||||
+ break;
|
||||
+ case ICE_DEV_ID_E810C_QSFP:
|
||||
+ if (pin_id == ZL_OUT2 || pin_id == ZL_OUT3 || pin_id == ZL_OUT4)
|
||||
+ can_change = false;
|
||||
+ break;
|
||||
+ case ICE_DEV_ID_E823L_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E823L_1GBE:
|
||||
+ case ICE_DEV_ID_E823L_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E823L_QSFP:
|
||||
+ case ICE_DEV_ID_E823L_SFP:
|
||||
+ case ICE_DEV_ID_E823C_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E823C_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E823C_QSFP:
|
||||
+ case ICE_DEV_ID_E823C_SFP:
|
||||
+ case ICE_DEV_ID_E823C_SGMII:
|
||||
+ if (hw->cgu_part_number ==
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032 &&
|
||||
+ pin_id == ZL_OUT2)
|
||||
+ can_change = false;
|
||||
+ else if (hw->cgu_part_number ==
|
||||
+ ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384 &&
|
||||
+ pin_id == SI_OUT1)
|
||||
+ can_change = false;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (can_change)
|
||||
+ *caps |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
||||
+ else
|
||||
+ *caps &= ~DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 4f71d4bfeadf..9dc30918f044 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -282,6 +282,8 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
|
||||
int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
|
||||
void ice_ptp_init_phy_model(struct ice_hw *hw);
|
||||
+int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
+ unsigned long *caps);
|
||||
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,75 +0,0 @@
|
||||
From f29c2ce39b0b42b323163a29fb1e0366f75b3e91 Mon Sep 17 00:00:00 2001
|
||||
From: Hao Ge <gehao@kylinos.cn>
|
||||
Date: Tue, 21 Nov 2023 09:37:09 +0800
|
||||
Subject: [PATCH 30/46] dpll: Fix potential msg memleak when genlmsg_put_reply
|
||||
failed
|
||||
|
||||
We should clean the skb resource if genlmsg_put_reply failed.
|
||||
|
||||
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
|
||||
Signed-off-by: Hao Ge <gehao@kylinos.cn>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Link: https://lore.kernel.org/r/20231121013709.73323-1-gehao@kylinos.cn
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit b6fe6f03716da246b453369f98a553d4ab21447c)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index a6dc3997bf5c..442a0ebeb953 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -1093,9 +1093,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||
DPLL_CMD_PIN_ID_GET);
|
||||
- if (!hdr)
|
||||
+ if (!hdr) {
|
||||
+ nlmsg_free(msg);
|
||||
return -EMSGSIZE;
|
||||
-
|
||||
+ }
|
||||
pin = dpll_pin_find_from_nlattr(info);
|
||||
if (!IS_ERR(pin)) {
|
||||
ret = dpll_msg_add_pin_handle(msg, pin);
|
||||
@@ -1123,8 +1124,10 @@ int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||
DPLL_CMD_PIN_GET);
|
||||
- if (!hdr)
|
||||
+ if (!hdr) {
|
||||
+ nlmsg_free(msg);
|
||||
return -EMSGSIZE;
|
||||
+ }
|
||||
ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
|
||||
if (ret) {
|
||||
nlmsg_free(msg);
|
||||
@@ -1256,8 +1259,10 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||
DPLL_CMD_DEVICE_ID_GET);
|
||||
- if (!hdr)
|
||||
+ if (!hdr) {
|
||||
+ nlmsg_free(msg);
|
||||
return -EMSGSIZE;
|
||||
+ }
|
||||
|
||||
dpll = dpll_device_find_from_nlattr(info);
|
||||
if (!IS_ERR(dpll)) {
|
||||
@@ -1284,8 +1289,10 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||
DPLL_CMD_DEVICE_GET);
|
||||
- if (!hdr)
|
||||
+ if (!hdr) {
|
||||
+ nlmsg_free(msg);
|
||||
return -EMSGSIZE;
|
||||
+ }
|
||||
|
||||
ret = dpll_device_get_one(dpll, msg, info->extack);
|
||||
if (ret) {
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,102 +0,0 @@
|
||||
From a13fb6033eb54791b67f6a62c2328baf1b3ed85a Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:40 -0800
|
||||
Subject: [PATCH 31/46] ice: add CGU info to devlink info callback
|
||||
|
||||
If Clock Generation Unit is present on NIC board user shall know its
|
||||
details.
|
||||
Provide the devlink info callback with a new:
|
||||
- fixed type object (cgu.id) indicating hardware variant of onboard CGU,
|
||||
- running type object (fw.cgu) consisting of CGU id, config and firmware
|
||||
versions.
|
||||
These information shall be known for debugging purposes.
|
||||
|
||||
Test (on NIC board with CGU)
|
||||
$ devlink dev info <bus_name>/<dev_name> | grep cgu
|
||||
cgu.id 36
|
||||
fw.cgu 8032.16973825.6021
|
||||
|
||||
Test (on NIC board without CGU)
|
||||
$ devlink dev info <bus_name>/<dev_name> | grep cgu -c
|
||||
0
|
||||
|
||||
Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit b86455a1cbef6829e8da3f93d37a233be2616569)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Documentation/networking/devlink/ice.rst | 9 +++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_devlink.c | 20 ++++++++++++++++++++
|
||||
2 files changed, 29 insertions(+)
|
||||
|
||||
diff --git a/Documentation/networking/devlink/ice.rst b/Documentation/networking/devlink/ice.rst
|
||||
index 2f60e34ab926..7f30ebd5debb 100644
|
||||
--- a/Documentation/networking/devlink/ice.rst
|
||||
+++ b/Documentation/networking/devlink/ice.rst
|
||||
@@ -38,6 +38,10 @@ The ``ice`` driver reports the following versions
|
||||
- fixed
|
||||
- K65390-000
|
||||
- The Product Board Assembly (PBA) identifier of the board.
|
||||
+ * - ``cgu.id``
|
||||
+ - fixed
|
||||
+ - 36
|
||||
+ - The Clock Generation Unit (CGU) hardware revision identifier.
|
||||
* - ``fw.mgmt``
|
||||
- running
|
||||
- 2.1.7
|
||||
@@ -104,6 +108,11 @@ The ``ice`` driver reports the following versions
|
||||
- running
|
||||
- 0xee16ced7
|
||||
- The first 4 bytes of the hash of the netlist module contents.
|
||||
+ * - ``fw.cgu``
|
||||
+ - running
|
||||
+ - 8032.16973825.6021
|
||||
+ - The version of Clock Generation Unit (CGU). Format:
|
||||
+ <CGU type>.<configuration version>.<firmware version>.
|
||||
|
||||
Flash Update
|
||||
============
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
index 80dc5445b50d..3a2261823d93 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
@@ -193,6 +193,24 @@ ice_info_pending_netlist_build(struct ice_pf __always_unused *pf,
|
||||
snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);
|
||||
}
|
||||
|
||||
+static void ice_info_cgu_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx)
|
||||
+{
|
||||
+ u32 id, cfg_ver, fw_ver;
|
||||
+
|
||||
+ if (!ice_is_feature_supported(pf, ICE_F_CGU))
|
||||
+ return;
|
||||
+ if (ice_aq_get_cgu_info(&pf->hw, &id, &cfg_ver, &fw_ver))
|
||||
+ return;
|
||||
+ snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", id, cfg_ver, fw_ver);
|
||||
+}
|
||||
+
|
||||
+static void ice_info_cgu_id(struct ice_pf *pf, struct ice_info_ctx *ctx)
|
||||
+{
|
||||
+ if (!ice_is_feature_supported(pf, ICE_F_CGU))
|
||||
+ return;
|
||||
+ snprintf(ctx->buf, sizeof(ctx->buf), "%u", pf->hw.cgu_part_number);
|
||||
+}
|
||||
+
|
||||
#define fixed(key, getter) { ICE_VERSION_FIXED, key, getter, NULL }
|
||||
#define running(key, getter) { ICE_VERSION_RUNNING, key, getter, NULL }
|
||||
#define stored(key, getter, fallback) { ICE_VERSION_STORED, key, getter, fallback }
|
||||
@@ -235,6 +253,8 @@ static const struct ice_devlink_version {
|
||||
running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id),
|
||||
combined("fw.netlist", ice_info_netlist_ver, ice_info_pending_netlist_ver),
|
||||
combined("fw.netlist.build", ice_info_netlist_build, ice_info_pending_netlist_build),
|
||||
+ fixed("cgu.id", ice_info_cgu_id),
|
||||
+ running("fw.cgu", ice_info_cgu_fw_build),
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 0fe793ace5580801d48d93b3670f84506c336d6f Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Mon, 11 Dec 2023 09:37:58 +0100
|
||||
Subject: [PATCH 32/46] dpll: sanitize possible null pointer dereference in
|
||||
dpll_pin_parent_pin_set()
|
||||
|
||||
User may not pass DPLL_A_PIN_STATE attribute in the pin set operation
|
||||
message. Sanitize that by checking if the attr pointer is not null
|
||||
and process the passed state attribute value only in that case.
|
||||
|
||||
Reported-by: Xingyuan Mo <hdthky0@gmail.com>
|
||||
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Link: https://lore.kernel.org/r/20231211083758.1082853-1-jiri@resnulli.us
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 65c95f78917ea6fa7ff189a2c19879c4fe161873)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index 442a0ebeb953..ce7cf736f020 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -925,7 +925,6 @@ dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[DPLL_A_PIN_MAX + 1];
|
||||
- enum dpll_pin_state state;
|
||||
u32 ppin_idx;
|
||||
int ret;
|
||||
|
||||
@@ -936,10 +935,14 @@ dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
|
||||
return -EINVAL;
|
||||
}
|
||||
ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
|
||||
- state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
|
||||
- ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+
|
||||
+ if (tb[DPLL_A_PIN_STATE]) {
|
||||
+ enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
|
||||
+
|
||||
+ ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 6bfe9392d6a26b04b24d310fc0e6342f139842eb Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Tue, 12 Dec 2023 16:06:05 +0100
|
||||
Subject: [PATCH 33/46] dpll: allocate pin ids in cycle
|
||||
|
||||
Pin ID is just a number. Nobody should rely on a certain value, instead,
|
||||
user should use either pin-id-get op or RTNetlink to get it.
|
||||
|
||||
Unify the pin ID allocation behavior with what there is already
|
||||
implemented for dpll devices.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Link: https://lore.kernel.org/r/20231212150605.1141261-1-jiri@resnulli.us
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 97f265ef7f5b526b33d6030b2a1fc69a2259bf4a)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_core.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
|
||||
index 3568149b9562..1eca8cc271f8 100644
|
||||
--- a/drivers/dpll/dpll_core.c
|
||||
+++ b/drivers/dpll/dpll_core.c
|
||||
@@ -22,7 +22,8 @@ DEFINE_MUTEX(dpll_lock);
|
||||
DEFINE_XARRAY_FLAGS(dpll_device_xa, XA_FLAGS_ALLOC);
|
||||
DEFINE_XARRAY_FLAGS(dpll_pin_xa, XA_FLAGS_ALLOC);
|
||||
|
||||
-static u32 dpll_xa_id;
|
||||
+static u32 dpll_device_xa_id;
|
||||
+static u32 dpll_pin_xa_id;
|
||||
|
||||
#define ASSERT_DPLL_REGISTERED(d) \
|
||||
WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED))
|
||||
@@ -246,7 +247,7 @@ dpll_device_alloc(const u64 clock_id, u32 device_idx, struct module *module)
|
||||
dpll->clock_id = clock_id;
|
||||
dpll->module = module;
|
||||
ret = xa_alloc_cyclic(&dpll_device_xa, &dpll->id, dpll, xa_limit_32b,
|
||||
- &dpll_xa_id, GFP_KERNEL);
|
||||
+ &dpll_device_xa_id, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
kfree(dpll);
|
||||
return ERR_PTR(ret);
|
||||
@@ -446,7 +447,8 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
refcount_set(&pin->refcount, 1);
|
||||
xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC);
|
||||
xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC);
|
||||
- ret = xa_alloc(&dpll_pin_xa, &pin->id, pin, xa_limit_16b, GFP_KERNEL);
|
||||
+ ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b,
|
||||
+ &dpll_pin_xa_id, GFP_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
return pin;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,105 +0,0 @@
|
||||
From aebb7cbbcfce883a276aebfd7840d5297a471204 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Mon, 18 Dec 2023 15:58:55 +0100
|
||||
Subject: [PATCH 34/46] ice: dpll: fix phase offset value
|
||||
|
||||
Stop dividing the phase_offset value received from firmware. This fault
|
||||
is present since the initial implementation.
|
||||
The phase_offset value received from firmware is in 0.01ps resolution.
|
||||
Dpll subsystem is using the value in 0.001ps, raw value is adjusted
|
||||
before providing it to the user.
|
||||
|
||||
The user can observe the value of phase offset with response to
|
||||
`pin-get` netlink message of dpll subsystem for an active pin:
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml \
|
||||
--do pin-get --json '{"id":2}'
|
||||
|
||||
Where example of correct response would be:
|
||||
{'board-label': 'C827_0-RCLKA',
|
||||
'capabilities': 6,
|
||||
'clock-id': 4658613174691613800,
|
||||
'frequency': 1953125,
|
||||
'id': 2,
|
||||
'module-name': 'ice',
|
||||
'parent-device': [{'direction': 'input',
|
||||
'parent-id': 6,
|
||||
'phase-offset': -216839550,
|
||||
'prio': 9,
|
||||
'state': 'connected'},
|
||||
{'direction': 'input',
|
||||
'parent-id': 7,
|
||||
'phase-offset': -42930,
|
||||
'prio': 8,
|
||||
'state': 'connected'}],
|
||||
'phase-adjust': 0,
|
||||
'phase-adjust-max': 16723,
|
||||
'phase-adjust-min': -16723,
|
||||
'type': 'mux'}
|
||||
|
||||
Provided phase-offset value (-42930) shall be divided by the user with
|
||||
DPLL_PHASE_OFFSET_DIVIDER to get actual value of -42.930 ps.
|
||||
|
||||
Before the fix, the response was not correct:
|
||||
{'board-label': 'C827_0-RCLKA',
|
||||
'capabilities': 6,
|
||||
'clock-id': 4658613174691613800,
|
||||
'frequency': 1953125,
|
||||
'id': 2,
|
||||
'module-name': 'ice',
|
||||
'parent-device': [{'direction': 'input',
|
||||
'parent-id': 6,
|
||||
'phase-offset': -216839,
|
||||
'prio': 9,
|
||||
'state': 'connected'},
|
||||
{'direction': 'input',
|
||||
'parent-id': 7,
|
||||
'phase-offset': -42,
|
||||
'prio': 8,
|
||||
'state': 'connected'}],
|
||||
'phase-adjust': 0,
|
||||
'phase-adjust-max': 16723,
|
||||
'phase-adjust-min': -16723,
|
||||
'type': 'mux'}
|
||||
|
||||
Where phase-offset value (-42), after division
|
||||
(DPLL_PHASE_OFFSET_DIVIDER) would be: -0.042 ps.
|
||||
|
||||
Fixes: 8a3a565ff210 ("ice: add admin commands to access cgu configuration")
|
||||
Fixes: 90e1c90750d7 ("ice: dpll: implement phase related callbacks")
|
||||
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 8278a6a43d030a3aa8d7768148e74844331e39e3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index a1f1f037f327..7674267a2d90 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -5303,7 +5303,6 @@ ice_aq_get_cgu_dpll_status(struct ice_hw *hw, u8 dpll_num, u8 *ref_state,
|
||||
u8 *eec_mode)
|
||||
{
|
||||
struct ice_aqc_get_cgu_dpll_status *cmd;
|
||||
- const s64 nsec_per_psec = 1000LL;
|
||||
struct ice_aq_desc desc;
|
||||
int status;
|
||||
|
||||
@@ -5319,8 +5318,7 @@ ice_aq_get_cgu_dpll_status(struct ice_hw *hw, u8 dpll_num, u8 *ref_state,
|
||||
*phase_offset = le32_to_cpu(cmd->phase_offset_h);
|
||||
*phase_offset <<= 32;
|
||||
*phase_offset += le32_to_cpu(cmd->phase_offset_l);
|
||||
- *phase_offset = div64_s64(sign_extend64(*phase_offset, 47),
|
||||
- nsec_per_psec);
|
||||
+ *phase_offset = sign_extend64(*phase_offset, 47);
|
||||
*eec_mode = cmd->eec_mode;
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 34cbb064beb22a19c3c69fcefbc0c84eaa14d076 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Fri, 19 Jan 2024 14:43:01 +0100
|
||||
Subject: [PATCH 35/46] dpll: fix broken error path in dpll_pin_alloc(..)
|
||||
|
||||
If pin type is not expected, or pin properities failed to allocate
|
||||
memory, the unwind error path shall not destroy pin's xarrays, which
|
||||
were not yet initialized.
|
||||
Add new goto label and use it to fix broken error path.
|
||||
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit b6a11a7fc4d6337f7ea720b9287d1b9749c4eae0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_core.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
|
||||
index 1eca8cc271f8..c08772ee9fd6 100644
|
||||
--- a/drivers/dpll/dpll_core.c
|
||||
+++ b/drivers/dpll/dpll_core.c
|
||||
@@ -441,7 +441,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX ||
|
||||
prop->type > DPLL_PIN_TYPE_MAX)) {
|
||||
ret = -EINVAL;
|
||||
- goto err;
|
||||
+ goto err_pin_prop;
|
||||
}
|
||||
pin->prop = prop;
|
||||
refcount_set(&pin->refcount, 1);
|
||||
@@ -450,11 +450,12 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b,
|
||||
&dpll_pin_xa_id, GFP_KERNEL);
|
||||
if (ret)
|
||||
- goto err;
|
||||
+ goto err_xa_alloc;
|
||||
return pin;
|
||||
-err:
|
||||
+err_xa_alloc:
|
||||
xa_destroy(&pin->dpll_refs);
|
||||
xa_destroy(&pin->parent_refs);
|
||||
+err_pin_prop:
|
||||
kfree(pin);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,255 +0,0 @@
|
||||
From 0d3ade390857fb44333de60cadc255a92011d46f Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Fri, 19 Jan 2024 14:43:02 +0100
|
||||
Subject: [PATCH 36/46] dpll: fix pin dump crash for rebound module
|
||||
|
||||
When a kernel module is unbound but the pin resources were not entirely
|
||||
freed (other kernel module instance of the same PCI device have had kept
|
||||
the reference to that pin), and kernel module is again bound, the pin
|
||||
properties would not be updated (the properties are only assigned when
|
||||
memory for the pin is allocated), prop pointer still points to the
|
||||
kernel module memory of the kernel module which was deallocated on the
|
||||
unbind.
|
||||
|
||||
If the pin dump is invoked in this state, the result is a kernel crash.
|
||||
Prevent the crash by storing persistent pin properties in dpll subsystem,
|
||||
copy the content from the kernel module when pin is allocated, instead of
|
||||
using memory of the kernel module.
|
||||
|
||||
Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions")
|
||||
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
|
||||
Reviewed-by: Jan Glaza <jan.glaza@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit 830ead5fb0c5855ce4d70ba2ed4a673b5f1e7d9b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_core.c | 55 +++++++++++++++++++++++++++++++++++--
|
||||
drivers/dpll/dpll_core.h | 4 +--
|
||||
drivers/dpll/dpll_netlink.c | 28 +++++++++----------
|
||||
3 files changed, 69 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
|
||||
index c08772ee9fd6..cb62696467d1 100644
|
||||
--- a/drivers/dpll/dpll_core.c
|
||||
+++ b/drivers/dpll/dpll_core.c
|
||||
@@ -425,6 +425,53 @@ void dpll_device_unregister(struct dpll_device *dpll,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dpll_device_unregister);
|
||||
|
||||
+static void dpll_pin_prop_free(struct dpll_pin_properties *prop)
|
||||
+{
|
||||
+ kfree(prop->package_label);
|
||||
+ kfree(prop->panel_label);
|
||||
+ kfree(prop->board_label);
|
||||
+ kfree(prop->freq_supported);
|
||||
+}
|
||||
+
|
||||
+static int dpll_pin_prop_dup(const struct dpll_pin_properties *src,
|
||||
+ struct dpll_pin_properties *dst)
|
||||
+{
|
||||
+ memcpy(dst, src, sizeof(*dst));
|
||||
+ if (src->freq_supported && src->freq_supported_num) {
|
||||
+ size_t freq_size = src->freq_supported_num *
|
||||
+ sizeof(*src->freq_supported);
|
||||
+ dst->freq_supported = kmemdup(src->freq_supported,
|
||||
+ freq_size, GFP_KERNEL);
|
||||
+ if (!src->freq_supported)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ if (src->board_label) {
|
||||
+ dst->board_label = kstrdup(src->board_label, GFP_KERNEL);
|
||||
+ if (!dst->board_label)
|
||||
+ goto err_board_label;
|
||||
+ }
|
||||
+ if (src->panel_label) {
|
||||
+ dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL);
|
||||
+ if (!dst->panel_label)
|
||||
+ goto err_panel_label;
|
||||
+ }
|
||||
+ if (src->package_label) {
|
||||
+ dst->package_label = kstrdup(src->package_label, GFP_KERNEL);
|
||||
+ if (!dst->package_label)
|
||||
+ goto err_package_label;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_package_label:
|
||||
+ kfree(dst->panel_label);
|
||||
+err_panel_label:
|
||||
+ kfree(dst->board_label);
|
||||
+err_board_label:
|
||||
+ kfree(dst->freq_supported);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
static struct dpll_pin *
|
||||
dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
const struct dpll_pin_properties *prop)
|
||||
@@ -443,7 +490,9 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
ret = -EINVAL;
|
||||
goto err_pin_prop;
|
||||
}
|
||||
- pin->prop = prop;
|
||||
+ ret = dpll_pin_prop_dup(prop, &pin->prop);
|
||||
+ if (ret)
|
||||
+ goto err_pin_prop;
|
||||
refcount_set(&pin->refcount, 1);
|
||||
xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC);
|
||||
xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC);
|
||||
@@ -455,6 +504,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
||||
err_xa_alloc:
|
||||
xa_destroy(&pin->dpll_refs);
|
||||
xa_destroy(&pin->parent_refs);
|
||||
+ dpll_pin_prop_free(&pin->prop);
|
||||
err_pin_prop:
|
||||
kfree(pin);
|
||||
return ERR_PTR(ret);
|
||||
@@ -515,6 +565,7 @@ void dpll_pin_put(struct dpll_pin *pin)
|
||||
xa_destroy(&pin->dpll_refs);
|
||||
xa_destroy(&pin->parent_refs);
|
||||
xa_erase(&dpll_pin_xa, pin->id);
|
||||
+ dpll_pin_prop_free(&pin->prop);
|
||||
kfree(pin);
|
||||
}
|
||||
mutex_unlock(&dpll_lock);
|
||||
@@ -637,7 +688,7 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin,
|
||||
unsigned long i, stop;
|
||||
int ret;
|
||||
|
||||
- if (WARN_ON(parent->prop->type != DPLL_PIN_TYPE_MUX))
|
||||
+ if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(!ops) ||
|
||||
diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h
|
||||
index 5585873c5c1b..717f715015c7 100644
|
||||
--- a/drivers/dpll/dpll_core.h
|
||||
+++ b/drivers/dpll/dpll_core.h
|
||||
@@ -44,7 +44,7 @@ struct dpll_device {
|
||||
* @module: module of creator
|
||||
* @dpll_refs: hold referencees to dplls pin was registered with
|
||||
* @parent_refs: hold references to parent pins pin was registered with
|
||||
- * @prop: pointer to pin properties given by registerer
|
||||
+ * @prop: pin properties copied from the registerer
|
||||
* @rclk_dev_name: holds name of device when pin can recover clock from it
|
||||
* @refcount: refcount
|
||||
**/
|
||||
@@ -55,7 +55,7 @@ struct dpll_pin {
|
||||
struct module *module;
|
||||
struct xarray dpll_refs;
|
||||
struct xarray parent_refs;
|
||||
- const struct dpll_pin_properties *prop;
|
||||
+ struct dpll_pin_properties prop;
|
||||
refcount_t refcount;
|
||||
};
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index ce7cf736f020..4c64611d32ac 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -278,17 +278,17 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq,
|
||||
DPLL_A_PIN_PAD))
|
||||
return -EMSGSIZE;
|
||||
- for (fs = 0; fs < pin->prop->freq_supported_num; fs++) {
|
||||
+ for (fs = 0; fs < pin->prop.freq_supported_num; fs++) {
|
||||
nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED);
|
||||
if (!nest)
|
||||
return -EMSGSIZE;
|
||||
- freq = pin->prop->freq_supported[fs].min;
|
||||
+ freq = pin->prop.freq_supported[fs].min;
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq),
|
||||
&freq, DPLL_A_PIN_PAD)) {
|
||||
nla_nest_cancel(msg, nest);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
- freq = pin->prop->freq_supported[fs].max;
|
||||
+ freq = pin->prop.freq_supported[fs].max;
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq),
|
||||
&freq, DPLL_A_PIN_PAD)) {
|
||||
nla_nest_cancel(msg, nest);
|
||||
@@ -304,9 +304,9 @@ static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
|
||||
{
|
||||
int fs;
|
||||
|
||||
- for (fs = 0; fs < pin->prop->freq_supported_num; fs++)
|
||||
- if (freq >= pin->prop->freq_supported[fs].min &&
|
||||
- freq <= pin->prop->freq_supported[fs].max)
|
||||
+ for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
|
||||
+ if (freq >= pin->prop.freq_supported[fs].min &&
|
||||
+ freq <= pin->prop.freq_supported[fs].max)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -396,7 +396,7 @@ static int
|
||||
dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
- const struct dpll_pin_properties *prop = pin->prop;
|
||||
+ const struct dpll_pin_properties *prop = &pin->prop;
|
||||
struct dpll_pin_ref *ref;
|
||||
int ret;
|
||||
|
||||
@@ -689,7 +689,7 @@ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
|
||||
int ret;
|
||||
|
||||
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
|
||||
- pin->prop->capabilities)) {
|
||||
+ pin->prop.capabilities)) {
|
||||
NL_SET_ERR_MSG(extack, "state changing is not allowed");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -725,7 +725,7 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
|
||||
int ret;
|
||||
|
||||
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
|
||||
- pin->prop->capabilities)) {
|
||||
+ pin->prop.capabilities)) {
|
||||
NL_SET_ERR_MSG(extack, "state changing is not allowed");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -752,7 +752,7 @@ dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
|
||||
int ret;
|
||||
|
||||
if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
|
||||
- pin->prop->capabilities)) {
|
||||
+ pin->prop.capabilities)) {
|
||||
NL_SET_ERR_MSG(extack, "prio changing is not allowed");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -780,7 +780,7 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
|
||||
int ret;
|
||||
|
||||
if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
|
||||
- pin->prop->capabilities)) {
|
||||
+ pin->prop.capabilities)) {
|
||||
NL_SET_ERR_MSG(extack, "direction changing is not allowed");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -810,8 +810,8 @@ dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
|
||||
int ret;
|
||||
|
||||
phase_adj = nla_get_s32(phase_adj_attr);
|
||||
- if (phase_adj > pin->prop->phase_range.max ||
|
||||
- phase_adj < pin->prop->phase_range.min) {
|
||||
+ if (phase_adj > pin->prop.phase_range.max ||
|
||||
+ phase_adj < pin->prop.phase_range.min) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
|
||||
"phase adjust value not supported");
|
||||
return -EINVAL;
|
||||
@@ -995,7 +995,7 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
|
||||
unsigned long i;
|
||||
|
||||
xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
|
||||
- prop = pin->prop;
|
||||
+ prop = &pin->prop;
|
||||
cid_match = clock_id ? pin->clock_id == clock_id : true;
|
||||
mod_match = mod_name_attr && module_name(pin->module) ?
|
||||
!nla_strcmp(mod_name_attr,
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,95 +0,0 @@
|
||||
From f4e9960be23f4982fc11fff1e5c78539254f0819 Mon Sep 17 00:00:00 2001
|
||||
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Date: Fri, 19 Jan 2024 14:43:03 +0100
|
||||
Subject: [PATCH 37/46] dpll: fix userspace availability of pins
|
||||
|
||||
If parent pin was unregistered but child pin was not, the userspace
|
||||
would see the "zombie" pins - the ones that were registered with
|
||||
a parent pin (dpll_pin_on_pin_register(..)).
|
||||
Technically those are not available - as there is no dpll device in the
|
||||
system. Do not dump those pins and prevent userspace from any
|
||||
interaction with them. Provide a unified function to determine if the
|
||||
pin is available and use it before acting/responding for user requests.
|
||||
|
||||
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
|
||||
Reviewed-by: Jan Glaza <jan.glaza@intel.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit db2ec3c94667eaeecc6a74d96594fab6baf80fdc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/dpll/dpll_netlink.c | 29 +++++++++++++++++++++++++++--
|
||||
1 file changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
||||
index 4c64611d32ac..7cc99d627942 100644
|
||||
--- a/drivers/dpll/dpll_netlink.c
|
||||
+++ b/drivers/dpll/dpll_netlink.c
|
||||
@@ -525,6 +525,24 @@ __dpll_device_change_ntf(struct dpll_device *dpll)
|
||||
return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll);
|
||||
}
|
||||
|
||||
+static bool dpll_pin_available(struct dpll_pin *pin)
|
||||
+{
|
||||
+ struct dpll_pin_ref *par_ref;
|
||||
+ unsigned long i;
|
||||
+
|
||||
+ if (!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED))
|
||||
+ return false;
|
||||
+ xa_for_each(&pin->parent_refs, i, par_ref)
|
||||
+ if (xa_get_mark(&dpll_pin_xa, par_ref->pin->id,
|
||||
+ DPLL_REGISTERED))
|
||||
+ return true;
|
||||
+ xa_for_each(&pin->dpll_refs, i, par_ref)
|
||||
+ if (xa_get_mark(&dpll_device_xa, par_ref->dpll->id,
|
||||
+ DPLL_REGISTERED))
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* dpll_device_change_ntf - notify that the dpll device has been changed
|
||||
* @dpll: registered dpll pointer
|
||||
@@ -551,7 +569,7 @@ dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin)
|
||||
int ret = -ENOMEM;
|
||||
void *hdr;
|
||||
|
||||
- if (WARN_ON(!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED)))
|
||||
+ if (!dpll_pin_available(pin))
|
||||
return -ENODEV;
|
||||
|
||||
msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
@@ -1102,6 +1120,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
pin = dpll_pin_find_from_nlattr(info);
|
||||
if (!IS_ERR(pin)) {
|
||||
+ if (!dpll_pin_available(pin)) {
|
||||
+ nlmsg_free(msg);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
ret = dpll_msg_add_pin_handle(msg, pin);
|
||||
if (ret) {
|
||||
nlmsg_free(msg);
|
||||
@@ -1151,6 +1173,8 @@ int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED,
|
||||
ctx->idx) {
|
||||
+ if (!dpll_pin_available(pin))
|
||||
+ continue;
|
||||
hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
&dpll_nl_family, NLM_F_MULTI,
|
||||
@@ -1413,7 +1437,8 @@ int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
}
|
||||
info->user_ptr[0] = xa_load(&dpll_pin_xa,
|
||||
nla_get_u32(info->attrs[DPLL_A_PIN_ID]));
|
||||
- if (!info->user_ptr[0]) {
|
||||
+ if (!info->user_ptr[0] ||
|
||||
+ !dpll_pin_available(info->user_ptr[0])) {
|
||||
NL_SET_ERR_MSG(info->extack, "pin not found");
|
||||
ret = -ENODEV;
|
||||
goto unlock_dev;
|
||||
--
|
||||
2.43.0
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user