]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.12
authorSasha Levin <sashal@kernel.org>
Sat, 18 Jan 2025 17:23:26 +0000 (12:23 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 18 Jan 2025 17:23:26 +0000 (12:23 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
36 files changed:
queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch [new file with mode: 0644]
queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch [new file with mode: 0644]
queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch [new file with mode: 0644]
queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch [new file with mode: 0644]
queue-6.12/drm-tests-helpers-fix-compiler-warning.patch [new file with mode: 0644]
queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch [new file with mode: 0644]
queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch [new file with mode: 0644]
queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch [new file with mode: 0644]
queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch [new file with mode: 0644]
queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch [new file with mode: 0644]
queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch [new file with mode: 0644]
queue-6.12/ice-add-correct-phy-lane-assignment.patch [new file with mode: 0644]
queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch [new file with mode: 0644]
queue-6.12/ice-fix-e825-initialization.patch [new file with mode: 0644]
queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch [new file with mode: 0644]
queue-6.12/ice-fix-quad-registers-read-on-e825.patch [new file with mode: 0644]
queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch [new file with mode: 0644]
queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch [new file with mode: 0644]
queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch [new file with mode: 0644]
queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch [new file with mode: 0644]
queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch [new file with mode: 0644]
queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch [new file with mode: 0644]
queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch [new file with mode: 0644]
queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch [new file with mode: 0644]
queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch [new file with mode: 0644]
queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch [new file with mode: 0644]
queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch [new file with mode: 0644]
queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch [new file with mode: 0644]
queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch [new file with mode: 0644]
queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch b/queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch
new file mode 100644 (file)
index 0000000..4667f1e
--- /dev/null
@@ -0,0 +1,112 @@
+From bf86ba00e5c71f0b2bbce7c3a95b15b71c46334f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 14:21:55 +0100
+Subject: bpf: Fix bpf_sk_select_reuseport() memory leak
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit b3af60928ab9129befa65e6df0310d27300942bf ]
+
+As pointed out in the original comment, lookup in sockmap can return a TCP
+ESTABLISHED socket. Such TCP socket may have had SO_ATTACH_REUSEPORT_EBPF
+set before it was ESTABLISHED. In other words, a non-NULL sk_reuseport_cb
+does not imply a non-refcounted socket.
+
+Drop sk's reference in both error paths.
+
+unreferenced object 0xffff888101911800 (size 2048):
+  comm "test_progs", pid 44109, jiffies 4297131437
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    80 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace (crc 9336483b):
+    __kmalloc_noprof+0x3bf/0x560
+    __reuseport_alloc+0x1d/0x40
+    reuseport_alloc+0xca/0x150
+    reuseport_attach_prog+0x87/0x140
+    sk_reuseport_attach_bpf+0xc8/0x100
+    sk_setsockopt+0x1181/0x1990
+    do_sock_setsockopt+0x12b/0x160
+    __sys_setsockopt+0x7b/0xc0
+    __x64_sys_setsockopt+0x1b/0x30
+    do_syscall_64+0x93/0x180
+    entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 64d85290d79c ("bpf: Allow bpf_map_lookup_elem for SOCKMAP and SOCKHASH")
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Martin KaFai Lau <martin.lau@kernel.org>
+Link: https://patch.msgid.link/20250110-reuseport-memleak-v1-1-fa1ddab0adfe@rbox.co
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 30 ++++++++++++++++++------------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 54a53fae9e98f..46da488ff0703 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -11263,6 +11263,7 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
+       bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY;
+       struct sock_reuseport *reuse;
+       struct sock *selected_sk;
++      int err;
+       selected_sk = map->ops->map_lookup_elem(map, key);
+       if (!selected_sk)
+@@ -11270,10 +11271,6 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
+       reuse = rcu_dereference(selected_sk->sk_reuseport_cb);
+       if (!reuse) {
+-              /* Lookup in sock_map can return TCP ESTABLISHED sockets. */
+-              if (sk_is_refcounted(selected_sk))
+-                      sock_put(selected_sk);
+-
+               /* reuseport_array has only sk with non NULL sk_reuseport_cb.
+                * The only (!reuse) case here is - the sk has already been
+                * unhashed (e.g. by close()), so treat it as -ENOENT.
+@@ -11281,24 +11278,33 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
+                * Other maps (e.g. sock_map) do not provide this guarantee and
+                * the sk may never be in the reuseport group to begin with.
+                */
+-              return is_sockarray ? -ENOENT : -EINVAL;
++              err = is_sockarray ? -ENOENT : -EINVAL;
++              goto error;
+       }
+       if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) {
+               struct sock *sk = reuse_kern->sk;
+-              if (sk->sk_protocol != selected_sk->sk_protocol)
+-                      return -EPROTOTYPE;
+-              else if (sk->sk_family != selected_sk->sk_family)
+-                      return -EAFNOSUPPORT;
+-
+-              /* Catch all. Likely bound to a different sockaddr. */
+-              return -EBADFD;
++              if (sk->sk_protocol != selected_sk->sk_protocol) {
++                      err = -EPROTOTYPE;
++              } else if (sk->sk_family != selected_sk->sk_family) {
++                      err = -EAFNOSUPPORT;
++              } else {
++                      /* Catch all. Likely bound to a different sockaddr. */
++                      err = -EBADFD;
++              }
++              goto error;
+       }
+       reuse_kern->selected_sk = selected_sk;
+       return 0;
++error:
++      /* Lookup in sock_map can return TCP ESTABLISHED sockets. */
++      if (sk_is_refcounted(selected_sk))
++              sock_put(selected_sk);
++
++      return err;
+ }
+ static const struct bpf_func_proto sk_select_reuseport_proto = {
+-- 
+2.39.5
+
diff --git a/queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch b/queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch
new file mode 100644 (file)
index 0000000..1b826be
--- /dev/null
@@ -0,0 +1,44 @@
+From e3209b40abc256afb1bf6d333855af2f3a448e8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 14:14:04 +1030
+Subject: btrfs: add the missing error handling inside get_canonical_dev_path
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit fe4de594f7a2e9bc49407de60fbd20809fad4192 ]
+
+Inside function get_canonical_dev_path(), we call d_path() to get the
+final device path.
+
+But d_path() can return error, and in that case the next strscpy() call
+will trigger an invalid memory access.
+
+Add back the missing error handling for d_path().
+
+Reported-by: Boris Burkov <boris@bur.io>
+Fixes: 7e06de7c83a7 ("btrfs: canonicalize the device path before adding it")
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 0c4d14c59ebec..395b8b880ce78 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -797,6 +797,10 @@ static int get_canonical_dev_path(const char *dev_path, char *canonical)
+       if (ret)
+               goto out;
+       resolved_path = d_path(&path, path_buf, PATH_MAX);
++      if (IS_ERR(resolved_path)) {
++              ret = PTR_ERR(resolved_path);
++              goto out;
++      }
+       ret = strscpy(canonical, resolved_path, PATH_MAX);
+ out:
+       kfree(path_buf);
+-- 
+2.39.5
+
diff --git a/queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch b/queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch
new file mode 100644 (file)
index 0000000..5ee96e4
--- /dev/null
@@ -0,0 +1,48 @@
+From 81762656f37ef8ad57ec798405377b45a893ec61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 11:23:10 +0530
+Subject: cpufreq: Move endif to the end of Kconfig file
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 7e265fc04690d449a40b413b0348b15c748cea6f ]
+
+It is possible to enable few cpufreq drivers, without the framework
+being enabled. This happened due to a bug while moving the entries
+earlier. Fix it.
+
+Fixes: 7ee1378736f0 ("cpufreq: Move CPPC configs to common Kconfig and add RISC-V")
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://patch.msgid.link/84ac7a8fa72a8fe20487bb0a350a758bce060965.1736488384.git.viresh.kumar@linaro.org
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index 2561b215432a8..588ab1cc6d557 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -311,8 +311,6 @@ config QORIQ_CPUFREQ
+         This adds the CPUFreq driver support for Freescale QorIQ SoCs
+         which are capable of changing the CPU's frequency dynamically.
+-endif
+-
+ config ACPI_CPPC_CPUFREQ
+       tristate "CPUFreq driver based on the ACPI CPPC spec"
+       depends on ACPI_PROCESSOR
+@@ -341,4 +339,6 @@ config ACPI_CPPC_CPUFREQ_FIE
+         If in doubt, say N.
++endif
++
+ endmenu
+-- 
+2.39.5
+
diff --git a/queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch b/queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch
new file mode 100644 (file)
index 0000000..db8d8bf
--- /dev/null
@@ -0,0 +1,163 @@
+From c81ea42a9926a06754cae3a300b94a34b8c15fd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 13:48:10 +0100
+Subject: cpuidle: teo: Update documentation after previous changes
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 5a597a19a2148d1c5cd987907a60c042ab0f62d5 ]
+
+After previous changes, the description of the teo governor in the
+documentation comment does not match the code any more, so update it
+as appropriate.
+
+Fixes: 449914398083 ("cpuidle: teo: Remove recent intercepts metric")
+Fixes: 2662342079f5 ("cpuidle: teo: Gather statistics regarding whether or not to stop the tick")
+Fixes: 6da8f9ba5a87 ("cpuidle: teo: Skip tick_nohz_get_sleep_length() call in some cases")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/6120335.lOV4Wx5bFT@rjwysocki.net
+[ rjw: Corrected 3 typos found by Christian ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/governors/teo.c | 91 +++++++++++++++++----------------
+ 1 file changed, 48 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c
+index f2992f92d8db8..173ddcac540ad 100644
+--- a/drivers/cpuidle/governors/teo.c
++++ b/drivers/cpuidle/governors/teo.c
+@@ -10,25 +10,27 @@
+  * DOC: teo-description
+  *
+  * The idea of this governor is based on the observation that on many systems
+- * timer events are two or more orders of magnitude more frequent than any
+- * other interrupts, so they are likely to be the most significant cause of CPU
+- * wakeups from idle states.  Moreover, information about what happened in the
+- * (relatively recent) past can be used to estimate whether or not the deepest
+- * idle state with target residency within the (known) time till the closest
+- * timer event, referred to as the sleep length, is likely to be suitable for
+- * the upcoming CPU idle period and, if not, then which of the shallower idle
+- * states to choose instead of it.
++ * timer interrupts are two or more orders of magnitude more frequent than any
++ * other interrupt types, so they are likely to dominate CPU wakeup patterns.
++ * Moreover, in principle, the time when the next timer event is going to occur
++ * can be determined at the idle state selection time, although doing that may
++ * be costly, so it can be regarded as the most reliable source of information
++ * for idle state selection.
+  *
+- * Of course, non-timer wakeup sources are more important in some use cases
+- * which can be covered by taking a few most recent idle time intervals of the
+- * CPU into account.  However, even in that context it is not necessary to
+- * consider idle duration values greater than the sleep length, because the
+- * closest timer will ultimately wake up the CPU anyway unless it is woken up
+- * earlier.
++ * Of course, non-timer wakeup sources are more important in some use cases,
++ * but even then it is generally unnecessary to consider idle duration values
++ * greater than the time time till the next timer event, referred as the sleep
++ * length in what follows, because the closest timer will ultimately wake up the
++ * CPU anyway unless it is woken up earlier.
+  *
+- * Thus this governor estimates whether or not the prospective idle duration of
+- * a CPU is likely to be significantly shorter than the sleep length and selects
+- * an idle state for it accordingly.
++ * However, since obtaining the sleep length may be costly, the governor first
++ * checks if it can select a shallow idle state using wakeup pattern information
++ * from recent times, in which case it can do without knowing the sleep length
++ * at all.  For this purpose, it counts CPU wakeup events and looks for an idle
++ * state whose target residency has not exceeded the idle duration (measured
++ * after wakeup) in the majority of relevant recent cases.  If the target
++ * residency of that state is small enough, it may be used right away and the
++ * sleep length need not be determined.
+  *
+  * The computations carried out by this governor are based on using bins whose
+  * boundaries are aligned with the target residency parameter values of the CPU
+@@ -39,7 +41,11 @@
+  * idle state 2, the third bin spans from the target residency of idle state 2
+  * up to, but not including, the target residency of idle state 3 and so on.
+  * The last bin spans from the target residency of the deepest idle state
+- * supplied by the driver to infinity.
++ * supplied by the driver to the scheduler tick period length or to infinity if
++ * the tick period length is less than the target residency of that state.  In
++ * the latter case, the governor also counts events with the measured idle
++ * duration between the tick period length and the target residency of the
++ * deepest idle state.
+  *
+  * Two metrics called "hits" and "intercepts" are associated with each bin.
+  * They are updated every time before selecting an idle state for the given CPU
+@@ -49,47 +55,46 @@
+  * sleep length and the idle duration measured after CPU wakeup fall into the
+  * same bin (that is, the CPU appears to wake up "on time" relative to the sleep
+  * length).  In turn, the "intercepts" metric reflects the relative frequency of
+- * situations in which the measured idle duration is so much shorter than the
+- * sleep length that the bin it falls into corresponds to an idle state
+- * shallower than the one whose bin is fallen into by the sleep length (these
+- * situations are referred to as "intercepts" below).
++ * non-timer wakeup events for which the measured idle duration falls into a bin
++ * that corresponds to an idle state shallower than the one whose bin is fallen
++ * into by the sleep length (these events are also referred to as "intercepts"
++ * below).
+  *
+  * In order to select an idle state for a CPU, the governor takes the following
+  * steps (modulo the possible latency constraint that must be taken into account
+  * too):
+  *
+- * 1. Find the deepest CPU idle state whose target residency does not exceed
+- *    the current sleep length (the candidate idle state) and compute 2 sums as
+- *    follows:
++ * 1. Find the deepest enabled CPU idle state (the candidate idle state) and
++ *    compute 2 sums as follows:
+  *
+- *    - The sum of the "hits" and "intercepts" metrics for the candidate state
+- *      and all of the deeper idle states (it represents the cases in which the
+- *      CPU was idle long enough to avoid being intercepted if the sleep length
+- *      had been equal to the current one).
++ *    - The sum of the "hits" metric for all of the idle states shallower than
++ *      the candidate one (it represents the cases in which the CPU was likely
++ *      woken up by a timer).
+  *
+- *    - The sum of the "intercepts" metrics for all of the idle states shallower
+- *      than the candidate one (it represents the cases in which the CPU was not
+- *      idle long enough to avoid being intercepted if the sleep length had been
+- *      equal to the current one).
++ *    - The sum of the "intercepts" metric for all of the idle states shallower
++ *      than the candidate one (it represents the cases in which the CPU was
++ *      likely woken up by a non-timer wakeup source).
+  *
+- * 2. If the second sum is greater than the first one the CPU is likely to wake
+- *    up early, so look for an alternative idle state to select.
++ * 2. If the second sum computed in step 1 is greater than a half of the sum of
++ *    both metrics for the candidate state bin and all subsequent bins(if any),
++ *    a shallower idle state is likely to be more suitable, so look for it.
+  *
+- *    - Traverse the idle states shallower than the candidate one in the
++ *    - Traverse the enabled idle states shallower than the candidate one in the
+  *      descending order.
+  *
+  *    - For each of them compute the sum of the "intercepts" metrics over all
+  *      of the idle states between it and the candidate one (including the
+  *      former and excluding the latter).
+  *
+- *    - If each of these sums that needs to be taken into account (because the
+- *      check related to it has indicated that the CPU is likely to wake up
+- *      early) is greater than a half of the corresponding sum computed in step
+- *      1 (which means that the target residency of the state in question had
+- *      not exceeded the idle duration in over a half of the relevant cases),
+- *      select the given idle state instead of the candidate one.
++ *    - If this sum is greater than a half of the second sum computed in step 1,
++ *      use the given idle state as the new candidate one.
+  *
+- * 3. By default, select the candidate state.
++ * 3. If the current candidate state is state 0 or its target residency is short
++ *    enough, return it and prevent the scheduler tick from being stopped.
++ *
++ * 4. Obtain the sleep length value and check if it is below the target
++ *    residency of the current candidate state, in which case a new shallower
++ *    candidate state needs to be found, so look for it.
+  */
+ #include <linux/cpuidle.h>
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-tests-helpers-fix-compiler-warning.patch b/queue-6.12/drm-tests-helpers-fix-compiler-warning.patch
new file mode 100644 (file)
index 0000000..5294750
--- /dev/null
@@ -0,0 +1,45 @@
+From e118e0787c354ebc3af802df44471ad75c49840c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jan 2025 00:51:33 +0800
+Subject: drm/tests: helpers: Fix compiler warning
+
+From: Yu-Chun Lin <eleanor15x@gmail.com>
+
+[ Upstream commit b9097e4c8bf3934e4e07e6f9b88741957fef351e ]
+
+Delete one line break to make the format correct, resolving the
+following warning during a W=1 build:
+
+>> drivers/gpu/drm/tests/drm_kunit_helpers.c:324: warning: bad line: for a KUnit test
+
+Fixes: caa714f86699 ("drm/tests: helpers: Add helper for drm_display_mode_from_cea_vic()")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202501032001.O6WY1VCW-lkp@intel.com/
+Reviewed-by: Kuan-Wei Chiu <visitorckw@gmail.com>
+Tested-by: Kuan-Wei Chiu <visitorckw@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250104165134.1695864-1-eleanor15x@gmail.com
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
+index 04a6b8cc62ac6..3c0b7824c0be3 100644
+--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
++++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
+@@ -320,8 +320,7 @@ static void kunit_action_drm_mode_destroy(void *ptr)
+ }
+ /**
+- * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC
+-                                         for a KUnit test
++ * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test
+  * @test: The test context object
+  * @dev: DRM device
+  * @video_code: CEA VIC of the mode
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch b/queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch
new file mode 100644 (file)
index 0000000..339994e
--- /dev/null
@@ -0,0 +1,66 @@
+From ab48977d8c5709ea1f62a31443c1d4dab2ea87b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 12:47:40 -0300
+Subject: drm/v3d: Ensure job pointer is set to NULL after job completion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit e4b5ccd392b92300a2b341705cc4805681094e49 ]
+
+After a job completes, the corresponding pointer in the device must
+be set to NULL. Failing to do so triggers a warning when unloading
+the driver, as it appears the job is still active. To prevent this,
+assign the job pointer to NULL after completing the job, indicating
+the job has finished.
+
+Fixes: 14d1d1908696 ("drm/v3d: Remove the bad signaled() implementation.")
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250113154741.67520-1-mcanal@igalia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_irq.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
+index 20bf33702c3c4..da203045df9be 100644
+--- a/drivers/gpu/drm/v3d/v3d_irq.c
++++ b/drivers/gpu/drm/v3d/v3d_irq.c
+@@ -108,6 +108,7 @@ v3d_irq(int irq, void *arg)
+               v3d_job_update_stats(&v3d->bin_job->base, V3D_BIN);
+               trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
+               dma_fence_signal(&fence->base);
++              v3d->bin_job = NULL;
+               status = IRQ_HANDLED;
+       }
+@@ -118,6 +119,7 @@ v3d_irq(int irq, void *arg)
+               v3d_job_update_stats(&v3d->render_job->base, V3D_RENDER);
+               trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
+               dma_fence_signal(&fence->base);
++              v3d->render_job = NULL;
+               status = IRQ_HANDLED;
+       }
+@@ -128,6 +130,7 @@ v3d_irq(int irq, void *arg)
+               v3d_job_update_stats(&v3d->csd_job->base, V3D_CSD);
+               trace_v3d_csd_irq(&v3d->drm, fence->seqno);
+               dma_fence_signal(&fence->base);
++              v3d->csd_job = NULL;
+               status = IRQ_HANDLED;
+       }
+@@ -165,6 +168,7 @@ v3d_hub_irq(int irq, void *arg)
+               v3d_job_update_stats(&v3d->tfu_job->base, V3D_TFU);
+               trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
+               dma_fence_signal(&fence->base);
++              v3d->tfu_job = NULL;
+               status = IRQ_HANDLED;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch b/queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch
new file mode 100644 (file)
index 0000000..3c3717e
--- /dev/null
@@ -0,0 +1,147 @@
+From b1e88bd6bb9183213adf646a54c792be356c04ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 12:53:35 -0600
+Subject: drm/vmwgfx: Add new keep_resv BO param
+
+From: Ian Forbes <ian.forbes@broadcom.com>
+
+[ Upstream commit b7d40627813799870e72729c6fc979a8a40d9ba6 ]
+
+Adds a new BO param that keeps the reservation locked after creation.
+This removes the need to re-reserve the BO after creation which is a
+waste of cycles.
+
+This also fixes a bug in vmw_prime_import_sg_table where the imported
+reservation is unlocked twice.
+
+Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
+Fixes: b32233acceff ("drm/vmwgfx: Fix prime import/export")
+Reviewed-by: Zack Rusin <zack.rusin@broadcom.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250110185335.15301-1-ian.forbes@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.c         | 3 ++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.h         | 3 ++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c        | 7 ++-----
+ drivers/gpu/drm/vmwgfx/vmwgfx_gem.c        | 1 +
+ drivers/gpu/drm/vmwgfx/vmwgfx_shader.c     | 7 ++-----
+ drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 5 ++---
+ 6 files changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+index a0e433fbcba67..183cda50094cb 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+@@ -443,7 +443,8 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
+       if (params->pin)
+               ttm_bo_pin(&vmw_bo->tbo);
+-      ttm_bo_unreserve(&vmw_bo->tbo);
++      if (!params->keep_resv)
++              ttm_bo_unreserve(&vmw_bo->tbo);
+       return 0;
+ }
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+index 43b5439ec9f76..c21ba7ff77368 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+@@ -56,8 +56,9 @@ struct vmw_bo_params {
+       u32 domain;
+       u32 busy_domain;
+       enum ttm_bo_type bo_type;
+-      size_t size;
+       bool pin;
++      bool keep_resv;
++      size_t size;
+       struct dma_resv *resv;
+       struct sg_table *sg;
+ };
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index 2825dd3149ed5..2e84e1029732d 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -401,7 +401,8 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
+               .busy_domain = VMW_BO_DOMAIN_SYS,
+               .bo_type = ttm_bo_type_kernel,
+               .size = PAGE_SIZE,
+-              .pin = true
++              .pin = true,
++              .keep_resv = true,
+       };
+       /*
+@@ -413,10 +414,6 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
+       if (unlikely(ret != 0))
+               return ret;
+-      ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
+-      BUG_ON(ret != 0);
+-      vmw_bo_pin_reserved(vbo, true);
+-
+       ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map);
+       if (likely(ret == 0)) {
+               result = ttm_kmap_obj_virtual(&map, &dummy);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+index b9857f37ca1ac..ed5015ced3920 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+@@ -206,6 +206,7 @@ struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev,
+               .bo_type = ttm_bo_type_sg,
+               .size = attach->dmabuf->size,
+               .pin = false,
++              .keep_resv = true,
+               .resv = attach->dmabuf->resv,
+               .sg = table,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+index a01ca3226d0af..7fb1c88bcc475 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+@@ -896,7 +896,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
+               .busy_domain = VMW_BO_DOMAIN_SYS,
+               .bo_type = ttm_bo_type_device,
+               .size = size,
+-              .pin = true
++              .pin = true,
++              .keep_resv = true,
+       };
+       if (!vmw_shader_id_ok(user_key, shader_type))
+@@ -906,10 +907,6 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
+       if (unlikely(ret != 0))
+               goto out;
+-      ret = ttm_bo_reserve(&buf->tbo, false, true, NULL);
+-      if (unlikely(ret != 0))
+-              goto no_reserve;
+-
+       /* Map and copy shader bytecode. */
+       ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map);
+       if (unlikely(ret != 0)) {
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+index 621d98b376bbb..5553892d7c3e0 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+@@ -572,15 +572,14 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
+               .busy_domain = domain,
+               .bo_type = ttm_bo_type_kernel,
+               .size = bo_size,
+-              .pin = true
++              .pin = true,
++              .keep_resv = true,
+       };
+       ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
+       if (unlikely(ret != 0))
+               return ret;
+-      ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
+-      BUG_ON(ret != 0);
+       ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx);
+       if (likely(ret == 0)) {
+               struct vmw_ttm_tt *vmw_tt =
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch b/queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch
new file mode 100644 (file)
index 0000000..486ad6d
--- /dev/null
@@ -0,0 +1,81 @@
+From f1c0d4f64ee64a22cf5f861c2714457f2ed0948e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Dec 2024 13:55:35 -0600
+Subject: drm/vmwgfx: Unreserve BO on error
+
+From: Ian Forbes <ian.forbes@broadcom.com>
+
+[ Upstream commit cb343ded122e0bf41e4b2a9f89386296451be109 ]
+
+Unlock BOs in reverse order.
+Add an acquire context so that lockdep doesn't complain.
+
+Fixes: d6667f0ddf46 ("drm/vmwgfx: Fix handling of dumb buffers")
+Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241210195535.2074918-1-ian.forbes@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 10d596cb4b402..5f99f7437ae61 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -750,6 +750,7 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
+       struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
+       struct vmw_bo *old_bo = NULL;
+       struct vmw_bo *new_bo = NULL;
++      struct ww_acquire_ctx ctx;
+       s32 hotspot_x, hotspot_y;
+       int ret;
+@@ -769,9 +770,11 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
+       if (du->cursor_surface)
+               du->cursor_age = du->cursor_surface->snooper.age;
++      ww_acquire_init(&ctx, &reservation_ww_class);
++
+       if (!vmw_user_object_is_null(&old_vps->uo)) {
+               old_bo = vmw_user_object_buffer(&old_vps->uo);
+-              ret = ttm_bo_reserve(&old_bo->tbo, false, false, NULL);
++              ret = ttm_bo_reserve(&old_bo->tbo, false, false, &ctx);
+               if (ret != 0)
+                       return;
+       }
+@@ -779,9 +782,14 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
+       if (!vmw_user_object_is_null(&vps->uo)) {
+               new_bo = vmw_user_object_buffer(&vps->uo);
+               if (old_bo != new_bo) {
+-                      ret = ttm_bo_reserve(&new_bo->tbo, false, false, NULL);
+-                      if (ret != 0)
++                      ret = ttm_bo_reserve(&new_bo->tbo, false, false, &ctx);
++                      if (ret != 0) {
++                              if (old_bo) {
++                                      ttm_bo_unreserve(&old_bo->tbo);
++                                      ww_acquire_fini(&ctx);
++                              }
+                               return;
++                      }
+               } else {
+                       new_bo = NULL;
+               }
+@@ -803,10 +811,12 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
+                                               hotspot_x, hotspot_y);
+       }
+-      if (old_bo)
+-              ttm_bo_unreserve(&old_bo->tbo);
+       if (new_bo)
+               ttm_bo_unreserve(&new_bo->tbo);
++      if (old_bo)
++              ttm_bo_unreserve(&old_bo->tbo);
++
++      ww_acquire_fini(&ctx);
+       du->cursor_x = new_state->crtc_x + du->set_gui_x;
+       du->cursor_y = new_state->crtc_y + du->set_gui_y;
+-- 
+2.39.5
+
diff --git a/queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch b/queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch
new file mode 100644 (file)
index 0000000..a1202d9
--- /dev/null
@@ -0,0 +1,164 @@
+From 00b3a2aaa45fc436fe1712cb62b516374720ef85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 20:30:57 -0800
+Subject: eth: bnxt: always recalculate features after XDP clearing, fix
+ null-deref
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit f0aa6a37a3dbb40b272df5fc6db93c114688adcd ]
+
+Recalculate features when XDP is detached.
+
+Before:
+  # ip li set dev eth0 xdp obj xdp_dummy.bpf.o sec xdp
+  # ip li set dev eth0 xdp off
+  # ethtool -k eth0 | grep gro
+  rx-gro-hw: off [requested on]
+
+After:
+  # ip li set dev eth0 xdp obj xdp_dummy.bpf.o sec xdp
+  # ip li set dev eth0 xdp off
+  # ethtool -k eth0 | grep gro
+  rx-gro-hw: on
+
+The fact that HW-GRO doesn't get re-enabled automatically is just
+a minor annoyance. The real issue is that the features will randomly
+come back during another reconfiguration which just happens to invoke
+netdev_update_features(). The driver doesn't handle reconfiguring
+two things at a time very robustly.
+
+Starting with commit 98ba1d931f61 ("bnxt_en: Fix RSS logic in
+__bnxt_reserve_rings()") we only reconfigure the RSS hash table
+if the "effective" number of Rx rings has changed. If HW-GRO is
+enabled "effective" number of rings is 2x what user sees.
+So if we are in the bad state, with HW-GRO re-enablement "pending"
+after XDP off, and we lower the rings by / 2 - the HW-GRO rings
+doing 2x and the ethtool -L doing / 2 may cancel each other out,
+and the:
+
+  if (old_rx_rings != bp->hw_resc.resv_rx_rings &&
+
+condition in __bnxt_reserve_rings() will be false.
+The RSS map won't get updated, and we'll crash with:
+
+  BUG: kernel NULL pointer dereference, address: 0000000000000168
+  RIP: 0010:__bnxt_hwrm_vnic_set_rss+0x13a/0x1a0
+    bnxt_hwrm_vnic_rss_cfg_p5+0x47/0x180
+    __bnxt_setup_vnic_p5+0x58/0x110
+    bnxt_init_nic+0xb72/0xf50
+    __bnxt_open_nic+0x40d/0xab0
+    bnxt_open_nic+0x2b/0x60
+    ethtool_set_channels+0x18c/0x1d0
+
+As we try to access a freed ring.
+
+The issue is present since XDP support was added, really, but
+prior to commit 98ba1d931f61 ("bnxt_en: Fix RSS logic in
+__bnxt_reserve_rings()") it wasn't causing major issues.
+
+Fixes: 1054aee82321 ("bnxt_en: Use NETIF_F_GRO_HW.")
+Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()")
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Link: https://patch.msgid.link/20250109043057.2888953-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 25 +++++++++++++++----
+ drivers/net/ethernet/broadcom/bnxt/bnxt.h     |  2 +-
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  7 ------
+ 3 files changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index c255445e97f3c..603e9c968c44b 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -4558,7 +4558,7 @@ void bnxt_set_ring_params(struct bnxt *bp)
+ /* Changing allocation mode of RX rings.
+  * TODO: Update when extending xdp_rxq_info to support allocation modes.
+  */
+-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
++static void __bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
+ {
+       struct net_device *dev = bp->dev;
+@@ -4579,15 +4579,30 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
+                       bp->rx_skb_func = bnxt_rx_page_skb;
+               }
+               bp->rx_dir = DMA_BIDIRECTIONAL;
+-              /* Disable LRO or GRO_HW */
+-              netdev_update_features(dev);
+       } else {
+               dev->max_mtu = bp->max_mtu;
+               bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
+               bp->rx_dir = DMA_FROM_DEVICE;
+               bp->rx_skb_func = bnxt_rx_skb;
+       }
+-      return 0;
++}
++
++void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
++{
++      __bnxt_set_rx_skb_mode(bp, page_mode);
++
++      if (!page_mode) {
++              int rx, tx;
++
++              bnxt_get_max_rings(bp, &rx, &tx, true);
++              if (rx > 1) {
++                      bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
++                      bp->dev->hw_features |= NETIF_F_LRO;
++              }
++      }
++
++      /* Update LRO and GRO_HW availability */
++      netdev_update_features(bp->dev);
+ }
+ static void bnxt_free_vnic_attributes(struct bnxt *bp)
+@@ -15909,7 +15924,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+       if (bp->max_fltr < BNXT_MAX_FLTR)
+               bp->max_fltr = BNXT_MAX_FLTR;
+       bnxt_init_l2_fltr_tbl(bp);
+-      bnxt_set_rx_skb_mode(bp, false);
++      __bnxt_set_rx_skb_mode(bp, false);
+       bnxt_set_tpa_flags(bp);
+       bnxt_set_ring_params(bp);
+       bnxt_rdma_aux_device_init(bp);
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index 9e05704d94450..bee645f58d0bd 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -2796,7 +2796,7 @@ void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data);
+ u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx);
+ void bnxt_set_tpa_flags(struct bnxt *bp);
+ void bnxt_set_ring_params(struct bnxt *);
+-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
++void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
+ void bnxt_insert_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
+ void bnxt_del_one_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
+ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index f88b641533fcc..dc51dce209d5f 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -422,15 +422,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
+               bnxt_set_rx_skb_mode(bp, true);
+               xdp_features_set_redirect_target(dev, true);
+       } else {
+-              int rx, tx;
+-
+               xdp_features_clear_redirect_target(dev);
+               bnxt_set_rx_skb_mode(bp, false);
+-              bnxt_get_max_rings(bp, &rx, &tx, true);
+-              if (rx > 1) {
+-                      bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
+-                      bp->dev->hw_features |= NETIF_F_LRO;
+-              }
+       }
+       bp->tx_nr_rings_xdp = tx_xdp;
+       bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
+-- 
+2.39.5
+
diff --git a/queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch b/queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch
new file mode 100644 (file)
index 0000000..1fc782c
--- /dev/null
@@ -0,0 +1,125 @@
+From 1dbe8acb4d039ee01ea2d4e95fef75cd569fbb4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 10:47:53 +0900
+Subject: gtp: Destroy device along with udp socket's netns dismantle.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit eb28fd76c0a08a47b470677c6cef9dd1c60e92d1 ]
+
+gtp_newlink() links the device to a list in dev_net(dev) instead of
+src_net, where a udp tunnel socket is created.
+
+Even when src_net is removed, the device stays alive on dev_net(dev).
+Then, removing src_net triggers the splat below. [0]
+
+In this example, gtp0 is created in ns2, and the udp socket is created
+in ns1.
+
+  ip netns add ns1
+  ip netns add ns2
+  ip -n ns1 link add netns ns2 name gtp0 type gtp role sgsn
+  ip netns del ns1
+
+Let's link the device to the socket's netns instead.
+
+Now, gtp_net_exit_batch_rtnl() needs another netdev iteration to remove
+all gtp devices in the netns.
+
+[0]:
+ref_tracker: net notrefcnt@000000003d6e7d05 has 1/2 users at
+     sk_alloc (./include/net/net_namespace.h:345 net/core/sock.c:2236)
+     inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252)
+     __sock_create (net/socket.c:1558)
+     udp_sock_create4 (net/ipv4/udp_tunnel_core.c:18)
+     gtp_create_sock (./include/net/udp_tunnel.h:59 drivers/net/gtp.c:1423)
+     gtp_create_sockets (drivers/net/gtp.c:1447)
+     gtp_newlink (drivers/net/gtp.c:1507)
+     rtnl_newlink (net/core/rtnetlink.c:3786 net/core/rtnetlink.c:3897 net/core/rtnetlink.c:4012)
+     rtnetlink_rcv_msg (net/core/rtnetlink.c:6922)
+     netlink_rcv_skb (net/netlink/af_netlink.c:2542)
+     netlink_unicast (net/netlink/af_netlink.c:1321 net/netlink/af_netlink.c:1347)
+     netlink_sendmsg (net/netlink/af_netlink.c:1891)
+     ____sys_sendmsg (net/socket.c:711 net/socket.c:726 net/socket.c:2583)
+     ___sys_sendmsg (net/socket.c:2639)
+     __sys_sendmsg (net/socket.c:2669)
+     do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
+
+WARNING: CPU: 1 PID: 60 at lib/ref_tracker.c:179 ref_tracker_dir_exit (lib/ref_tracker.c:179)
+Modules linked in:
+CPU: 1 UID: 0 PID: 60 Comm: kworker/u16:2 Not tainted 6.13.0-rc5-00147-g4c1224501e9d #5
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+Workqueue: netns cleanup_net
+RIP: 0010:ref_tracker_dir_exit (lib/ref_tracker.c:179)
+Code: 00 00 00 fc ff df 4d 8b 26 49 bd 00 01 00 00 00 00 ad de 4c 39 f5 0f 85 df 00 00 00 48 8b 74 24 08 48 89 df e8 a5 cc 12 02 90 <0f> 0b 90 48 8d 6b 44 be 04 00 00 00 48 89 ef e8 80 de 67 ff 48 89
+RSP: 0018:ff11000009a07b60 EFLAGS: 00010286
+RAX: 0000000000002bd3 RBX: ff1100000f4e1aa0 RCX: 1ffffffff0e40ac6
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8423ee3c
+RBP: ff1100000f4e1af0 R08: 0000000000000001 R09: fffffbfff0e395ae
+R10: 0000000000000001 R11: 0000000000036001 R12: ff1100000f4e1af0
+R13: dead000000000100 R14: ff1100000f4e1af0 R15: dffffc0000000000
+FS:  0000000000000000(0000) GS:ff1100006ce80000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f9b2464bd98 CR3: 0000000005286005 CR4: 0000000000771ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? __warn (kernel/panic.c:748)
+ ? ref_tracker_dir_exit (lib/ref_tracker.c:179)
+ ? report_bug (lib/bug.c:201 lib/bug.c:219)
+ ? handle_bug (arch/x86/kernel/traps.c:285)
+ ? exc_invalid_op (arch/x86/kernel/traps.c:309 (discriminator 1))
+ ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621)
+ ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:97 ./arch/x86/include/asm/irqflags.h:155 ./include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194)
+ ? ref_tracker_dir_exit (lib/ref_tracker.c:179)
+ ? __pfx_ref_tracker_dir_exit (lib/ref_tracker.c:158)
+ ? kfree (mm/slub.c:4613 mm/slub.c:4761)
+ net_free (net/core/net_namespace.c:476 net/core/net_namespace.c:467)
+ cleanup_net (net/core/net_namespace.c:664 (discriminator 3))
+ process_one_work (kernel/workqueue.c:3229)
+ worker_thread (kernel/workqueue.c:3304 kernel/workqueue.c:3391)
+ kthread (kernel/kthread.c:389)
+ ret_from_fork (arch/x86/kernel/process.c:147)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:257)
+ </TASK>
+
+Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)")
+Reported-by: Xiao Liang <shaw.leon@gmail.com>
+Closes: https://lore.kernel.org/netdev/20250104125732.17335-1-shaw.leon@gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/gtp.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 819ce4b756d23..47406ce990161 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -1526,7 +1526,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
+               goto out_encap;
+       }
+-      gn = net_generic(dev_net(dev), gtp_net_id);
++      gn = net_generic(src_net, gtp_net_id);
+       list_add(&gtp->list, &gn->gtp_dev_list);
+       dev->priv_destructor = gtp_destructor;
+@@ -2487,6 +2487,11 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
+       list_for_each_entry(net, net_list, exit_list) {
+               struct gtp_net *gn = net_generic(net, gtp_net_id);
+               struct gtp_dev *gtp, *gtp_next;
++              struct net_device *dev;
++
++              for_each_netdev(net, dev)
++                      if (dev->rtnl_link_ops == &gtp_link_ops)
++                              gtp_dellink(dev, dev_to_kill);
+               list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
+                       gtp_dellink(gtp->dev, dev_to_kill);
+-- 
+2.39.5
+
diff --git a/queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch b/queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch
new file mode 100644 (file)
index 0000000..4a0f7cc
--- /dev/null
@@ -0,0 +1,91 @@
+From 204c25494333cbe7d49f426e6860dc021be4a7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 10:47:52 +0900
+Subject: gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 46841c7053e6d25fb33e0534ef023833bf03e382 ]
+
+gtp_newlink() links the gtp device to a list in dev_net(dev).
+
+However, even after the gtp device is moved to another netns,
+it stays on the list but should be invisible.
+
+Let's use for_each_netdev_rcu() for netdev traversal in
+gtp_genl_dump_pdp().
+
+Note that gtp_dev_list is no longer used under RCU, so list
+helpers are converted to the non-RCU variant.
+
+Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)")
+Reported-by: Xiao Liang <shaw.leon@gmail.com>
+Closes: https://lore.kernel.org/netdev/CABAhCOQdBL6h9M2C+kd+bGivRJ9Q72JUxW+-gur0nub_=PmFPA@mail.gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/gtp.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 70f981887518a..819ce4b756d23 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -1527,7 +1527,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
+       }
+       gn = net_generic(dev_net(dev), gtp_net_id);
+-      list_add_rcu(&gtp->list, &gn->gtp_dev_list);
++      list_add(&gtp->list, &gn->gtp_dev_list);
+       dev->priv_destructor = gtp_destructor;
+       netdev_dbg(dev, "registered new GTP interface\n");
+@@ -1553,7 +1553,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
+               hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid)
+                       pdp_context_delete(pctx);
+-      list_del_rcu(&gtp->list);
++      list_del(&gtp->list);
+       unregister_netdevice_queue(dev, head);
+ }
+@@ -2279,16 +2279,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
+       struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
+       int i, j, bucket = cb->args[0], skip = cb->args[1];
+       struct net *net = sock_net(skb->sk);
++      struct net_device *dev;
+       struct pdp_ctx *pctx;
+-      struct gtp_net *gn;
+-
+-      gn = net_generic(net, gtp_net_id);
+       if (cb->args[4])
+               return 0;
+       rcu_read_lock();
+-      list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
++      for_each_netdev_rcu(net, dev) {
++              if (dev->rtnl_link_ops != &gtp_link_ops)
++                      continue;
++
++              gtp = netdev_priv(dev);
++
+               if (last_gtp && last_gtp != gtp)
+                       continue;
+               else
+@@ -2483,9 +2486,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
+       list_for_each_entry(net, net_list, exit_list) {
+               struct gtp_net *gn = net_generic(net, gtp_net_id);
+-              struct gtp_dev *gtp;
++              struct gtp_dev *gtp, *gtp_next;
+-              list_for_each_entry(gtp, &gn->gtp_dev_list, list)
++              list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
+                       gtp_dellink(gtp->dev, dev_to_kill);
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-add-correct-phy-lane-assignment.patch b/queue-6.12/ice-add-correct-phy-lane-assignment.patch
new file mode 100644 (file)
index 0000000..601c422
--- /dev/null
@@ -0,0 +1,303 @@
+From ff7d5ac3e7743791f9d8444534229248faf20446 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 13:29:16 +0100
+Subject: ice: Add correct PHY lane assignment
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit 258f5f905815979f15d5151d2ea4f20d8e057fe1 ]
+
+Driver always naively assumes, that for PTP purposes, PHY lane to
+configure is corresponding to PF ID.
+
+This is not true for some port configurations, e.g.:
+- 2x50G per quad, where lanes used are 0 and 2 on each quad, but PF IDs
+  are 0 and 1
+- 100G per quad on 2 quads, where lanes used are 0 and 4, but PF IDs are
+  0 and 1
+
+Use correct PHY lane assignment by getting and parsing port options.
+This is read from the NVM by the FW and provided to the driver with
+the indication of active port split.
+
+Remove ice_is_muxed_topo(), which is no longer needed.
+
+Fixes: 4409ea1726cb ("ice: Adjust PTP init for 2x50G E825C devices")
+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>
+Signed-off-by: Grzegorz Nitka <grzegorz.nitka@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: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  1 +
+ drivers/net/ethernet/intel/ice/ice_common.c   | 51 +++++++++++++++++++
+ drivers/net/ethernet/intel/ice/ice_common.h   |  1 +
+ drivers/net/ethernet/intel/ice/ice_main.c     |  6 +--
+ drivers/net/ethernet/intel/ice/ice_ptp.c      | 23 ++++-----
+ drivers/net/ethernet/intel/ice/ice_ptp.h      |  4 +-
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c   | 26 +---------
+ drivers/net/ethernet/intel/ice/ice_type.h     |  1 -
+ 8 files changed, 68 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+index 79a6edd0be0ec..80f3dfd271243 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
++++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+@@ -1648,6 +1648,7 @@ struct ice_aqc_get_port_options_elem {
+ #define ICE_AQC_PORT_OPT_MAX_LANE_25G 5
+ #define ICE_AQC_PORT_OPT_MAX_LANE_50G 6
+ #define ICE_AQC_PORT_OPT_MAX_LANE_100G        7
++#define ICE_AQC_PORT_OPT_MAX_LANE_200G        8
+       u8 global_scid[2];
+       u8 phy_scid[2];
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
+index f1324e25b2af1..068a467de1d56 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.c
++++ b/drivers/net/ethernet/intel/ice/ice_common.c
+@@ -4074,6 +4074,57 @@ ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
+       return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+ }
++/**
++ * ice_get_phy_lane_number - Get PHY lane number for current adapter
++ * @hw: pointer to the hw struct
++ *
++ * Return: PHY lane number on success, negative error code otherwise.
++ */
++int ice_get_phy_lane_number(struct ice_hw *hw)
++{
++      struct ice_aqc_get_port_options_elem *options;
++      unsigned int lport = 0;
++      unsigned int lane;
++      int err;
++
++      options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL);
++      if (!options)
++              return -ENOMEM;
++
++      for (lane = 0; lane < ICE_MAX_PORT_PER_PCI_DEV; lane++) {
++              u8 options_count = ICE_AQC_PORT_OPT_MAX;
++              u8 speed, active_idx, pending_idx;
++              bool active_valid, pending_valid;
++
++              err = ice_aq_get_port_options(hw, options, &options_count, lane,
++                                            true, &active_idx, &active_valid,
++                                            &pending_idx, &pending_valid);
++              if (err)
++                      goto err;
++
++              if (!active_valid)
++                      continue;
++
++              speed = options[active_idx].max_lane_speed;
++              /* If we don't get speed for this lane, it's unoccupied */
++              if (speed > ICE_AQC_PORT_OPT_MAX_LANE_200G)
++                      continue;
++
++              if (hw->pf_id == lport) {
++                      kfree(options);
++                      return lane;
++              }
++
++              lport++;
++      }
++
++      /* PHY lane not found */
++      err = -ENXIO;
++err:
++      kfree(options);
++      return err;
++}
++
+ /**
+  * ice_aq_sff_eeprom
+  * @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 27208a60cece5..fe6f88cfd9486 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.h
++++ b/drivers/net/ethernet/intel/ice/ice_common.h
+@@ -193,6 +193,7 @@ ice_aq_get_port_options(struct ice_hw *hw,
+ int
+ ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
+                      u8 new_option);
++int ice_get_phy_lane_number(struct ice_hw *hw);
+ int
+ ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
+                 u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 8f2e758c39427..45eefe22fb5b7 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -1144,7 +1144,7 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
+       if (link_up == old_link && link_speed == old_link_speed)
+               return 0;
+-      ice_ptp_link_change(pf, pf->hw.pf_id, link_up);
++      ice_ptp_link_change(pf, link_up);
+       if (ice_is_dcb_active(pf)) {
+               if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
+@@ -6744,7 +6744,7 @@ static int ice_up_complete(struct ice_vsi *vsi)
+               ice_print_link_msg(vsi, true);
+               netif_tx_start_all_queues(vsi->netdev);
+               netif_carrier_on(vsi->netdev);
+-              ice_ptp_link_change(pf, pf->hw.pf_id, true);
++              ice_ptp_link_change(pf, true);
+       }
+       /* Perform an initial read of the statistics registers now to
+@@ -7214,7 +7214,7 @@ int ice_down(struct ice_vsi *vsi)
+       if (vsi->netdev) {
+               vlan_err = ice_vsi_del_vlan_zero(vsi);
+-              ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false);
++              ice_ptp_link_change(vsi->back, false);
+               netif_carrier_off(vsi->netdev);
+               netif_tx_disable(vsi->netdev);
+       }
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index 0b3dd87a331c7..7c6f81beaee46 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -1466,10 +1466,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
+ /**
+  * ice_ptp_link_change - Reconfigure PTP after link status change
+  * @pf: Board private structure
+- * @port: Port for which the PHY start is set
+  * @linkup: Link is up or down
+  */
+-void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
++void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
+ {
+       struct ice_ptp_port *ptp_port;
+       struct ice_hw *hw = &pf->hw;
+@@ -1477,14 +1476,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 >= hw->ptp.num_lports))
+-              return;
+-
+       ptp_port = &pf->ptp.port;
+-      if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
+-              port *= 2;
+-      if (WARN_ON_ONCE(ptp_port->port_num != port))
+-              return;
+       /* Update cached link status for this port immediately */
+       ptp_port->link_up = linkup;
+@@ -3383,10 +3375,17 @@ void ice_ptp_init(struct ice_pf *pf)
+ {
+       struct ice_ptp *ptp = &pf->ptp;
+       struct ice_hw *hw = &pf->hw;
+-      int err;
++      int lane_num, err;
+       ptp->state = ICE_PTP_INITIALIZING;
++      lane_num = ice_get_phy_lane_number(hw);
++      if (lane_num < 0) {
++              err = lane_num;
++              goto err_exit;
++      }
++
++      ptp->port.port_num = (u8)lane_num;
+       ice_ptp_init_hw(hw);
+       ice_ptp_init_tx_interrupt_mode(pf);
+@@ -3407,10 +3406,6 @@ void ice_ptp_init(struct ice_pf *pf)
+       if (err)
+               goto err_exit;
+-      ptp->port.port_num = hw->pf_id;
+-      if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
+-              ptp->port.port_num = hw->pf_id * 2;
+-
+       err = ice_ptp_init_port(pf, &ptp->port);
+       if (err)
+               goto err_exit;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
+index 5615efc42c624..f1cfa6aa4e76b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
+@@ -332,7 +332,7 @@ 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);
++void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
+ #else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
+ static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
+ {
+@@ -380,7 +380,7 @@ static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
+ }
+ 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)
++static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
+ {
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index 28bd4815ebcf3..7190fde16c868 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -2698,26 +2698,6 @@ static int ice_get_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw, u8 port,
+       return 0;
+ }
+-/**
+- * ice_is_muxed_topo - detect breakout 2x50G topology for E825C
+- * @hw: pointer to the HW struct
+- *
+- * Return: true if it's 2x50 breakout topology, false otherwise
+- */
+-static bool ice_is_muxed_topo(struct ice_hw *hw)
+-{
+-      u8 link_topo;
+-      bool mux;
+-      u32 val;
+-
+-      val = rd32(hw, GLGEN_SWITCH_MODE_CONFIG);
+-      mux = FIELD_GET(GLGEN_SWITCH_MODE_CONFIG_25X4_QUAD_M, val);
+-      val = rd32(hw, GLGEN_MAC_LINK_TOPO);
+-      link_topo = FIELD_GET(GLGEN_MAC_LINK_TOPO_LINK_TOPO_M, val);
+-
+-      return (mux && link_topo == ICE_LINK_TOPO_UP_TO_2_LINKS);
+-}
+-
+ /**
+  * ice_ptp_init_phy_e825 - initialize PHY parameters
+  * @hw: pointer to the HW struct
+@@ -2740,12 +2720,8 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw)
+       ice_sb_access_ena_eth56g(hw, true);
+       err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev);
+-      if (err || phy_rev != PHY_REVISION_ETH56G) {
++      if (err || phy_rev != PHY_REVISION_ETH56G)
+               ptp->phy_model = ICE_PHY_UNSUP;
+-              return;
+-      }
+-
+-      ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw);
+ }
+ /* E822 family functions
+diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
+index 479227bdff75e..609f31e0dfded 100644
+--- a/drivers/net/ethernet/intel/ice/ice_type.h
++++ b/drivers/net/ethernet/intel/ice/ice_type.h
+@@ -880,7 +880,6 @@ struct ice_ptp_hw {
+       union ice_phy_params phy;
+       u8 num_lports;
+       u8 ports_per_phy;
+-      bool is_2x50g_muxed_topo;
+ };
+ /* Port hardware description */
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch b/queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch
new file mode 100644 (file)
index 0000000..d9ea3e6
--- /dev/null
@@ -0,0 +1,79 @@
+From e100d854a338dbf390b9076ddd54556f4b0da4a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 15:09:54 +0200
+Subject: ice: Add ice_get_ctrl_ptp() wrapper to simplify the code
+
+From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+
+[ Upstream commit 97ed20a01f5b96e8738b53f56ae84b06953a2853 ]
+
+Add ice_get_ctrl_ptp() wrapper to simplify the PTP support code
+in the functions that do not use ctrl_pf directly.
+Add the control PF pointer to struct ice_adapter
+Rearrange fields in struct ice_adapter
+
+Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@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>
+Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.h |  5 ++++-
+ drivers/net/ethernet/intel/ice/ice_ptp.c     | 12 ++++++++++++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index 9d11014ec02ff..eb7cac01c2427 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -8,18 +8,21 @@
+ #include <linux/refcount_types.h>
+ struct pci_dev;
++struct ice_pf;
+ /**
+  * struct ice_adapter - PCI adapter resources shared across PFs
+  * @ptp_gltsyn_time_lock: Spinlock protecting access to the GLTSYN_TIME
+  *                        register of the PTP clock.
+  * @refcount: Reference count. struct ice_pf objects hold the references.
++ * @ctrl_pf: Control PF of the adapter
+  */
+ struct ice_adapter {
++      refcount_t refcount;
+       /* For access to the GLTSYN_TIME register */
+       spinlock_t ptp_gltsyn_time_lock;
+-      refcount_t refcount;
++      struct ice_pf *ctrl_pf;
+ };
+ struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev);
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index d534c8e571cee..2fb73ab41bc20 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -16,6 +16,18 @@ static const struct ptp_pin_desc ice_pin_desc_e810t[] = {
+       { "U.FL2", UFL2, PTP_PF_NONE, 2, { 0, } },
+ };
++static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf)
++{
++      return !pf->adapter ? NULL : pf->adapter->ctrl_pf;
++}
++
++static __maybe_unused struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf)
++{
++      struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf);
++
++      return !ctrl_pf ? NULL : &ctrl_pf->ptp;
++}
++
+ /**
+  * ice_get_sma_config_e810t
+  * @hw: pointer to the hw struct
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-fix-e825-initialization.patch b/queue-6.12/ice-fix-e825-initialization.patch
new file mode 100644 (file)
index 0000000..6fce616
--- /dev/null
@@ -0,0 +1,79 @@
+From f3367479563eb8ed8303f527e3bb82d45926221a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 13:29:13 +0100
+Subject: ice: Fix E825 initialization
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit d79c304c76e9b30ff5527afc176b5c4f9f0374b6 ]
+
+Current implementation checks revision of all PHYs on all PFs, which is
+incorrect and may result in initialization failure. Check only the
+revision of the current PHY.
+
+Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
+Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Signed-off-by: Grzegorz Nitka <grzegorz.nitka@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: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 +++++++++------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index 3816e45b6ab44..f6816c2f71438 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -2664,14 +2664,15 @@ static bool ice_is_muxed_topo(struct ice_hw *hw)
+ }
+ /**
+- * ice_ptp_init_phy_e825c - initialize PHY parameters
++ * ice_ptp_init_phy_e825 - initialize PHY parameters
+  * @hw: pointer to the HW struct
+  */
+-static void ice_ptp_init_phy_e825c(struct ice_hw *hw)
++static void ice_ptp_init_phy_e825(struct ice_hw *hw)
+ {
+       struct ice_ptp_hw *ptp = &hw->ptp;
+       struct ice_eth56g_params *params;
+-      u8 phy;
++      u32 phy_rev;
++      int err;
+       ptp->phy_model = ICE_PHY_ETH56G;
+       params = &ptp->phy.eth56g;
+@@ -2685,15 +2686,10 @@ static void ice_ptp_init_phy_e825c(struct ice_hw *hw)
+       ptp->num_lports = params->num_phys * ptp->ports_per_phy;
+       ice_sb_access_ena_eth56g(hw, true);
+-      for (phy = 0; phy < params->num_phys; phy++) {
+-              u32 phy_rev;
+-              int err;
+-
+-              err = ice_read_phy_eth56g(hw, phy, PHY_REG_REVISION, &phy_rev);
+-              if (err || phy_rev != PHY_REVISION_ETH56G) {
+-                      ptp->phy_model = ICE_PHY_UNSUP;
+-                      return;
+-              }
++      err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev);
++      if (err || phy_rev != PHY_REVISION_ETH56G) {
++              ptp->phy_model = ICE_PHY_UNSUP;
++              return;
+       }
+       ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw);
+@@ -5395,7 +5391,7 @@ void ice_ptp_init_hw(struct ice_hw *hw)
+       else if (ice_is_e810(hw))
+               ice_ptp_init_phy_e810(ptp);
+       else if (ice_is_e825c(hw))
+-              ice_ptp_init_phy_e825c(hw);
++              ice_ptp_init_phy_e825(hw);
+       else
+               ptp->phy_model = ICE_PHY_UNSUP;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch b/queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch
new file mode 100644 (file)
index 0000000..ea57df5
--- /dev/null
@@ -0,0 +1,41 @@
+From 3b4066672e0b53c25af72680e200f8f4964ce868 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 13:29:15 +0100
+Subject: ice: Fix ETH56G FC-FEC Rx offset value
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit 2e60560f1ec9b722f9c6699ec5d966f1732d14dd ]
+
+Fix ETH56G FC-FEC incorrect Rx offset value by changing it from -255.96
+to -469.26 ns.
+
+Those values are derived from HW spec and reflect internal delays.
+Hex value is a fixed point representation in Q23.9 format.
+
+Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
+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> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ptp_consts.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h
+index 3005dd252a102..bdb1020147d1c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h
+@@ -131,7 +131,7 @@ struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = {
+               .rx_offset = {
+                       .serdes = 0xffffeb27, /* -10.42424 */
+                       .no_fec = 0xffffcccd, /* -25.6 */
+-                      .fc = 0xfffe0014, /* -255.96 */
++                      .fc = 0xfffc557b, /* -469.26 */
+                       .sfd = 0x4a4, /* 2.32 */
+                       .bs_ds = 0x32 /* 0.0969697 */
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-fix-quad-registers-read-on-e825.patch b/queue-6.12/ice-fix-quad-registers-read-on-e825.patch
new file mode 100644 (file)
index 0000000..936111f
--- /dev/null
@@ -0,0 +1,459 @@
+From 63a45c1b0d95af055c17c2fc2eb6f2c3d747fd31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 13:29:14 +0100
+Subject: ice: Fix quad registers read on E825
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit dc26548d729e5f732197d2b210fb77c745b01495 ]
+
+Quad registers are read/written incorrectly. E825 devices always use
+quad 0 address and differentiate between the PHYs by changing SBQ
+destination device (phy_0 or phy_0_peer).
+
+Add helpers for reading/writing PTP registers shared per quad and use
+correct quad address and SBQ destination device based on port.
+
+Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
+Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Signed-off-by: Grzegorz Nitka <grzegorz.nitka@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: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 219 ++++++++++++--------
+ drivers/net/ethernet/intel/ice/ice_type.h   |   1 -
+ 2 files changed, 133 insertions(+), 87 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index f6816c2f71438..64c36620a02f3 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -877,31 +877,46 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
+  * The following functions operate on devices with the ETH 56G PHY.
+  */
++/**
++ * ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
++ * @hw: pointer to the HW struct
++ * @port: destination port
++ *
++ * Return: destination sideband queue PHY device.
++ */
++static enum ice_sbq_msg_dev ice_ptp_get_dest_dev_e825(struct ice_hw *hw,
++                                                    u8 port)
++{
++      /* On a single complex E825, PHY 0 is always destination device phy_0
++       * and PHY 1 is phy_0_peer.
++       */
++      if (port >= hw->ptp.ports_per_phy)
++              return eth56g_phy_1;
++      else
++              return eth56g_phy_0;
++}
++
+ /**
+  * ice_write_phy_eth56g - Write a PHY port register
+  * @hw: pointer to the HW struct
+- * @phy_idx: PHY index
++ * @port: destination port
+  * @addr: PHY register address
+  * @val: Value to write
+  *
+  * Return: 0 on success, other error codes when failed to write to PHY
+  */
+-static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
+-                              u32 val)
++static int ice_write_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 val)
+ {
+-      struct ice_sbq_msg_input phy_msg;
++      struct ice_sbq_msg_input msg = {
++              .dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
++              .opcode = ice_sbq_msg_wr,
++              .msg_addr_low = lower_16_bits(addr),
++              .msg_addr_high = upper_16_bits(addr),
++              .data = val
++      };
+       int err;
+-      phy_msg.opcode = ice_sbq_msg_wr;
+-
+-      phy_msg.msg_addr_low = lower_16_bits(addr);
+-      phy_msg.msg_addr_high = upper_16_bits(addr);
+-
+-      phy_msg.data = val;
+-      phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
+-
+-      err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
+-
++      err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
+       if (err)
+               ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
+                         err);
+@@ -912,41 +927,36 @@ static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
+ /**
+  * ice_read_phy_eth56g - Read a PHY port register
+  * @hw: pointer to the HW struct
+- * @phy_idx: PHY index
++ * @port: destination port
+  * @addr: PHY register address
+  * @val: Value to write
+  *
+  * Return: 0 on success, other error codes when failed to read from PHY
+  */
+-static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
+-                             u32 *val)
++static int ice_read_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 *val)
+ {
+-      struct ice_sbq_msg_input phy_msg;
++      struct ice_sbq_msg_input msg = {
++              .dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
++              .opcode = ice_sbq_msg_rd,
++              .msg_addr_low = lower_16_bits(addr),
++              .msg_addr_high = upper_16_bits(addr)
++      };
+       int err;
+-      phy_msg.opcode = ice_sbq_msg_rd;
+-
+-      phy_msg.msg_addr_low = lower_16_bits(addr);
+-      phy_msg.msg_addr_high = upper_16_bits(addr);
+-
+-      phy_msg.data = 0;
+-      phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
+-
+-      err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
+-      if (err) {
++      err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
++      if (err)
+               ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
+                         err);
+-              return err;
+-      }
+-
+-      *val = phy_msg.data;
++      else
++              *val = msg.data;
+-      return 0;
++      return err;
+ }
+ /**
+  * ice_phy_res_address_eth56g - Calculate a PHY port register address
+- * @port: Port number to be written
++ * @hw: pointer to the HW struct
++ * @lane: Lane number to be written
+  * @res_type: resource type (register/memory)
+  * @offset: Offset from PHY port register base
+  * @addr: The result address
+@@ -955,17 +965,19 @@ static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
+  * * %0      - success
+  * * %EINVAL - invalid port number or resource type
+  */
+-static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
+-                                    u32 offset, u32 *addr)
++static int ice_phy_res_address_eth56g(struct ice_hw *hw, u8 lane,
++                                    enum eth56g_res_type res_type,
++                                    u32 offset,
++                                    u32 *addr)
+ {
+-      u8 lane = port % ICE_PORTS_PER_QUAD;
+-      u8 phy = ICE_GET_QUAD_NUM(port);
+-
+       if (res_type >= NUM_ETH56G_PHY_RES)
+               return -EINVAL;
+-      *addr = eth56g_phy_res[res_type].base[phy] +
++      /* Lanes 4..7 are in fact 0..3 on a second PHY */
++      lane %= hw->ptp.ports_per_phy;
++      *addr = eth56g_phy_res[res_type].base[0] +
+               lane * eth56g_phy_res[res_type].step + offset;
++
+       return 0;
+ }
+@@ -985,19 +997,17 @@ static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
+ static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
+                                u32 val, enum eth56g_res_type res_type)
+ {
+-      u8 phy_port = port % hw->ptp.ports_per_phy;
+-      u8 phy_idx = port / hw->ptp.ports_per_phy;
+       u32 addr;
+       int err;
+       if (port >= hw->ptp.num_lports)
+               return -EINVAL;
+-      err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
++      err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
+       if (err)
+               return err;
+-      return ice_write_phy_eth56g(hw, phy_idx, addr, val);
++      return ice_write_phy_eth56g(hw, port, addr, val);
+ }
+ /**
+@@ -1016,19 +1026,17 @@ static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
+ static int ice_read_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
+                               u32 *val, enum eth56g_res_type res_type)
+ {
+-      u8 phy_port = port % hw->ptp.ports_per_phy;
+-      u8 phy_idx = port / hw->ptp.ports_per_phy;
+       u32 addr;
+       int err;
+       if (port >= hw->ptp.num_lports)
+               return -EINVAL;
+-      err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
++      err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
+       if (err)
+               return err;
+-      return ice_read_phy_eth56g(hw, phy_idx, addr, val);
++      return ice_read_phy_eth56g(hw, port, addr, val);
+ }
+ /**
+@@ -1177,6 +1185,56 @@ static int ice_write_port_mem_eth56g(struct ice_hw *hw, u8 port, u16 offset,
+       return ice_write_port_eth56g(hw, port, offset, val, ETH56G_PHY_MEM_PTP);
+ }
++/**
++ * ice_write_quad_ptp_reg_eth56g - Write a PHY quad register
++ * @hw: pointer to the HW struct
++ * @offset: PHY register offset
++ * @port: Port number
++ * @val: Value to write
++ *
++ * Return:
++ * * %0     - success
++ * * %EIO  - invalid port number or resource type
++ * * %other - failed to write to PHY
++ */
++static int ice_write_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
++                                       u32 offset, u32 val)
++{
++      u32 addr;
++
++      if (port >= hw->ptp.num_lports)
++              return -EIO;
++
++      addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
++
++      return ice_write_phy_eth56g(hw, port, addr, val);
++}
++
++/**
++ * ice_read_quad_ptp_reg_eth56g - Read a PHY quad register
++ * @hw: pointer to the HW struct
++ * @offset: PHY register offset
++ * @port: Port number
++ * @val: Value to read
++ *
++ * Return:
++ * * %0     - success
++ * * %EIO  - invalid port number or resource type
++ * * %other - failed to read from PHY
++ */
++static int ice_read_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
++                                      u32 offset, u32 *val)
++{
++      u32 addr;
++
++      if (port >= hw->ptp.num_lports)
++              return -EIO;
++
++      addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
++
++      return ice_read_phy_eth56g(hw, port, addr, val);
++}
++
+ /**
+  * ice_is_64b_phy_reg_eth56g - Check if this is a 64bit PHY register
+  * @low_addr: the low address to check
+@@ -1896,7 +1954,6 @@ ice_phy_get_speed_eth56g(struct ice_link_status *li)
+  */
+ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
+ {
+-      u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
+       u32 val;
+       int err;
+@@ -1911,8 +1968,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
+       switch (ice_phy_get_speed_eth56g(&hw->port_info->phy.link_info)) {
+       case ICE_ETH56G_LNK_SPD_1G:
+       case ICE_ETH56G_LNK_SPD_2_5G:
+-              err = ice_read_ptp_reg_eth56g(hw, port_blk,
+-                                            PHY_GPCS_CONFIG_REG0, &val);
++              err = ice_read_quad_ptp_reg_eth56g(hw, port,
++                                                 PHY_GPCS_CONFIG_REG0, &val);
+               if (err) {
+                       ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_GPCS_CONFIG_REG0, status: %d",
+                                 err);
+@@ -1923,8 +1980,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
+               val |= FIELD_PREP(PHY_GPCS_CONFIG_REG0_TX_THR_M,
+                                 ICE_ETH56G_NOMINAL_TX_THRESH);
+-              err = ice_write_ptp_reg_eth56g(hw, port_blk,
+-                                             PHY_GPCS_CONFIG_REG0, val);
++              err = ice_write_quad_ptp_reg_eth56g(hw, port,
++                                                  PHY_GPCS_CONFIG_REG0, val);
+               if (err) {
+                       ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_GPCS_CONFIG_REG0, status: %d",
+                                 err);
+@@ -1965,50 +2022,47 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
+  */
+ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
+ {
+-      u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
+-      u8 blk_port = port & (ICE_PORTS_PER_QUAD - 1);
++      u8 quad_lane = port % ICE_PORTS_PER_QUAD;
++      u32 addr, val, peer_delay;
+       bool enable, sfd_ena;
+-      u32 val, peer_delay;
+       int err;
+       enable = hw->ptp.phy.eth56g.onestep_ena;
+       peer_delay = hw->ptp.phy.eth56g.peer_delay;
+       sfd_ena = hw->ptp.phy.eth56g.sfd_ena;
+-      /* PHY_PTP_1STEP_CONFIG */
+-      err = ice_read_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, &val);
++      addr = PHY_PTP_1STEP_CONFIG;
++      err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &val);
+       if (err)
+               return err;
+       if (enable)
+-              val |= blk_port;
++              val |= BIT(quad_lane);
+       else
+-              val &= ~blk_port;
++              val &= ~BIT(quad_lane);
+       val &= ~(PHY_PTP_1STEP_T1S_UP64_M | PHY_PTP_1STEP_T1S_DELTA_M);
+-      err = ice_write_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, val);
++      err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
+       if (err)
+               return err;
+-      /* PHY_PTP_1STEP_PEER_DELAY */
++      addr = PHY_PTP_1STEP_PEER_DELAY(quad_lane);
+       val = FIELD_PREP(PHY_PTP_1STEP_PD_DELAY_M, peer_delay);
+       if (peer_delay)
+               val |= PHY_PTP_1STEP_PD_ADD_PD_M;
+       val |= PHY_PTP_1STEP_PD_DLY_V_M;
+-      err = ice_write_ptp_reg_eth56g(hw, port_blk,
+-                                     PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
++      err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
+       if (err)
+               return err;
+       val &= ~PHY_PTP_1STEP_PD_DLY_V_M;
+-      err = ice_write_ptp_reg_eth56g(hw, port_blk,
+-                                     PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
++      err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
+       if (err)
+               return err;
+-      /* PHY_MAC_XIF_MODE */
+-      err = ice_read_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, &val);
++      addr = PHY_MAC_XIF_MODE;
++      err = ice_read_mac_reg_eth56g(hw, port, addr, &val);
+       if (err)
+               return err;
+@@ -2028,7 +2082,7 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
+              FIELD_PREP(PHY_MAC_XIF_TS_BIN_MODE_M, enable) |
+              FIELD_PREP(PHY_MAC_XIF_TS_SFD_ENA_M, sfd_ena);
+-      return ice_write_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, val);
++      return ice_write_mac_reg_eth56g(hw, port, addr, val);
+ }
+ /**
+@@ -2070,21 +2124,22 @@ static u32 ice_ptp_calc_bitslip_eth56g(struct ice_hw *hw, u8 port, u32 bs,
+                                      bool fc, bool rs,
+                                      enum ice_eth56g_link_spd spd)
+ {
+-      u8 port_offset = port & (ICE_PORTS_PER_QUAD - 1);
+-      u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
+       u32 bitslip;
+       int err;
+       if (!bs || rs)
+               return 0;
+-      if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G)
++      if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G) {
+               err = ice_read_gpcs_reg_eth56g(hw, port, PHY_GPCS_BITSLIP,
+                                              &bitslip);
+-      else
+-              err = ice_read_ptp_reg_eth56g(hw, port_blk,
+-                                            PHY_REG_SD_BIT_SLIP(port_offset),
+-                                            &bitslip);
++      } else {
++              u8 quad_lane = port % ICE_PORTS_PER_QUAD;
++              u32 addr;
++
++              addr = PHY_REG_SD_BIT_SLIP(quad_lane);
++              err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &bitslip);
++      }
+       if (err)
+               return 0;
+@@ -2679,8 +2734,6 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw)
+       params->onestep_ena = false;
+       params->peer_delay = 0;
+       params->sfd_ena = false;
+-      params->phy_addr[0] = eth56g_phy_0;
+-      params->phy_addr[1] = eth56g_phy_1;
+       params->num_phys = 2;
+       ptp->ports_per_phy = 4;
+       ptp->num_lports = params->num_phys * ptp->ports_per_phy;
+@@ -2711,10 +2764,9 @@ 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;
++      int phy_port, quadtype;
+       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);
+@@ -2726,12 +2778,7 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
+               msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
+       }
+-      if (phy == 0)
+-              msg->dest_dev = rmn_0;
+-      else if (phy == 1)
+-              msg->dest_dev = rmn_1;
+-      else
+-              msg->dest_dev = rmn_2;
++      msg->dest_dev = rmn_0;
+ }
+ /**
+diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
+index 45768796691fe..479227bdff75e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_type.h
++++ b/drivers/net/ethernet/intel/ice/ice_type.h
+@@ -850,7 +850,6 @@ struct ice_mbx_data {
+ struct ice_eth56g_params {
+       u8 num_phys;
+-      u8 phy_addr[2];
+       bool onestep_ena;
+       bool sfd_ena;
+       u32 peer_delay;
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch b/queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch
new file mode 100644 (file)
index 0000000..76cbd0d
--- /dev/null
@@ -0,0 +1,231 @@
+From f893b9f439504421f64e661cc1707c39aa9cde4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 15:09:53 +0200
+Subject: ice: Introduce ice_get_phy_model() wrapper
+
+From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+
+[ Upstream commit 5e0776451d89eefe66b19e010e48ece1cca07e58 ]
+
+Introduce ice_get_phy_model() to improve code readability
+
+Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@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>
+Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h        |  5 +++++
+ drivers/net/ethernet/intel/ice/ice_ptp.c    | 19 +++++++++---------
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 ++++++++++-----------
+ 3 files changed, 25 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
+index d6f80da30decf..558cda577191d 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -1047,5 +1047,10 @@ static inline void ice_clear_rdma_cap(struct ice_pf *pf)
+       clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
+ }
++static inline enum ice_phy_model ice_get_phy_model(const struct ice_hw *hw)
++{
++      return hw->ptp.phy_model;
++}
++
+ extern const struct xdp_metadata_ops ice_xdp_md_ops;
+ #endif /* _ICE_H_ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index ef2e858f49bb0..d534c8e571cee 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -1363,7 +1363,7 @@ ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port)
+       mutex_lock(&ptp_port->ps_lock);
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               err = ice_stop_phy_timer_eth56g(hw, port, true);
+               break;
+@@ -1409,7 +1409,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
+       mutex_lock(&ptp_port->ps_lock);
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               err = ice_start_phy_timer_eth56g(hw, port);
+               break;
+@@ -1480,8 +1480,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
+       /* Skip HW writes if reset is in progress */
+       if (pf->hw.reset_ongoing)
+               return;
+-
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_E810:
+               /* Do not reconfigure E810 PHY */
+               return;
+@@ -1514,7 +1513,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
+       ice_ptp_reset_ts_memory(hw);
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G: {
+               int port;
+@@ -1553,7 +1552,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
+       case ICE_PHY_UNSUP:
+       default:
+               dev_warn(dev, "%s: Unexpected PHY model %d\n", __func__,
+-                       hw->ptp.phy_model);
++                       ice_get_phy_model(hw));
+               return -EOPNOTSUPP;
+       }
+ }
+@@ -2059,7 +2058,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
+       /* For Vernier mode on E82X, we need to recalibrate after new settime.
+        * Start with marking timestamps as invalid.
+        */
+-      if (hw->ptp.phy_model == ICE_PHY_E82X) {
++      if (ice_get_phy_model(hw) == ICE_PHY_E82X) {
+               err = ice_ptp_clear_phy_offset_ready_e82x(hw);
+               if (err)
+                       dev_warn(ice_pf_to_dev(pf), "Failed to mark timestamps as invalid before settime\n");
+@@ -2083,7 +2082,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->ptp.phy_model == ICE_PHY_E82X)
++      if (ice_get_phy_model(hw) == ICE_PHY_E82X)
+               ice_ptp_restart_all_phy(pf);
+ exit:
+       if (err) {
+@@ -3209,7 +3208,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx,
+                                             ptp_port->port_num);
+@@ -3307,7 +3306,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.ptp.phy_model) {
++      switch (ice_get_phy_model(&pf->hw)) {
+       case ICE_PHY_E82X:
+               /* E822 based PHY has the clock owner process the interrupt
+                * for all ports.
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index 64c36620a02f3..28bd4815ebcf3 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -804,7 +804,7 @@ static u32 ice_ptp_tmr_cmd_to_port_reg(struct ice_hw *hw,
+       /* Certain hardware families share the same register values for the
+        * port register and source timer register.
+        */
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_E810:
+               return ice_ptp_tmr_cmd_to_src_reg(hw, cmd) & TS_CMD_MASK_E810;
+       default:
+@@ -5461,7 +5461,7 @@ void ice_ptp_init_hw(struct ice_hw *hw)
+ static int ice_ptp_write_port_cmd(struct ice_hw *hw, u8 port,
+                                 enum ice_ptp_tmr_cmd cmd)
+ {
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_ptp_write_port_cmd_eth56g(hw, port, cmd);
+       case ICE_PHY_E82X:
+@@ -5526,7 +5526,7 @@ static int ice_ptp_port_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
+       u32 port;
+       /* PHY models which can program all ports simultaneously */
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_E810:
+               return ice_ptp_port_cmd_e810(hw, cmd);
+       default:
+@@ -5605,7 +5605,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               err = ice_ptp_prep_phy_time_eth56g(hw,
+                                                  (u32)(time & 0xFFFFFFFF));
+@@ -5651,7 +5651,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               err = ice_ptp_prep_phy_incval_eth56g(hw, incval);
+               break;
+@@ -5720,7 +5720,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               err = ice_ptp_prep_phy_adj_eth56g(hw, adj);
+               break;
+@@ -5753,7 +5753,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_read_ptp_tstamp_eth56g(hw, block, idx, tstamp);
+       case ICE_PHY_E810:
+@@ -5783,7 +5783,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_clear_ptp_tstamp_eth56g(hw, block, idx);
+       case ICE_PHY_E810:
+@@ -5846,7 +5846,7 @@ static int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
+  */
+ void ice_ptp_reset_ts_memory(struct ice_hw *hw)
+ {
+-      switch (hw->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               ice_ptp_reset_ts_memory_eth56g(hw);
+               break;
+@@ -5875,7 +5875,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_ptp_init_phc_eth56g(hw);
+       case ICE_PHY_E810:
+@@ -5900,7 +5900,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->ptp.phy_model) {
++      switch (ice_get_phy_model(hw)) {
+       case ICE_PHY_ETH56G:
+               return ice_get_phy_tx_tstamp_ready_eth56g(hw, block,
+                                                         tstamp_ready);
+-- 
+2.39.5
+
diff --git a/queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch b/queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch
new file mode 100644 (file)
index 0000000..87e657b
--- /dev/null
@@ -0,0 +1,423 @@
+From 13950ae904c8b1b0bb82b6f65485d3a701716110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 15:09:56 +0200
+Subject: ice: Use ice_adapter for PTP shared data instead of auxdev
+
+From: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+
+[ Upstream commit e800654e85b5b27966fc6493201f5f8cf658beb6 ]
+
+Use struct ice_adapter to hold shared PTP data and control PTP
+related actions instead of auxbus. This allows significant code
+simplification and faster access to the container fields used in
+the PTP support code.
+
+Move the PTP port list to the ice_adapter container to simplify
+the code and avoid race conditions which could occur due to the
+synchronous nature of the initialization/access and
+certain memory saving can be achieved by moving PTP data into
+the ice_adapter itself.
+
+Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@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>
+Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.c |   6 +
+ drivers/net/ethernet/intel/ice/ice_adapter.h |  17 +++
+ drivers/net/ethernet/intel/ice/ice_ptp.c     | 115 ++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_ptp.h     |   5 +-
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.h  |   5 +
+ 5 files changed, 105 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index ad84d8ad49a63..f3e195974a8ef 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -40,11 +40,17 @@ static struct ice_adapter *ice_adapter_new(void)
+       spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+       refcount_set(&adapter->refcount, 1);
++      mutex_init(&adapter->ports.lock);
++      INIT_LIST_HEAD(&adapter->ports.ports);
++
+       return adapter;
+ }
+ static void ice_adapter_free(struct ice_adapter *adapter)
+ {
++      WARN_ON(!list_empty(&adapter->ports.ports));
++      mutex_destroy(&adapter->ports.lock);
++
+       kfree(adapter);
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index eb7cac01c2427..e233225848b38 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -4,18 +4,34 @@
+ #ifndef _ICE_ADAPTER_H_
+ #define _ICE_ADAPTER_H_
++#include <linux/types.h>
+ #include <linux/spinlock_types.h>
+ #include <linux/refcount_types.h>
+ struct pci_dev;
+ struct ice_pf;
++/**
++ * struct ice_port_list - data used to store the list of adapter ports
++ *
++ * This structure contains data used to maintain a list of adapter ports
++ *
++ * @ports: list of ports
++ * @lock: protect access to the ports list
++ */
++struct ice_port_list {
++      struct list_head ports;
++      /* To synchronize the ports list operations */
++      struct mutex lock;
++};
++
+ /**
+  * struct ice_adapter - PCI adapter resources shared across PFs
+  * @ptp_gltsyn_time_lock: Spinlock protecting access to the GLTSYN_TIME
+  *                        register of the PTP clock.
+  * @refcount: Reference count. struct ice_pf objects hold the references.
+  * @ctrl_pf: Control PF of the adapter
++ * @ports: Ports list
+  */
+ struct ice_adapter {
+       refcount_t refcount;
+@@ -23,6 +39,7 @@ struct ice_adapter {
+       spinlock_t ptp_gltsyn_time_lock;
+       struct ice_pf *ctrl_pf;
++      struct ice_port_list ports;
+ };
+ struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev);
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index 2fb73ab41bc20..0b3dd87a331c7 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -21,7 +21,7 @@ static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf)
+       return !pf->adapter ? NULL : pf->adapter->ctrl_pf;
+ }
+-static __maybe_unused struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf)
++static struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf)
+ {
+       struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf);
+@@ -812,8 +812,8 @@ 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) {
++      mutex_lock(&pf->adapter->ports.lock);
++      list_for_each_entry(port, &pf->adapter->ports.ports, list_node) {
+               struct ice_ptp_tx *tx = &port->tx;
+               if (!tx || !tx->init)
+@@ -821,7 +821,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
+               ice_ptp_process_tx_tstamp(tx);
+       }
+-      mutex_unlock(&pf->ptp.ports_owner.lock);
++      mutex_unlock(&pf->adapter->ports.lock);
+       for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
+               u64 tstamp_ready;
+@@ -986,7 +986,7 @@ 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)
++      list_for_each_entry(port, &pf->adapter->ports.ports, list_node)
+               ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
+ }
+@@ -1586,10 +1586,10 @@ static void ice_ptp_restart_all_phy(struct ice_pf *pf)
+ {
+       struct list_head *entry;
+-      list_for_each(entry, &pf->ptp.ports_owner.ports) {
++      list_for_each(entry, &pf->adapter->ports.ports) {
+               struct ice_ptp_port *port = list_entry(entry,
+                                                      struct ice_ptp_port,
+-                                                     list_member);
++                                                     list_node);
+               if (port->link_up)
+                       ice_ptp_port_phy_restart(port);
+@@ -2906,6 +2906,50 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
+       dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
+ }
++static bool ice_is_primary(struct ice_hw *hw)
++{
++      return ice_is_e825c(hw) && ice_is_dual(hw) ?
++              !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) : true;
++}
++
++static int ice_ptp_setup_adapter(struct ice_pf *pf)
++{
++      if (!ice_pf_src_tmr_owned(pf) || !ice_is_primary(&pf->hw))
++              return -EPERM;
++
++      pf->adapter->ctrl_pf = pf;
++
++      return 0;
++}
++
++static int ice_ptp_setup_pf(struct ice_pf *pf)
++{
++      struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf);
++      struct ice_ptp *ptp = &pf->ptp;
++
++      if (WARN_ON(!ctrl_ptp) || ice_get_phy_model(&pf->hw) == ICE_PHY_UNSUP)
++              return -ENODEV;
++
++      INIT_LIST_HEAD(&ptp->port.list_node);
++      mutex_lock(&pf->adapter->ports.lock);
++
++      list_add(&ptp->port.list_node,
++               &pf->adapter->ports.ports);
++      mutex_unlock(&pf->adapter->ports.lock);
++
++      return 0;
++}
++
++static void ice_ptp_cleanup_pf(struct ice_pf *pf)
++{
++      struct ice_ptp *ptp = &pf->ptp;
++
++      if (ice_get_phy_model(&pf->hw) != ICE_PHY_UNSUP) {
++              mutex_lock(&pf->adapter->ports.lock);
++              list_del(&ptp->port.list_node);
++              mutex_unlock(&pf->adapter->ports.lock);
++      }
++}
+ /**
+  * 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
+@@ -2957,9 +3001,9 @@ static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev,
+       if (WARN_ON(!owner_pf))
+               return -ENODEV;
+-      INIT_LIST_HEAD(&aux_pf->ptp.port.list_member);
++      INIT_LIST_HEAD(&aux_pf->ptp.port.list_node);
+       mutex_lock(&owner_pf->ptp.ports_owner.lock);
+-      list_add(&aux_pf->ptp.port.list_member,
++      list_add(&aux_pf->ptp.port.list_node,
+                &owner_pf->ptp.ports_owner.ports);
+       mutex_unlock(&owner_pf->ptp.ports_owner.lock);
+@@ -2976,7 +3020,7 @@ static void ice_ptp_auxbus_remove(struct auxiliary_device *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);
++      list_del(&aux_pf->ptp.port.list_node);
+       mutex_unlock(&owner_pf->ptp.ports_owner.lock);
+ }
+@@ -3036,7 +3080,7 @@ ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name)
+  * 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)
++static int __always_unused ice_ptp_register_auxbus_driver(struct ice_pf *pf)
+ {
+       struct auxiliary_driver *aux_driver;
+       struct ice_ptp *ptp;
+@@ -3079,7 +3123,7 @@ static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
+  * 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)
++static void __always_unused ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
+ {
+       struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver;
+@@ -3098,15 +3142,12 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
+  */
+ int ice_ptp_clock_index(struct ice_pf *pf)
+ {
+-      struct auxiliary_device *aux_dev;
+-      struct ice_pf *owner_pf;
++      struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(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)
++      if (!ctrl_ptp)
+               return -1;
+-      clock = owner_pf->ptp.clock;
++      clock = ctrl_ptp->clock;
+       return clock ? ptp_clock_index(clock) : -1;
+ }
+@@ -3166,15 +3207,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
+       if (err)
+               goto err_clk;
+-      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:
+-      ptp_clock_unregister(pf->ptp.clock);
+ err_clk:
+       pf->ptp.clock = NULL;
+ err_exit:
+@@ -3250,7 +3283,7 @@ static void ice_ptp_release_auxbus_device(struct device *dev)
+  * 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)
++static __always_unused int ice_ptp_create_auxbus_device(struct ice_pf *pf)
+ {
+       struct auxiliary_device *aux_dev;
+       struct ice_ptp *ptp;
+@@ -3297,7 +3330,7 @@ static int ice_ptp_create_auxbus_device(struct ice_pf *pf)
+  * 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)
++static __always_unused void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
+ {
+       struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev;
+@@ -3361,19 +3394,26 @@ 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 (ice_pf_src_tmr_owned(pf)) {
++      if (ice_pf_src_tmr_owned(pf) && ice_is_primary(hw)) {
++              err = ice_ptp_setup_adapter(pf);
++              if (err)
++                      goto err_exit;
+               err = ice_ptp_init_owner(pf);
+               if (err)
+-                      goto err;
++                      goto err_exit;
+       }
++      err = ice_ptp_setup_pf(pf);
++      if (err)
++              goto err_exit;
++
+       ptp->port.port_num = hw->pf_id;
+       if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
+               ptp->port.port_num = hw->pf_id * 2;
+       err = ice_ptp_init_port(pf, &ptp->port);
+       if (err)
+-              goto err;
++              goto err_exit;
+       /* Start the PHY timestamping block */
+       ice_ptp_reset_phy_timestamping(pf);
+@@ -3381,20 +3421,16 @@ void ice_ptp_init(struct ice_pf *pf)
+       /* Configure initial Tx interrupt settings */
+       ice_ptp_cfg_tx_interrupt(pf);
+-      err = ice_ptp_create_auxbus_device(pf);
+-      if (err)
+-              goto err;
+-
+       ptp->state = ICE_PTP_READY;
+       err = ice_ptp_init_work(pf, ptp);
+       if (err)
+-              goto err;
++              goto err_exit;
+       dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
+       return;
+-err:
++err_exit:
+       /* If we registered a PTP clock, release it */
+       if (pf->ptp.clock) {
+               ptp_clock_unregister(ptp->clock);
+@@ -3421,7 +3457,7 @@ void ice_ptp_release(struct ice_pf *pf)
+       /* Disable timestamping for both Tx and Rx */
+       ice_ptp_disable_timestamp_mode(pf);
+-      ice_ptp_remove_auxbus_device(pf);
++      ice_ptp_cleanup_pf(pf);
+       ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
+@@ -3436,9 +3472,6 @@ 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;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
+index 2db2257a0fb2f..5615efc42c624 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
+@@ -169,7 +169,7 @@ 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
++ * @list_node: list member structure
+  * @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
+@@ -179,7 +179,7 @@ struct ice_ptp_tx {
+  * @port_num: the port number this structure represents
+  */
+ struct ice_ptp_port {
+-      struct list_head list_member;
++      struct list_head list_node;
+       struct ice_ptp_tx tx;
+       struct auxiliary_device aux_dev;
+       struct kthread_delayed_work ov_work;
+@@ -205,6 +205,7 @@ enum ice_ptp_tx_interrupt {
+  * @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;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+index 4c8b845713442..3499062218b59 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+@@ -452,6 +452,11 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw)
+       }
+ }
++static inline bool ice_is_dual(struct ice_hw *hw)
++{
++      return !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_DUAL_M);
++}
++
+ #define PFTSYN_SEM_BYTES      4
+ #define ICE_PTP_CLOCK_INDEX_0 0x00
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch b/queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch
new file mode 100644 (file)
index 0000000..a049f6c
--- /dev/null
@@ -0,0 +1,86 @@
+From 08066a194d4b435268fe89c571c760b35b657dc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 22:54:33 +0530
+Subject: net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
+
+From: Sudheer Kumar Doredla <s-doredla@ti.com>
+
+[ Upstream commit 03d120f27d050336f7e7d21879891542c4741f81 ]
+
+CPSW ALE has 75-bit ALE entries stored across three 32-bit words.
+The cpsw_ale_get_field() and cpsw_ale_set_field() functions support
+ALE field entries spanning up to two words at the most.
+
+The cpsw_ale_get_field() and cpsw_ale_set_field() functions work as
+expected when ALE field spanned across word1 and word2, but fails when
+ALE field spanned across word2 and word3.
+
+For example, while reading the ALE field spanned across word2 and word3
+(i.e. bits 62 to 64), the word3 data shifted to an incorrect position
+due to the index becoming zero while flipping.
+The same issue occurred when setting an ALE entry.
+
+This issue has not been seen in practice but will be an issue in the future
+if the driver supports accessing ALE fields spanning word2 and word3
+
+Fix the methods to handle getting/setting fields spanning up to two words.
+
+Fixes: b685f1a58956 ("net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()")
+Signed-off-by: Sudheer Kumar Doredla <s-doredla@ti.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Link: https://patch.msgid.link/20250108172433.311694-1-s-doredla@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/cpsw_ale.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
+index 8d02d2b214293..dc5e247ca5d1a 100644
+--- a/drivers/net/ethernet/ti/cpsw_ale.c
++++ b/drivers/net/ethernet/ti/cpsw_ale.c
+@@ -127,15 +127,15 @@ struct cpsw_ale_dev_id {
+ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
+ {
+-      int idx, idx2;
++      int idx, idx2, index;
+       u32 hi_val = 0;
+       idx    = start / 32;
+       idx2 = (start + bits - 1) / 32;
+       /* Check if bits to be fetched exceed a word */
+       if (idx != idx2) {
+-              idx2 = 2 - idx2; /* flip */
+-              hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
++              index = 2 - idx2; /* flip */
++              hi_val = ale_entry[index] << ((idx2 * 32) - start);
+       }
+       start -= idx * 32;
+       idx    = 2 - idx; /* flip */
+@@ -145,16 +145,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
+ static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
+                                     u32 value)
+ {
+-      int idx, idx2;
++      int idx, idx2, index;
+       value &= BITMASK(bits);
+       idx = start / 32;
+       idx2 = (start + bits - 1) / 32;
+       /* Check if bits to be set exceed a word */
+       if (idx != idx2) {
+-              idx2 = 2 - idx2; /* flip */
+-              ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
+-              ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
++              index = 2 - idx2; /* flip */
++              ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
++              ale_entry[index] |= (value >> ((idx2 * 32) - start));
+       }
+       start -= idx * 32;
+       idx = 2 - idx; /* flip */
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch b/queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch
new file mode 100644 (file)
index 0000000..7f90f5a
--- /dev/null
@@ -0,0 +1,96 @@
+From 7c38868fc6519ce1066b30e5a4bda7acdb32b298 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 10:48:45 -0500
+Subject: net: fec: handle page_pool_dev_alloc_pages error
+
+From: Kevin Groeneveld <kgroeneveld@lenbrook.com>
+
+[ Upstream commit 001ba0902046cb6c352494df610718c0763e77a5 ]
+
+The fec_enet_update_cbd function calls page_pool_dev_alloc_pages but did
+not handle the case when it returned NULL. There was a WARN_ON(!new_page)
+but it would still proceed to use the NULL pointer and then crash.
+
+This case does seem somewhat rare but when the system is under memory
+pressure it can happen. One case where I can duplicate this with some
+frequency is when writing over a smbd share to a SATA HDD attached to an
+imx6q.
+
+Setting /proc/sys/vm/min_free_kbytes to higher values also seems to solve
+the problem for my test case. But it still seems wrong that the fec driver
+ignores the memory allocation error and can crash.
+
+This commit handles the allocation error by dropping the current packet.
+
+Fixes: 95698ff6177b5 ("net: fec: using page pool to manage RX buffers")
+Signed-off-by: Kevin Groeneveld <kgroeneveld@lenbrook.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20250113154846.1765414-1-kgroeneveld@lenbrook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 9d9fcec41488e..49d1748e0c043 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1591,19 +1591,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget)
+               fec_enet_tx_queue(ndev, i, budget);
+ }
+-static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
++static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
+                               struct bufdesc *bdp, int index)
+ {
+       struct page *new_page;
+       dma_addr_t phys_addr;
+       new_page = page_pool_dev_alloc_pages(rxq->page_pool);
+-      WARN_ON(!new_page);
+-      rxq->rx_skb_info[index].page = new_page;
++      if (unlikely(!new_page))
++              return -ENOMEM;
++      rxq->rx_skb_info[index].page = new_page;
+       rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;
+       phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;
+       bdp->cbd_bufaddr = cpu_to_fec32(phys_addr);
++
++      return 0;
+ }
+ static u32
+@@ -1698,6 +1701,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+       int cpu = smp_processor_id();
+       struct xdp_buff xdp;
+       struct page *page;
++      __fec32 cbd_bufaddr;
+       u32 sub_len = 4;
+ #if !defined(CONFIG_M5272)
+@@ -1766,12 +1770,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               page = rxq->rx_skb_info[index].page;
++              cbd_bufaddr = bdp->cbd_bufaddr;
++              if (fec_enet_update_cbd(rxq, bdp, index)) {
++                      ndev->stats.rx_dropped++;
++                      goto rx_processing_done;
++              }
++
+               dma_sync_single_for_cpu(&fep->pdev->dev,
+-                                      fec32_to_cpu(bdp->cbd_bufaddr),
++                                      fec32_to_cpu(cbd_bufaddr),
+                                       pkt_len,
+                                       DMA_FROM_DEVICE);
+               prefetch(page_address(page));
+-              fec_enet_update_cbd(rxq, bdp, index);
+               if (xdp_prog) {
+                       xdp_buff_clear_frags_flag(&xdp);
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch b/queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch
new file mode 100644 (file)
index 0000000..f84270d
--- /dev/null
@@ -0,0 +1,39 @@
+From 1cfae25c3112fee653b469824140de68e4fb7d26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 14:06:22 -0800
+Subject: net: make page_pool_ref_netmem work with net iovs
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit cbc16bceea784210d585a42ac9f8f10ce62b300e ]
+
+page_pool_ref_netmem() should work with either netmem representation, but
+currently it casts to a page with netmem_to_page(), which will fail with
+net iovs. Use netmem_get_pp_ref_count_ref() instead.
+
+Fixes: 8ab79ed50cf1 ("page_pool: devmem support")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: David Wei <dw@davidwei.uk>
+Link: https://lore.kernel.org/20250108220644.3528845-2-dw@davidwei.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/page_pool/helpers.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
+index 793e6fd78bc5c..60a5347922bec 100644
+--- a/include/net/page_pool/helpers.h
++++ b/include/net/page_pool/helpers.h
+@@ -294,7 +294,7 @@ static inline long page_pool_unref_page(struct page *page, long nr)
+ static inline void page_pool_ref_netmem(netmem_ref netmem)
+ {
+-      atomic_long_inc(&netmem_to_page(netmem)->pp_ref_count);
++      atomic_long_inc(netmem_get_pp_ref_count_ref(netmem));
+ }
+ static inline void page_pool_ref_page(struct page *page)
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch b/queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch
new file mode 100644 (file)
index 0000000..06666db
--- /dev/null
@@ -0,0 +1,107 @@
+From c1cb7d99d032c187b2fea5a32b3c8f09741c9c58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:07 +0200
+Subject: net/mlx5: Clear port select structure when fail to create
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit 5641e82cb55b4ecbc6366a499300917d2f3e6790 ]
+
+Clear the port select structure on error so no stale values left after
+definers are destroyed. That's because the mlx5_lag_destroy_definers()
+always try to destroy all lag definers in the tt_map, so in the flow
+below lag definers get double-destroyed and cause kernel crash:
+
+  mlx5_lag_port_sel_create()
+    mlx5_lag_create_definers()
+      mlx5_lag_create_definer()     <- Failed on tt 1
+        mlx5_lag_destroy_definers() <- definers[tt=0] gets destroyed
+  mlx5_lag_port_sel_create()
+    mlx5_lag_create_definers()
+      mlx5_lag_create_definer()     <- Failed on tt 0
+        mlx5_lag_destroy_definers() <- definers[tt=0] gets double-destroyed
+
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
+ Mem abort info:
+   ESR = 0x0000000096000005
+   EC = 0x25: DABT (current EL), IL = 32 bits
+   SET = 0, FnV = 0
+   EA = 0, S1PTW = 0
+   FSC = 0x05: level 1 translation fault
+ Data abort info:
+   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
+   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ user pgtable: 64k pages, 48-bit VAs, pgdp=0000000112ce2e00
+ [0000000000000008] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+ Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
+ Modules linked in: iptable_raw bonding ip_gre ip6_gre gre ip6_tunnel tunnel6 geneve ip6_udp_tunnel udp_tunnel ipip tunnel4 ip_tunnel rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) ib_uverbs(OE) mlx5_fwctl(OE) fwctl(OE) mlx5_core(OE) mlxdevm(OE) ib_core(OE) mlxfw(OE) memtrack(OE) mlx_compat(OE) openvswitch nsh nf_conncount psample xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xfrm_user xfrm_algo xt_addrtype iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter bridge stp llc netconsole overlay efi_pstore sch_fq_codel zram ip_tables crct10dif_ce qemu_fw_cfg fuse ipv6 crc_ccitt [last unloaded: mlx_compat(OE)]
+  CPU: 3 UID: 0 PID: 217 Comm: kworker/u53:2 Tainted: G           OE      6.11.0+ #2
+  Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+  Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
+  Workqueue: mlx5_lag mlx5_do_bond_work [mlx5_core]
+  pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+  pc : mlx5_del_flow_rules+0x24/0x2c0 [mlx5_core]
+  lr : mlx5_lag_destroy_definer+0x54/0x100 [mlx5_core]
+  sp : ffff800085fafb00
+  x29: ffff800085fafb00 x28: ffff0000da0c8000 x27: 0000000000000000
+  x26: ffff0000da0c8000 x25: ffff0000da0c8000 x24: ffff0000da0c8000
+  x23: ffff0000c31f81a0 x22: 0400000000000000 x21: ffff0000da0c8000
+  x20: 0000000000000000 x19: 0000000000000001 x18: 0000000000000000
+  x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffff8b0c9350
+  x14: 0000000000000000 x13: ffff800081390d18 x12: ffff800081dc3cc0
+  x11: 0000000000000001 x10: 0000000000000b10 x9 : ffff80007ab7304c
+  x8 : ffff0000d00711f0 x7 : 0000000000000004 x6 : 0000000000000190
+  x5 : ffff00027edb3010 x4 : 0000000000000000 x3 : 0000000000000000
+  x2 : ffff0000d39b8000 x1 : ffff0000d39b8000 x0 : 0400000000000000
+  Call trace:
+   mlx5_del_flow_rules+0x24/0x2c0 [mlx5_core]
+   mlx5_lag_destroy_definer+0x54/0x100 [mlx5_core]
+   mlx5_lag_destroy_definers+0xa0/0x108 [mlx5_core]
+   mlx5_lag_port_sel_create+0x2d4/0x6f8 [mlx5_core]
+   mlx5_activate_lag+0x60c/0x6f8 [mlx5_core]
+   mlx5_do_bond_work+0x284/0x5c8 [mlx5_core]
+   process_one_work+0x170/0x3e0
+   worker_thread+0x2d8/0x3e0
+   kthread+0x11c/0x128
+   ret_from_fork+0x10/0x20
+  Code: a9025bf5 aa0003f6 a90363f7 f90023f9 (f9400400)
+  ---[ end trace 0000000000000000 ]---
+
+Fixes: dc48516ec7d3 ("net/mlx5: Lag, add support to create definers for LAG")
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c
+index ab2717012b79b..39e80704b1c42 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c
+@@ -530,7 +530,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev,
+       set_tt_map(port_sel, hash_type);
+       err = mlx5_lag_create_definers(ldev, hash_type, ports);
+       if (err)
+-              return err;
++              goto clear_port_sel;
+       if (port_sel->tunnel) {
+               err = mlx5_lag_create_inner_ttc_table(ldev);
+@@ -549,6 +549,8 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev,
+               mlx5_destroy_ttc_table(port_sel->inner.ttc);
+ destroy_definers:
+       mlx5_lag_destroy_definers(ldev);
++clear_port_sel:
++      memset(port_sel, 0, sizeof(*port_sel));
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch b/queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch
new file mode 100644 (file)
index 0000000..0975cfe
--- /dev/null
@@ -0,0 +1,182 @@
+From 8ad0d10eec030a9460c1d4ca779ae6b39445d0ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:05 +0200
+Subject: net/mlx5: Fix a lockdep warning as part of the write combining test
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit 1b10a519a45704d4b06ebd9245b272d145752c18 ]
+
+Fix a lockdep warning [1] observed during the write combining test.
+
+The warning indicates a potential nested lock scenario that could lead
+to a deadlock.
+
+However, this is a false positive alarm because the SF lock and its
+parent lock are distinct ones.
+
+The lockdep confusion arises because the locks belong to the same object
+class (i.e., struct mlx5_core_dev).
+
+To resolve this, the code has been refactored to avoid taking both
+locks. Instead, only the parent lock is acquired.
+
+[1]
+raw_ethernet_bw/2118 is trying to acquire lock:
+[  213.619032] ffff88811dd75e08 (&dev->wc_state_lock){+.+.}-{3:3}, at:
+               mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.620270]
+[  213.620270] but task is already holding lock:
+[  213.620943] ffff88810b585e08 (&dev->wc_state_lock){+.+.}-{3:3}, at:
+               mlx5_wc_support_get+0x10c/0x210 [mlx5_core]
+[  213.622045]
+[  213.622045] other info that might help us debug this:
+[  213.622778]  Possible unsafe locking scenario:
+[  213.622778]
+[  213.623465]        CPU0
+[  213.623815]        ----
+[  213.624148]   lock(&dev->wc_state_lock);
+[  213.624615]   lock(&dev->wc_state_lock);
+[  213.625071]
+[  213.625071]  *** DEADLOCK ***
+[  213.625071]
+[  213.625805]  May be due to missing lock nesting notation
+[  213.625805]
+[  213.626522] 4 locks held by raw_ethernet_bw/2118:
+[  213.627019]  #0: ffff88813f80d578 (&uverbs_dev->disassociate_srcu){.+.+}-{0:0},
+                at: ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs]
+[  213.628088]  #1: ffff88810fb23930 (&file->hw_destroy_rwsem){.+.+}-{3:3},
+                at: ib_init_ucontext+0x2d/0xf0 [ib_uverbs]
+[  213.629094]  #2: ffff88810fb23878 (&file->ucontext_lock){+.+.}-{3:3},
+                at: ib_init_ucontext+0x49/0xf0 [ib_uverbs]
+[  213.630106]  #3: ffff88810b585e08 (&dev->wc_state_lock){+.+.}-{3:3},
+                at: mlx5_wc_support_get+0x10c/0x210 [mlx5_core]
+[  213.631185]
+[  213.631185] stack backtrace:
+[  213.631718] CPU: 1 UID: 0 PID: 2118 Comm: raw_ethernet_bw Not tainted
+               6.12.0-rc7_internal_net_next_mlx5_89a0ad0 #1
+[  213.632722] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+               rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+[  213.633785] Call Trace:
+[  213.634099]
+[  213.634393]  dump_stack_lvl+0x7e/0xc0
+[  213.634806]  print_deadlock_bug+0x278/0x3c0
+[  213.635265]  __lock_acquire+0x15f4/0x2c40
+[  213.635712]  lock_acquire+0xcd/0x2d0
+[  213.636120]  ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.636722]  ? mlx5_ib_enable_lb+0x24/0xa0 [mlx5_ib]
+[  213.637277]  __mutex_lock+0x81/0xda0
+[  213.637697]  ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.638305]  ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.638902]  ? rcu_read_lock_sched_held+0x3f/0x70
+[  213.639400]  ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.640016]  mlx5_wc_support_get+0x18c/0x210 [mlx5_core]
+[  213.640615]  set_ucontext_resp+0x68/0x2b0 [mlx5_ib]
+[  213.641144]  ? debug_mutex_init+0x33/0x40
+[  213.641586]  mlx5_ib_alloc_ucontext+0x18e/0x7b0 [mlx5_ib]
+[  213.642145]  ib_init_ucontext+0xa0/0xf0 [ib_uverbs]
+[  213.642679]  ib_uverbs_handler_UVERBS_METHOD_GET_CONTEXT+0x95/0xc0
+                [ib_uverbs]
+[  213.643426]  ? _copy_from_user+0x46/0x80
+[  213.643878]  ib_uverbs_cmd_verbs+0xa6b/0xc80 [ib_uverbs]
+[  213.644426]  ? ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x130/0x130
+               [ib_uverbs]
+[  213.645213]  ? __lock_acquire+0xa99/0x2c40
+[  213.645675]  ? lock_acquire+0xcd/0x2d0
+[  213.646101]  ? ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs]
+[  213.646625]  ? reacquire_held_locks+0xcf/0x1f0
+[  213.647102]  ? do_user_addr_fault+0x45d/0x770
+[  213.647586]  ib_uverbs_ioctl+0xe0/0x170 [ib_uverbs]
+[  213.648102]  ? ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs]
+[  213.648632]  __x64_sys_ioctl+0x4d3/0xaa0
+[  213.649060]  ? do_user_addr_fault+0x4a8/0x770
+[  213.649528]  do_syscall_64+0x6d/0x140
+[  213.649947]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  213.650478] RIP: 0033:0x7fa179b0737b
+[  213.650893] Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c
+               89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8
+               10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d
+               7d 2a 0f 00 f7 d8 64 89 01 48
+[  213.652619] RSP: 002b:00007ffd2e6d46e8 EFLAGS: 00000246 ORIG_RAX:
+               0000000000000010
+[  213.653390] RAX: ffffffffffffffda RBX: 00007ffd2e6d47f8 RCX:
+               00007fa179b0737b
+[  213.654084] RDX: 00007ffd2e6d47e0 RSI: 00000000c0181b01 RDI:
+               0000000000000003
+[  213.654767] RBP: 00007ffd2e6d47c0 R08: 00007fa1799be010 R09:
+               0000000000000002
+[  213.655453] R10: 00007ffd2e6d4960 R11: 0000000000000246 R12:
+               00007ffd2e6d487c
+[  213.656170] R13: 0000000000000027 R14: 0000000000000001 R15:
+               00007ffd2e6d4f70
+
+Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test")
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
+Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/wc.c | 24 ++++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+index 1bed75eca97db..740b719e7072d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+@@ -382,6 +382,7 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
+ bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
+ {
++      struct mutex *wc_state_lock = &mdev->wc_state_lock;
+       struct mlx5_core_dev *parent = NULL;
+       if (!MLX5_CAP_GEN(mdev, bf)) {
+@@ -400,32 +401,31 @@ bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
+                */
+               goto out;
+-      mutex_lock(&mdev->wc_state_lock);
+-
+-      if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED)
+-              goto unlock;
+-
+ #ifdef CONFIG_MLX5_SF
+-      if (mlx5_core_is_sf(mdev))
++      if (mlx5_core_is_sf(mdev)) {
+               parent = mdev->priv.parent_mdev;
++              wc_state_lock = &parent->wc_state_lock;
++      }
+ #endif
+-      if (parent) {
+-              mutex_lock(&parent->wc_state_lock);
++      mutex_lock(wc_state_lock);
++      if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED)
++              goto unlock;
++
++      if (parent) {
+               mlx5_core_test_wc(parent);
+               mlx5_core_dbg(mdev, "parent set wc_state=%d\n",
+                             parent->wc_state);
+               mdev->wc_state = parent->wc_state;
+-              mutex_unlock(&parent->wc_state_lock);
++      } else {
++              mlx5_core_test_wc(mdev);
+       }
+-      mlx5_core_test_wc(mdev);
+-
+ unlock:
+-      mutex_unlock(&mdev->wc_state_lock);
++      mutex_unlock(wc_state_lock);
+ out:
+       mlx5_core_dbg(mdev, "wc_state=%d\n", mdev->wc_state);
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch b/queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch
new file mode 100644 (file)
index 0000000..ad127f9
--- /dev/null
@@ -0,0 +1,39 @@
+From 9af9e9d637f1b404a1de562e5cd29a56f3ac597d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:04 +0200
+Subject: net/mlx5: Fix RDMA TX steering prio
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit c08d3e62b2e73e14da318a1d20b52d0486a28ee0 ]
+
+User added steering rules at RDMA_TX were being added to the first prio,
+which is the counters prio.
+Fix that so that they are correctly added to the BYPASS_PRIO instead.
+
+Fixes: 24670b1a3166 ("net/mlx5: Add support for RDMA TX steering")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 2eabfcc247c6a..0ce999706d412 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -2709,6 +2709,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
+               break;
+       case MLX5_FLOW_NAMESPACE_RDMA_TX:
+               root_ns = steering->rdma_tx_root_ns;
++              prio = RDMA_TX_BYPASS_PRIO;
+               break;
+       case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
+               root_ns = steering->rdma_rx_root_ns;
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch b/queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch
new file mode 100644 (file)
index 0000000..378c7f1
--- /dev/null
@@ -0,0 +1,42 @@
+From e6450ecb8ab8d0e193a4f6d1c632f164e429fb78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:06 +0200
+Subject: net/mlx5: SF, Fix add port error handling
+
+From: Chris Mi <cmi@nvidia.com>
+
+[ Upstream commit 2011a2a18ef00b5b8e4b753acbe6451a8c5f2260 ]
+
+If failed to add SF, error handling doesn't delete the SF from the
+SF table. But the hw resources are deleted. So when unload driver,
+hw resources will be deleted again. Firmware will report syndrome
+0x68def3 which means "SF is not allocated can not deallocate".
+
+Fix it by delete SF from SF table if failed to add SF.
+
+Fixes: 2597ee190b4e ("net/mlx5: Call mlx5_sf_id_erase() once in mlx5_sf_dealloc()")
+Signed-off-by: Chris Mi <cmi@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index a96be98be032f..b96909fbeb12d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -257,6 +257,7 @@ static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
+       return 0;
+ esw_err:
++      mlx5_sf_function_id_erase(table, sf);
+       mlx5_sf_free(table, sf);
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch b/queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch
new file mode 100644 (file)
index 0000000..d4bcf1c
--- /dev/null
@@ -0,0 +1,85 @@
+From 35956515527c7d8b6c6f1490e30e19ed941755fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:10 +0200
+Subject: net/mlx5e: Always start IPsec sequence number from 1
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 7f95b0247764acd739d949ff247db4b76138e55a ]
+
+According to RFC4303, section "3.3.3. Sequence Number Generation",
+the first packet sent using a given SA will contain a sequence
+number of 1.
+
+This is applicable to both ESN and non-ESN mode, which was not covered
+in commit mentioned in Fixes line.
+
+Fixes: 3d42c8cc67a8 ("net/mlx5e: Ensure that IPsec sequence packet number starts from 1")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c  |  6 ++++++
+ .../mellanox/mlx5/core/en_accel/ipsec_offload.c       | 11 ++++++++---
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 21857474ad83f..1baf8933a07cb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -724,6 +724,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+       /* check esn */
+       if (x->props.flags & XFRM_STATE_ESN)
+               mlx5e_ipsec_update_esn_state(sa_entry);
++      else
++              /* According to RFC4303, section "3.3.3. Sequence Number Generation",
++               * the first packet sent using a given SA will contain a sequence
++               * number of 1.
++               */
++              sa_entry->esn_state.esn = 1;
+       mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
+index 53cfa39188cb0..820debf3fbbf2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
+@@ -91,8 +91,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
+ EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
+ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
+-                                   struct mlx5_accel_esp_xfrm_attrs *attrs)
++                                   struct mlx5e_ipsec_sa_entry *sa_entry)
+ {
++      struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
+       void *aso_ctx;
+       aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
+@@ -120,8 +121,12 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
+        * active.
+        */
+       MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
+-      if (attrs->dir == XFRM_DEV_OFFLOAD_OUT)
++      if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) {
+               MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
++              if (!attrs->replay_esn.trigger)
++                      MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
++                               sa_entry->esn_state.esn);
++      }
+       if (attrs->lft.hard_packet_limit != XFRM_INF) {
+               MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
+@@ -175,7 +180,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
+       res = &mdev->mlx5e_res.hw_objs;
+       if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
+-              mlx5e_ipsec_packet_setup(obj, res->pdn, attrs);
++              mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry);
+       err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+       if (!err)
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch b/queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch
new file mode 100644 (file)
index 0000000..d148daa
--- /dev/null
@@ -0,0 +1,342 @@
+From cd922d46de1ad35629a41840d55e837edafa6a7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:08 +0200
+Subject: net/mlx5e: Fix inversion dependency warning while enabling IPsec
+ tunnel
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 2c3688090f8a1f085230aa839cc63e4a7b977df0 ]
+
+Attempt to enable IPsec packet offload in tunnel mode in debug kernel
+generates the following kernel panic, which is happening due to two
+issues:
+1. In SA add section, the should be _bh() variant when marking SA mode.
+2. There is not needed flush_workqueue in SA delete routine. It is not
+needed as at this stage as it is removed from SADB and the running work
+will be canceled later in SA free.
+
+ =====================================================
+ WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
+ 6.12.0+ #4 Not tainted
+ -----------------------------------------------------
+ charon/1337 [HC0[0]:SC0[4]:HE1:SE0] is trying to acquire:
+ ffff88810f365020 (&xa->xa_lock#24){+.+.}-{3:3}, at: mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core]
+
+ and this task is already holding:
+ ffff88813e0f0d48 (&x->lock){+.-.}-{3:3}, at: xfrm_state_delete+0x16/0x30
+ which would create a new lock dependency:
+  (&x->lock){+.-.}-{3:3} -> (&xa->xa_lock#24){+.+.}-{3:3}
+
+ but this new dependency connects a SOFTIRQ-irq-safe lock:
+  (&x->lock){+.-.}-{3:3}
+
+ ... which became SOFTIRQ-irq-safe at:
+   lock_acquire+0x1be/0x520
+   _raw_spin_lock_bh+0x34/0x40
+   xfrm_timer_handler+0x91/0xd70
+   __hrtimer_run_queues+0x1dd/0xa60
+   hrtimer_run_softirq+0x146/0x2e0
+   handle_softirqs+0x266/0x860
+   irq_exit_rcu+0x115/0x1a0
+   sysvec_apic_timer_interrupt+0x6e/0x90
+   asm_sysvec_apic_timer_interrupt+0x16/0x20
+   default_idle+0x13/0x20
+   default_idle_call+0x67/0xa0
+   do_idle+0x2da/0x320
+   cpu_startup_entry+0x50/0x60
+   start_secondary+0x213/0x2a0
+   common_startup_64+0x129/0x138
+
+ to a SOFTIRQ-irq-unsafe lock:
+  (&xa->xa_lock#24){+.+.}-{3:3}
+
+ ... which became SOFTIRQ-irq-unsafe at:
+ ...
+   lock_acquire+0x1be/0x520
+   _raw_spin_lock+0x2c/0x40
+   xa_set_mark+0x70/0x110
+   mlx5e_xfrm_add_state+0xe48/0x2290 [mlx5_core]
+   xfrm_dev_state_add+0x3bb/0xd70
+   xfrm_add_sa+0x2451/0x4a90
+   xfrm_user_rcv_msg+0x493/0x880
+   netlink_rcv_skb+0x12e/0x380
+   xfrm_netlink_rcv+0x6d/0x90
+   netlink_unicast+0x42f/0x740
+   netlink_sendmsg+0x745/0xbe0
+   __sock_sendmsg+0xc5/0x190
+   __sys_sendto+0x1fe/0x2c0
+   __x64_sys_sendto+0xdc/0x1b0
+   do_syscall_64+0x6d/0x140
+   entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+ other info that might help us debug this:
+
+  Possible interrupt unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+   lock(&xa->xa_lock#24);
+                                local_irq_disable();
+                                lock(&x->lock);
+                                lock(&xa->xa_lock#24);
+   <Interrupt>
+     lock(&x->lock);
+
+  *** DEADLOCK ***
+
+ 2 locks held by charon/1337:
+  #0: ffffffff87f8f858 (&net->xfrm.xfrm_cfg_mutex){+.+.}-{4:4}, at: xfrm_netlink_rcv+0x5e/0x90
+  #1: ffff88813e0f0d48 (&x->lock){+.-.}-{3:3}, at: xfrm_state_delete+0x16/0x30
+
+ the dependencies between SOFTIRQ-irq-safe lock and the holding lock:
+ -> (&x->lock){+.-.}-{3:3} ops: 29 {
+    HARDIRQ-ON-W at:
+                     lock_acquire+0x1be/0x520
+                     _raw_spin_lock_bh+0x34/0x40
+                     xfrm_alloc_spi+0xc0/0xe60
+                     xfrm_alloc_userspi+0x5f6/0xbc0
+                     xfrm_user_rcv_msg+0x493/0x880
+                     netlink_rcv_skb+0x12e/0x380
+                     xfrm_netlink_rcv+0x6d/0x90
+                     netlink_unicast+0x42f/0x740
+                     netlink_sendmsg+0x745/0xbe0
+                     __sock_sendmsg+0xc5/0x190
+                     __sys_sendto+0x1fe/0x2c0
+                     __x64_sys_sendto+0xdc/0x1b0
+                     do_syscall_64+0x6d/0x140
+                     entry_SYSCALL_64_after_hwframe+0x4b/0x53
+    IN-SOFTIRQ-W at:
+                     lock_acquire+0x1be/0x520
+                     _raw_spin_lock_bh+0x34/0x40
+                     xfrm_timer_handler+0x91/0xd70
+                     __hrtimer_run_queues+0x1dd/0xa60
+                     hrtimer_run_softirq+0x146/0x2e0
+                     handle_softirqs+0x266/0x860
+                     irq_exit_rcu+0x115/0x1a0
+                     sysvec_apic_timer_interrupt+0x6e/0x90
+                     asm_sysvec_apic_timer_interrupt+0x16/0x20
+                     default_idle+0x13/0x20
+                     default_idle_call+0x67/0xa0
+                     do_idle+0x2da/0x320
+                     cpu_startup_entry+0x50/0x60
+                     start_secondary+0x213/0x2a0
+                     common_startup_64+0x129/0x138
+    INITIAL USE at:
+                    lock_acquire+0x1be/0x520
+                    _raw_spin_lock_bh+0x34/0x40
+                    xfrm_alloc_spi+0xc0/0xe60
+                    xfrm_alloc_userspi+0x5f6/0xbc0
+                    xfrm_user_rcv_msg+0x493/0x880
+                    netlink_rcv_skb+0x12e/0x380
+                    xfrm_netlink_rcv+0x6d/0x90
+                    netlink_unicast+0x42f/0x740
+                    netlink_sendmsg+0x745/0xbe0
+                    __sock_sendmsg+0xc5/0x190
+                    __sys_sendto+0x1fe/0x2c0
+                    __x64_sys_sendto+0xdc/0x1b0
+                    do_syscall_64+0x6d/0x140
+                    entry_SYSCALL_64_after_hwframe+0x4b/0x53
+  }
+  ... key      at: [<ffffffff87f9cd20>] __key.18+0x0/0x40
+
+ the dependencies between the lock to be acquired
+  and SOFTIRQ-irq-unsafe lock:
+ -> (&xa->xa_lock#24){+.+.}-{3:3} ops: 9 {
+    HARDIRQ-ON-W at:
+                     lock_acquire+0x1be/0x520
+                     _raw_spin_lock_bh+0x34/0x40
+                     mlx5e_xfrm_add_state+0xc5b/0x2290 [mlx5_core]
+                     xfrm_dev_state_add+0x3bb/0xd70
+                     xfrm_add_sa+0x2451/0x4a90
+                     xfrm_user_rcv_msg+0x493/0x880
+                     netlink_rcv_skb+0x12e/0x380
+                     xfrm_netlink_rcv+0x6d/0x90
+                     netlink_unicast+0x42f/0x740
+                     netlink_sendmsg+0x745/0xbe0
+                     __sock_sendmsg+0xc5/0x190
+                     __sys_sendto+0x1fe/0x2c0
+                     __x64_sys_sendto+0xdc/0x1b0
+                     do_syscall_64+0x6d/0x140
+                     entry_SYSCALL_64_after_hwframe+0x4b/0x53
+    SOFTIRQ-ON-W at:
+                     lock_acquire+0x1be/0x520
+                     _raw_spin_lock+0x2c/0x40
+                     xa_set_mark+0x70/0x110
+                     mlx5e_xfrm_add_state+0xe48/0x2290 [mlx5_core]
+                     xfrm_dev_state_add+0x3bb/0xd70
+                     xfrm_add_sa+0x2451/0x4a90
+                     xfrm_user_rcv_msg+0x493/0x880
+                     netlink_rcv_skb+0x12e/0x380
+                     xfrm_netlink_rcv+0x6d/0x90
+                     netlink_unicast+0x42f/0x740
+                     netlink_sendmsg+0x745/0xbe0
+                     __sock_sendmsg+0xc5/0x190
+                     __sys_sendto+0x1fe/0x2c0
+                     __x64_sys_sendto+0xdc/0x1b0
+                     do_syscall_64+0x6d/0x140
+                     entry_SYSCALL_64_after_hwframe+0x4b/0x53
+    INITIAL USE at:
+                    lock_acquire+0x1be/0x520
+                    _raw_spin_lock_bh+0x34/0x40
+                    mlx5e_xfrm_add_state+0xc5b/0x2290 [mlx5_core]
+                    xfrm_dev_state_add+0x3bb/0xd70
+                    xfrm_add_sa+0x2451/0x4a90
+                    xfrm_user_rcv_msg+0x493/0x880
+                    netlink_rcv_skb+0x12e/0x380
+                    xfrm_netlink_rcv+0x6d/0x90
+                    netlink_unicast+0x42f/0x740
+                    netlink_sendmsg+0x745/0xbe0
+                    __sock_sendmsg+0xc5/0x190
+                    __sys_sendto+0x1fe/0x2c0
+                    __x64_sys_sendto+0xdc/0x1b0
+                    do_syscall_64+0x6d/0x140
+                    entry_SYSCALL_64_after_hwframe+0x4b/0x53
+  }
+  ... key      at: [<ffffffffa078ff60>] __key.48+0x0/0xfffffffffff210a0 [mlx5_core]
+  ... acquired at:
+    __lock_acquire+0x30a0/0x5040
+    lock_acquire+0x1be/0x520
+    _raw_spin_lock_bh+0x34/0x40
+    mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core]
+    xfrm_dev_state_delete+0x90/0x160
+    __xfrm_state_delete+0x662/0xae0
+    xfrm_state_delete+0x1e/0x30
+    xfrm_del_sa+0x1c2/0x340
+    xfrm_user_rcv_msg+0x493/0x880
+    netlink_rcv_skb+0x12e/0x380
+    xfrm_netlink_rcv+0x6d/0x90
+    netlink_unicast+0x42f/0x740
+    netlink_sendmsg+0x745/0xbe0
+    __sock_sendmsg+0xc5/0x190
+    __sys_sendto+0x1fe/0x2c0
+    __x64_sys_sendto+0xdc/0x1b0
+    do_syscall_64+0x6d/0x140
+    entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+ stack backtrace:
+ CPU: 7 UID: 0 PID: 1337 Comm: charon Not tainted 6.12.0+ #4
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x74/0xd0
+  check_irq_usage+0x12e8/0x1d90
+  ? print_shortest_lock_dependencies_backwards+0x1b0/0x1b0
+  ? check_chain_key+0x1bb/0x4c0
+  ? __lockdep_reset_lock+0x180/0x180
+  ? check_path.constprop.0+0x24/0x50
+  ? mark_lock+0x108/0x2fb0
+  ? print_circular_bug+0x9b0/0x9b0
+  ? mark_lock+0x108/0x2fb0
+  ? print_usage_bug.part.0+0x670/0x670
+  ? check_prev_add+0x1c4/0x2310
+  check_prev_add+0x1c4/0x2310
+  __lock_acquire+0x30a0/0x5040
+  ? lockdep_set_lock_cmp_fn+0x190/0x190
+  ? lockdep_set_lock_cmp_fn+0x190/0x190
+  lock_acquire+0x1be/0x520
+  ? mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core]
+  ? lockdep_hardirqs_on_prepare+0x400/0x400
+  ? __xfrm_state_delete+0x5f0/0xae0
+  ? lock_downgrade+0x6b0/0x6b0
+  _raw_spin_lock_bh+0x34/0x40
+  ? mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core]
+  mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core]
+  xfrm_dev_state_delete+0x90/0x160
+  __xfrm_state_delete+0x662/0xae0
+  xfrm_state_delete+0x1e/0x30
+  xfrm_del_sa+0x1c2/0x340
+  ? xfrm_get_sa+0x250/0x250
+  ? check_chain_key+0x1bb/0x4c0
+  xfrm_user_rcv_msg+0x493/0x880
+  ? copy_sec_ctx+0x270/0x270
+  ? check_chain_key+0x1bb/0x4c0
+  ? lockdep_set_lock_cmp_fn+0x190/0x190
+  ? lockdep_set_lock_cmp_fn+0x190/0x190
+  netlink_rcv_skb+0x12e/0x380
+  ? copy_sec_ctx+0x270/0x270
+  ? netlink_ack+0xd90/0xd90
+  ? netlink_deliver_tap+0xcd/0xb60
+  xfrm_netlink_rcv+0x6d/0x90
+  netlink_unicast+0x42f/0x740
+  ? netlink_attachskb+0x730/0x730
+  ? lock_acquire+0x1be/0x520
+  netlink_sendmsg+0x745/0xbe0
+  ? netlink_unicast+0x740/0x740
+  ? __might_fault+0xbb/0x170
+  ? netlink_unicast+0x740/0x740
+  __sock_sendmsg+0xc5/0x190
+  ? fdget+0x163/0x1d0
+  __sys_sendto+0x1fe/0x2c0
+  ? __x64_sys_getpeername+0xb0/0xb0
+  ? do_user_addr_fault+0x856/0xe30
+  ? lock_acquire+0x1be/0x520
+  ? __task_pid_nr_ns+0x117/0x410
+  ? lock_downgrade+0x6b0/0x6b0
+  __x64_sys_sendto+0xdc/0x1b0
+  ? lockdep_hardirqs_on_prepare+0x284/0x400
+  do_syscall_64+0x6d/0x140
+  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+ RIP: 0033:0x7f7d31291ba4
+ Code: 7d e8 89 4d d4 e8 4c 42 f7 ff 44 8b 4d d0 4c 8b 45 c8 89 c3 44 8b 55 d4 8b 7d e8 b8 2c 00 00 00 48 8b 55 d8 48 8b 75 e0 0f 05 <48> 3d 00 f0 ff ff 77 34 89 df 48 89 45 e8 e8 99 42 f7 ff 48 8b 45
+ RSP: 002b:00007f7d2ccd94f0 EFLAGS: 00000297 ORIG_RAX: 000000000000002c
+ RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f7d31291ba4
+ RDX: 0000000000000028 RSI: 00007f7d2ccd96a0 RDI: 000000000000000a
+ RBP: 00007f7d2ccd9530 R08: 00007f7d2ccd9598 R09: 000000000000000c
+ R10: 0000000000000000 R11: 0000000000000297 R12: 0000000000000028
+ R13: 00007f7d2ccd9598 R14: 00007f7d2ccd96a0 R15: 00000000000000e1
+  </TASK>
+
+Fixes: 4c24272b4e2b ("net/mlx5e: Listen to ARP events to update IPsec L2 headers in tunnel mode")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index ca92e518be766..21857474ad83f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -768,9 +768,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+                                  MLX5_IPSEC_RESCHED);
+       if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
+-          x->props.mode == XFRM_MODE_TUNNEL)
+-              xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
+-                          MLX5E_IPSEC_TUNNEL_SA);
++          x->props.mode == XFRM_MODE_TUNNEL) {
++              xa_lock_bh(&ipsec->sadb);
++              __xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
++                            MLX5E_IPSEC_TUNNEL_SA);
++              xa_unlock_bh(&ipsec->sadb);
++      }
+ out:
+       x->xso.offload_handle = (unsigned long)sa_entry;
+@@ -797,7 +800,6 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
+ {
+       struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
+-      struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
+       struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
+       struct mlx5e_ipsec_sa_entry *old;
+@@ -806,12 +808,6 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
+       old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id);
+       WARN_ON(old != sa_entry);
+-
+-      if (attrs->mode == XFRM_MODE_TUNNEL &&
+-          attrs->type == XFRM_DEV_OFFLOAD_PACKET)
+-              /* Make sure that no ARP requests are running in parallel */
+-              flush_workqueue(ipsec->wq);
+-
+ }
+ static void mlx5e_xfrm_free_state(struct xfrm_state *x)
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch b/queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch
new file mode 100644 (file)
index 0000000..869fdbc
--- /dev/null
@@ -0,0 +1,87 @@
+From 69a19552242212aee287e902b20da2a7f5444f34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 13:39:09 +0200
+Subject: net/mlx5e: Rely on reqid in IPsec tunnel mode
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 25f23524dfa227959beb3b2c2c0f38e0222f4cfa ]
+
+All packet offloads SAs have reqid in it to make sure they have
+corresponding policy. While it is not strictly needed for transparent
+mode, it is extremely important in tunnel mode. In that mode, policy and
+SAs have different match criteria.
+
+Policy catches the whole subnet addresses, and SA catches the tunnel gateways
+addresses. The source address of such tunnel is not known during egress packet
+traversal in flow steering as it is added only after successful encryption.
+
+As reqid is required for packet offload and it is unique for every SA,
+we can safely rely on it only.
+
+The output below shows the configured egress policy and SA by strongswan:
+
+[leonro@vm ~]$ sudo ip x s
+src 192.169.101.2 dst 192.169.101.1
+        proto esp spi 0xc88b7652 reqid 1 mode tunnel
+        replay-window 0 flag af-unspec esn
+        aead rfc4106(gcm(aes)) 0xe406a01083986e14d116488549094710e9c57bc6 128
+        anti-replay esn context:
+         seq-hi 0x0, seq 0x0, oseq-hi 0x0, oseq 0x0
+         replay_window 1, bitmap-length 1
+         00000000
+        crypto offload parameters: dev eth2 dir out mode packet
+
+[leonro@064 ~]$ sudo ip x p
+src 192.170.0.0/16 dst 192.170.0.0/16
+        dir out priority 383615 ptype main
+        tmpl src 192.169.101.2 dst 192.169.101.1
+                proto esp spi 0xc88b7652 reqid 1 mode tunnel
+        crypto offload parameters: dev eth2 mode packet
+
+Fixes: b3beba1fb404 ("net/mlx5e: Allow policies with reqid 0, to support IKE policy holes")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c  | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+index e51b03d4c717f..57861d34d46f8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+@@ -1718,23 +1718,21 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
+               goto err_alloc;
+       }
+-      if (attrs->family == AF_INET)
+-              setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
+-      else
+-              setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
+-
+       setup_fte_no_frags(spec);
+       setup_fte_upper_proto_match(spec, &attrs->upspec);
+       switch (attrs->type) {
+       case XFRM_DEV_OFFLOAD_CRYPTO:
++              if (attrs->family == AF_INET)
++                      setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
++              else
++                      setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
+               setup_fte_spi(spec, attrs->spi, false);
+               setup_fte_esp(spec);
+               setup_fte_reg_a(spec);
+               break;
+       case XFRM_DEV_OFFLOAD_PACKET:
+-              if (attrs->reqid)
+-                      setup_fte_reg_c4(spec, attrs->reqid);
++              setup_fte_reg_c4(spec, attrs->reqid);
+               err = setup_pkt_reformat(ipsec, attrs, &flow_act);
+               if (err)
+                       goto err_pkt_reformat;
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch b/queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch
new file mode 100644 (file)
index 0000000..bfcca6f
--- /dev/null
@@ -0,0 +1,51 @@
+From 15142367fbab4567e4d720c9799725e57555ac8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 11:37:06 +0000
+Subject: net: ravb: Fix max TX frame size for RZ/V2M
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paul Barker <paul.barker.ct@bp.renesas.com>
+
+[ Upstream commit e7e441a4100e4bc90b52f80494a28a9667993975 ]
+
+When tx_max_frame_size was added to struct ravb_hw_info, no value was
+set in ravb_rzv2m_hw_info so the default value of zero was used.
+
+The maximum MTU is set by subtracting from tx_max_frame_size to allow
+space for headers and frame checksums. As ndev->max_mtu is unsigned,
+this subtraction wraps around leading to a ridiculously large positive
+value that is obviously incorrect.
+
+Before tx_max_frame_size was introduced, the maximum MTU was based on
+rx_max_frame_size. So, we can restore the correct maximum MTU by copying
+the rx_max_frame_size value into tx_max_frame_size for RZ/V2M.
+
+Fixes: 1d63864299ca ("net: ravb: Fix maximum TX frame size for GbEth devices")
+Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Link: https://patch.msgid.link/20250109113706.1409149-1-paul.barker.ct@bp.renesas.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/ravb_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 907af4651c553..6f6b0566c65bc 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -2756,6 +2756,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
+       .net_features = NETIF_F_RXCSUM,
+       .stats_len = ARRAY_SIZE(ravb_gstrings_stats),
+       .tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
++      .tx_max_frame_size = SZ_2K,
+       .rx_max_frame_size = SZ_2K,
+       .rx_buffer_size = SZ_2K +
+                         SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
+-- 
+2.39.5
+
diff --git a/queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch b/queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch
new file mode 100644 (file)
index 0000000..476285a
--- /dev/null
@@ -0,0 +1,48 @@
+From 342433c5833d7c376bc8a8c6a46405719814dc87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 11:30:00 -0500
+Subject: net: xilinx: axienet: Fix IRQ coalescing packet count overflow
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit c17ff476f53afb30f90bb3c2af77de069c81a622 ]
+
+If coalesce_count is greater than 255 it will not fit in the register and
+will overflow. This can be reproduced by running
+
+    # ethtool -C ethX rx-frames 256
+
+which will result in a timeout of 0us instead. Fix this by checking for
+invalid values and reporting an error.
+
+Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Link: https://patch.msgid.link/20250113163001.2335235-1-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 1fcbcaa85ebdb..de10a2d08c428 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -2056,6 +2056,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
+               return -EBUSY;
+       }
++      if (ecoalesce->rx_max_coalesced_frames > 255 ||
++          ecoalesce->tx_max_coalesced_frames > 255) {
++              NL_SET_ERR_MSG(extack, "frames must be less than 256");
++              return -EINVAL;
++      }
++
+       if (ecoalesce->rx_max_coalesced_frames)
+               lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
+       if (ecoalesce->rx_coalesce_usecs)
+-- 
+2.39.5
+
diff --git a/queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch b/queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch
new file mode 100644 (file)
index 0000000..78d182c
--- /dev/null
@@ -0,0 +1,93 @@
+From 2864b1203fcb0a464ff17450bbea10e524401a93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 08:14:36 -0800
+Subject: netdev: avoid CFI problems with sock priv helpers
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a50da36562cd62b41de9bef08edbb3e8af00f118 ]
+
+Li Li reports that casting away callback type may cause issues
+for CFI. Let's generate a small wrapper for each callback,
+to make sure compiler sees the anticipated types.
+
+Reported-by: Li Li <dualli@chromium.org>
+Link: https://lore.kernel.org/CANBPYPjQVqmzZ4J=rVQX87a9iuwmaetULwbK_5_3YWk2eGzkaA@mail.gmail.com
+Fixes: 170aafe35cb9 ("netdev: support binding dma-buf to netdevice")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Link: https://patch.msgid.link/20250115161436.648646-1-kuba@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netdev-genl-gen.c | 14 ++++++++++++--
+ tools/net/ynl/ynl-gen-c.py | 16 +++++++++++++---
+ 2 files changed, 25 insertions(+), 5 deletions(-)
+
+diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
+index b28424ae06d5f..8614988fc67b9 100644
+--- a/net/core/netdev-genl-gen.c
++++ b/net/core/netdev-genl-gen.c
+@@ -178,6 +178,16 @@ static const struct genl_multicast_group netdev_nl_mcgrps[] = {
+       [NETDEV_NLGRP_PAGE_POOL] = { "page-pool", },
+ };
++static void __netdev_nl_sock_priv_init(void *priv)
++{
++      netdev_nl_sock_priv_init(priv);
++}
++
++static void __netdev_nl_sock_priv_destroy(void *priv)
++{
++      netdev_nl_sock_priv_destroy(priv);
++}
++
+ struct genl_family netdev_nl_family __ro_after_init = {
+       .name           = NETDEV_FAMILY_NAME,
+       .version        = NETDEV_FAMILY_VERSION,
+@@ -189,6 +199,6 @@ struct genl_family netdev_nl_family __ro_after_init = {
+       .mcgrps         = netdev_nl_mcgrps,
+       .n_mcgrps       = ARRAY_SIZE(netdev_nl_mcgrps),
+       .sock_priv_size = sizeof(struct list_head),
+-      .sock_priv_init = (void *)netdev_nl_sock_priv_init,
+-      .sock_priv_destroy = (void *)netdev_nl_sock_priv_destroy,
++      .sock_priv_init = __netdev_nl_sock_priv_init,
++      .sock_priv_destroy = __netdev_nl_sock_priv_destroy,
+ };
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index 717530bc9c52e..463f1394ab971 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -2361,6 +2361,17 @@ def print_kernel_family_struct_src(family, cw):
+     if not kernel_can_gen_family_struct(family):
+         return
++    if 'sock-priv' in family.kernel_family:
++        # Generate "trampolines" to make CFI happy
++        cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_init",
++                      [f"{family.c_name}_nl_sock_priv_init(priv);"],
++                      ["void *priv"])
++        cw.nl()
++        cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_destroy",
++                      [f"{family.c_name}_nl_sock_priv_destroy(priv);"],
++                      ["void *priv"])
++        cw.nl()
++
+     cw.block_start(f"struct genl_family {family.ident_name}_nl_family __ro_after_init =")
+     cw.p('.name\t\t= ' + family.fam_key + ',')
+     cw.p('.version\t= ' + family.ver_key + ',')
+@@ -2378,9 +2389,8 @@ def print_kernel_family_struct_src(family, cw):
+         cw.p(f'.n_mcgrps\t= ARRAY_SIZE({family.c_name}_nl_mcgrps),')
+     if 'sock-priv' in family.kernel_family:
+         cw.p(f'.sock_priv_size\t= sizeof({family.kernel_family["sock-priv"]}),')
+-        # Force cast here, actual helpers take pointer to the real type.
+-        cw.p(f'.sock_priv_init\t= (void *){family.c_name}_nl_sock_priv_init,')
+-        cw.p(f'.sock_priv_destroy = (void *){family.c_name}_nl_sock_priv_destroy,')
++        cw.p(f'.sock_priv_init\t= __{family.c_name}_nl_sock_priv_init,')
++        cw.p(f'.sock_priv_destroy = __{family.c_name}_nl_sock_priv_destroy,')
+     cw.block_end(';')
+-- 
+2.39.5
+
diff --git a/queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch b/queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch
new file mode 100644 (file)
index 0000000..520025d
--- /dev/null
@@ -0,0 +1,39 @@
+From 12894bff3f5ec9792233e44ba2bf2577320da2b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 09:18:39 +0300
+Subject: nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 16ebb6f5b6295c9688749862a39a4889c56227f8 ]
+
+The "sizeof(struct cmsg_bpf_event) + pkt_size + data_size" math could
+potentially have an integer wrapping bug on 32bit systems.  Check for
+this and return an error.
+
+Fixes: 9816dd35ecec ("nfp: bpf: perf event output helpers support")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/6074805b-e78d-4b8a-bf05-e929b5377c28@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/netronome/nfp/bpf/offload.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+index 9d97cd281f18e..c03558adda91e 100644
+--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
++++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+@@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
+       map_id_full = be64_to_cpu(cbe->map_ptr);
+       map_id = map_id_full;
+-      if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
++      if (size_add(pkt_size, data_size) > INT_MAX ||
++          len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
+               return -EINVAL;
+       if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
+               return -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch b/queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch
new file mode 100644 (file)
index 0000000..5a5d678
--- /dev/null
@@ -0,0 +1,79 @@
+From 02e5baf0f944e0762b522142b1e4f146266358e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 13:21:24 +0100
+Subject: openvswitch: fix lockup on tx to unregistering netdev with carrier
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 47e55e4b410f7d552e43011baa5be1aab4093990 ]
+
+Commit in a fixes tag attempted to fix the issue in the following
+sequence of calls:
+
+    do_output
+    -> ovs_vport_send
+       -> dev_queue_xmit
+          -> __dev_queue_xmit
+             -> netdev_core_pick_tx
+                -> skb_tx_hash
+
+When device is unregistering, the 'dev->real_num_tx_queues' goes to
+zero and the 'while (unlikely(hash >= qcount))' loop inside the
+'skb_tx_hash' becomes infinite, locking up the core forever.
+
+But unfortunately, checking just the carrier status is not enough to
+fix the issue, because some devices may still be in unregistering
+state while reporting carrier status OK.
+
+One example of such device is a net/dummy.  It sets carrier ON
+on start, but it doesn't implement .ndo_stop to set the carrier off.
+And it makes sense, because dummy doesn't really have a carrier.
+Therefore, while this device is unregistering, it's still easy to hit
+the infinite loop in the skb_tx_hash() from the OVS datapath.  There
+might be other drivers that do the same, but dummy by itself is
+important for the OVS ecosystem, because it is frequently used as a
+packet sink for tcpdump while debugging OVS deployments.  And when the
+issue is hit, the only way to recover is to reboot.
+
+Fix that by also checking if the device is running.  The running
+state is handled by the net core during unregistering, so it covers
+unregistering case better, and we don't really need to send packets
+to devices that are not running anyway.
+
+While only checking the running state might be enough, the carrier
+check is preserved.  The running and the carrier states seem disjoined
+throughout the code and different drivers.  And other core functions
+like __dev_direct_xmit() check both before attempting to transmit
+a packet.  So, it seems safer to check both flags in OVS as well.
+
+Fixes: 066b86787fa3 ("net: openvswitch: fix race on port output")
+Reported-by: Friedrich Weber <f.weber@proxmox.com>
+Closes: https://mail.openvswitch.org/pipermail/ovs-discuss/2025-January/053423.html
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Tested-by: Friedrich Weber <f.weber@proxmox.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20250109122225.4034688-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/actions.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
+index 16e2600146844..704c858cf2093 100644
+--- a/net/openvswitch/actions.c
++++ b/net/openvswitch/actions.c
+@@ -934,7 +934,9 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
+ {
+       struct vport *vport = ovs_vport_rcu(dp, out_port);
+-      if (likely(vport && netif_carrier_ok(vport->dev))) {
++      if (likely(vport &&
++                 netif_running(vport->dev) &&
++                 netif_carrier_ok(vport->dev))) {
+               u16 mru = OVS_CB(skb)->mru;
+               u32 cutlen = OVS_CB(skb)->cutlen;
+-- 
+2.39.5
+
diff --git a/queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch b/queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch
new file mode 100644 (file)
index 0000000..695642a
--- /dev/null
@@ -0,0 +1,148 @@
+From 6880ad5a6e0826a49b0f5f191c9d7687221d3d5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 10:47:54 +0900
+Subject: pfcp: Destroy device along with udp socket's netns dismantle.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit ffc90e9ca61b0f619326a1417ff32efd6cc71ed2 ]
+
+pfcp_newlink() links the device to a list in dev_net(dev) instead
+of net, where a udp tunnel socket is created.
+
+Even when net is removed, the device stays alive on dev_net(dev).
+Then, removing net triggers the splat below. [0]
+
+In this example, pfcp0 is created in ns2, but the udp socket is
+created in ns1.
+
+  ip netns add ns1
+  ip netns add ns2
+  ip -n ns1 link add netns ns2 name pfcp0 type pfcp
+  ip netns del ns1
+
+Let's link the device to the socket's netns instead.
+
+Now, pfcp_net_exit() needs another netdev iteration to remove
+all pfcp devices in the netns.
+
+pfcp_dev_list is not used under RCU, so the list API is converted
+to the non-RCU variant.
+
+pfcp_net_exit() can be converted to .exit_batch_rtnl() in net-next.
+
+[0]:
+ref_tracker: net notrefcnt@00000000128b34dc has 1/1 users at
+     sk_alloc (./include/net/net_namespace.h:345 net/core/sock.c:2236)
+     inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252)
+     __sock_create (net/socket.c:1558)
+     udp_sock_create4 (net/ipv4/udp_tunnel_core.c:18)
+     pfcp_create_sock (drivers/net/pfcp.c:168)
+     pfcp_newlink (drivers/net/pfcp.c:182 drivers/net/pfcp.c:197)
+     rtnl_newlink (net/core/rtnetlink.c:3786 net/core/rtnetlink.c:3897 net/core/rtnetlink.c:4012)
+     rtnetlink_rcv_msg (net/core/rtnetlink.c:6922)
+     netlink_rcv_skb (net/netlink/af_netlink.c:2542)
+     netlink_unicast (net/netlink/af_netlink.c:1321 net/netlink/af_netlink.c:1347)
+     netlink_sendmsg (net/netlink/af_netlink.c:1891)
+     ____sys_sendmsg (net/socket.c:711 net/socket.c:726 net/socket.c:2583)
+     ___sys_sendmsg (net/socket.c:2639)
+     __sys_sendmsg (net/socket.c:2669)
+     do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
+     entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+WARNING: CPU: 1 PID: 11 at lib/ref_tracker.c:179 ref_tracker_dir_exit (lib/ref_tracker.c:179)
+Modules linked in:
+CPU: 1 UID: 0 PID: 11 Comm: kworker/u16:0 Not tainted 6.13.0-rc5-00147-g4c1224501e9d #5
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+Workqueue: netns cleanup_net
+RIP: 0010:ref_tracker_dir_exit (lib/ref_tracker.c:179)
+Code: 00 00 00 fc ff df 4d 8b 26 49 bd 00 01 00 00 00 00 ad de 4c 39 f5 0f 85 df 00 00 00 48 8b 74 24 08 48 89 df e8 a5 cc 12 02 90 <0f> 0b 90 48 8d 6b 44 be 04 00 00 00 48 89 ef e8 80 de 67 ff 48 89
+RSP: 0018:ff11000007f3fb60 EFLAGS: 00010286
+RAX: 00000000000020ef RBX: ff1100000d6481e0 RCX: 1ffffffff0e40d82
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8423ee3c
+RBP: ff1100000d648230 R08: 0000000000000001 R09: fffffbfff0e395af
+R10: 0000000000000001 R11: 0000000000000000 R12: ff1100000d648230
+R13: dead000000000100 R14: ff1100000d648230 R15: dffffc0000000000
+FS:  0000000000000000(0000) GS:ff1100006ce80000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00005620e1363990 CR3: 000000000eeb2002 CR4: 0000000000771ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? __warn (kernel/panic.c:748)
+ ? ref_tracker_dir_exit (lib/ref_tracker.c:179)
+ ? report_bug (lib/bug.c:201 lib/bug.c:219)
+ ? handle_bug (arch/x86/kernel/traps.c:285)
+ ? exc_invalid_op (arch/x86/kernel/traps.c:309 (discriminator 1))
+ ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621)
+ ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:97 ./arch/x86/include/asm/irqflags.h:155 ./include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194)
+ ? ref_tracker_dir_exit (lib/ref_tracker.c:179)
+ ? __pfx_ref_tracker_dir_exit (lib/ref_tracker.c:158)
+ ? kfree (mm/slub.c:4613 mm/slub.c:4761)
+ net_free (net/core/net_namespace.c:476 net/core/net_namespace.c:467)
+ cleanup_net (net/core/net_namespace.c:664 (discriminator 3))
+ process_one_work (kernel/workqueue.c:3229)
+ worker_thread (kernel/workqueue.c:3304 kernel/workqueue.c:3391)
+ kthread (kernel/kthread.c:389)
+ ret_from_fork (arch/x86/kernel/process.c:147)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:257)
+  </TASK>
+
+Fixes: 76c8764ef36a ("pfcp: add PFCP module")
+Reported-by: Xiao Liang <shaw.leon@gmail.com>
+Closes: https://lore.kernel.org/netdev/20250104125732.17335-1-shaw.leon@gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/pfcp.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c
+index 69434fd13f961..68d0d9e92a220 100644
+--- a/drivers/net/pfcp.c
++++ b/drivers/net/pfcp.c
+@@ -206,8 +206,8 @@ static int pfcp_newlink(struct net *net, struct net_device *dev,
+               goto exit_del_pfcp_sock;
+       }
+-      pn = net_generic(dev_net(dev), pfcp_net_id);
+-      list_add_rcu(&pfcp->list, &pn->pfcp_dev_list);
++      pn = net_generic(net, pfcp_net_id);
++      list_add(&pfcp->list, &pn->pfcp_dev_list);
+       netdev_dbg(dev, "registered new PFCP interface\n");
+@@ -224,7 +224,7 @@ static void pfcp_dellink(struct net_device *dev, struct list_head *head)
+ {
+       struct pfcp_dev *pfcp = netdev_priv(dev);
+-      list_del_rcu(&pfcp->list);
++      list_del(&pfcp->list);
+       unregister_netdevice_queue(dev, head);
+ }
+@@ -247,11 +247,16 @@ static int __net_init pfcp_net_init(struct net *net)
+ static void __net_exit pfcp_net_exit(struct net *net)
+ {
+       struct pfcp_net *pn = net_generic(net, pfcp_net_id);
+-      struct pfcp_dev *pfcp;
++      struct pfcp_dev *pfcp, *pfcp_next;
++      struct net_device *dev;
+       LIST_HEAD(list);
+       rtnl_lock();
+-      list_for_each_entry(pfcp, &pn->pfcp_dev_list, list)
++      for_each_netdev(net, dev)
++              if (dev->rtnl_link_ops == &pfcp_link_ops)
++                      pfcp_dellink(dev, &list);
++
++      list_for_each_entry_safe(pfcp, pfcp_next, &pn->pfcp_dev_list, list)
+               pfcp_dellink(pfcp->dev, &list);
+       unregister_netdevice_many(&list);
+-- 
+2.39.5
+
diff --git a/queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch b/queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch
new file mode 100644 (file)
index 0000000..f122c81
--- /dev/null
@@ -0,0 +1,68 @@
+From d7478c91ea91ff3933bf837b1ad00904ddce04f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 11:30:39 +0300
+Subject: pktgen: Avoid out-of-bounds access in get_imix_entries
+
+From: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+
+[ Upstream commit 76201b5979768500bca362871db66d77cb4c225e ]
+
+Passing a sufficient amount of imix entries leads to invalid access to the
+pkt_dev->imix_entries array because of the incorrect boundary check.
+
+UBSAN: array-index-out-of-bounds in net/core/pktgen.c:874:24
+index 20 is out of range for type 'imix_pkt [20]'
+CPU: 2 PID: 1210 Comm: bash Not tainted 6.10.0-rc1 #121
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
+Call Trace:
+<TASK>
+dump_stack_lvl lib/dump_stack.c:117
+__ubsan_handle_out_of_bounds lib/ubsan.c:429
+get_imix_entries net/core/pktgen.c:874
+pktgen_if_write net/core/pktgen.c:1063
+pde_write fs/proc/inode.c:334
+proc_reg_write fs/proc/inode.c:346
+vfs_write fs/read_write.c:593
+ksys_write fs/read_write.c:644
+do_syscall_64 arch/x86/entry/common.c:83
+entry_SYSCALL_64_after_hwframe arch/x86/entry/entry_64.S:130
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 52a62f8603f9 ("pktgen: Parse internet mix (imix) input")
+Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+[ fp: allow to fill the array completely; minor changelog cleanup ]
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/pktgen.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index 34f68ef74b8f2..b6db4910359bb 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -851,6 +851,9 @@ static ssize_t get_imix_entries(const char __user *buffer,
+               unsigned long weight;
+               unsigned long size;
++              if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES)
++                      return -E2BIG;
++
+               len = num_arg(&buffer[i], max_digits, &size);
+               if (len < 0)
+                       return len;
+@@ -880,9 +883,6 @@ static ssize_t get_imix_entries(const char __user *buffer,
+               i++;
+               pkt_dev->n_imix_entries++;
+-
+-              if (pkt_dev->n_imix_entries > MAX_IMIX_ENTRIES)
+-                      return -E2BIG;
+       } while (c == ' ');
+       return i;
+-- 
+2.39.5
+
index a2f60826d5a6b41f28d6b861d0d3b67958bdebeb..b643f30bfa01493abcaa853290a109992c281086 100644 (file)
@@ -1 +1,36 @@
 efi-zboot-limit-compression-options-to-gzip-and-zstd.patch
+net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch
+bpf-fix-bpf_sk_select_reuseport-memory-leak.patch
+eth-bnxt-always-recalculate-features-after-xdp-clear.patch
+net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch
+openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch
+pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch
+ice-fix-e825-initialization.patch
+ice-fix-quad-registers-read-on-e825.patch
+ice-fix-eth56g-fc-fec-rx-offset-value.patch
+ice-introduce-ice_get_phy_model-wrapper.patch
+ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch
+ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch
+ice-add-correct-phy-lane-assignment.patch
+cpuidle-teo-update-documentation-after-previous-chan.patch
+btrfs-add-the-missing-error-handling-inside-get_cano.patch
+gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch
+gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch
+pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch
+cpufreq-move-endif-to-the-end-of-kconfig-file.patch
+nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch
+net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch
+net-fec-handle-page_pool_dev_alloc_pages-error.patch
+net-make-page_pool_ref_netmem-work-with-net-iovs.patch
+net-mlx5-fix-rdma-tx-steering-prio.patch
+net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch
+net-mlx5-sf-fix-add-port-error-handling.patch
+net-mlx5-clear-port-select-structure-when-fail-to-cr.patch
+net-mlx5e-fix-inversion-dependency-warning-while-ena.patch
+net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch
+net-mlx5e-always-start-ipsec-sequence-number-from-1.patch
+netdev-avoid-cfi-problems-with-sock-priv-helpers.patch
+drm-tests-helpers-fix-compiler-warning.patch
+drm-vmwgfx-unreserve-bo-on-error.patch
+drm-vmwgfx-add-new-keep_resv-bo-param.patch
+drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch