]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Mon, 1 Dec 2025 11:28:41 +0000 (06:28 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 1 Dec 2025 11:28:41 +0000 (06:28 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
184 files changed:
queue-5.10/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-5.10/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-5.10/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-5.10/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-5.10/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-5.10/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-5.15/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-5.15/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-5.15/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-5.15/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-5.15/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-5.15/net-dsa-sja1105-convert-to-mdiobus_c45_read.patch [new file with mode: 0644]
queue-5.15/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch [new file with mode: 0644]
queue-5.15/net-dsa-sja1105-simplify-static-configuration-reload.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-5.15/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-5.15/platform-x86-intel-punit_ipc-fix-memory-corruption.patch [new file with mode: 0644]
queue-5.15/revert-block-don-t-add-or-resize-partition-on-the-di.patch [new file with mode: 0644]
queue-5.15/revert-block-move-checking-genhd_fl_no_part-to-bdev_.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-6.1/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch [new file with mode: 0644]
queue-6.1/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-6.1/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch [new file with mode: 0644]
queue-6.1/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch [new file with mode: 0644]
queue-6.1/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-6.1/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch [new file with mode: 0644]
queue-6.1/mailbox-allow-direct-registration-to-a-channel.patch [new file with mode: 0644]
queue-6.1/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-add-support-for-platform-notification-ha.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-don-t-zero-error-register.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch [new file with mode: 0644]
queue-6.1/mailbox-pcc-use-mbox_bind_client.patch [new file with mode: 0644]
queue-6.1/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-6.1/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-6.1/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch [new file with mode: 0644]
queue-6.1/net-dsa-sja1105-simplify-static-configuration-reload.patch [new file with mode: 0644]
queue-6.1/net-lan966x-fix-the-initialization-of-taprio.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-6.1/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-6.1/platform-x86-intel-punit_ipc-fix-memory-corruption.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-6.12/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch [new file with mode: 0644]
queue-6.12/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch [new file with mode: 0644]
queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-29525 [new file with mode: 0644]
queue-6.12/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch [new file with mode: 0644]
queue-6.12/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-6.12/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch [new file with mode: 0644]
queue-6.12/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch [new file with mode: 0644]
queue-6.12/eth-fbnic-fix-counter-roll-over-issue.patch [new file with mode: 0644]
queue-6.12/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch [new file with mode: 0644]
queue-6.12/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch [new file with mode: 0644]
queue-6.12/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-6.12/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch [new file with mode: 0644]
queue-6.12/mailbox-pcc-don-t-zero-error-register.patch [new file with mode: 0644]
queue-6.12/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch [new file with mode: 0644]
queue-6.12/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-6.12/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-6.12/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch [new file with mode: 0644]
queue-6.12/net-dsa-sja1105-simplify-static-configuration-reload.patch [new file with mode: 0644]
queue-6.12/net-fec-cancel-perout_timer-when-perout-is-disabled.patch [new file with mode: 0644]
queue-6.12/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch [new file with mode: 0644]
queue-6.12/net-fec-do-not-register-pps-event-for-perout.patch [new file with mode: 0644]
queue-6.12/net-fec-do-not-update-perout-if-it-is-enabled.patch [new file with mode: 0644]
queue-6.12/net-lan966x-fix-the-initialization-of-taprio.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-6.12/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch [new file with mode: 0644]
queue-6.12/net-sched-generalize-check-for-no-queue-qdisc-on-tx-.patch [new file with mode: 0644]
queue-6.12/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-6.12/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch [new file with mode: 0644]
queue-6.12/platform-x86-intel-punit_ipc-fix-memory-corruption.patch [new file with mode: 0644]
queue-6.12/series [new file with mode: 0644]
queue-6.12/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch [new file with mode: 0644]
queue-6.12/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-6.12/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch [new file with mode: 0644]
queue-6.12/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch [new file with mode: 0644]
queue-6.12/spi-spi-mem-add-a-new-controller-capability.patch [new file with mode: 0644]
queue-6.12/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch [new file with mode: 0644]
queue-6.12/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch [new file with mode: 0644]
queue-6.12/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch [new file with mode: 0644]
queue-6.12/spi-spi-nxp-fspi-remove-the-goto-in-probe.patch [new file with mode: 0644]
queue-6.12/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch [new file with mode: 0644]
queue-6.12/team-move-team-device-type-change-at-the-end-of-team.patch [new file with mode: 0644]
queue-6.12/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch [new file with mode: 0644]
queue-6.12/veth-apply-qdisc-backpressure-on-full-ptr_ring-to-re.patch [new file with mode: 0644]
queue-6.12/veth-more-robust-handing-of-race-to-avoid-txq-gettin.patch [new file with mode: 0644]
queue-6.12/veth-prevent-null-pointer-dereference-in-veth_xdp_rc.patch [new file with mode: 0644]
queue-6.12/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch [new file with mode: 0644]
queue-6.17/afs-fix-delayed-allocation-of-a-cell-s-anonymous-key.patch [new file with mode: 0644]
queue-6.17/afs-fix-uninit-var-in-afs_alloc_anon_key.patch [new file with mode: 0644]
queue-6.17/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch [new file with mode: 0644]
queue-6.17/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch [new file with mode: 0644]
queue-6.17/bluetooth-hci_core-lookup-hci_conn-on-rx-path-on-pro.patch [new file with mode: 0644]
queue-6.17/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch [new file with mode: 0644]
queue-6.17/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch [new file with mode: 0644]
queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-24056 [new file with mode: 0644]
queue-6.17/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch [new file with mode: 0644]
queue-6.17/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-6.17/dma-direct-fix-missing-sg_dma_len-assignment-in-p2pd.patch [new file with mode: 0644]
queue-6.17/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch [new file with mode: 0644]
queue-6.17/drm-bridge-sii902x-fix-hdmi-detection-with-drm_bridg.patch [new file with mode: 0644]
queue-6.17/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch [new file with mode: 0644]
queue-6.17/eth-fbnic-fix-counter-roll-over-issue.patch [new file with mode: 0644]
queue-6.17/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch [new file with mode: 0644]
queue-6.17/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch [new file with mode: 0644]
queue-6.17/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-6.17/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch [new file with mode: 0644]
queue-6.17/mailbox-pcc-don-t-zero-error-register.patch [new file with mode: 0644]
queue-6.17/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-6.17/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-6.17/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch [new file with mode: 0644]
queue-6.17/net-fec-cancel-perout_timer-when-perout-is-disabled.patch [new file with mode: 0644]
queue-6.17/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch [new file with mode: 0644]
queue-6.17/net-fec-do-not-register-pps-event-for-perout.patch [new file with mode: 0644]
queue-6.17/net-fec-do-not-update-perout-if-it-is-enabled.patch [new file with mode: 0644]
queue-6.17/net-lan966x-fix-the-initialization-of-taprio.patch [new file with mode: 0644]
queue-6.17/net-mctp-unconditionally-set-skb-dev-on-dst-output.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-6.17/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch [new file with mode: 0644]
queue-6.17/net-phy-mxl-gpy-fix-link-properties-on-usxgmii-and-i.patch [new file with mode: 0644]
queue-6.17/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-6.17/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch [new file with mode: 0644]
queue-6.17/ovl-fail-ovl_lock_rename_workdir-if-either-target-is.patch [new file with mode: 0644]
queue-6.17/platform-x86-intel-punit_ipc-fix-memory-corruption.patch [new file with mode: 0644]
queue-6.17/riscv-dts-allwinner-d1-fix-vlenb-property.patch [new file with mode: 0644]
queue-6.17/series [new file with mode: 0644]
queue-6.17/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch [new file with mode: 0644]
queue-6.17/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-6.17/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch [new file with mode: 0644]
queue-6.17/spi-spi-cadence-quadspi-enable-pm-runtime-earlier-to.patch [new file with mode: 0644]
queue-6.17/spi-spi-cadence-quadspi-remove-duplicate-pm_runtime_.patch [new file with mode: 0644]
queue-6.17/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch [new file with mode: 0644]
queue-6.17/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch [new file with mode: 0644]
queue-6.17/team-move-team-device-type-change-at-the-end-of-team.patch [new file with mode: 0644]
queue-6.17/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch [new file with mode: 0644]
queue-6.17/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch [new file with mode: 0644]
queue-6.17/xhci-sideband-add-api-to-trace-sideband-usage.patch [new file with mode: 0644]
queue-6.17/xhci-sideband-fix-race-condition-in-sideband-unregis.patch [new file with mode: 0644]
queue-6.17/xsk-avoid-data-corruption-on-cq-descriptor-number.patch [new file with mode: 0644]
queue-6.17/xsk-avoid-overwriting-skb-fields-for-multi-buffer-tr.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch [new file with mode: 0644]
queue-6.6/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch [new file with mode: 0644]
queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch [new file with mode: 0644]
queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-2290 [new file with mode: 0644]
queue-6.6/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch [new file with mode: 0644]
queue-6.6/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch [new file with mode: 0644]
queue-6.6/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch [new file with mode: 0644]
queue-6.6/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch [new file with mode: 0644]
queue-6.6/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch [new file with mode: 0644]
queue-6.6/mailbox-pcc-don-t-zero-error-register.patch [new file with mode: 0644]
queue-6.6/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch [new file with mode: 0644]
queue-6.6/net-aquantia-add-missing-descriptor-cache-invalidati.patch [new file with mode: 0644]
queue-6.6/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch [new file with mode: 0644]
queue-6.6/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch [new file with mode: 0644]
queue-6.6/net-dsa-sja1105-simplify-static-configuration-reload.patch [new file with mode: 0644]
queue-6.6/net-fec-cancel-perout_timer-when-perout-is-disabled.patch [new file with mode: 0644]
queue-6.6/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch [new file with mode: 0644]
queue-6.6/net-fec-do-not-register-pps-event-for-perout.patch [new file with mode: 0644]
queue-6.6/net-fec-do-not-update-perout-if-it-is-enabled.patch [new file with mode: 0644]
queue-6.6/net-lan966x-fix-the-initialization-of-taprio.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-fix-validation-logic-in-rate-limiting.patch [new file with mode: 0644]
queue-6.6/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch [new file with mode: 0644]
queue-6.6/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch [new file with mode: 0644]
queue-6.6/platform-x86-intel-punit_ipc-fix-memory-corruption.patch [new file with mode: 0644]
queue-6.6/series [new file with mode: 0644]
queue-6.6/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch [new file with mode: 0644]
queue-6.6/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch [new file with mode: 0644]
queue-6.6/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch [new file with mode: 0644]
queue-6.6/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch [new file with mode: 0644]
queue-6.6/spi-spi-mem-add-a-new-controller-capability.patch [new file with mode: 0644]
queue-6.6/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch [new file with mode: 0644]
queue-6.6/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch [new file with mode: 0644]
queue-6.6/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch [new file with mode: 0644]
queue-6.6/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch [new file with mode: 0644]

diff --git a/queue-5.10/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-5.10/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..e495bbd
--- /dev/null
@@ -0,0 +1,87 @@
+From 640db2238d6ef51f4fa56c77430fef02b116dad3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index fc896d39a6d95..79550d115364e 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2131,7 +2131,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2183,24 +2183,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2221,11 +2203,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-5.10/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-5.10/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..8b224ec
--- /dev/null
@@ -0,0 +1,62 @@
+From ac75463fa7dccb4dbb575156e1dc1dd0f512c25e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index f06d63db9077b..df0460e3633c5 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -609,7 +609,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1571,7 +1571,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-5.10/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-5.10/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..6bffb4c
--- /dev/null
@@ -0,0 +1,38 @@
+From 80951cd3e40c00d65475fb735cdcfa1095d92a90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index abcee58e851c2..29c04157b5e88 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -267,7 +267,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-5.10/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..9c6480b
--- /dev/null
@@ -0,0 +1,144 @@
+From e531ecd8d1df22162e87c2a783bee8e613cc400e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 45c17c585d743..2236bc9ba54d2 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index c76ccdc77ba60..98d4ba879dd08 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-5.10/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..e70e487
--- /dev/null
@@ -0,0 +1,93 @@
+From 0ae576feb2cca8e7e9fc7ffaa349e20490d52893 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index 98e8997f80366..5a85999987b51 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -363,6 +363,11 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-5.10/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..c28f4b2
--- /dev/null
@@ -0,0 +1,63 @@
+From ec944ba8223659be12f78a3d2861954451f454a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 5c48a4872f35d..5d0be9703a48e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -606,7 +606,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-5.10/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..2e663dc
--- /dev/null
@@ -0,0 +1,47 @@
+From 12dcd3112fd40c76a265e5307b26a7a1babe1675 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index b1dd6189638b3..9c745d48f54b0 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1518,8 +1518,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
index 4a4b5a7211945d4d96372541b9f4a4122c4e2119..b408256b186a8c00a87e83e808668e999f13125e 100644 (file)
@@ -255,3 +255,11 @@ mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch
 usb-deprecate-the-third-argument-of-usb_maxpacket.patch
 input-remove-third-argument-of-usb_maxpacket.patch
 input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
diff --git a/queue-5.10/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-5.10/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..57c40f6
--- /dev/null
@@ -0,0 +1,68 @@
+From 470b7cb63012aa36a0e070ff4db165f6e2b9de26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index da559b86f6b17..e05f8913ccda9 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -257,6 +257,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-5.15/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..ab4716e
--- /dev/null
@@ -0,0 +1,87 @@
+From 63f0138108df7382a3ebadf08c81700b8a868d98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index 697ec98b07982..d1ba41153b66a 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2130,7 +2130,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2182,24 +2182,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2220,11 +2202,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-5.15/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-5.15/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..ea2d4dc
--- /dev/null
@@ -0,0 +1,62 @@
+From 371a6daac73aa67adcd2cdce99eed93faec04488 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 43ec056646661..b6cef22a53e77 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -610,7 +610,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1568,7 +1568,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-5.15/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-5.15/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..5a44e3d
--- /dev/null
@@ -0,0 +1,38 @@
+From b64719d251d172e1e13abebb78a0ede52319225b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index abcee58e851c2..29c04157b5e88 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -267,7 +267,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-5.15/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..a809487
--- /dev/null
@@ -0,0 +1,144 @@
+From cf1a2253aee7b16583890e24cd7cc914af719ba4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 15ede7285fb5d..b50c9b6dfb5bf 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index 5dfc751572edc..bc4e1b6035e08 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-5.15/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..9e537f7
--- /dev/null
@@ -0,0 +1,93 @@
+From 57ab00a7fad6120b0fea857846123f0e2e0fb55f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index 98e8997f80366..5a85999987b51 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -363,6 +363,11 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-dsa-sja1105-convert-to-mdiobus_c45_read.patch b/queue-5.15/net-dsa-sja1105-convert-to-mdiobus_c45_read.patch
new file mode 100644 (file)
index 0000000..e42d5cb
--- /dev/null
@@ -0,0 +1,47 @@
+From 51f827d77bb1d58680b1616cad4c38c138736e7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 19:30:36 +0200
+Subject: net: dsa: sja1105: Convert to mdiobus_c45_read
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+[ Upstream commit 639e4b93ab68f5f5fc4734c766124ca96c167f14 ]
+
+Stop using the helpers to construct a special phy address which
+indicates C45. Instead use the C45 accessors, which will call the
+busses C45 specific read/write API.
+
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index ec1c0ad591184..5c37478a7e822 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -2180,14 +2180,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+        * change it through the dynamic interface later.
+        */
+       for (i = 0; i < ds->num_ports; i++) {
+-              u32 reg_addr = mdiobus_c45_addr(MDIO_MMD_VEND2, MDIO_CTRL1);
+-
+               speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
+                                                             mac[i].speed);
+               mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];
+               if (priv->xpcs[i])
+-                      bmcr[i] = mdiobus_read(priv->mdio_pcs, i, reg_addr);
++                      bmcr[i] = mdiobus_c45_read(priv->mdio_pcs, i,
++                                                 MDIO_MMD_VEND2, MDIO_CTRL1);
+       }
+       /* No PTP operations can run right now */
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch b/queue-5.15/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
new file mode 100644 (file)
index 0000000..f8af960
--- /dev/null
@@ -0,0 +1,73 @@
+From 2d0825ffb6c49ecde155caa9259ec64eda3eeb3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 13:13:24 +0200
+Subject: net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing
+ traffic
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
+
+When using the SGMII PCS as a fixed-link chip-to-chip connection, it is
+easy to miss the fact that traffic passes only at 1G, since that's what
+any normal such connection would use.
+
+When using the SGMII PCS connected towards an on-board PHY or an SFP
+module, it is immediately noticeable that when the link resolves to a
+speed other than 1G, traffic from the MAC fails to pass: TX counters
+increase, but nothing gets decoded by the other end, and no local RX
+counters increase either.
+
+Artificially lowering a fixed-link rate to speed = <100> makes us able
+to see the same issue as in the case of having an SGMII PHY.
+
+Some debugging shows that the XPCS configuration is A-OK, but that the
+MAC Configuration Table entry for the port has the SPEED bits still set
+to 1000Mbps, due to a special condition in the driver. Deleting that
+condition, and letting the resolved link speed be programmed directly
+into the MAC speed field, results in a functional link at all 3 speeds.
+
+This piece of evidence, based on testing on both generations with SGMII
+support (SJA1105S and SJA1110A) directly contradicts the statement from
+the blamed commit that "the MAC is fixed at 1 Gbps and we need to
+configure the PCS only (if even that)". Worse, that statement is not
+backed by any documentation, and no one from NXP knows what it might
+refer to.
+
+I am unable to recall sufficient context regarding my testing from March
+2020 to understand what led me to draw such a braindead and factually
+incorrect conclusion. Yet, there is nothing of value regarding forcing
+the MAC speed, either for SGMII or 2500Base-X (introduced at a later
+stage), so remove all such logic.
+
+Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index 5773d5e72b06f..3a5674e90d77d 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1238,14 +1238,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
+        * table, since this will be used for the clocking setup, and we no
+        * longer need to store it in the static config (already told hardware
+        * we want auto during upload phase).
+-       * Actually for the SGMII port, the MAC is fixed at 1 Gbps and
+-       * we need to configure the PCS only (if even that).
+        */
+-      if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+-      else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-
+       mac[port].speed = speed;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-dsa-sja1105-simplify-static-configuration-reload.patch b/queue-5.15/net-dsa-sja1105-simplify-static-configuration-reload.patch
new file mode 100644 (file)
index 0000000..5d4bbd7
--- /dev/null
@@ -0,0 +1,159 @@
+From 4a3d64177f9face7d14909b614ca74e5bb2e86b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 17:04:36 +0100
+Subject: net: dsa: sja1105: simplify static configuration reload
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit a18891b55703a45b700618ef40edd5e9aaecc345 ]
+
+The static configuration reload saves the port speed in the static
+configuration tables by first converting it from the internal
+respresentation to the SPEED_xxx ethtool representation, and then
+converts it back to restore the setting. This is because
+sja1105_adjust_port_config() takes the speed as SPEED_xxx.
+
+However, this is unnecessarily complex. If we split
+sja1105_adjust_port_config() up, we can simply save and restore the
+mac[port].speed member in the static configuration tables.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------
+ 1 file changed, 34 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index 5c37478a7e822..5773d5e72b06f 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1192,29 +1192,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)
+       return rc;
+ }
+-/* Convert link speed from SJA1105 to ethtool encoding */
+-static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv,
+-                                       u64 speed)
+-{
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS])
+-              return SPEED_10;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS])
+-              return SPEED_100;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS])
+-              return SPEED_1000;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS])
+-              return SPEED_2500;
+-      return SPEED_UNKNOWN;
+-}
+-
+-/* Set link speed in the MAC configuration for a specific port. */
+-static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+-                                    int speed_mbps)
++static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
++                                int speed_mbps)
+ {
+       struct sja1105_mac_config_entry *mac;
+-      struct device *dev = priv->ds->dev;
+       u64 speed;
+-      int rc;
+       /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
+        * tables. On E/T, MAC reconfig tables are not readable, only writable.
+@@ -1248,7 +1230,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+               speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+               break;
+       default:
+-              dev_err(dev, "Invalid speed %iMbps\n", speed_mbps);
++              dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps);
+               return -EINVAL;
+       }
+@@ -1260,11 +1242,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+        * we need to configure the PCS only (if even that).
+        */
+       if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
++              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+       else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-      else
+-              mac[port].speed = speed;
++              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
++
++      mac[port].speed = speed;
++
++      return 0;
++}
++
++/* Write the MAC Configuration Table entry and, if necessary, the CGU settings,
++ * after a link speedchange for this port.
++ */
++static int sja1105_set_port_config(struct sja1105_private *priv, int port)
++{
++      struct sja1105_mac_config_entry *mac;
++      struct device *dev = priv->ds->dev;
++      int rc;
++
++      /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
++       * tables. On E/T, MAC reconfig tables are not readable, only writable.
++       * We have to *know* what the MAC looks like.  For the sake of keeping
++       * the code common, we'll use the static configuration tables as a
++       * reasonable approximation for both E/T and P/Q/R/S.
++       */
++      mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+       /* Write to the dynamic reconfiguration tables */
+       rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+@@ -1335,7 +1337,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
+ {
+       struct sja1105_private *priv = ds->priv;
+-      sja1105_adjust_port_config(priv, port, speed);
++      if (!sja1105_set_port_speed(priv, port, speed))
++              sja1105_set_port_config(priv, port);
+       sja1105_inhibit_tx(priv, BIT(port), false);
+ }
+@@ -2161,8 +2164,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+ {
+       struct ptp_system_timestamp ptp_sts_before;
+       struct ptp_system_timestamp ptp_sts_after;
+-      int speed_mbps[SJA1105_MAX_NUM_PORTS];
+       u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0};
++      u64 mac_speed[SJA1105_MAX_NUM_PORTS];
+       struct sja1105_mac_config_entry *mac;
+       struct dsa_switch *ds = priv->ds;
+       s64 t1, t2, t3, t4;
+@@ -2174,14 +2177,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+       mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+-      /* Back up the dynamic link speed changed by sja1105_adjust_port_config
++      /* Back up the dynamic link speed changed by sja1105_set_port_speed()
+        * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the
+        * switch wants to see in the static config in order to allow us to
+        * change it through the dynamic interface later.
+        */
+       for (i = 0; i < ds->num_ports; i++) {
+-              speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
+-                                                            mac[i].speed);
++              mac_speed[i] = mac[i].speed;
+               mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];
+               if (priv->xpcs[i])
+@@ -2244,7 +2246,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+               struct dw_xpcs *xpcs = priv->xpcs[i];
+               unsigned int mode;
+-              rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
++              mac[i].speed = mac_speed[i];
++              rc = sja1105_set_port_config(priv, i);
+               if (rc < 0)
+                       goto out;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-5.15/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..d38dbc9
--- /dev/null
@@ -0,0 +1,63 @@
+From 924fce4678eaebf7bcbfeabf4f97636fc469c97c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 86545554abb4e..dae944d28ee26 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -606,7 +606,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-5.15/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..4633759
--- /dev/null
@@ -0,0 +1,47 @@
+From 8f6b17346c6077f9522020218876ea62efde5fc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index 1b415fe6f9b9f..1fe687b594f9d 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1518,8 +1518,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
diff --git a/queue-5.15/platform-x86-intel-punit_ipc-fix-memory-corruption.patch b/queue-5.15/platform-x86-intel-punit_ipc-fix-memory-corruption.patch
new file mode 100644 (file)
index 0000000..6808bd6
--- /dev/null
@@ -0,0 +1,46 @@
+From e6827d0db89e9fa282c89ea13ca42dac005f72c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 20:51:28 +0300
+Subject: platform/x86: intel: punit_ipc: fix memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
+
+This passes the address of the pointer "&punit_ipcdev" when the intent
+was to pass the pointer itself "punit_ipcdev" (without the ampersand).
+This means that the:
+
+       complete(&ipcdev->cmd_complete);
+
+in intel_punit_ioc() will write to a wrong memory address corrupting it.
+
+Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/punit_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
+index 66bb39fd0ef90..8602f4175f123 100644
+--- a/drivers/platform/x86/intel/punit_ipc.c
++++ b/drivers/platform/x86/intel/punit_ipc.c
+@@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
+       } else {
+               ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+                                      IRQF_NO_SUSPEND, "intel_punit_ipc",
+-                                     &punit_ipcdev);
++                                     punit_ipcdev);
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-5.15/revert-block-don-t-add-or-resize-partition-on-the-di.patch b/queue-5.15/revert-block-don-t-add-or-resize-partition-on-the-di.patch
new file mode 100644 (file)
index 0000000..542d8a9
--- /dev/null
@@ -0,0 +1,73 @@
+From cf477fe84e1ca4677cb1b3c358f48e95facc12da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 17:54:15 +0000
+Subject: Revert "block: don't add or resize partition on the disk with
+ GENHD_FL_NO_PART"
+
+From: Gulam Mohamed <gulam.mohamed@oracle.com>
+
+This reverts commit 1a721de8489fa559ff4471f73c58bb74ac5580d3.
+
+The commit 1a721de8489f ("block: don't add or resize partition on the disk
+with GENHD_FL_NO_PART") and the commit 7777f47f2ea6 ("block: Move checking
+GENHD_FL_NO_PART to bdev_add_partition()") used the flag GENHD_FL_NO_PART
+to prevent the add or resize of partitions in 5.15 stable kernels.But in
+these 5.15 kernels, this is giving an issue with the following error
+where the loop driver wants to create a partition when the partscan is
+disabled on the loop device:
+
+dd if=/dev/zero of=loopDisk.dsk bs=1M count=1 seek=10240;
+losetup -f loopDisk.dsk;parted -s /dev/loop0 -- mklabel gpt mkpart primary
+           2048s 4096s
+1+0 records in
+1+0 records out
+1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0016293 s, 644 MB/s
+""
+Error: Partition(s) 1 on /dev/loop0 have been written, but we have been
+unable to inform the kernel of the change, probably because it/they are
+in use.  As a result, the old partition(s) will remain in use.  You should
+reboot now before making further changes.
+""
+If the partition scan is not enabled on the loop device, this flag
+GENHD_FL_NO_PART is getting set and when partition creation is tried,
+it returns an error EINVAL thereby preventing the creation of partitions.
+So, there is no such distinction between disabling of partition scan and
+partition creation.
+
+Later in 6.xxx kernels, the commit b9684a71fca7 ("block, loop: support
+partitions without scanning") a new flag GD_SUPPRESS_PART_SCAN was
+introduced that just disables the partition scan and uses GENHD_FL_NO_PART
+only to prevent creating partition scan. So, the partition creationg can
+proceed with even if partition scan is disabled.
+
+As the commit b9684a71fca7 ("block, loop: support partitions without
+scanning") is not available in 5.15 stable kernel, and since there is no
+distinction between disabling of "partition scan" and "partition
+creation", we need to revert the commits 1a721de8489f and 7777f47f2ea6
+from 5.15 stable kernel to allow partition creation when partscan is
+disabled.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Gulam Mohamed <gulam.mohamed@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/ioctl.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/block/ioctl.c b/block/ioctl.c
+index d25b844412378..a260e39e56a48 100644
+--- a/block/ioctl.c
++++ b/block/ioctl.c
+@@ -20,8 +20,6 @@ static int blkpg_do_ioctl(struct block_device *bdev,
+       struct blkpg_partition p;
+       sector_t start, length;
+-      if (disk->flags & GENHD_FL_NO_PART)
+-              return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
+-- 
+2.51.0
+
diff --git a/queue-5.15/revert-block-move-checking-genhd_fl_no_part-to-bdev_.patch b/queue-5.15/revert-block-move-checking-genhd_fl_no_part-to-bdev_.patch
new file mode 100644 (file)
index 0000000..32079cb
--- /dev/null
@@ -0,0 +1,73 @@
+From f8e2b74a8c26db44964e8cb800305f135fc53f2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 17:54:14 +0000
+Subject: Revert "block: Move checking GENHD_FL_NO_PART to
+ bdev_add_partition()"
+
+From: Gulam Mohamed <gulam.mohamed@oracle.com>
+
+This reverts commit 7777f47f2ea64efd1016262e7b59fab34adfb869.
+
+The commit 1a721de8489f ("block: don't add or resize partition on the disk
+with GENHD_FL_NO_PART") and the commit 7777f47f2ea6 ("block: Move checking
+GENHD_FL_NO_PART to bdev_add_partition()") used the flag GENHD_FL_NO_PART
+to prevent the add or resize of partitions in 5.15 stable kernels.But in
+these 5.15 kernels, this is giving an issue with the following error
+where the loop driver wants to create a partition when the partscan is
+disabled on the loop device:
+
+dd if=/dev/zero of=loopDisk.dsk bs=1M count=1 seek=10240;
+losetup -f loopDisk.dsk;parted -s /dev/loop0 -- mklabel gpt mkpart primary
+           2048s 4096s
+1+0 records in
+1+0 records out
+1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0016293 s, 644 MB/s
+""
+Error: Partition(s) 1 on /dev/loop0 have been written, but we have been
+unable to inform the kernel of the change, probably because it/they are
+in use.  As a result, the old partition(s) will remain in use.  You should
+reboot now before making further changes.
+""
+If the partition scan is not enabled on the loop device, this flag
+GENHD_FL_NO_PART is getting set and when partition creation is tried,
+it returns an error EINVAL thereby preventing the creation of partitions.
+So, there is no such distinction between disabling of partition scan and
+partition creation.
+
+Later in 6.xxx kernels, the commit b9684a71fca7 ("block, loop: support
+partitions without scanning") a new flag GD_SUPPRESS_PART_SCAN was
+introduced that just disables the partition scan and uses GENHD_FL_NO_PART
+only to prevent creating partition scan. So, the partition creationg can
+proceed with even if partition scan is disabled.
+
+As the commit b9684a71fca7 ("block, loop: support partitions without
+scanning") is not available in 5.15 stable kernel, and since there is no
+distinction between disabling of "partition scan" and "partition
+creation", we need to revert the commits 1a721de8489f and 7777f47f2ea6
+from 5.15 stable kernel to allow partition creation when partscan is
+disabled.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Gulam Mohamed <gulam.mohamed@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/ioctl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/block/ioctl.c b/block/ioctl.c
+index a260e39e56a48..d25b844412378 100644
+--- a/block/ioctl.c
++++ b/block/ioctl.c
+@@ -20,6 +20,8 @@ static int blkpg_do_ioctl(struct block_device *bdev,
+       struct blkpg_partition p;
+       sector_t start, length;
++      if (disk->flags & GENHD_FL_NO_PART)
++              return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
+-- 
+2.51.0
+
index 6a6cd0cad83e063ede580ffac7949ae1e7052b66..5020d3b5375e96e05530a444f409d102cae2e025 100644 (file)
@@ -335,3 +335,17 @@ mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch
 mptcp-do-not-fallback-when-ooo-is-present.patch
 revert-block-move-checking-genhd_fl_no_part-to-bdev_add_partition.patch
 revert-block-don-t-add-or-resize-partition-on-the-disk-with-genhd_fl_no_part.patch
+revert-block-move-checking-genhd_fl_no_part-to-bdev_.patch
+revert-block-don-t-add-or-resize-partition-on-the-di.patch
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+platform-x86-intel-punit_ipc-fix-memory-corruption.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+net-dsa-sja1105-convert-to-mdiobus_c45_read.patch
+net-dsa-sja1105-simplify-static-configuration-reload.patch
+net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
diff --git a/queue-5.15/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-5.15/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..d785106
--- /dev/null
@@ -0,0 +1,68 @@
+From 25cca6d7953458218129d11947a40d5f1ddf3e41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index 2f2a130464651..e57e1f75cd9f9 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -257,6 +257,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.1/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch b/queue-6.1/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch
new file mode 100644 (file)
index 0000000..4b83edd
--- /dev/null
@@ -0,0 +1,53 @@
+From c10092f3509fec38d5df8844584d544eea4a4c0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 17:26:10 +0100
+Subject: ACPI: PCC: Add PCC shared memory region command and status bitfields
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 55d235ebb684b993b3247740c1c8e273f8af4a54 ]
+
+Define the common macros to use when referring to various bitfields in
+the PCC generic communications channel command and status fields.
+
+Currently different drivers that need to use these bitfields have defined
+these locally. This common macro is intended to consolidate and replace
+those.
+
+Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20230927-pcc_defines-v2-1-0b8ffeaef2e5@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/acpi/pcc.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
+index 73e806fe7ce70..9b373d172a776 100644
+--- a/include/acpi/pcc.h
++++ b/include/acpi/pcc.h
+@@ -18,7 +18,20 @@ struct pcc_mbox_chan {
+       u16 min_turnaround_time;
+ };
++/* Generic Communications Channel Shared Memory Region */
++#define PCC_SIGNATURE                 0x50434300
++/* Generic Communications Channel Command Field */
++#define PCC_CMD_GENERATE_DB_INTR      BIT(15)
++/* Generic Communications Channel Status Field */
++#define PCC_STATUS_CMD_COMPLETE               BIT(0)
++#define PCC_STATUS_SCI_DOORBELL               BIT(1)
++#define PCC_STATUS_ERROR              BIT(2)
++#define PCC_STATUS_PLATFORM_NOTIFY    BIT(3)
++/* Initiator Responder Communications Channel Flags */
++#define PCC_CMD_COMPLETION_NOTIFY     BIT(0)
++
+ #define MAX_PCC_SUBSPACES     256
++
+ #ifdef CONFIG_PCC
+ extern struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-6.1/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..7728e66
--- /dev/null
@@ -0,0 +1,87 @@
+From 8661da0cb140918eedf8e7eda8f64812c98f2f76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index a03920fe44d94..d8a77bfe65a62 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2130,7 +2130,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2182,24 +2182,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2220,11 +2202,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-6.1/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch b/queue-6.1/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
new file mode 100644 (file)
index 0000000..ef08ed7
--- /dev/null
@@ -0,0 +1,92 @@
+From 53c30c3182bee84ab1ececd153dbed7aaf1647e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:02 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing header
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf ]
+
+The driver expects to receive a struct gs_host_frame in
+gs_usb_receive_bulk_callback().
+
+Use struct_group to describe the header of the struct gs_host_frame and
+check that we have at least received the header before accessing any
+members of it.
+
+To resubmit the URB, do not dereference the pointer chain
+"dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since
+"urb->context" contains "parent", it is always defined, while "dev" is not
+defined if the URB it too short.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-2-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 7fe9d497491d1..5d0cee57ab970 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -252,13 +252,15 @@ struct canfd_quirk {
+ } __packed;
+ struct gs_host_frame {
+-      u32 echo_id;
+-      __le32 can_id;
++      struct_group(header,
++              u32 echo_id;
++              __le32 can_id;
+-      u8 can_dlc;
+-      u8 channel;
+-      u8 flags;
+-      u8 reserved;
++              u8 can_dlc;
++              u8 channel;
++              u8 flags;
++              u8 reserved;
++      );
+       union {
+               DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
+@@ -528,6 +530,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
++      unsigned int minimum_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -546,6 +549,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+               return;
+       }
++      minimum_length = sizeof(hf->header);
++      if (urb->actual_length < minimum_length) {
++              dev_err_ratelimited(&parent->udev->dev,
++                                  "short read (actual_length=%u, minimum_length=%u)\n",
++                                  urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
+       /* device reports out of range channel id */
+       if (hf->channel >= parent->channel_cnt)
+               goto device_detach;
+@@ -642,7 +654,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ resubmit_urb:
+       usb_fill_bulk_urb(urb, parent->udev,
+                         parent->pipe_in,
+-                        hf, dev->parent->hf_size_rx,
++                        hf, parent->hf_size_rx,
+                         gs_usb_receive_bulk_callback, parent);
+       rc = usb_submit_urb(urb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.1/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch b/queue-6.1/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
new file mode 100644 (file)
index 0000000..44a60d2
--- /dev/null
@@ -0,0 +1,60 @@
+From 0b84d409e3c3bb7e862287010890a4878cfbfd0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:01 +0100
+Subject: can: gs_usb: gs_usb_xmit_callback(): fix handling of failed
+ transmitted URBs
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 ]
+
+The driver lacks the cleanup of failed transfers of URBs. This reduces the
+number of available URBs per error by 1. This leads to reduced performance
+and ultimately to a complete stop of the transmission.
+
+If the sending of a bulk URB fails do proper cleanup:
+- increase netdev stats
+- mark the echo_sbk as free
+- free the driver's context and do accounting
+- wake the send queue
+
+Closes: https://github.com/candle-usb/candleLight_fw/issues/187
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-1-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 2cacea6b00f80..7fe9d497491d1 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -707,8 +707,21 @@ static void gs_usb_xmit_callback(struct urb *urb)
+       struct gs_can *dev = txc->dev;
+       struct net_device *netdev = dev->netdev;
+-      if (urb->status)
+-              netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
++      if (!urb->status)
++              return;
++
++      if (urb->status != -ESHUTDOWN && net_ratelimit())
++              netdev_info(netdev, "failed to xmit URB %u: %pe\n",
++                          txc->echo_id, ERR_PTR(urb->status));
++
++      netdev->stats.tx_dropped++;
++      netdev->stats.tx_errors++;
++
++      can_free_echo_skb(netdev, txc->echo_id, NULL);
++      gs_free_tx_context(txc);
++      atomic_dec(&dev->active_tx_urbs);
++
++      netif_wake_queue(netdev);
+ }
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+-- 
+2.51.0
+
diff --git a/queue-6.1/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-6.1/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..7e2bab6
--- /dev/null
@@ -0,0 +1,62 @@
+From 8f6a5d0f33bdabbd2436a714c22aaa38c14e6b09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index b423fd4c79890..57c68bc926d8d 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -608,7 +608,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1567,7 +1567,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-6.1/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch b/queue-6.1/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
new file mode 100644 (file)
index 0000000..6e99369
--- /dev/null
@@ -0,0 +1,39 @@
+From cd8ba40e3698b9edbd6fe5d11f9d231b8ee58ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 09:40:31 -0500
+Subject: drm/amdgpu: fix cyan_skillfish2 gpu info fw handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 ]
+
+If the board supports IP discovery, we don't need to
+parse the gpu info firmware.
+
+Backport to 6.18.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4721
+Fixes: fa819e3a7c1e ("drm/amdgpu: add support for cyan skillfish gpu_info")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5427e32fa3a0ba9a016db83877851ed277b065fb)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index f18f165876043..38b81ae236cb3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2021,6 +2021,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
+               chip_name = "navi12";
+               break;
+       case CHIP_CYAN_SKILLFISH:
++              if (adev->mman.discovery_bin)
++                      return 0;
+               chip_name = "cyan_skillfish";
+               break;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-allow-direct-registration-to-a-channel.patch b/queue-6.1/mailbox-allow-direct-registration-to-a-channel.patch
new file mode 100644 (file)
index 0000000..4f87b52
--- /dev/null
@@ -0,0 +1,159 @@
+From ae7efac83b4d5e53609f06c67dfd9d02d61d77e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 09:16:52 -0700
+Subject: mailbox: Allow direct registration to a channel
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+[ Upstream commit 85a953806557dbf25d16e8c132b5b9b100d16496 ]
+
+Support virtual mailbox controllers and clients which are not platform
+devices or come from the devicetree by allowing them to match client to
+channel via some other mechanism.
+
+Tested-by: Sudeep Holla <sudeep.holla@arm.com> (pcc)
+Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox.c      | 96 ++++++++++++++++++++++++----------
+ include/linux/mailbox_client.h |  1 +
+ 2 files changed, 69 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
+index cb31ad917b352..f4cfbdfe4111c 100644
+--- a/drivers/mailbox/mailbox.c
++++ b/drivers/mailbox/mailbox.c
+@@ -317,6 +317,71 @@ int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
+ }
+ EXPORT_SYMBOL_GPL(mbox_flush);
++static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl)
++{
++      struct device *dev = cl->dev;
++      unsigned long flags;
++      int ret;
++
++      if (chan->cl || !try_module_get(chan->mbox->dev->driver->owner)) {
++              dev_dbg(dev, "%s: mailbox not free\n", __func__);
++              return -EBUSY;
++      }
++
++      spin_lock_irqsave(&chan->lock, flags);
++      chan->msg_free = 0;
++      chan->msg_count = 0;
++      chan->active_req = NULL;
++      chan->cl = cl;
++      init_completion(&chan->tx_complete);
++
++      if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
++              chan->txdone_method = TXDONE_BY_ACK;
++
++      spin_unlock_irqrestore(&chan->lock, flags);
++
++      if (chan->mbox->ops->startup) {
++              ret = chan->mbox->ops->startup(chan);
++
++              if (ret) {
++                      dev_err(dev, "Unable to startup the chan (%d)\n", ret);
++                      mbox_free_channel(chan);
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++
++/**
++ * mbox_bind_client - Request a mailbox channel.
++ * @chan: The mailbox channel to bind the client to.
++ * @cl: Identity of the client requesting the channel.
++ *
++ * The Client specifies its requirements and capabilities while asking for
++ * a mailbox channel. It can't be called from atomic context.
++ * The channel is exclusively allocated and can't be used by another
++ * client before the owner calls mbox_free_channel.
++ * After assignment, any packet received on this channel will be
++ * handed over to the client via the 'rx_callback'.
++ * The framework holds reference to the client, so the mbox_client
++ * structure shouldn't be modified until the mbox_free_channel returns.
++ *
++ * Return: 0 if the channel was assigned to the client successfully.
++ *         <0 for request failure.
++ */
++int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl)
++{
++      int ret;
++
++      mutex_lock(&con_mutex);
++      ret = __mbox_bind_client(chan, cl);
++      mutex_unlock(&con_mutex);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(mbox_bind_client);
++
+ /**
+  * mbox_request_channel - Request a mailbox channel.
+  * @cl: Identity of the client requesting the channel.
+@@ -340,7 +405,6 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
+       struct mbox_controller *mbox;
+       struct of_phandle_args spec;
+       struct mbox_chan *chan;
+-      unsigned long flags;
+       int ret;
+       if (!dev || !dev->of_node) {
+@@ -373,33 +437,9 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
+               return chan;
+       }
+-      if (chan->cl || !try_module_get(mbox->dev->driver->owner)) {
+-              dev_dbg(dev, "%s: mailbox not free\n", __func__);
+-              mutex_unlock(&con_mutex);
+-              return ERR_PTR(-EBUSY);
+-      }
+-
+-      spin_lock_irqsave(&chan->lock, flags);
+-      chan->msg_free = 0;
+-      chan->msg_count = 0;
+-      chan->active_req = NULL;
+-      chan->cl = cl;
+-      init_completion(&chan->tx_complete);
+-
+-      if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
+-              chan->txdone_method = TXDONE_BY_ACK;
+-
+-      spin_unlock_irqrestore(&chan->lock, flags);
+-
+-      if (chan->mbox->ops->startup) {
+-              ret = chan->mbox->ops->startup(chan);
+-
+-              if (ret) {
+-                      dev_err(dev, "Unable to startup the chan (%d)\n", ret);
+-                      mbox_free_channel(chan);
+-                      chan = ERR_PTR(ret);
+-              }
+-      }
++      ret = __mbox_bind_client(chan, cl);
++      if (ret)
++              chan = ERR_PTR(ret);
+       mutex_unlock(&con_mutex);
+       return chan;
+diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
+index 65229a45590f1..734694912ef74 100644
+--- a/include/linux/mailbox_client.h
++++ b/include/linux/mailbox_client.h
+@@ -37,6 +37,7 @@ struct mbox_client {
+       void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
+ };
++int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
+ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
+                                             const char *name);
+ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-6.1/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..212f184
--- /dev/null
@@ -0,0 +1,38 @@
+From 5b2af21ee3f824906068e45ada8445ce48cc60ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index abcee58e851c2..29c04157b5e88 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -267,7 +267,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-add-support-for-platform-notification-ha.patch b/queue-6.1/mailbox-pcc-add-support-for-platform-notification-ha.patch
new file mode 100644 (file)
index 0000000..daea01d
--- /dev/null
@@ -0,0 +1,141 @@
+From f65f37153f3255f5e21581d4e8177e384653d841 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 14:38:26 +0800
+Subject: mailbox: pcc: Add support for platform notification handling
+
+From: Huisong Li <lihuisong@huawei.com>
+
+[ Upstream commit 60c40b06fa68694dd08a1a0038ea8b9de3f3b1ca ]
+
+Currently, PCC driver doesn't support the processing of platform
+notification for type 4 PCC subspaces.
+
+According to ACPI specification, if platform sends a notification
+to OSPM, it must clear the command complete bit and trigger platform
+interrupt. OSPM needs to check whether the command complete bit is
+cleared, clear platform interrupt, process command, and then set the
+command complete and ring doorbell to the Platform.
+
+Let us stash the value of the pcc type and use the same while processing
+the interrupt of the channel. We also need to set the command complete
+bit and ring doorbell in the interrupt handler for the type 4 channel to
+complete the communication flow after processing the notification from
+the Platform.
+
+Signed-off-by: Huisong Li <lihuisong@huawei.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+Link: https://lore.kernel.org/r/20230801063827.25336-2-lihuisong@huawei.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 50 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 41 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index a44d4b3e5beb2..80310b48bfb6a 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -91,6 +91,7 @@ struct pcc_chan_reg {
+  * @cmd_update: PCC register bundle for the command complete update register
+  * @error: PCC register bundle for the error status register
+  * @plat_irq: platform interrupt
++ * @type: PCC subspace type
+  */
+ struct pcc_chan_info {
+       struct pcc_mbox_chan chan;
+@@ -100,12 +101,15 @@ struct pcc_chan_info {
+       struct pcc_chan_reg cmd_update;
+       struct pcc_chan_reg error;
+       int plat_irq;
++      u8 type;
+ };
+ #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
+ static struct pcc_chan_info *chan_info;
+ static int pcc_chan_count;
++static int pcc_send_data(struct mbox_chan *chan, void *data);
++
+ /*
+  * PCC can be used with perf critical drivers such as CPPC
+  * So it makes sense to locally cache the virtual address and
+@@ -221,6 +225,34 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
+       return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+ }
++static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
++{
++      u64 val;
++      int ret;
++
++      ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
++      if (ret)
++              return false;
++
++      if (!pchan->cmd_complete.gas)
++              return true;
++
++      /*
++       * Judge if the channel respond the interrupt based on the value of
++       * command complete.
++       */
++      val &= pchan->cmd_complete.status_mask;
++      /*
++       * If this is PCC slave subspace channel, and the command complete
++       * bit 0 indicates that Platform is sending a notification and OSPM
++       * needs to respond this interrupt to process this command.
++       */
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              return !val;
++
++      return !!val;
++}
++
+ /**
+  * pcc_mbox_irq - PCC mailbox interrupt handler
+  * @irq:      interrupt number
+@@ -236,17 +268,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       int ret;
+       pchan = chan->con_priv;
+-
+-      ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
+-      if (ret)
++      if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+-      if (val) { /* Ensure GAS exists and value is non-zero */
+-              val &= pchan->cmd_complete.status_mask;
+-              if (!val)
+-                      return IRQ_NONE;
+-      }
+-
+       ret = pcc_chan_reg_read(&pchan->error, &val);
+       if (ret)
+               return IRQ_NONE;
+@@ -262,6 +286,13 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       mbox_chan_received_data(chan, NULL);
++      /*
++       * The PCC slave subspace channel needs to set the command complete bit
++       * and ring doorbell after processing message.
++       */
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              pcc_send_data(chan, NULL);
++
+       return IRQ_HANDLED;
+ }
+@@ -698,6 +729,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)
+               pcc_parse_subspace_shmem(pchan, pcct_entry);
++              pchan->type = pcct_entry->type;
+               pcct_entry = (struct acpi_subtable_header *)
+                       ((unsigned long) pcct_entry + pcct_entry->length);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch b/queue-6.1/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch
new file mode 100644 (file)
index 0000000..204006c
--- /dev/null
@@ -0,0 +1,167 @@
+From 31ee578b37bca7aeaa4876bfe83356e48bd638d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Nov 2024 14:02:14 -0500
+Subject: mailbox: pcc: Check before sending MCTP PCC response ACK
+
+From: Adam Young <admiyo@os.amperecomputing.com>
+
+[ Upstream commit 7f9e19f207be0c534d517d65e01417ba968cdd34 ]
+
+Type 4 PCC channels have an option to send back a response
+to the platform when they are done processing the request.
+The flag to indicate whether or not to respond is inside
+the message body, and thus is not available to the pcc
+mailbox.
+
+If the flag is not set, still set command completion
+bit after processing message.
+
+In order to read the flag, this patch maps the shared
+buffer to virtual memory. To avoid duplication of mapping
+the shared buffer is then made available to be used by
+the driver that uses the mailbox.
+
+Signed-off-by: Adam Young <admiyo@os.amperecomputing.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 61 +++++++++++++++++++++++++++++++++++++------
+ include/acpi/pcc.h    |  7 +++++
+ 2 files changed, 60 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 94885e411085a..82102a4c5d688 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -269,6 +269,35 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+       return !!val;
+ }
++static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
++{
++      struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
++
++      if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              return;
++      /* If the memory region has not been mapped, we cannot
++       * determine if we need to send the message, but we still
++       * need to set the cmd_update flag before returning.
++       */
++      if (pchan->chan.shmem == NULL) {
++              pcc_chan_reg_read_modify_write(&pchan->cmd_update);
++              return;
++      }
++      memcpy_fromio(&pcc_hdr, pchan->chan.shmem,
++                    sizeof(struct acpi_pcct_ext_pcc_shared_memory));
++      /*
++       * The PCC slave subspace channel needs to set the command complete bit
++       * after processing message. If the PCC_ACK_FLAG is set, it should also
++       * ring the doorbell.
++       *
++       * The PCC master subspace channel clears chan_in_use to free channel.
++       */
++      if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK)
++              pcc_send_data(chan, NULL);
++      else
++              pcc_chan_reg_read_modify_write(&pchan->cmd_update);
++}
++
+ /**
+  * pcc_mbox_irq - PCC mailbox interrupt handler
+  * @irq:      interrupt number
+@@ -306,14 +335,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       mbox_chan_received_data(chan, NULL);
+-      /*
+-       * The PCC slave subspace channel needs to set the command complete bit
+-       * and ring doorbell after processing message.
+-       *
+-       * The PCC master subspace channel clears chan_in_use to free channel.
+-       */
+-      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
+-              pcc_send_data(chan, NULL);
++      check_and_ack(pchan, chan);
+       pchan->chan_in_use = false;
+       return IRQ_HANDLED;
+@@ -365,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
+ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
+ {
+       struct mbox_chan *chan = pchan->mchan;
++      struct pcc_chan_info *pchan_info;
++      struct pcc_mbox_chan *pcc_mbox_chan;
+       if (!chan || !chan->cl)
+               return;
++      pchan_info = chan->con_priv;
++      pcc_mbox_chan = &pchan_info->chan;
++      if (pcc_mbox_chan->shmem) {
++              iounmap(pcc_mbox_chan->shmem);
++              pcc_mbox_chan->shmem = NULL;
++      }
+       mbox_free_channel(chan);
+ }
+ EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
++int pcc_mbox_ioremap(struct mbox_chan *chan)
++{
++      struct pcc_chan_info *pchan_info;
++      struct pcc_mbox_chan *pcc_mbox_chan;
++
++      if (!chan || !chan->cl)
++              return -1;
++      pchan_info = chan->con_priv;
++      pcc_mbox_chan = &pchan_info->chan;
++      pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr,
++                                     pcc_mbox_chan->shmem_size);
++      return 0;
++}
++EXPORT_SYMBOL_GPL(pcc_mbox_ioremap);
++
+ /**
+  * pcc_send_data - Called from Mailbox Controller code. Used
+  *            here only to ring the channel doorbell. The PCC client
+diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
+index 9b373d172a776..699c1a37b8e78 100644
+--- a/include/acpi/pcc.h
++++ b/include/acpi/pcc.h
+@@ -12,6 +12,7 @@
+ struct pcc_mbox_chan {
+       struct mbox_chan *mchan;
+       u64 shmem_base_addr;
++      void __iomem *shmem;
+       u64 shmem_size;
+       u32 latency;
+       u32 max_access_rate;
+@@ -31,11 +32,13 @@ struct pcc_mbox_chan {
+ #define PCC_CMD_COMPLETION_NOTIFY     BIT(0)
+ #define MAX_PCC_SUBSPACES     256
++#define PCC_ACK_FLAG_MASK     0x1
+ #ifdef CONFIG_PCC
+ extern struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
+ extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan);
++extern int pcc_mbox_ioremap(struct mbox_chan *chan);
+ #else
+ static inline struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+@@ -43,6 +46,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+       return ERR_PTR(-ENODEV);
+ }
+ static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { }
++static inline int pcc_mbox_ioremap(struct mbox_chan *chan)
++{
++      return 0;
++};
+ #endif
+ #endif /* _PCC_H */
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-don-t-zero-error-register.patch b/queue-6.1/mailbox-pcc-don-t-zero-error-register.patch
new file mode 100644 (file)
index 0000000..4cce407
--- /dev/null
@@ -0,0 +1,57 @@
+From 15c1568ebe1ead5b1508c755245dc54c3af8a49f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:42:29 +0000
+Subject: mailbox: pcc: don't zero error register
+
+From: Jamie Iles <jamie.iles@oss.qualcomm.com>
+
+[ Upstream commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 ]
+
+The error status mask for a type 3/4 subspace is used for reading the
+error status, and the bitwise inverse is used for clearing the error
+with the intent being to preserve any of the non-error bits.  However,
+we were previously applying the mask to extract the status and then
+applying the inverse to the result which ended up clearing all bits.
+
+Instead, store the inverse mask in the preserve mask and then use that
+on the original value read from the error status so that only the error
+is cleared.
+
+Fixes: c45ded7e1135 ("mailbox: pcc: Add support for PCCT extended PCC subspaces(type 3/4)")
+Signed-off-by: Jamie Iles <jamie.iles@oss.qualcomm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@oss.qualcomm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 94e99b87496d2..0729988467554 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -278,9 +278,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
+       if (ret)
+               return ret;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
++      if (val & pchan->error.status_mask) {
++              val &= pchan->error.preserve_mask;
+               pcc_chan_reg_write(&pchan->error, val);
+               return -EIO;
+       }
+@@ -662,7 +661,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
+               ret = pcc_chan_reg_init(&pchan->error,
+                                       &pcct_ext->error_status_register,
+-                                      0, 0, pcct_ext->error_status_mask,
++                                      ~pcct_ext->error_status_mask, 0,
++                                      pcct_ext->error_status_mask,
+                                       "Error Status");
+       }
+       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch b/queue-6.1/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
new file mode 100644 (file)
index 0000000..94b5a61
--- /dev/null
@@ -0,0 +1,92 @@
+From 54e5515087563c57fcbb80116ced6ee72a119ed9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 15:28:52 +0000
+Subject: mailbox: pcc: Refactor error handling in irq handler into separate
+ function
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 3a675f50415b95f2ae10bfd932e2154ba1a08ee7 ]
+
+The existing error handling logic in pcc_mbox_irq() is intermixed with the
+main flow of the function. The command complete check and the complete
+complete update/acknowledgment are nicely factored into separate functions.
+
+Moves error detection and clearing logic into a separate function called:
+pcc_mbox_error_check_and_clear() by extracting error-handling logic from
+pcc_mbox_irq().
+
+This ensures error checking and clearing are handled separately and it
+improves maintainability by keeping the IRQ handler focused on processing
+events.
+
+Acked-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Adam Young <admiyo@os.amperecomputing.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 82102a4c5d688..94e99b87496d2 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -269,6 +269,25 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+       return !!val;
+ }
++static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
++{
++      u64 val;
++      int ret;
++
++      ret = pcc_chan_reg_read(&pchan->error, &val);
++      if (ret)
++              return ret;
++
++      val &= pchan->error.status_mask;
++      if (val) {
++              val &= ~pchan->error.status_mask;
++              pcc_chan_reg_write(&pchan->error, val);
++              return -EIO;
++      }
++
++      return 0;
++}
++
+ static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
+ {
+       struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
+@@ -309,8 +328,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+ {
+       struct pcc_chan_info *pchan;
+       struct mbox_chan *chan = p;
+-      u64 val;
+-      int ret;
+       pchan = chan->con_priv;
+       if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
+@@ -320,15 +337,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+-      ret = pcc_chan_reg_read(&pchan->error, &val);
+-      if (ret)
++      if (pcc_mbox_error_check_and_clear(pchan))
+               return IRQ_NONE;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
+-              pcc_chan_reg_write(&pchan->error, val);
+-              return IRQ_NONE;
+-      }
+       if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
+               return IRQ_NONE;
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch b/queue-6.1/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch
new file mode 100644 (file)
index 0000000..831a848
--- /dev/null
@@ -0,0 +1,178 @@
+From bb36470504b0749cda9e02dfe00d2eed7385d06e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 14:38:27 +0800
+Subject: mailbox: pcc: Support shared interrupt for multiple subspaces
+
+From: Huisong Li <lihuisong@huawei.com>
+
+[ Upstream commit 3db174e478cb0bb34888c20a531608b70aec9c1f ]
+
+If the platform acknowledge interrupt is level triggered, then it can
+be shared by multiple subspaces provided each one has a unique platform
+interrupt ack preserve and ack set masks.
+
+If it can be shared, then we can request the irq with IRQF_SHARED and
+IRQF_ONESHOT flags. The first one indicating it can be shared and the
+latter one to keep the interrupt disabled until the hardirq handler
+finished.
+
+Further, since there is no way to detect if the interrupt is for a given
+channel as the interrupt ack preserve and ack set masks are for clearing
+the interrupt and not for reading the status(in case Irq Ack register
+may be write-only on some platforms), we need a way to identify if the
+given channel is in use and expecting the interrupt.
+
+PCC type0, type1 and type5 do not support shared level triggered interrupt.
+The methods of determining whether a given channel for remaining types
+should respond to an interrupt are as follows:
+ - type2: Whether the interrupt belongs to a given channel is only
+          determined by the status field in Generic Communications Channel
+          Shared Memory Region, which is done in rx_callback of PCC client.
+ - type3: This channel checks chan_in_use flag first and then checks the
+          command complete bit(value '1' indicates that the command has
+          been completed).
+ - type4: Platform ensure that the default value of the command complete
+          bit corresponding to the type4 channel is '1'. This command
+          complete bit is '0' when receive a platform notification.
+
+The new field, 'chan_in_use' is used by the type only support the
+communication from OSPM to Platform (like type3) and should be completely
+ignored by other types so as to avoid too many type unnecessary checks in
+IRQ handler.
+
+Signed-off-by: Huisong Li <lihuisong@huawei.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+Link: https://lore.kernel.org/r/20230801063827.25336-3-lihuisong@huawei.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 43 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 40 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 80310b48bfb6a..94885e411085a 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -92,6 +92,13 @@ struct pcc_chan_reg {
+  * @error: PCC register bundle for the error status register
+  * @plat_irq: platform interrupt
+  * @type: PCC subspace type
++ * @plat_irq_flags: platform interrupt flags
++ * @chan_in_use: this flag is used just to check if the interrupt needs
++ *            handling when it is shared. Since only one transfer can occur
++ *            at a time and mailbox takes care of locking, this flag can be
++ *            accessed without a lock. Note: the type only support the
++ *            communication from OSPM to Platform, like type3, use it, and
++ *            other types completely ignore it.
+  */
+ struct pcc_chan_info {
+       struct pcc_mbox_chan chan;
+@@ -102,6 +109,8 @@ struct pcc_chan_info {
+       struct pcc_chan_reg error;
+       int plat_irq;
+       u8 type;
++      unsigned int plat_irq_flags;
++      bool chan_in_use;
+ };
+ #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
+@@ -225,6 +234,12 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
+       return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+ }
++static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan)
++{
++      return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) ==
++              ACPI_LEVEL_SENSITIVE;
++}
++
+ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+ {
+       u64 val;
+@@ -242,6 +257,7 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+        * command complete.
+        */
+       val &= pchan->cmd_complete.status_mask;
++
+       /*
+        * If this is PCC slave subspace channel, and the command complete
+        * bit 0 indicates that Platform is sending a notification and OSPM
+@@ -268,6 +284,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       int ret;
+       pchan = chan->con_priv;
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
++          !pchan->chan_in_use)
++              return IRQ_NONE;
++
+       if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+@@ -289,9 +309,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       /*
+        * The PCC slave subspace channel needs to set the command complete bit
+        * and ring doorbell after processing message.
++       *
++       * The PCC master subspace channel clears chan_in_use to free channel.
+        */
+       if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
+               pcc_send_data(chan, NULL);
++      pchan->chan_in_use = false;
+       return IRQ_HANDLED;
+ }
+@@ -371,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
+       if (ret)
+               return ret;
+-      return pcc_chan_reg_read_modify_write(&pchan->db);
++      ret = pcc_chan_reg_read_modify_write(&pchan->db);
++      if (!ret && pchan->plat_irq > 0)
++              pchan->chan_in_use = true;
++
++      return ret;
+ }
+ /**
+@@ -384,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
+ static int pcc_startup(struct mbox_chan *chan)
+ {
+       struct pcc_chan_info *pchan = chan->con_priv;
++      unsigned long irqflags;
+       int rc;
+       if (pchan->plat_irq > 0) {
+-              rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
+-                                    MBOX_IRQ_NAME, chan);
++              irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ?
++                                              IRQF_SHARED | IRQF_ONESHOT : 0;
++              rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,
++                                    irqflags, MBOX_IRQ_NAME, chan);
+               if (unlikely(rc)) {
+                       dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
+                               pchan->plat_irq);
+@@ -494,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
+                      pcct_ss->platform_interrupt);
+               return -EINVAL;
+       }
++      pchan->plat_irq_flags = pcct_ss->flags;
+       if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
+               struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
+@@ -515,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
+                                       "PLAT IRQ ACK");
+       }
++      if (pcc_chan_plat_irq_can_be_shared(pchan) &&
++          !pchan->plat_irq_ack.gas) {
++              pr_err("PCC subspace has level IRQ with no ACK register\n");
++              return -EINVAL;
++      }
++
+       return ret;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mailbox-pcc-use-mbox_bind_client.patch b/queue-6.1/mailbox-pcc-use-mbox_bind_client.patch
new file mode 100644 (file)
index 0000000..9c64cbb
--- /dev/null
@@ -0,0 +1,157 @@
+From c185b001ab28b0fd7d83b038d62719c60bfe0b54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 09:16:54 -0700
+Subject: mailbox: pcc: Use mbox_bind_client
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+[ Upstream commit 76d4adacd52e78bea2e393081f2a5766261d1e3a ]
+
+Use generic mbox_bind_client() to bind omap mailbox channel to a client.
+
+mbox_bind_client is identical to the replaced lines, except that it:
+ - Does the operation under con_mutex which prevents possible races in
+   removal path
+ - Sets TXDONE_BY_ACK if pcc uses TXDONE_BY_POLL and the client knows
+   when tx is done. TXDONE_BY_ACK is already set if there's no interrupt,
+   so this is not applicable.
+ - Calls chan->mbox->ops->startup. This is usecase for requesting irq:
+   move the devm_request_irq into the startup callback and unregister it
+   in the shutdown path.
+
+Tested-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 84 +++++++++++++++++++++++--------------------
+ 1 file changed, 45 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 105d46c9801ba..a44d4b3e5beb2 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -282,8 +282,7 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+ {
+       struct pcc_chan_info *pchan;
+       struct mbox_chan *chan;
+-      struct device *dev;
+-      unsigned long flags;
++      int rc;
+       if (subspace_id < 0 || subspace_id >= pcc_chan_count)
+               return ERR_PTR(-ENOENT);
+@@ -294,32 +293,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+               pr_err("Channel not found for idx: %d\n", subspace_id);
+               return ERR_PTR(-EBUSY);
+       }
+-      dev = chan->mbox->dev;
+-      spin_lock_irqsave(&chan->lock, flags);
+-      chan->msg_free = 0;
+-      chan->msg_count = 0;
+-      chan->active_req = NULL;
+-      chan->cl = cl;
+-      init_completion(&chan->tx_complete);
+-
+-      if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
+-              chan->txdone_method = TXDONE_BY_ACK;
+-
+-      spin_unlock_irqrestore(&chan->lock, flags);
+-
+-      if (pchan->plat_irq > 0) {
+-              int rc;
+-
+-              rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
+-                                    MBOX_IRQ_NAME, chan);
+-              if (unlikely(rc)) {
+-                      dev_err(dev, "failed to register PCC interrupt %d\n",
+-                              pchan->plat_irq);
+-                      pcc_mbox_free_channel(&pchan->chan);
+-                      return ERR_PTR(rc);
+-              }
+-      }
++      rc = mbox_bind_client(chan, cl);
++      if (rc)
++              return ERR_PTR(rc);
+       return &pchan->chan;
+ }
+@@ -333,23 +310,12 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
+  */
+ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
+ {
+-      struct pcc_chan_info *pchan_info = to_pcc_chan_info(pchan);
+       struct mbox_chan *chan = pchan->mchan;
+-      unsigned long flags;
+       if (!chan || !chan->cl)
+               return;
+-      if (pchan_info->plat_irq > 0)
+-              devm_free_irq(chan->mbox->dev, pchan_info->plat_irq, chan);
+-
+-      spin_lock_irqsave(&chan->lock, flags);
+-      chan->cl = NULL;
+-      chan->active_req = NULL;
+-      if (chan->txdone_method == TXDONE_BY_ACK)
+-              chan->txdone_method = TXDONE_BY_POLL;
+-
+-      spin_unlock_irqrestore(&chan->lock, flags);
++      mbox_free_channel(chan);
+ }
+ EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
+@@ -377,8 +343,48 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
+       return pcc_chan_reg_read_modify_write(&pchan->db);
+ }
++/**
++ * pcc_startup - Called from Mailbox Controller code. Used here
++ *            to request the interrupt.
++ * @chan: Pointer to Mailbox channel to startup.
++ *
++ * Return: Err if something failed else 0 for success.
++ */
++static int pcc_startup(struct mbox_chan *chan)
++{
++      struct pcc_chan_info *pchan = chan->con_priv;
++      int rc;
++
++      if (pchan->plat_irq > 0) {
++              rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
++                                    MBOX_IRQ_NAME, chan);
++              if (unlikely(rc)) {
++                      dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
++                              pchan->plat_irq);
++                      return rc;
++              }
++      }
++
++      return 0;
++}
++
++/**
++ * pcc_shutdown - Called from Mailbox Controller code. Used here
++ *            to free the interrupt.
++ * @chan: Pointer to Mailbox channel to shutdown.
++ */
++static void pcc_shutdown(struct mbox_chan *chan)
++{
++      struct pcc_chan_info *pchan = chan->con_priv;
++
++      if (pchan->plat_irq > 0)
++              devm_free_irq(chan->mbox->dev, pchan->plat_irq, chan);
++}
++
+ static const struct mbox_chan_ops pcc_chan_ops = {
+       .send_data = pcc_send_data,
++      .startup = pcc_startup,
++      .shutdown = pcc_shutdown,
+ };
+ /**
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-6.1/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..eb3d35b
--- /dev/null
@@ -0,0 +1,144 @@
+From 622ce66063a00d295e9e251828ee7723775f5643 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 54e70f07b5734..7b4814b3ba442 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index 5dfc751572edc..bc4e1b6035e08 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-6.1/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..b89b9a6
--- /dev/null
@@ -0,0 +1,93 @@
+From 1dee0dcf941d6e0091a374eac158b31c207b86ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index 0eaaba3a18ee0..c8466ebd4a031 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch b/queue-6.1/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
new file mode 100644 (file)
index 0000000..5f15b69
--- /dev/null
@@ -0,0 +1,73 @@
+From a46862e235b951513cca251e5e79ede0b9aa43ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 13:13:24 +0200
+Subject: net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing
+ traffic
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
+
+When using the SGMII PCS as a fixed-link chip-to-chip connection, it is
+easy to miss the fact that traffic passes only at 1G, since that's what
+any normal such connection would use.
+
+When using the SGMII PCS connected towards an on-board PHY or an SFP
+module, it is immediately noticeable that when the link resolves to a
+speed other than 1G, traffic from the MAC fails to pass: TX counters
+increase, but nothing gets decoded by the other end, and no local RX
+counters increase either.
+
+Artificially lowering a fixed-link rate to speed = <100> makes us able
+to see the same issue as in the case of having an SGMII PHY.
+
+Some debugging shows that the XPCS configuration is A-OK, but that the
+MAC Configuration Table entry for the port has the SPEED bits still set
+to 1000Mbps, due to a special condition in the driver. Deleting that
+condition, and letting the resolved link speed be programmed directly
+into the MAC speed field, results in a functional link at all 3 speeds.
+
+This piece of evidence, based on testing on both generations with SGMII
+support (SJA1105S and SJA1110A) directly contradicts the statement from
+the blamed commit that "the MAC is fixed at 1 Gbps and we need to
+configure the PCS only (if even that)". Worse, that statement is not
+backed by any documentation, and no one from NXP knows what it might
+refer to.
+
+I am unable to recall sufficient context regarding my testing from March
+2020 to understand what led me to draw such a braindead and factually
+incorrect conclusion. Yet, there is nothing of value regarding forcing
+the MAC speed, either for SGMII or 2500Base-X (introduced at a later
+stage), so remove all such logic.
+
+Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index 8350696bdda5b..cb6f924b92ac0 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1308,14 +1308,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
+        * table, since this will be used for the clocking setup, and we no
+        * longer need to store it in the static config (already told hardware
+        * we want auto during upload phase).
+-       * Actually for the SGMII port, the MAC is fixed at 1 Gbps and
+-       * we need to configure the PCS only (if even that).
+        */
+-      if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+-      else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-
+       mac[port].speed = speed;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-dsa-sja1105-simplify-static-configuration-reload.patch b/queue-6.1/net-dsa-sja1105-simplify-static-configuration-reload.patch
new file mode 100644 (file)
index 0000000..3d8837f
--- /dev/null
@@ -0,0 +1,159 @@
+From 5be00a02f66dd2f15b8bad770709d11fd6ab2972 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 17:04:36 +0100
+Subject: net: dsa: sja1105: simplify static configuration reload
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit a18891b55703a45b700618ef40edd5e9aaecc345 ]
+
+The static configuration reload saves the port speed in the static
+configuration tables by first converting it from the internal
+respresentation to the SPEED_xxx ethtool representation, and then
+converts it back to restore the setting. This is because
+sja1105_adjust_port_config() takes the speed as SPEED_xxx.
+
+However, this is unnecessarily complex. If we split
+sja1105_adjust_port_config() up, we can simply save and restore the
+mac[port].speed member in the static configuration tables.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------
+ 1 file changed, 34 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index d51d982c4bc01..8350696bdda5b 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1262,29 +1262,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)
+       return rc;
+ }
+-/* Convert link speed from SJA1105 to ethtool encoding */
+-static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv,
+-                                       u64 speed)
+-{
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS])
+-              return SPEED_10;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS])
+-              return SPEED_100;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS])
+-              return SPEED_1000;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS])
+-              return SPEED_2500;
+-      return SPEED_UNKNOWN;
+-}
+-
+-/* Set link speed in the MAC configuration for a specific port. */
+-static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+-                                    int speed_mbps)
++static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
++                                int speed_mbps)
+ {
+       struct sja1105_mac_config_entry *mac;
+-      struct device *dev = priv->ds->dev;
+       u64 speed;
+-      int rc;
+       /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
+        * tables. On E/T, MAC reconfig tables are not readable, only writable.
+@@ -1318,7 +1300,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+               speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+               break;
+       default:
+-              dev_err(dev, "Invalid speed %iMbps\n", speed_mbps);
++              dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps);
+               return -EINVAL;
+       }
+@@ -1330,11 +1312,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+        * we need to configure the PCS only (if even that).
+        */
+       if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
++              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+       else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-      else
+-              mac[port].speed = speed;
++              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
++
++      mac[port].speed = speed;
++
++      return 0;
++}
++
++/* Write the MAC Configuration Table entry and, if necessary, the CGU settings,
++ * after a link speedchange for this port.
++ */
++static int sja1105_set_port_config(struct sja1105_private *priv, int port)
++{
++      struct sja1105_mac_config_entry *mac;
++      struct device *dev = priv->ds->dev;
++      int rc;
++
++      /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
++       * tables. On E/T, MAC reconfig tables are not readable, only writable.
++       * We have to *know* what the MAC looks like.  For the sake of keeping
++       * the code common, we'll use the static configuration tables as a
++       * reasonable approximation for both E/T and P/Q/R/S.
++       */
++      mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+       /* Write to the dynamic reconfiguration tables */
+       rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+@@ -1384,7 +1386,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
+ {
+       struct sja1105_private *priv = ds->priv;
+-      sja1105_adjust_port_config(priv, port, speed);
++      if (!sja1105_set_port_speed(priv, port, speed))
++              sja1105_set_port_config(priv, port);
+       sja1105_inhibit_tx(priv, BIT(port), false);
+ }
+@@ -2291,8 +2294,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+ {
+       struct ptp_system_timestamp ptp_sts_before;
+       struct ptp_system_timestamp ptp_sts_after;
+-      int speed_mbps[SJA1105_MAX_NUM_PORTS];
+       u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0};
++      u64 mac_speed[SJA1105_MAX_NUM_PORTS];
+       struct sja1105_mac_config_entry *mac;
+       struct dsa_switch *ds = priv->ds;
+       s64 t1, t2, t3, t4;
+@@ -2305,14 +2308,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+       mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+-      /* Back up the dynamic link speed changed by sja1105_adjust_port_config
++      /* Back up the dynamic link speed changed by sja1105_set_port_speed()
+        * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the
+        * switch wants to see in the static config in order to allow us to
+        * change it through the dynamic interface later.
+        */
+       for (i = 0; i < ds->num_ports; i++) {
+-              speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
+-                                                            mac[i].speed);
++              mac_speed[i] = mac[i].speed;
+               mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];
+               if (priv->xpcs[i])
+@@ -2375,7 +2377,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+               struct dw_xpcs *xpcs = priv->xpcs[i];
+               unsigned int mode;
+-              rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
++              mac[i].speed = mac_speed[i];
++              rc = sja1105_set_port_config(priv, i);
+               if (rc < 0)
+                       goto out;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-lan966x-fix-the-initialization-of-taprio.patch b/queue-6.1/net-lan966x-fix-the-initialization-of-taprio.patch
new file mode 100644 (file)
index 0000000..88586ca
--- /dev/null
@@ -0,0 +1,54 @@
+From 8f13327be824045192b392cd804c9f4aff7c22b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 07:14:11 +0100
+Subject: net: lan966x: Fix the initialization of taprio
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 ]
+
+To initialize the taprio block in lan966x, it is required to configure
+the register REVISIT_DLY. The purpose of this register is to set the
+delay before revisit the next gate and the value of this register depends
+on the system clock. The problem is that the we calculated wrong the value
+of the system clock period in picoseconds. The actual system clock is
+~165.617754MHZ and this correspond to a period of 6038 pico seconds and
+not 15125 as currently set.
+
+Fixes: e462b2717380b4 ("net: lan966x: Add offload support for taprio")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121061411.810571-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index 0a0e233f36ab0..667f2651ee309 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -1,9 +1,12 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/ptp_classify.h>
++#include <linux/units.h>
+ #include "lan966x_main.h"
++#define LAN9X66_CLOCK_RATE    165617754
++
+ #define LAN966X_MAX_PTP_ID    512
+ /* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
+@@ -896,5 +899,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u32 lan966x_ptp_get_period_ps(void)
+ {
+       /* This represents the system clock period in picoseconds */
+-      return 15125;
++      return PICO / LAN9X66_CLOCK_RATE;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-6.1/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..2e7e38a
--- /dev/null
@@ -0,0 +1,63 @@
+From a1e787f3d117d25fa45ecce95fb1324f8caa048e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 29e633e6dd3f0..e29a8ed7e7ac1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -619,7 +619,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-6.1/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..13007a6
--- /dev/null
@@ -0,0 +1,47 @@
+From 9dfb7317bc032f61baa757228f2d9adc937f8839 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index 9664f029fa161..f6f99712d562e 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1521,8 +1521,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
diff --git a/queue-6.1/platform-x86-intel-punit_ipc-fix-memory-corruption.patch b/queue-6.1/platform-x86-intel-punit_ipc-fix-memory-corruption.patch
new file mode 100644 (file)
index 0000000..307bccd
--- /dev/null
@@ -0,0 +1,46 @@
+From 53121c5124e56870b3ab7c0ff34a614bc2f14372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 20:51:28 +0300
+Subject: platform/x86: intel: punit_ipc: fix memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
+
+This passes the address of the pointer "&punit_ipcdev" when the intent
+was to pass the pointer itself "punit_ipcdev" (without the ampersand).
+This means that the:
+
+       complete(&ipcdev->cmd_complete);
+
+in intel_punit_ioc() will write to a wrong memory address corrupting it.
+
+Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/punit_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
+index 66bb39fd0ef90..8602f4175f123 100644
+--- a/drivers/platform/x86/intel/punit_ipc.c
++++ b/drivers/platform/x86/intel/punit_ipc.c
+@@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
+       } else {
+               ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+                                      IRQF_NO_SUSPEND, "intel_punit_ipc",
+-                                     &punit_ipcdev);
++                                     punit_ipcdev);
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+                       return ret;
+-- 
+2.51.0
+
index 73f37f2d277ae238e70c587ce4288dc9964d3149..23363f20d4e921b587d8baf326041cfa6ff9967f 100644 (file)
@@ -492,3 +492,26 @@ pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch
 pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch
 filemap-cap-pte-range-to-be-created-to-allowed-zero-.patch
 mm-memory-do-not-populate-page-table-entries-beyond-.patch
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+platform-x86-intel-punit_ipc-fix-memory-corruption.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-lan966x-fix-the-initialization-of-taprio.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
+net-dsa-sja1105-simplify-static-configuration-reload.patch
+net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+mailbox-allow-direct-registration-to-a-channel.patch
+mailbox-pcc-use-mbox_bind_client.patch
+mailbox-pcc-add-support-for-platform-notification-ha.patch
+mailbox-pcc-support-shared-interrupt-for-multiple-su.patch
+acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch
+mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch
+mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
+mailbox-pcc-don-t-zero-error-register.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
diff --git a/queue-6.1/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-6.1/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..bbe920a
--- /dev/null
@@ -0,0 +1,68 @@
+From 1e119775f5a82b39349c92d7d8e5bc6cbc3439fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index 2f2a130464651..e57e1f75cd9f9 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -257,6 +257,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch b/queue-6.12/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch
new file mode 100644 (file)
index 0000000..6ab50ad
--- /dev/null
@@ -0,0 +1,132 @@
+From 61b99f35b56f17619f1a7e86df35c48a90a862ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Nov 2025 15:53:34 +0800
+Subject: Bluetooth: btusb: mediatek: Fix kernel crash when releasing mtk iso
+ interface
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 4015b979767125cf8a2233a145a3b3af78bfd8fb ]
+
+When performing reset tests and encountering abnormal card drop issues
+that lead to a kernel crash, it is necessary to perform a null check
+before releasing resources to avoid attempting to release a null pointer.
+
+<4>[   29.158070] Hardware name: Google Quigon sku196612/196613 board (DT)
+<4>[   29.158076] Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+<4>[   29.158154] pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+<4>[   29.158162] pc : klist_remove+0x90/0x158
+<4>[   29.158174] lr : klist_remove+0x88/0x158
+<4>[   29.158180] sp : ffffffc0846b3c00
+<4>[   29.158185] pmr_save: 000000e0
+<4>[   29.158188] x29: ffffffc0846b3c30 x28: ffffff80cd31f880 x27: ffffff80c1bdc058
+<4>[   29.158199] x26: dead000000000100 x25: ffffffdbdc624ea3 x24: ffffff80c1bdc4c0
+<4>[   29.158209] x23: ffffffdbdc62a3e6 x22: ffffff80c6c07000 x21: ffffffdbdc829290
+<4>[   29.158219] x20: 0000000000000000 x19: ffffff80cd3e0648 x18: 000000031ec97781
+<4>[   29.158229] x17: ffffff80c1bdc4a8 x16: ffffffdc10576548 x15: ffffff80c1180428
+<4>[   29.158238] x14: 0000000000000000 x13: 000000000000e380 x12: 0000000000000018
+<4>[   29.158248] x11: ffffff80c2a7fd10 x10: 0000000000000000 x9 : 0000000100000000
+<4>[   29.158257] x8 : 0000000000000000 x7 : 7f7f7f7f7f7f7f7f x6 : 2d7223ff6364626d
+<4>[   29.158266] x5 : 0000008000000000 x4 : 0000000000000020 x3 : 2e7325006465636e
+<4>[   29.158275] x2 : ffffffdc11afeff8 x1 : 0000000000000000 x0 : ffffffdc11be4d0c
+<4>[   29.158285] Call trace:
+<4>[   29.158290]  klist_remove+0x90/0x158
+<4>[   29.158298]  device_release_driver_internal+0x20c/0x268
+<4>[   29.158308]  device_release_driver+0x1c/0x30
+<4>[   29.158316]  usb_driver_release_interface+0x70/0x88
+<4>[   29.158325]  btusb_mtk_release_iso_intf+0x68/0xd8 [btusb (HASH:e8b6 5)]
+<4>[   29.158347]  btusb_mtk_reset+0x5c/0x480 [btusb (HASH:e8b6 5)]
+<4>[   29.158361]  hci_cmd_sync_work+0x10c/0x188 [bluetooth (HASH:a4fa 6)]
+<4>[   29.158430]  process_scheduled_works+0x258/0x4e8
+<4>[   29.158441]  worker_thread+0x300/0x428
+<4>[   29.158448]  kthread+0x108/0x1d0
+<4>[   29.158455]  ret_from_fork+0x10/0x20
+<0>[   29.158467] Code: 91343000 940139d1 f9400268 927ff914 (f9401297)
+<4>[   29.158474] ---[ end trace 0000000000000000 ]---
+<0>[   29.167129] Kernel panic - not syncing: Oops: Fatal exception
+<2>[   29.167144] SMP: stopping secondary CPUs
+<4>[   29.167158] ------------[ cut here ]------------
+
+Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions")
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c        | 34 +++++++++++++++++++++++++-------
+ include/net/bluetooth/hci_core.h |  1 -
+ 2 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index aedb478614000..b6c37e87c6a08 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2704,9 +2704,16 @@ static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb)
+ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
+ {
+-      struct btmtk_data *btmtk_data = hci_get_priv(data->hdev);
++      struct btmtk_data *btmtk_data;
+       int err;
++      if (!data->hdev)
++              return;
++
++      btmtk_data = hci_get_priv(data->hdev);
++      if (!btmtk_data)
++              return;
++
+       /*
+        * The function usb_driver_claim_interface() is documented to need
+        * locks held if it's not called from a probe routine. The code here
+@@ -2728,17 +2735,30 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
+ static void btusb_mtk_release_iso_intf(struct hci_dev *hdev)
+ {
+-      struct btmtk_data *btmtk_data = hci_get_priv(hdev);
++      struct btmtk_data *btmtk_data;
++
++      if (!hdev)
++              return;
++
++      btmtk_data = hci_get_priv(hdev);
++      if (!btmtk_data)
++              return;
+       if (test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) {
+               usb_kill_anchored_urbs(&btmtk_data->isopkt_anchor);
+               clear_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags);
+-              dev_kfree_skb_irq(btmtk_data->isopkt_skb);
+-              btmtk_data->isopkt_skb = NULL;
+-              usb_set_intfdata(btmtk_data->isopkt_intf, NULL);
+-              usb_driver_release_interface(&btusb_driver,
+-                                           btmtk_data->isopkt_intf);
++              if (btmtk_data->isopkt_skb) {
++                      dev_kfree_skb_irq(btmtk_data->isopkt_skb);
++                      btmtk_data->isopkt_skb = NULL;
++              }
++
++              if (btmtk_data->isopkt_intf) {
++                      usb_set_intfdata(btmtk_data->isopkt_intf, NULL);
++                      usb_driver_release_interface(&btusb_driver,
++                                                   btmtk_data->isopkt_intf);
++                      btmtk_data->isopkt_intf = NULL;
++              }
+       }
+       clear_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags);
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 35b5f58b562cb..ba5d176069a69 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -732,7 +732,6 @@ struct hci_conn {
+       __u8            remote_cap;
+       __u8            remote_auth;
+-      __u8            remote_id;
+       unsigned int    sent;
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch b/queue-6.12/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch
new file mode 100644 (file)
index 0000000..c591c80
--- /dev/null
@@ -0,0 +1,85 @@
+From a2b27d70304d4d67afa414884a4deb711fccdc8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 09:49:27 -0500
+Subject: Bluetooth: hci_core: Fix triggering cmd_timer for HCI_OP_NOP
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 275ddfeb3fdc274050c2173ffd985b1e80a9aa37 ]
+
+HCI_OP_NOP means no command was actually sent so there is no point in
+triggering cmd_timer which may cause a hdev->reset in the process since
+it is assumed that the controller is stuck processing a command.
+
+Fixes: e2d471b7806b ("Bluetooth: ISO: Fix not using SID from adv report")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index b74ada8092378..ba01d0fa07193 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4076,7 +4076,7 @@ static void hci_rx_work(struct work_struct *work)
+       }
+ }
+-static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
++static int hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+       int err;
+@@ -4088,16 +4088,19 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+       if (!hdev->sent_cmd) {
+               skb_queue_head(&hdev->cmd_q, skb);
+               queue_work(hdev->workqueue, &hdev->cmd_work);
+-              return;
++              return -EINVAL;
+       }
+       if (hci_skb_opcode(skb) != HCI_OP_NOP) {
+               err = hci_send_frame(hdev, skb);
+               if (err < 0) {
+                       hci_cmd_sync_cancel_sync(hdev, -err);
+-                      return;
++                      return err;
+               }
+               atomic_dec(&hdev->cmd_cnt);
++      } else {
++              err = -ENODATA;
++              kfree_skb(skb);
+       }
+       if (hdev->req_status == HCI_REQ_PEND &&
+@@ -4105,12 +4108,15 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+               kfree_skb(hdev->req_skb);
+               hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
+       }
++
++      return err;
+ }
+ static void hci_cmd_work(struct work_struct *work)
+ {
+       struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
+       struct sk_buff *skb;
++      int err;
+       BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
+              atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
+@@ -4121,7 +4127,9 @@ static void hci_cmd_work(struct work_struct *work)
+               if (!skb)
+                       return;
+-              hci_send_cmd_sync(hdev, skb);
++              err = hci_send_cmd_sync(hdev, skb);
++              if (err)
++                      return;
+               rcu_read_lock();
+               if (test_bit(HCI_RESET, &hdev->flags) ||
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch b/queue-6.12/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
new file mode 100644 (file)
index 0000000..78bf24f
--- /dev/null
@@ -0,0 +1,72 @@
+From cc46f235e97e47f8d296605d8e5f3b906c410ac0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Nov 2025 17:04:43 +0800
+Subject: Bluetooth: hci_sock: Prevent race in socket write iter and sock bind
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 89bb613511cc21ed5ba6bddc1c9b9ae9c0dad392 ]
+
+There is a potential race condition between sock bind and socket write
+iter. bind may free the same cmd via mgmt_pending before write iter sends
+the cmd, just as syzbot reported in UAF[1].
+
+Here we use hci_dev_lock to synchronize the two, thereby avoiding the
+UAF mentioned in [1].
+
+[1]
+syzbot reported:
+BUG: KASAN: slab-use-after-free in mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+Read of size 8 at addr ffff888077164818 by task syz.0.17/5989
+Call Trace:
+ mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+ set_link_security+0x5c2/0x710 net/bluetooth/mgmt.c:1918
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Allocated by task 5989:
+ mgmt_pending_add+0x35/0x140 net/bluetooth/mgmt_util.c:296
+ set_link_security+0x557/0x710 net/bluetooth/mgmt.c:1910
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Freed by task 5991:
+ mgmt_pending_free net/bluetooth/mgmt_util.c:311 [inline]
+ mgmt_pending_foreach+0x30d/0x380 net/bluetooth/mgmt_util.c:257
+ mgmt_index_removed+0x112/0x2f0 net/bluetooth/mgmt.c:9477
+ hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314
+
+Fixes: 6fe26f694c82 ("Bluetooth: MGMT: Protect mgmt_pending list with its own lock")
+Reported-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=9aa47cd4633a3cf92a80
+Tested-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 4ad5296d79345..fbfc962374a88 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -1304,7 +1304,9 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+                       goto done;
+               }
++              hci_dev_lock(hdev);
+               mgmt_index_removed(hdev);
++              hci_dev_unlock(hdev);
+               err = hci_dev_open(hdev->id);
+               if (err) {
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-6.12/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..34730a8
--- /dev/null
@@ -0,0 +1,87 @@
+From fc62ce142acc8e734b80255ea0f1a13d7b05b4a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index a31971fe2fd7e..3a33fd06e6a4c 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2136,7 +2136,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2188,24 +2188,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2226,11 +2208,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch b/queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
new file mode 100644 (file)
index 0000000..9faaafb
--- /dev/null
@@ -0,0 +1,92 @@
+From 0e0553f9067c4ef44a37ec3613ea6381c4ee4a51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:02 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing header
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf ]
+
+The driver expects to receive a struct gs_host_frame in
+gs_usb_receive_bulk_callback().
+
+Use struct_group to describe the header of the struct gs_host_frame and
+check that we have at least received the header before accessing any
+members of it.
+
+To resubmit the URB, do not dereference the pointer chain
+"dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since
+"urb->context" contains "parent", it is always defined, while "dev" is not
+defined if the URB it too short.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-2-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index fd34945d831e9..b2cfdc3558a5a 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -259,13 +259,15 @@ struct canfd_quirk {
+ } __packed;
+ struct gs_host_frame {
+-      u32 echo_id;
+-      __le32 can_id;
++      struct_group(header,
++              u32 echo_id;
++              __le32 can_id;
+-      u8 can_dlc;
+-      u8 channel;
+-      u8 flags;
+-      u8 reserved;
++              u8 can_dlc;
++              u8 channel;
++              u8 flags;
++              u8 reserved;
++      );
+       union {
+               DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
+@@ -573,6 +575,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
++      unsigned int minimum_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -591,6 +594,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+               return;
+       }
++      minimum_length = sizeof(hf->header);
++      if (urb->actual_length < minimum_length) {
++              dev_err_ratelimited(&parent->udev->dev,
++                                  "short read (actual_length=%u, minimum_length=%u)\n",
++                                  urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
+       /* device reports out of range channel id */
+       if (hf->channel >= parent->channel_cnt)
+               goto device_detach;
+@@ -684,7 +696,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ resubmit_urb:
+       usb_fill_bulk_urb(urb, parent->udev,
+                         parent->pipe_in,
+-                        hf, dev->parent->hf_size_rx,
++                        hf, parent->hf_size_rx,
+                         gs_usb_receive_bulk_callback, parent);
+       rc = usb_submit_urb(urb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-29525 b/queue-6.12/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-29525
new file mode 100644 (file)
index 0000000..791d9a9
--- /dev/null
@@ -0,0 +1,140 @@
+From 91ae7e804275c479b48875f1862b4c4c569c9d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:03 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing data
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 395d988f93861101ec89d0dd9e3b876ae9392a5b ]
+
+The URB received in gs_usb_receive_bulk_callback() contains a struct
+gs_host_frame. The length of the data after the header depends on the
+gs_host_frame hf::flags and the active device features (e.g. time
+stamping).
+
+Introduce a new function gs_usb_get_minimum_length() and check that we have
+at least received the required amount of data before accessing it. Only
+copy the data to that skb that has actually been received.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-3-a29b42eacada@pengutronix.de
+[mkl: rename gs_usb_get_minimum_length() -> +gs_usb_get_minimum_rx_length()]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 59 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index b2cfdc3558a5a..36540a2544586 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -258,6 +258,11 @@ struct canfd_quirk {
+       u8 quirk;
+ } __packed;
++/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates
++ * a regular RX'ed CAN frame
++ */
++#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff
++
+ struct gs_host_frame {
+       struct_group(header,
+               u32 echo_id;
+@@ -567,6 +572,37 @@ gs_usb_get_echo_skb(struct gs_can *dev, struct sk_buff *skb,
+       return len;
+ }
++static unsigned int
++gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf,
++                           unsigned int *data_length_p)
++{
++      unsigned int minimum_length, data_length = 0;
++
++      if (hf->flags & GS_CAN_FLAG_FD) {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX)
++                      data_length = can_fd_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, canfd_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      } else {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX &&
++                  !(hf->can_id & cpu_to_le32(CAN_RTR_FLAG)))
++                      data_length = can_cc_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, classic_can_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      }
++
++      *data_length_p = data_length;
++      return minimum_length;
++}
++
+ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ {
+       struct gs_usb *parent = urb->context;
+@@ -575,7 +611,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
+-      unsigned int minimum_length;
++      unsigned int minimum_length, data_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -618,20 +654,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       if (!netif_running(netdev))
+               goto resubmit_urb;
+-      if (hf->echo_id == -1) { /* normal rx */
++      minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length);
++      if (urb->actual_length < minimum_length) {
++              stats->rx_errors++;
++              stats->rx_length_errors++;
++
++              if (net_ratelimit())
++                      netdev_err(netdev,
++                                 "short read (actual_length=%u, minimum_length=%u)\n",
++                                 urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
++      if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */
+               if (hf->flags & GS_CAN_FLAG_FD) {
+                       skb = alloc_canfd_skb(netdev, &cfd);
+                       if (!skb)
+                               return;
+                       cfd->can_id = le32_to_cpu(hf->can_id);
+-                      cfd->len = can_fd_dlc2len(hf->can_dlc);
++                      cfd->len = data_length;
+                       if (hf->flags & GS_CAN_FLAG_BRS)
+                               cfd->flags |= CANFD_BRS;
+                       if (hf->flags & GS_CAN_FLAG_ESI)
+                               cfd->flags |= CANFD_ESI;
+-                      memcpy(cfd->data, hf->canfd->data, cfd->len);
++                      memcpy(cfd->data, hf->canfd->data, data_length);
+               } else {
+                       skb = alloc_can_skb(netdev, &cf);
+                       if (!skb)
+@@ -640,7 +689,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+                       cf->can_id = le32_to_cpu(hf->can_id);
+                       can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
+-                      memcpy(cf->data, hf->classic_can->data, 8);
++                      memcpy(cf->data, hf->classic_can->data, data_length);
+                       /* ERROR frames tell us information about the controller */
+                       if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
+-- 
+2.51.0
+
diff --git a/queue-6.12/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch b/queue-6.12/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
new file mode 100644 (file)
index 0000000..035cf62
--- /dev/null
@@ -0,0 +1,60 @@
+From 9972b3d20d06ff86c3547243fb5494043e3367ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:01 +0100
+Subject: can: gs_usb: gs_usb_xmit_callback(): fix handling of failed
+ transmitted URBs
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 ]
+
+The driver lacks the cleanup of failed transfers of URBs. This reduces the
+number of available URBs per error by 1. This leads to reduced performance
+and ultimately to a complete stop of the transmission.
+
+If the sending of a bulk URB fails do proper cleanup:
+- increase netdev stats
+- mark the echo_sbk as free
+- free the driver's context and do accounting
+- wake the send queue
+
+Closes: https://github.com/candle-usb/candleLight_fw/issues/187
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-1-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index fb904dc28b8ee..fd34945d831e9 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -747,8 +747,21 @@ static void gs_usb_xmit_callback(struct urb *urb)
+       struct gs_can *dev = txc->dev;
+       struct net_device *netdev = dev->netdev;
+-      if (urb->status)
+-              netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
++      if (!urb->status)
++              return;
++
++      if (urb->status != -ESHUTDOWN && net_ratelimit())
++              netdev_info(netdev, "failed to xmit URB %u: %pe\n",
++                          txc->echo_id, ERR_PTR(urb->status));
++
++      netdev->stats.tx_dropped++;
++      netdev->stats.tx_errors++;
++
++      can_free_echo_skb(netdev, txc->echo_id, NULL);
++      gs_free_tx_context(txc);
++      atomic_dec(&dev->active_tx_urbs);
++
++      netif_wake_queue(netdev);
+ }
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+-- 
+2.51.0
+
diff --git a/queue-6.12/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-6.12/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..2bd9b52
--- /dev/null
@@ -0,0 +1,62 @@
+From 39dfb19f39b5ad569b73c6b593fa62207cdacf93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 6b9122ab1464f..b7f6935686c96 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -662,7 +662,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1672,7 +1672,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-6.12/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch b/queue-6.12/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
new file mode 100644 (file)
index 0000000..98fa92b
--- /dev/null
@@ -0,0 +1,39 @@
+From 3a9fa1cfaecdeb25e179d0442f5efed26fc3ba9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 09:40:31 -0500
+Subject: drm/amdgpu: fix cyan_skillfish2 gpu info fw handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 ]
+
+If the board supports IP discovery, we don't need to
+parse the gpu info firmware.
+
+Backport to 6.18.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4721
+Fixes: fa819e3a7c1e ("drm/amdgpu: add support for cyan skillfish gpu_info")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5427e32fa3a0ba9a016db83877851ed277b065fb)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index b93afd52a0094..9e1716a3f70ba 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2414,6 +2414,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
+               chip_name = "navi12";
+               break;
+       case CHIP_CYAN_SKILLFISH:
++              if (adev->mman.discovery_bin)
++                      return 0;
+               chip_name = "cyan_skillfish";
+               break;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch b/queue-6.12/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch
new file mode 100644 (file)
index 0000000..3497988
--- /dev/null
@@ -0,0 +1,54 @@
+From 61ed2e84e90037089f287ab249c66a1455611e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 11:48:43 -0800
+Subject: drm/xe: Fix conversion from clock ticks to milliseconds
+
+From: Harish Chegondi <harish.chegondi@intel.com>
+
+[ Upstream commit 7276878b069c57d9a9cca5db01d2f7a427b73456 ]
+
+When tick counts are large and multiplication by MSEC_PER_SEC is larger
+than 64 bits, the conversion from clock ticks to milliseconds can go bad.
+
+Use mul_u64_u32_div() instead.
+
+Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Signed-off-by: Harish Chegondi <harish.chegondi@intel.com>
+Suggested-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+Fixes: 49cc215aad7f ("drm/xe: Add xe_gt_clock_interval_to_ms helper")
+Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Link: https://patch.msgid.link/1562f1b62d5be3fbaee100f09107f3cc49e40dd1.1763408584.git.harish.chegondi@intel.com
+(cherry picked from commit 96b93ac214f9dd66294d975d86c5dee256faef91)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt_clock.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_clock.c b/drivers/gpu/drm/xe/xe_gt_clock.c
+index 86c2d62b4bdc3..fa66295695c01 100644
+--- a/drivers/gpu/drm/xe/xe_gt_clock.c
++++ b/drivers/gpu/drm/xe/xe_gt_clock.c
+@@ -82,11 +82,6 @@ int xe_gt_clock_init(struct xe_gt *gt)
+       return 0;
+ }
+-static u64 div_u64_roundup(u64 n, u32 d)
+-{
+-      return div_u64(n + d - 1, d);
+-}
+-
+ /**
+  * xe_gt_clock_interval_to_ms - Convert sampled GT clock ticks to msec
+  *
+@@ -97,5 +92,5 @@ static u64 div_u64_roundup(u64 n, u32 d)
+  */
+ u64 xe_gt_clock_interval_to_ms(struct xe_gt *gt, u64 count)
+ {
+-      return div_u64_roundup(count * MSEC_PER_SEC, gt->info.reference_clock);
++      return mul_u64_u32_div(count, MSEC_PER_SEC, gt->info.reference_clock);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/eth-fbnic-fix-counter-roll-over-issue.patch b/queue-6.12/eth-fbnic-fix-counter-roll-over-issue.patch
new file mode 100644 (file)
index 0000000..e3651cc
--- /dev/null
@@ -0,0 +1,43 @@
+From 2115dde7cccd1ac0075de73f12c73c8a77147956 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 13:17:04 -0800
+Subject: eth: fbnic: Fix counter roll-over issue
+
+From: Mohsin Bashir <mohsin.bashr@gmail.com>
+
+[ Upstream commit 6d66e093e0740d39a36ef742c60eec247df26f41 ]
+
+Fix a potential counter roll-over issue in fbnic_mbx_alloc_rx_msgs()
+when calculating descriptor slots. The issue occurs when head - tail
+results in a large positive value (unsigned) and the compiler interprets
+head - tail - 1 as a signed value.
+
+Since FBNIC_IPC_MBX_DESC_LEN is a power of two, use a masking operation,
+which is a common way of avoiding this problem when dealing with these
+sort of ring space calculations.
+
+Fixes: da3cde08209e ("eth: fbnic: Add FW communication mechanism")
+Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20251125211704.3222413-1-mohsin.bashr@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+index d6cf97ecf3276..6f606bdfd2296 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+@@ -198,7 +198,7 @@ static int fbnic_mbx_alloc_rx_msgs(struct fbnic_dev *fbd)
+               return -ENODEV;
+       /* Fill all but 1 unused descriptors in the Rx queue. */
+-      count = (head - tail - 1) % FBNIC_IPC_MBX_DESC_LEN;
++      count = (head - tail - 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
+       while (!err && count--) {
+               struct fbnic_tlv_msg *msg;
+-- 
+2.51.0
+
diff --git a/queue-6.12/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch b/queue-6.12/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch
new file mode 100644 (file)
index 0000000..6dc7af8
--- /dev/null
@@ -0,0 +1,53 @@
+From bc381b5617c95412054f09590692275839f1060c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 07:19:53 +0000
+Subject: fs/namespace: fix reference leak in grab_requested_mnt_ns
+
+From: Andrei Vagin <avagin@google.com>
+
+[ Upstream commit 7b6dcd9bfd869eee7693e45b1817dac8c56e5f86 ]
+
+lookup_mnt_ns() already takes a reference on mnt_ns.
+grab_requested_mnt_ns() doesn't need to take an extra reference.
+
+Fixes: 78f0e33cd6c93 ("fs/namespace: correctly handle errors returned by grab_requested_mnt_ns")
+Signed-off-by: Andrei Vagin <avagin@google.com>
+Link: https://patch.msgid.link/20251122071953.3053755-1-avagin@google.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 035d6f1f0b6ef..c3702f3303a89 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -5345,6 +5345,8 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
+       if (kreq->mnt_ns_id) {
+               mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id);
++              if (!mnt_ns)
++                      return ERR_PTR(-ENOENT);
+       } else if (kreq->mnt_ns_fd) {
+               struct ns_common *ns;
+@@ -5360,13 +5362,12 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
+                       return ERR_PTR(-EINVAL);
+               mnt_ns = to_mnt_ns(ns);
++              refcount_inc(&mnt_ns->passive);
+       } else {
+               mnt_ns = current->nsproxy->mnt_ns;
++              refcount_inc(&mnt_ns->passive);
+       }
+-      if (!mnt_ns)
+-              return ERR_PTR(-ENOENT);
+-      refcount_inc(&mnt_ns->passive);
+       return mnt_ns;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch b/queue-6.12/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
new file mode 100644 (file)
index 0000000..2c3f149
--- /dev/null
@@ -0,0 +1,132 @@
+From 078c2076d76c6541087be5c36b92c07006962abc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 18:16:19 +0200
+Subject: iio: st_lsm6dsx: Fixed calibrated timestamp calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Tesi <martepisa@gmail.com>
+
+[ Upstream commit 8abbf45fcda028c2c05ba38eb14ede9fa9e7341b ]
+
+The calibrated timestamp is calculated from the nominal value using the
+formula:
+  ts_gain[ns] â‰ˆ ts_sensitivity - (ts_trim_coeff * val) / 1000.
+
+The values of ts_sensitivity and ts_trim_coeff are not the same for all
+devices, so it is necessary to differentiate them based on the part name.
+For the correct values please consult the relevant AN.
+
+Fixes: cb3b6b8e1bc0 ("iio: imu: st_lsm6dsx: add odr calibration feature")
+Signed-off-by: Mario Tesi <mario.tesi@st.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h      | 18 ++++++++++++++++++
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 19 ++++++++-----------
+ 2 files changed, 26 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+index a3b93566533bc..6689621b33e05 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+@@ -192,6 +192,22 @@ struct st_lsm6dsx_fifo_ops {
+  * @fifo_en: Hw timer FIFO enable register info (addr + mask).
+  * @decimator: Hw timer FIFO decimator register info (addr + mask).
+  * @freq_fine: Difference in % of ODR with respect to the typical.
++ * @ts_sensitivity: Nominal timestamp sensitivity.
++ * @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
++ *                 This coefficient comes into play when linearizing the formula
++ *                 used to calculate the calibrated timestamp (please see the
++ *                 relevant formula in the AN for the specific IMU).
++ *                 For example, in the case of LSM6DSO we have:
++ *
++ *                  1 / (1 + x) ~= 1 - x (Taylor’s Series)
++ *                  ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
++ *                  ttrim[ns] ~= 25000 - 37.5 * val
++ *                  ttrim[ns] ~= 25000 - (37500 * val) / 1000
++ *
++ *                  so, replacing ts_sensitivity = 25000 and
++ *                  ts_trim_coeff = 37500
++ *
++ *                  ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
+  */
+ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg timer_en;
+@@ -199,6 +215,8 @@ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg fifo_en;
+       struct st_lsm6dsx_reg decimator;
+       u8 freq_fine;
++      u16 ts_sensitivity;
++      u16 ts_trim_coeff;
+ };
+ /**
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index ed02679297252..11e144be85303 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -94,8 +94,6 @@
+ #define ST_LSM6DSX_REG_WHOAMI_ADDR            0x0f
+-#define ST_LSM6DSX_TS_SENSITIVITY             25000UL /* 25us */
+-
+ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+@@ -983,6 +981,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -1196,6 +1196,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .event_settings = {
+                       .enable_reg = {
+@@ -1371,6 +1373,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x4f,
++                      .ts_sensitivity = 21701,
++                      .ts_trim_coeff = 28212,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -2254,20 +2258,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
+       }
+       /* calibrate timestamp sensitivity */
+-      hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
++      hw->ts_gain = ts_settings->ts_sensitivity;
+       if (ts_settings->freq_fine) {
+               err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
+               if (err < 0)
+                       return err;
+-              /*
+-               * linearize the AN5192 formula:
+-               * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
+-               * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
+-               * ttrim[ns] ~= 25000 - 37.5 * val
+-               * ttrim[ns] ~= 25000 - (37500 * val) / 1000
+-               */
+-              hw->ts_gain -= ((s8)val * 37500) / 1000;
++              hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000;
+       }
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.12/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-6.12/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..676a383
--- /dev/null
@@ -0,0 +1,38 @@
+From acd1022d791c2ca3764fc065907ced9ae47df70b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index 3386b4e72551c..e416ce9e2d674 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -268,7 +268,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch b/queue-6.12/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch
new file mode 100644 (file)
index 0000000..140a9e3
--- /dev/null
@@ -0,0 +1,169 @@
+From 5910dafc0cfebfed985bc202989112557eb28678 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 01:16:30 +0800
+Subject: mailbox: mtk-cmdq: Refine DMA address handling for the command buffer
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit a195c7ccfb7a21b8118139835e25936ec8722596 ]
+
+GCE can only fetch the command buffer address from a 32-bit register.
+Some SoCs support a 35-bit command buffer address for GCE, which
+requires a right shift of 3 bits before setting the address into
+the 32-bit register. A comment has been added to the header of
+cmdq_get_shift_pa() to explain this requirement.
+
+To prevent the GCE command buffer address from being DMA mapped beyond
+its supported bit range, the DMA bit mask for the device is set during
+initialization.
+
+Additionally, to ensure the correct shift is applied when setting or
+reading the register that stores the GCE command buffer address,
+new APIs, cmdq_convert_gce_addr() and cmdq_revert_gce_addr(), have
+been introduced for consistent operations on this register.
+
+The variable type for the command buffer address has been standardized
+to dma_addr_t to prevent handling issues caused by type mismatches.
+
+Fixes: 0858fde496f8 ("mailbox: cmdq: variablize address shift in platform")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mtk-cmdq-mailbox.c       | 45 ++++++++++++++++--------
+ include/linux/mailbox/mtk-cmdq-mailbox.h | 10 ++++++
+ 2 files changed, 41 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
+index 38ab35157c85f..80a10361492b0 100644
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c
+@@ -92,6 +92,18 @@ struct gce_plat {
+       u32 gce_num;
+ };
++static inline u32 cmdq_convert_gce_addr(dma_addr_t addr, const struct gce_plat *pdata)
++{
++      /* Convert DMA addr (PA or IOVA) to GCE readable addr */
++      return addr >> pdata->shift;
++}
++
++static inline dma_addr_t cmdq_revert_gce_addr(u32 addr, const struct gce_plat *pdata)
++{
++      /* Revert GCE readable addr to DMA addr (PA or IOVA) */
++      return (dma_addr_t)addr << pdata->shift;
++}
++
+ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+ {
+       struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+@@ -188,13 +200,12 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
+       struct cmdq_task *prev_task = list_last_entry(
+                       &thread->task_busy_list, typeof(*task), list_entry);
+       u64 *prev_task_base = prev_task->pkt->va_base;
++      u32 gce_addr = cmdq_convert_gce_addr(task->pa_base, task->cmdq->pdata);
+       /* let previous task jump to this task */
+       dma_sync_single_for_cpu(dev, prev_task->pa_base,
+                               prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+-      prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
+-              (u64)CMDQ_JUMP_BY_PA << 32 |
+-              (task->pa_base >> task->cmdq->pdata->shift);
++      prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] = (u64)CMDQ_JUMP_BY_PA << 32 | gce_addr;
+       dma_sync_single_for_device(dev, prev_task->pa_base,
+                                  prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+@@ -237,7 +248,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+                                   struct cmdq_thread *thread)
+ {
+       struct cmdq_task *task, *tmp, *curr_task = NULL;
+-      u32 curr_pa, irq_flag, task_end_pa;
++      u32 irq_flag, gce_addr;
++      dma_addr_t curr_pa, task_end_pa;
+       bool err;
+       irq_flag = readl(thread->base + CMDQ_THR_IRQ_STATUS);
+@@ -259,7 +271,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+       else
+               return;
+-      curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
++      gce_addr = readl(thread->base + CMDQ_THR_CURR_ADDR);
++      curr_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
+       list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+                                list_entry) {
+@@ -378,7 +391,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+       struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+       struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+       struct cmdq_task *task;
+-      unsigned long curr_pa, end_pa;
++      u32 gce_addr;
++      dma_addr_t curr_pa, end_pa;
+       /* Client should not flush new tasks if suspended. */
+       WARN_ON(cmdq->suspended);
+@@ -402,20 +416,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+                */
+               WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
+-              writel(task->pa_base >> cmdq->pdata->shift,
+-                     thread->base + CMDQ_THR_CURR_ADDR);
+-              writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
+-                     thread->base + CMDQ_THR_END_ADDR);
++              gce_addr = cmdq_convert_gce_addr(task->pa_base, cmdq->pdata);
++              writel(gce_addr, thread->base + CMDQ_THR_CURR_ADDR);
++              gce_addr = cmdq_convert_gce_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata);
++              writel(gce_addr, thread->base + CMDQ_THR_END_ADDR);
+               writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
+               writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
+               writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+       } else {
+               WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+-              curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+-                      cmdq->pdata->shift;
+-              end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+-                      cmdq->pdata->shift;
++              gce_addr = readl(thread->base + CMDQ_THR_CURR_ADDR);
++              curr_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
++              gce_addr = readl(thread->base + CMDQ_THR_END_ADDR);
++              end_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
+               /* check boundary */
+               if (curr_pa == end_pa - CMDQ_INST_SIZE ||
+                   curr_pa == end_pa) {
+@@ -646,6 +660,9 @@ static int cmdq_probe(struct platform_device *pdev)
+       if (err)
+               return err;
++      dma_set_coherent_mask(dev,
++                            DMA_BIT_MASK(sizeof(u32) * BITS_PER_BYTE + cmdq->pdata->shift));
++
+       cmdq->mbox.dev = dev;
+       cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr,
+                                       sizeof(*cmdq->mbox.chans), GFP_KERNEL);
+diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
+index a8f0070c7aa98..9914dcd33e2d9 100644
+--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
++++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
+@@ -78,6 +78,16 @@ struct cmdq_pkt {
+       void                    *cl;
+ };
++/**
++ * cmdq_get_shift_pa() - get the shift bits of physical address
++ * @chan: mailbox channel
++ *
++ * GCE can only fetch the command buffer address from a 32-bit register.
++ * Some SOCs support more than 32-bit command buffer address for GCE, which
++ * requires some shift bits to make the address fit into the 32-bit register.
++ *
++ * Return: the shift bits of physical address
++ */
+ u8 cmdq_get_shift_pa(struct mbox_chan *chan);
+ #endif /* __MTK_CMDQ_MAILBOX_H__ */
+-- 
+2.51.0
+
diff --git a/queue-6.12/mailbox-pcc-don-t-zero-error-register.patch b/queue-6.12/mailbox-pcc-don-t-zero-error-register.patch
new file mode 100644 (file)
index 0000000..984ec90
--- /dev/null
@@ -0,0 +1,57 @@
+From a9e2d7a5c04ab0f50d71d0f1deba045f9348b61a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:42:29 +0000
+Subject: mailbox: pcc: don't zero error register
+
+From: Jamie Iles <jamie.iles@oss.qualcomm.com>
+
+[ Upstream commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 ]
+
+The error status mask for a type 3/4 subspace is used for reading the
+error status, and the bitwise inverse is used for clearing the error
+with the intent being to preserve any of the non-error bits.  However,
+we were previously applying the mask to extract the status and then
+applying the inverse to the result which ended up clearing all bits.
+
+Instead, store the inverse mask in the preserve mask and then use that
+on the original value read from the error status so that only the error
+is cleared.
+
+Fixes: c45ded7e1135 ("mailbox: pcc: Add support for PCCT extended PCC subspaces(type 3/4)")
+Signed-off-by: Jamie Iles <jamie.iles@oss.qualcomm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@oss.qualcomm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index bb977cf8ad423..2b7d0bc920726 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -278,9 +278,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
+       if (ret)
+               return ret;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
++      if (val & pchan->error.status_mask) {
++              val &= pchan->error.preserve_mask;
+               pcc_chan_reg_write(&pchan->error, val);
+               return -EIO;
+       }
+@@ -673,7 +672,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
+               ret = pcc_chan_reg_init(&pchan->error,
+                                       &pcct_ext->error_status_register,
+-                                      0, 0, pcct_ext->error_status_mask,
++                                      ~pcct_ext->error_status_mask, 0,
++                                      pcct_ext->error_status_mask,
+                                       "Error Status");
+       }
+       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.12/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch b/queue-6.12/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
new file mode 100644 (file)
index 0000000..fbe339c
--- /dev/null
@@ -0,0 +1,92 @@
+From 3a9cae1572b1b430772cbf437f495e081abad781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 15:28:52 +0000
+Subject: mailbox: pcc: Refactor error handling in irq handler into separate
+ function
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 3a675f50415b95f2ae10bfd932e2154ba1a08ee7 ]
+
+The existing error handling logic in pcc_mbox_irq() is intermixed with the
+main flow of the function. The command complete check and the complete
+complete update/acknowledgment are nicely factored into separate functions.
+
+Moves error detection and clearing logic into a separate function called:
+pcc_mbox_error_check_and_clear() by extracting error-handling logic from
+pcc_mbox_irq().
+
+This ensures error checking and clearing are handled separately and it
+improves maintainability by keeping the IRQ handler focused on processing
+events.
+
+Acked-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Adam Young <admiyo@os.amperecomputing.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 49254d99a8ad6..bb977cf8ad423 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -269,6 +269,25 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+       return !!val;
+ }
++static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
++{
++      u64 val;
++      int ret;
++
++      ret = pcc_chan_reg_read(&pchan->error, &val);
++      if (ret)
++              return ret;
++
++      val &= pchan->error.status_mask;
++      if (val) {
++              val &= ~pchan->error.status_mask;
++              pcc_chan_reg_write(&pchan->error, val);
++              return -EIO;
++      }
++
++      return 0;
++}
++
+ static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
+ {
+       struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
+@@ -309,8 +328,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+ {
+       struct pcc_chan_info *pchan;
+       struct mbox_chan *chan = p;
+-      u64 val;
+-      int ret;
+       pchan = chan->con_priv;
+@@ -324,15 +341,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+-      ret = pcc_chan_reg_read(&pchan->error, &val);
+-      if (ret)
++      if (pcc_mbox_error_check_and_clear(pchan))
+               return IRQ_NONE;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
+-              pcc_chan_reg_write(&pchan->error, val);
+-              return IRQ_NONE;
+-      }
+       /*
+        * Clear this flag after updating interrupt ack register and just
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-6.12/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..7cd6b6e
--- /dev/null
@@ -0,0 +1,144 @@
+From f6f30312746dc9fbda75909231ecad06c43609db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 56c46266bb0ae..3a0b6d65d5fca 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index b0ed572e88c67..0ce9caae8799c 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-6.12/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..4b4b41c
--- /dev/null
@@ -0,0 +1,93 @@
+From 9d204ddeac9473a0cef886508d2fa3d65dfc6267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index f21de0c21e524..d23d23bed39fe 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch b/queue-6.12/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
new file mode 100644 (file)
index 0000000..64562fc
--- /dev/null
@@ -0,0 +1,73 @@
+From 8a5d9d136f5c005aaf122ee93d28ba166d52e79b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 13:13:24 +0200
+Subject: net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing
+ traffic
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
+
+When using the SGMII PCS as a fixed-link chip-to-chip connection, it is
+easy to miss the fact that traffic passes only at 1G, since that's what
+any normal such connection would use.
+
+When using the SGMII PCS connected towards an on-board PHY or an SFP
+module, it is immediately noticeable that when the link resolves to a
+speed other than 1G, traffic from the MAC fails to pass: TX counters
+increase, but nothing gets decoded by the other end, and no local RX
+counters increase either.
+
+Artificially lowering a fixed-link rate to speed = <100> makes us able
+to see the same issue as in the case of having an SGMII PHY.
+
+Some debugging shows that the XPCS configuration is A-OK, but that the
+MAC Configuration Table entry for the port has the SPEED bits still set
+to 1000Mbps, due to a special condition in the driver. Deleting that
+condition, and letting the resolved link speed be programmed directly
+into the MAC speed field, results in a functional link at all 3 speeds.
+
+This piece of evidence, based on testing on both generations with SGMII
+support (SJA1105S and SJA1110A) directly contradicts the statement from
+the blamed commit that "the MAC is fixed at 1 Gbps and we need to
+configure the PCS only (if even that)". Worse, that statement is not
+backed by any documentation, and no one from NXP knows what it might
+refer to.
+
+I am unable to recall sufficient context regarding my testing from March
+2020 to understand what led me to draw such a braindead and factually
+incorrect conclusion. Yet, there is nothing of value regarding forcing
+the MAC speed, either for SGMII or 2500Base-X (introduced at a later
+stage), so remove all such logic.
+
+Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index f3bb49a9e63c0..a078653531b51 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1303,14 +1303,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
+        * table, since this will be used for the clocking setup, and we no
+        * longer need to store it in the static config (already told hardware
+        * we want auto during upload phase).
+-       * Actually for the SGMII port, the MAC is fixed at 1 Gbps and
+-       * we need to configure the PCS only (if even that).
+        */
+-      if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+-      else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-
+       mac[port].speed = speed;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-dsa-sja1105-simplify-static-configuration-reload.patch b/queue-6.12/net-dsa-sja1105-simplify-static-configuration-reload.patch
new file mode 100644 (file)
index 0000000..ca84163
--- /dev/null
@@ -0,0 +1,159 @@
+From daabb4df84ed9210d4630eb7f07baedc6e909a97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 17:04:36 +0100
+Subject: net: dsa: sja1105: simplify static configuration reload
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit a18891b55703a45b700618ef40edd5e9aaecc345 ]
+
+The static configuration reload saves the port speed in the static
+configuration tables by first converting it from the internal
+respresentation to the SPEED_xxx ethtool representation, and then
+converts it back to restore the setting. This is because
+sja1105_adjust_port_config() takes the speed as SPEED_xxx.
+
+However, this is unnecessarily complex. If we split
+sja1105_adjust_port_config() up, we can simply save and restore the
+mac[port].speed member in the static configuration tables.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------
+ 1 file changed, 34 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index fbac2a647b20b..f3bb49a9e63c0 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1257,29 +1257,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)
+       return rc;
+ }
+-/* Convert link speed from SJA1105 to ethtool encoding */
+-static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv,
+-                                       u64 speed)
+-{
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS])
+-              return SPEED_10;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS])
+-              return SPEED_100;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS])
+-              return SPEED_1000;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS])
+-              return SPEED_2500;
+-      return SPEED_UNKNOWN;
+-}
+-
+-/* Set link speed in the MAC configuration for a specific port. */
+-static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+-                                    int speed_mbps)
++static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
++                                int speed_mbps)
+ {
+       struct sja1105_mac_config_entry *mac;
+-      struct device *dev = priv->ds->dev;
+       u64 speed;
+-      int rc;
+       /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
+        * tables. On E/T, MAC reconfig tables are not readable, only writable.
+@@ -1313,7 +1295,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+               speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+               break;
+       default:
+-              dev_err(dev, "Invalid speed %iMbps\n", speed_mbps);
++              dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps);
+               return -EINVAL;
+       }
+@@ -1325,11 +1307,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+        * we need to configure the PCS only (if even that).
+        */
+       if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
++              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+       else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-      else
+-              mac[port].speed = speed;
++              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
++
++      mac[port].speed = speed;
++
++      return 0;
++}
++
++/* Write the MAC Configuration Table entry and, if necessary, the CGU settings,
++ * after a link speedchange for this port.
++ */
++static int sja1105_set_port_config(struct sja1105_private *priv, int port)
++{
++      struct sja1105_mac_config_entry *mac;
++      struct device *dev = priv->ds->dev;
++      int rc;
++
++      /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
++       * tables. On E/T, MAC reconfig tables are not readable, only writable.
++       * We have to *know* what the MAC looks like.  For the sake of keeping
++       * the code common, we'll use the static configuration tables as a
++       * reasonable approximation for both E/T and P/Q/R/S.
++       */
++      mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+       /* Write to the dynamic reconfiguration tables */
+       rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+@@ -1390,7 +1392,8 @@ static void sja1105_mac_link_up(struct phylink_config *config,
+       struct sja1105_private *priv = dp->ds->priv;
+       int port = dp->index;
+-      sja1105_adjust_port_config(priv, port, speed);
++      if (!sja1105_set_port_speed(priv, port, speed))
++              sja1105_set_port_config(priv, port);
+       sja1105_inhibit_tx(priv, BIT(port), false);
+ }
+@@ -2289,8 +2292,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+ {
+       struct ptp_system_timestamp ptp_sts_before;
+       struct ptp_system_timestamp ptp_sts_after;
+-      int speed_mbps[SJA1105_MAX_NUM_PORTS];
+       u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0};
++      u64 mac_speed[SJA1105_MAX_NUM_PORTS];
+       struct sja1105_mac_config_entry *mac;
+       struct dsa_switch *ds = priv->ds;
+       s64 t1, t2, t3, t4;
+@@ -2303,14 +2306,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+       mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+-      /* Back up the dynamic link speed changed by sja1105_adjust_port_config
++      /* Back up the dynamic link speed changed by sja1105_set_port_speed()
+        * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the
+        * switch wants to see in the static config in order to allow us to
+        * change it through the dynamic interface later.
+        */
+       for (i = 0; i < ds->num_ports; i++) {
+-              speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
+-                                                            mac[i].speed);
++              mac_speed[i] = mac[i].speed;
+               mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];
+               if (priv->xpcs[i])
+@@ -2373,7 +2375,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+               struct dw_xpcs *xpcs = priv->xpcs[i];
+               unsigned int neg_mode;
+-              rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
++              mac[i].speed = mac_speed[i];
++              rc = sja1105_set_port_config(priv, i);
+               if (rc < 0)
+                       goto out;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-cancel-perout_timer-when-perout-is-disabled.patch b/queue-6.12/net-fec-cancel-perout_timer-when-perout-is-disabled.patch
new file mode 100644 (file)
index 0000000..b8ba6d5
--- /dev/null
@@ -0,0 +1,42 @@
+From 9e17d38c2f980c5a26030649086f6a67013de11f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:07 +0800
+Subject: net: fec: cancel perout_timer when PEROUT is disabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 50caa744689e505414673c20359b04aa918439e3 ]
+
+The PEROUT allows the user to set a specified future time to output the
+periodic signal. If the future time is far from the current time, the FEC
+driver will use hrtimer to configure PEROUT one second before the future
+time. However, the hrtimer will not be canceled if the PEROUT is disabled
+before the hrtimer expires. So the PEROUT will be configured when the
+hrtimer expires, which is not as expected. Therefore, cancel the hrtimer
+in fec_ptp_pps_disable() to fix this issue.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-2-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index 7f6b574320716..cb3f05da3eee6 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -498,6 +498,8 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+ {
+       unsigned long flags;
++      hrtimer_cancel(&fep->perout_timer);
++
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch b/queue-6.12/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
new file mode 100644 (file)
index 0000000..97eb437
--- /dev/null
@@ -0,0 +1,58 @@
+From dedd616c8f583437908bb4dd7ab7dfc3bd27e95b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:09 +0800
+Subject: net: fec: do not allow enabling PPS and PEROUT simultaneously
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit c0a1f3d7e128e8d1b6c0fe09c68eac5ebcf677c8 ]
+
+In the current driver, PPS and PEROUT use the same channel to generate
+the events, so they cannot be enabled at the same time. Otherwise, the
+later configuration will overwrite the earlier configuration. Therefore,
+when configuring PPS, the driver will check whether PEROUT is enabled.
+Similarly, when configuring PEROUT, the driver will check whether PPS
+is enabled.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-4-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index a3853fccdc7b6..beb1d98fa741a 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -129,6 +129,12 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      if (fep->perout_enable) {
++              spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++              dev_err(&fep->pdev->dev, "PEROUT is running");
++              return -EBUSY;
++      }
++
+       if (fep->pps_enable == enable) {
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return 0;
+@@ -572,6 +578,12 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++                      if (fep->pps_enable) {
++                              dev_err(&fep->pdev->dev, "PPS is running");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       if (fep->perout_enable) {
+                               dev_err(&fep->pdev->dev,
+                                       "PEROUT has been enabled\n");
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-do-not-register-pps-event-for-perout.patch b/queue-6.12/net-fec-do-not-register-pps-event-for-perout.patch
new file mode 100644 (file)
index 0000000..daf6a1f
--- /dev/null
@@ -0,0 +1,48 @@
+From 858da6f8f5f0cb23b937dc1620577a1861726ec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:10 +0800
+Subject: net: fec: do not register PPS event for PEROUT
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 9a060d0fac9e75524f72864adec6d8cdb70a5bca ]
+
+There are currently two situations that can trigger the PTP interrupt,
+one is the PPS event, the other is the PEROUT event. However, the irq
+handler fec_pps_interrupt() does not check the irq event type and
+directly registers a PPS event into the system, but the event may be
+a PEROUT event. This is incorrect because PEROUT is an output signal,
+while PPS is the input of the kernel PPS system. Therefore, add a check
+for the event type, if pps_enable is true, it means that the current
+event is a PPS event, and then the PPS event is registered.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-5-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index beb1d98fa741a..4bb894b5afcb9 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -719,8 +719,11 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id)
+               fep->next_counter = (fep->next_counter + fep->reload_period) &
+                               fep->cc.mask;
+-              event.type = PTP_CLOCK_PPS;
+-              ptp_clock_event(fep->ptp_clock, &event);
++              if (fep->pps_enable) {
++                      event.type = PTP_CLOCK_PPS;
++                      ptp_clock_event(fep->ptp_clock, &event);
++              }
++
+               return IRQ_HANDLED;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-do-not-update-perout-if-it-is-enabled.patch b/queue-6.12/net-fec-do-not-update-perout-if-it-is-enabled.patch
new file mode 100644 (file)
index 0000000..d1f1d5f
--- /dev/null
@@ -0,0 +1,137 @@
+From e2342f4b379e8b069528f3b9d1f1d6264886ff5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:08 +0800
+Subject: net: fec: do not update PEROUT if it is enabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e97faa0c20ea8840f45569ba434e30538fff8fc9 ]
+
+If the previously set PEROUT is already active, updating it will cause
+the new PEROUT to start immediately instead of at the specified time.
+This is because fep->reload_period is updated whithout check whether
+the PEROUT is enabled, and the old PEROUT is not disabled. Therefore,
+the pulse period will be updated immediately in the pulse interrupt
+handler fec_pps_interrupt().
+
+Currently, the driver does not support directly updating PEROUT and it
+will make the logic be more complicated. To fix the current issue, add
+a check before enabling the PEROUT, the driver will return an error if
+PEROUT is enabled. If users wants to update a new PEROUT, they should
+disable the old PEROUT first.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-3-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec.h     |  1 +
+ drivers/net/ethernet/freescale/fec_ptp.c | 43 ++++++++++++++++++------
+ 2 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 1cca0425d4939..03fa6d6e6f0a8 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -683,6 +683,7 @@ struct fec_enet_private {
+       unsigned int reload_period;
+       int pps_enable;
+       unsigned int next_counter;
++      bool perout_enable;
+       struct hrtimer perout_timer;
+       u64 perout_stime;
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index cb3f05da3eee6..a3853fccdc7b6 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -244,6 +244,7 @@ static int fec_ptp_pps_perout(struct fec_enet_private *fep)
+        * the FEC_TCCR register in time and missed the start time.
+        */
+       if (fep->perout_stime < curr_time + 100 * NSEC_PER_MSEC) {
++              fep->perout_enable = false;
+               dev_err(&fep->pdev->dev, "Current time is too close to the start time!\n");
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return -1;
+@@ -501,6 +502,7 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+       hrtimer_cancel(&fep->perout_timer);
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      fep->perout_enable = false;
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+@@ -532,6 +534,8 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+               return ret;
+       } else if (rq->type == PTP_CLK_REQ_PEROUT) {
++              u32 reload_period;
++
+               /* Reject requests with unsupported flags */
+               if (rq->perout.flags)
+                       return -EOPNOTSUPP;
+@@ -551,12 +555,14 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       return -EOPNOTSUPP;
+               }
+-              fep->reload_period = div_u64(period_ns, 2);
+-              if (on && fep->reload_period) {
++              reload_period = div_u64(period_ns, 2);
++              if (on && reload_period) {
++                      u64 perout_stime;
++
+                       /* Convert 1588 timestamp to ns*/
+                       start_time.tv_sec = rq->perout.start.sec;
+                       start_time.tv_nsec = rq->perout.start.nsec;
+-                      fep->perout_stime = timespec64_to_ns(&start_time);
++                      perout_stime = timespec64_to_ns(&start_time);
+                       mutex_lock(&fep->ptp_clk_mutex);
+                       if (!fep->ptp_clk_on) {
+@@ -565,18 +571,35 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                               return -EOPNOTSUPP;
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++
++                      if (fep->perout_enable) {
++                              dev_err(&fep->pdev->dev,
++                                      "PEROUT has been enabled\n");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       /* Read current timestamp */
+                       curr_time = timecounter_read(&fep->tc);
+-                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-                      mutex_unlock(&fep->ptp_clk_mutex);
++                      if (perout_stime <= curr_time) {
++                              dev_err(&fep->pdev->dev,
++                                      "Start time must be greater than current time\n");
++                              ret = -EINVAL;
++                              goto unlock;
++                      }
+                       /* Calculate time difference */
+-                      delta = fep->perout_stime - curr_time;
++                      delta = perout_stime - curr_time;
++                      fep->reload_period = reload_period;
++                      fep->perout_stime = perout_stime;
++                      fep->perout_enable = true;
+-                      if (fep->perout_stime <= curr_time) {
+-                              dev_err(&fep->pdev->dev, "Start time must larger than current time!\n");
+-                              return -EINVAL;
+-                      }
++unlock:
++                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++                      mutex_unlock(&fep->ptp_clk_mutex);
++
++                      if (ret)
++                              return ret;
+                       /* Because the timer counter of FEC only has 31-bits, correspondingly,
+                        * the time comparison register FEC_TCCR also only low 31 bits can be
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-lan966x-fix-the-initialization-of-taprio.patch b/queue-6.12/net-lan966x-fix-the-initialization-of-taprio.patch
new file mode 100644 (file)
index 0000000..dfdf193
--- /dev/null
@@ -0,0 +1,56 @@
+From d8167e280e823bec74617a9b0ec81f80f8115fdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 07:14:11 +0100
+Subject: net: lan966x: Fix the initialization of taprio
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 ]
+
+To initialize the taprio block in lan966x, it is required to configure
+the register REVISIT_DLY. The purpose of this register is to set the
+delay before revisit the next gate and the value of this register depends
+on the system clock. The problem is that the we calculated wrong the value
+of the system clock period in picoseconds. The actual system clock is
+~165.617754MHZ and this correspond to a period of 6038 pico seconds and
+not 15125 as currently set.
+
+Fixes: e462b2717380b4 ("net: lan966x: Add offload support for taprio")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121061411.810571-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index 87e5e81d40dc6..84f5b4410e48e 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -1,11 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/ptp_classify.h>
++#include <linux/units.h>
+ #include "lan966x_main.h"
+ #include "vcap_api.h"
+ #include "vcap_api_client.h"
++#define LAN9X66_CLOCK_RATE    165617754
++
+ #define LAN966X_MAX_PTP_ID    512
+ /* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
+@@ -1132,5 +1135,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u32 lan966x_ptp_get_period_ps(void)
+ {
+       /* This represents the system clock period in picoseconds */
+-      return 15125;
++      return PICO / LAN9X66_CLOCK_RATE;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-6.12/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..49027be
--- /dev/null
@@ -0,0 +1,63 @@
+From 2e87d68851a5163272c3db1a7dd38470debeca97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 2ca32fb1961e1..84e700777941e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -627,7 +627,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch b/queue-6.12/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
new file mode 100644 (file)
index 0000000..efa8661
--- /dev/null
@@ -0,0 +1,42 @@
+From 87e97999cb5188ca95aeced3e7bfa12815a1ceb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 14:17:13 +0000
+Subject: net: phy: mxl-gpy: fix bogus error on USXGMII and integrated PHY
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit ec3803b5917b6ff2f86ea965d0985c95d8a85119 ]
+
+As the interface mode doesn't need to be updated on PHYs connected with
+USXGMII and integrated PHYs, gpy_update_interface() should just return 0
+in these cases rather than -EINVAL which has wrongly been introduced by
+commit 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface()
+function return type"), as this breaks support for those PHYs.
+
+Fixes: 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface() function return type")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/f744f721a1fcc5e2e936428c62ff2c7d94d2a293.1763648168.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mxl-gpy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index e5f8ac4b4604b..17b0654644de5 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -523,7 +523,7 @@ static int gpy_update_interface(struct phy_device *phydev)
+       /* Interface mode is fixed for USXGMII and integrated PHY */
+       if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
+           phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
+-              return -EINVAL;
++              return 0;
+       /* Automatically switch SERDES interface between SGMII and 2500-BaseX
+        * according to speed. Disable ANEG in 2500-BaseX mode.
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sched-generalize-check-for-no-queue-qdisc-on-tx-.patch b/queue-6.12/net-sched-generalize-check-for-no-queue-qdisc-on-tx-.patch
new file mode 100644 (file)
index 0000000..be14e13
--- /dev/null
@@ -0,0 +1,93 @@
+From 9b66850e20d804ced348db390eff4e42dcfa2db7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 16:55:31 +0200
+Subject: net: sched: generalize check for no-queue qdisc on TX queue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit 34dd0fecaa02d654c447d43a7e4c72f9b18b7033 ]
+
+The "noqueue" qdisc can either be directly attached, or get default
+attached if net_device priv_flags has IFF_NO_QUEUE. In both cases, the
+allocated Qdisc structure gets it's enqueue function pointer reset to
+NULL by noqueue_init() via noqueue_qdisc_ops.
+
+This is a common case for software virtual net_devices. For these devices
+with no-queue, the transmission path in __dev_queue_xmit() will bypass
+the qdisc layer. Directly invoking device drivers ndo_start_xmit (via
+dev_hard_start_xmit).  In this mode the device driver is not allowed to
+ask for packets to be queued (either via returning NETDEV_TX_BUSY or
+stopping the TXQ).
+
+The simplest and most reliable way to identify this no-queue case is by
+checking if enqueue == NULL.
+
+The vrf driver currently open-codes this check (!qdisc->enqueue). While
+functionally correct, this low-level detail is better encapsulated in a
+dedicated helper for clarity and long-term maintainability.
+
+To make this behavior more explicit and reusable, this patch introduce a
+new helper: qdisc_txq_has_no_queue(). Helper will also be used by the
+veth driver in the next patch, which introduces optional qdisc-based
+backpressure.
+
+This is a non-functional change.
+
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/174559293172.827981.7583862632045264175.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a14602fcae17 ("veth: reduce XDP no_direct return section to fix race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vrf.c         | 4 +---
+ include/net/sch_generic.h | 8 ++++++++
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 89dde220058a2..b62462d8eff26 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -352,15 +352,13 @@ static int vrf_ifindex_lookup_by_table_id(struct net *net, u32 table_id)
+ static bool qdisc_tx_is_default(const struct net_device *dev)
+ {
+       struct netdev_queue *txq;
+-      struct Qdisc *qdisc;
+       if (dev->num_tx_queues > 1)
+               return false;
+       txq = netdev_get_tx_queue(dev, 0);
+-      qdisc = rcu_access_pointer(txq->qdisc);
+-      return !qdisc->enqueue;
++      return qdisc_txq_has_no_queue(txq);
+ }
+ /* Local traffic destined to local address. Reinsert the packet to rx
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index a9d7e9ecee6b5..1e002b1dea629 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -803,6 +803,14 @@ static inline bool qdisc_tx_changing(const struct net_device *dev)
+       return false;
+ }
++/* "noqueue" qdisc identified by not having any enqueue, see noqueue_init() */
++static inline bool qdisc_txq_has_no_queue(const struct netdev_queue *txq)
++{
++      struct Qdisc *qdisc = rcu_access_pointer(txq->qdisc);
++
++      return qdisc->enqueue == NULL;
++}
++
+ /* Is the device using the noop qdisc on all queues?  */
+ static inline bool qdisc_tx_is_noop(const struct net_device *dev)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-6.12/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..a7a3670
--- /dev/null
@@ -0,0 +1,47 @@
+From 8171f61800bbaca80129765f10f323b2665e05ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index 12c8396b6942d..d2ba283f6123f 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1520,8 +1520,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch b/queue-6.12/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch
new file mode 100644 (file)
index 0000000..20ba137
--- /dev/null
@@ -0,0 +1,39 @@
+From 64f442434126357abc7bc388b5c84d354375f63c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 15:09:00 +0800
+Subject: net: wwan: mhi: Keep modem name match with Foxconn T99W640
+
+From: Slark Xiao <slark_xiao@163.com>
+
+[ Upstream commit 4fcb8ab4a09b1855dbfd7062605dd13abd64c086 ]
+
+Correct it since M.2 device T99W640 has updated from T99W515.
+We need to align it with MHI side otherwise this modem can't
+get the network.
+
+Fixes: ae5a34264354 ("bus: mhi: host: pci_generic: Fix the modem name of Foxconn T99W640")
+Signed-off-by: Slark Xiao <slark_xiao@163.com>
+Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251125070900.33324-1-slark_xiao@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wwan/mhi_wwan_mbim.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
+index c814fbd756a1e..f8bc9a39bfa30 100644
+--- a/drivers/net/wwan/mhi_wwan_mbim.c
++++ b/drivers/net/wwan/mhi_wwan_mbim.c
+@@ -98,7 +98,7 @@ static struct mhi_mbim_link *mhi_mbim_get_link_rcu(struct mhi_mbim_context *mbim
+ static int mhi_mbim_get_link_mux_id(struct mhi_controller *cntrl)
+ {
+       if (strcmp(cntrl->name, "foxconn-dw5934e") == 0 ||
+-          strcmp(cntrl->name, "foxconn-t99w515") == 0)
++          strcmp(cntrl->name, "foxconn-t99w640") == 0)
+               return WDS_BIND_MUX_DATA_PORT_MUX_ID;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.12/platform-x86-intel-punit_ipc-fix-memory-corruption.patch b/queue-6.12/platform-x86-intel-punit_ipc-fix-memory-corruption.patch
new file mode 100644 (file)
index 0000000..decd78f
--- /dev/null
@@ -0,0 +1,46 @@
+From 1ca2959c0ce20254654f5be5245e6d2b794f750f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 20:51:28 +0300
+Subject: platform/x86: intel: punit_ipc: fix memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
+
+This passes the address of the pointer "&punit_ipcdev" when the intent
+was to pass the pointer itself "punit_ipcdev" (without the ampersand).
+This means that the:
+
+       complete(&ipcdev->cmd_complete);
+
+in intel_punit_ioc() will write to a wrong memory address corrupting it.
+
+Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/punit_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
+index cd0ba84cc8e4a..9e48229538a5e 100644
+--- a/drivers/platform/x86/intel/punit_ipc.c
++++ b/drivers/platform/x86/intel/punit_ipc.c
+@@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
+       } else {
+               ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+                                      IRQF_NO_SUSPEND, "intel_punit_ipc",
+-                                     &punit_ipcdev);
++                                     punit_ipcdev);
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.12/series b/queue-6.12/series
new file mode 100644 (file)
index 0000000..d7c4f1f
--- /dev/null
@@ -0,0 +1,48 @@
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-29525
+bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch
+bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch
+bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+net-sched-generalize-check-for-no-queue-qdisc-on-tx-.patch
+veth-apply-qdisc-backpressure-on-full-ptr_ring-to-re.patch
+veth-prevent-null-pointer-dereference-in-veth_xdp_rc.patch
+veth-more-robust-handing-of-race-to-avoid-txq-gettin.patch
+veth-reduce-xdp-no_direct-return-section-to-fix-race.patch
+net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
+platform-x86-intel-punit_ipc-fix-memory-corruption.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-lan966x-fix-the-initialization-of-taprio.patch
+drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+team-move-team-device-type-change-at-the-end-of-team.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
+net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch
+net-dsa-sja1105-simplify-static-configuration-reload.patch
+net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
+eth-fbnic-fix-counter-roll-over-issue.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+net-fec-cancel-perout_timer-when-perout-is-disabled.patch
+net-fec-do-not-update-perout-if-it-is-enabled.patch
+net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
+net-fec-do-not-register-pps-event-for-perout.patch
+iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
+usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch
+mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
+mailbox-pcc-don-t-zero-error-register.patch
+fs-namespace-fix-reference-leak-in-grab_requested_mn.patch
+spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
+spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
+spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch
+spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch
+spi-spi-mem-add-a-new-controller-capability.patch
+spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch
+spi-spi-nxp-fspi-remove-the-goto-in-probe.patch
+spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch
+spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
diff --git a/queue-6.12/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch b/queue-6.12/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
new file mode 100644 (file)
index 0000000..291fbc0
--- /dev/null
@@ -0,0 +1,42 @@
+From d02ea71712ac6d7278d2c9952421151a109e3ea8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 09:58:52 +0800
+Subject: spi: amlogic-spifc-a1: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit a90903c2a3c38bce475f46ea3f93dbf6a9971553 ]
+
+devm_pm_runtime_enable() can fail due to memory allocation. The current
+code ignores its return value, potentially causing runtime PM operations
+to fail silently after autosuspend configuration.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 909fac05b926 ("spi: add support for Amlogic A1 SPI Flash Controller")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20251124015852.937-1-vulab@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-amlogic-spifc-a1.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c
+index fadf6667cd51c..b430bca4f8bce 100644
+--- a/drivers/spi/spi-amlogic-spifc-a1.c
++++ b/drivers/spi/spi-amlogic-spifc-a1.c
+@@ -349,7 +349,9 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
+       pm_runtime_set_autosuspend_delay(spifc->dev, 500);
+       pm_runtime_use_autosuspend(spifc->dev);
+-      devm_pm_runtime_enable(spifc->dev);
++      ret = devm_pm_runtime_enable(spifc->dev);
++      if (ret)
++              return ret;
+       ctrl->num_chipselect = 1;
+       ctrl->dev.of_node = pdev->dev.of_node;
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-6.12/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..eb3f13d
--- /dev/null
@@ -0,0 +1,68 @@
+From fdb8049d0611c0c32852f7d681ea8b09dc3e1b7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index a95badb7b7114..ba66fe9f1f543 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch b/queue-6.12/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
new file mode 100644 (file)
index 0000000..c390a5f
--- /dev/null
@@ -0,0 +1,78 @@
+From 8c154dd6ae76e73b331b36ebf0efe10212a83add Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:25:01 +0100
+Subject: spi: nxp-fspi: Propagate fwnode in ACPI case as well
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 40ad64ac25bb736740f895d99a4aebbda9b80991 ]
+
+Propagate fwnode of the ACPI device to the SPI controller Linux device.
+Currently only OF case propagates fwnode to the controller.
+
+While at it, replace several calls to dev_fwnode() with a single one
+cached in a local variable, and unify checks for fwnode type by using
+is_*_node() APIs.
+
+Fixes: 55ab8487e01d ("spi: spi-nxp-fspi: Add ACPI support")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20251126202501.2319679-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 6cdeee9c581bd..5100b189c9050 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -1173,7 +1173,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctlr;
+       struct device *dev = &pdev->dev;
+-      struct device_node *np = dev->of_node;
++      struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct resource *res;
+       struct nxp_fspi *f;
+       int ret, irq;
+@@ -1195,7 +1195,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, f);
+       /* find the resources - configuration register address space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               f->iobase = devm_platform_ioremap_resource(pdev, 0);
+       else
+               f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base");
+@@ -1203,7 +1203,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+               return PTR_ERR(f->iobase);
+       /* find the resources - controller memory mapped space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               res = platform_get_resource_byname(pdev,
+@@ -1216,7 +1216,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       f->memmap_phy_size = resource_size(res);
+       /* find the clocks */
+-      if (dev_of_node(&pdev->dev)) {
++      if (is_of_node(fwnode)) {
+               f->clk_en = devm_clk_get(dev, "fspi_en");
+               if (IS_ERR(f->clk_en))
+                       return PTR_ERR(f->clk_en);
+@@ -1260,7 +1260,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       else
+               ctlr->mem_caps = &nxp_fspi_mem_caps;
+-      ctlr->dev.of_node = np;
++      device_set_node(&ctlr->dev, fwnode);
+       return devm_spi_register_controller(&pdev->dev, ctlr);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch b/queue-6.12/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch
new file mode 100644 (file)
index 0000000..1246708
--- /dev/null
@@ -0,0 +1,77 @@
+From 5fecf9bf71a022b479d18c4410bca6041c984cd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:57 +0100
+Subject: spi: nxp-fspi: Support per spi-mem operation frequency switches
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 26851cf65ffca2d3a8d529a125e54cf0084d69e7 ]
+
+Every ->exec_op() call correctly configures the spi bus speed to the
+maximum allowed frequency for the memory using the constant spi default
+parameter. Since we can now have per-operation constraints, let's use
+the value that comes from the spi-mem operation structure instead. In
+case there is no specific limitation for this operation, the default spi
+device value will be given anyway.
+
+The per-operation frequency capability is thus advertised to the spi-mem
+core.
+
+Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-12-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index b569302f22e61..78afef8851fc9 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -711,9 +711,10 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+  * Value for rest of the CS FLSHxxCR0 register would be zero.
+  *
+  */
+-static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
++static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
++                              const struct spi_mem_op *op)
+ {
+-      unsigned long rate = spi->max_speed_hz;
++      unsigned long rate = op->max_freq;
+       int ret;
+       uint64_t size_kb;
+@@ -937,7 +938,7 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+                                  FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true);
+       WARN_ON(err);
+-      nxp_fspi_select_mem(f, mem->spi);
++      nxp_fspi_select_mem(f, mem->spi, op);
+       nxp_fspi_prepare_lut(f, op);
+       /*
+@@ -1155,6 +1156,10 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
+       .get_name = nxp_fspi_get_name,
+ };
++static const struct spi_controller_mem_caps nxp_fspi_mem_caps = {
++      .per_op_freq = true,
++};
++
+ static int nxp_fspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctlr;
+@@ -1252,6 +1257,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       ctlr->bus_num = -1;
+       ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
+       ctlr->mem_ops = &nxp_fspi_mem_ops;
++      ctlr->mem_caps = &nxp_fspi_mem_caps;
+       nxp_fspi_default_setup(f);
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-spi-mem-add-a-new-controller-capability.patch b/queue-6.12/spi-spi-mem-add-a-new-controller-capability.patch
new file mode 100644 (file)
index 0000000..6a6e75c
--- /dev/null
@@ -0,0 +1,73 @@
+From 2a6a79330cff2c4bddcc807db162d1b3e13baf02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:47 +0100
+Subject: spi: spi-mem: Add a new controller capability
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 1248c9b8d54120950fda10fbeb98fb8932b4d45c ]
+
+There are spi devices with multiple frequency limitations depending on
+the invoked command. We probably do not want to afford running at the
+lowest supported frequency all the time, so if we want to get the most
+of our hardware, we need to allow per-operation frequency limitations.
+
+Among all the SPI memory controllers, I believe all are capable of
+changing the spi frequency on the fly. Some of the drivers do not make
+any frequency setup though. And some others will derive a per chip
+prescaler value which will be used forever.
+
+Actually changing the frequency on the fly is something new in Linux, so
+we need to carefully flag the drivers which do and do not support it. A
+controller capability is created for that, and the presence for this
+capability will always be checked before accepting such pattern.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-2-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mem.c       | 6 ++++++
+ include/linux/spi/spi-mem.h | 2 ++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index 12299ce89a1cc..96374afd0193c 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -191,6 +191,12 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+           op->max_freq < mem->spi->controller->min_speed_hz)
+               return false;
++      if (op->max_freq &&
++          op->max_freq < mem->spi->max_speed_hz) {
++              if (!spi_mem_controller_is_capable(ctlr, per_op_freq))
++                      return false;
++      }
++
+       return spi_mem_check_buswidth(mem, op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index 84ec524987921..c7a7719c26484 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -311,11 +311,13 @@ struct spi_controller_mem_ops {
+  * @ecc: Supports operations with error correction
+  * @swap16: Supports swapping bytes on a 16 bit boundary when configured in
+  *        Octal DTR
++ * @per_op_freq: Supports per operation frequency switching
+  */
+ struct spi_controller_mem_caps {
+       bool dtr;
+       bool ecc;
+       bool swap16;
++      bool per_op_freq;
+ };
+ #define spi_mem_controller_is_capable(ctlr, cap)      \
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch b/queue-6.12/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch
new file mode 100644 (file)
index 0000000..5d2411c
--- /dev/null
@@ -0,0 +1,93 @@
+From f87fd2c63f7b55b4ffc9862c94ef267f69038355 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Sep 2024 22:19:52 +0800
+Subject: spi: spi-mem: Allow specifying the byte order in Octal DTR mode
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 030ace430afcf847f537227afceb22dfe8fb8fc8 ]
+
+There are NOR flashes (Macronix) that swap the bytes on a 16-bit
+boundary when configured in Octal DTR mode. The byte order of
+16-bit words is swapped when read or written in Octal Double
+Transfer Rate (DTR) mode compared to Single Transfer Rate (STR)
+modes. If one writes D0 D1 D2 D3 bytes using 1-1-1 mode, and uses
+8D-8D-8D SPI mode for reading, it will read back D1 D0 D3 D2.
+Swapping the bytes may introduce some endianness problems. It can
+affect the boot sequence if the entire boot sequence is not handled
+in either 8D-8D-8D mode or 1-1-1 mode. Therefore, it is necessary
+to swap the bytes back to ensure the same byte order as in STR modes.
+Fortunately there are controllers that could swap the bytes back at
+runtime, addressing the flash's endianness requirements. Provide a
+way for the upper layers to specify the byte order in Octal DTR mode.
+
+Merge Tudor's patch and add modifications for suiting newer version
+of Linux kernel.
+
+Suggested-by: Michael Walle <mwalle@kernel.org>
+Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
+Signed-off-by: AlvinZhou <alvinzhou@mxic.com.tw>
+Acked-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240926141956.2386374-3-alvinzhou.tw@gmail.com
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mem.c       | 3 +++
+ include/linux/spi/spi-mem.h | 8 +++++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index 17b8baf749e6a..abc6792e738c7 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -172,6 +172,9 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+               if (!spi_mem_controller_is_capable(ctlr, dtr))
+                       return false;
++              if (op->data.swap16 && !spi_mem_controller_is_capable(ctlr, swap16))
++                      return false;
++
+               if (op->cmd.nbytes != 2)
+                       return false;
+       } else {
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index f866d5c8ed32a..c46d2b8029be5 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -90,6 +90,8 @@ enum spi_mem_data_dir {
+  * @data.buswidth: number of IO lanes used to send/receive the data
+  * @data.dtr: whether the data should be sent in DTR mode or not
+  * @data.ecc: whether error correction is required or not
++ * @data.swap16: whether the byte order of 16-bit words is swapped when read
++ *             or written in Octal DTR mode compared to STR mode.
+  * @data.dir: direction of the transfer
+  * @data.nbytes: number of data bytes to send/receive. Can be zero if the
+  *             operation does not involve transferring data
+@@ -124,7 +126,8 @@ struct spi_mem_op {
+               u8 buswidth;
+               u8 dtr : 1;
+               u8 ecc : 1;
+-              u8 __pad : 6;
++              u8 swap16 : 1;
++              u8 __pad : 5;
+               enum spi_mem_data_dir dir;
+               unsigned int nbytes;
+               union {
+@@ -297,10 +300,13 @@ struct spi_controller_mem_ops {
+  * struct spi_controller_mem_caps - SPI memory controller capabilities
+  * @dtr: Supports DTR operations
+  * @ecc: Supports operations with error correction
++ * @swap16: Supports swapping bytes on a 16 bit boundary when configured in
++ *        Octal DTR
+  */
+ struct spi_controller_mem_caps {
+       bool dtr;
+       bool ecc;
++      bool swap16;
+ };
+ #define spi_mem_controller_is_capable(ctlr, cap)      \
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch b/queue-6.12/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch
new file mode 100644 (file)
index 0000000..146a8f0
--- /dev/null
@@ -0,0 +1,221 @@
+From ef874c7a2c988d3e4e86dd78238594e189e029e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:46 +0100
+Subject: spi: spi-mem: Extend spi-mem operations with a per-operation maximum
+ frequency
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 0fefeade90e74bc8f40ab0e460f483565c492e28 ]
+
+In the spi subsystem, the bus frequency is derived as follows:
+- the controller may expose a minimum and maximum operating frequency
+- the hardware description, through the spi peripheral properties,
+  advise what is the maximum acceptable frequency from a device/wiring
+  point of view.
+Transfers must be observed at a frequency which fits both (so in
+practice, the lowest maximum).
+
+Actually, this second point mixes two information and already takes the
+lowest frequency among:
+- what the spi device is capable of (what is written in the component
+  datasheet)
+- what the wiring allows (electromagnetic sensibility, crossovers,
+  terminations, antenna effect, etc).
+
+This logic works until spi devices are no longer capable of sustaining
+their highest frequency regardless of the operation. Spi memories are
+typically subject to such variation. Some devices are capable of
+spitting their internally stored data (essentially in read mode) at a
+very fast rate, typically up to 166MHz on Winbond SPI-NAND chips, using
+"fast" commands. However, some of the low-end operations, such as
+regular page read-from-cache commands, are more limited and can only be
+executed at 54MHz at most. This is currently a problem in the SPI-NAND
+subsystem. Another situation, even if not yet supported, will be with
+DTR commands, when the data is latched on both edges of the clock. The
+same chips as mentioned previously are in this case limited to
+80MHz. Yet another example might be continuous reads, which, under
+certain circumstances, can also run at most at 104 or 120MHz.
+
+As a matter of fact, the "one frequency per chip" policy is outdated and
+more fine grain configuration is needed: we need to allow per-operation
+frequency limitations. So far, all datasheets I encountered advertise a
+maximum default frequency, which need to be lowered for certain specific
+operations. So based on the current infrastructure, we can still expect
+firmware (device trees in general) to continued advertising the same
+maximum speed which is a mix between the PCB limitations and the chip
+maximum capability, and expect per-operation lower frequencies when this
+is relevant.
+
+Add a `struct spi_mem_op` member to carry this information. Not
+providing this field explicitly from upper layers means that there is no
+further constraint and the default spi device maximum speed will be
+carried instead. The SPI_MEM_OP() macro is also expanded with an
+optional frequency argument, because virtually all operations can be
+subject to such a limitation, and this will allow for a smooth and
+discrete transition.
+
+For controller drivers which do not implement the spi-mem interface, the
+per-transfer speed is also set acordingly to a lower (than the maximum
+default) speed when relevant.
+
+Acked-by: Pratyush Yadav <pratyush@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-1-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/spi/core.c |  2 ++
+ drivers/spi/spi-mem.c       | 28 ++++++++++++++++++++++++++++
+ include/linux/spi/spi-mem.h | 12 +++++++++++-
+ 3 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index c523a1a22c2b0..57b8807b19482 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1217,6 +1217,8 @@ spinand_select_op_variant(struct spinand_device *spinand,
+                       if (ret)
+                               break;
++                      spi_mem_adjust_op_freq(spinand->spimem, &op);
++
+                       if (!spi_mem_supports_op(spinand->spimem, &op))
+                               break;
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index abc6792e738c7..12299ce89a1cc 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -187,6 +187,10 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+                       return false;
+       }
++      if (op->max_freq && mem->spi->controller->min_speed_hz &&
++          op->max_freq < mem->spi->controller->min_speed_hz)
++              return false;
++
+       return spi_mem_check_buswidth(mem, op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+@@ -364,6 +368,9 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+       u8 *tmpbuf;
+       int ret;
++      /* Make sure the operation frequency is correct before going futher */
++      spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op);
++
+       ret = spi_mem_check_op(op);
+       if (ret)
+               return ret;
+@@ -410,6 +417,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+       xfers[xferpos].tx_buf = tmpbuf;
+       xfers[xferpos].len = op->cmd.nbytes;
+       xfers[xferpos].tx_nbits = op->cmd.buswidth;
++      xfers[xferpos].speed_hz = op->max_freq;
+       spi_message_add_tail(&xfers[xferpos], &msg);
+       xferpos++;
+       totalxferlen++;
+@@ -424,6 +432,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               xfers[xferpos].tx_buf = tmpbuf + 1;
+               xfers[xferpos].len = op->addr.nbytes;
+               xfers[xferpos].tx_nbits = op->addr.buswidth;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->addr.nbytes;
+@@ -435,6 +444,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               xfers[xferpos].len = op->dummy.nbytes;
+               xfers[xferpos].tx_nbits = op->dummy.buswidth;
+               xfers[xferpos].dummy_data = 1;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->dummy.nbytes;
+@@ -450,6 +460,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               }
+               xfers[xferpos].len = op->data.nbytes;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->data.nbytes;
+@@ -528,6 +539,23 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
++/**
++ * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation to
++ *                          match controller, PCB and chip limitations
++ * @mem: the SPI memory
++ * @op: the operation to adjust
++ *
++ * Some chips have per-op frequency limitations and must adapt the maximum
++ * speed. This function allows SPI mem drivers to set @op->max_freq to the
++ * maximum supported value.
++ */
++void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
++{
++      if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
++              op->max_freq = mem->spi->max_speed_hz;
++}
++EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
++
+ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+                                     u64 offs, size_t len, void *buf)
+ {
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index c46d2b8029be5..84ec524987921 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -68,6 +68,9 @@ enum spi_mem_data_dir {
+       SPI_MEM_DATA_OUT,
+ };
++#define SPI_MEM_OP_MAX_FREQ(__freq)                           \
++      .max_freq = __freq
++
+ /**
+  * struct spi_mem_op - describes a SPI memory operation
+  * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
+@@ -97,6 +100,9 @@ enum spi_mem_data_dir {
+  *             operation does not involve transferring data
+  * @data.buf.in: input buffer (must be DMA-able)
+  * @data.buf.out: output buffer (must be DMA-able)
++ * @max_freq: frequency limitation wrt this operation. 0 means there is no
++ *          specific constraint and the highest achievable frequency can be
++ *          attempted.
+  */
+ struct spi_mem_op {
+       struct {
+@@ -135,14 +141,17 @@ struct spi_mem_op {
+                       const void *out;
+               } buf;
+       } data;
++
++      unsigned int max_freq;
+ };
+-#define SPI_MEM_OP(__cmd, __addr, __dummy, __data)            \
++#define SPI_MEM_OP(__cmd, __addr, __dummy, __data, ...)               \
+       {                                                       \
+               .cmd = __cmd,                                   \
+               .addr = __addr,                                 \
+               .dummy = __dummy,                               \
+               .data = __data,                                 \
++              __VA_ARGS__                                     \
+       }
+ /**
+@@ -371,6 +380,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ #endif /* CONFIG_SPI_MEM */
+ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
++void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op);
+ bool spi_mem_supports_op(struct spi_mem *mem,
+                        const struct spi_mem_op *op);
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch b/queue-6.12/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch
new file mode 100644 (file)
index 0000000..b43cb0f
--- /dev/null
@@ -0,0 +1,79 @@
+From f8c93ff4d0ad8a8d5c8c2a216504d72b41e0da2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 15:27:10 +0800
+Subject: spi: spi-nxp-fspi: Add OCT-DTR mode support
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 0f67557763accbdd56681f17ed5350735198c57b ]
+
+Add OCT-DTR mode support in default, since flexspi do not supports
+swapping bytes on a 16 bit boundary in OCT-DTR mode, so mark swap16
+as false.
+
+lx2160a do not support DQS, so add a quirk to disable DTR mode for this
+platform.
+
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20250917-flexspi-ddr-v2-5-bb9fe2a01889@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 825b2a36377c2..6cdeee9c581bd 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -325,6 +325,8 @@
+ /* Access flash memory using IP bus only */
+ #define FSPI_QUIRK_USE_IP_ONLY        BIT(0)
++/* Disable DTR */
++#define FSPI_QUIRK_DISABLE_DTR        BIT(1)
+ struct nxp_fspi_devtype_data {
+       unsigned int rxfifo;
+@@ -339,7 +341,7 @@ static struct nxp_fspi_devtype_data lx2160a_data = {
+       .rxfifo = SZ_512,       /* (64  * 64 bits)  */
+       .txfifo = SZ_1K,        /* (128 * 64 bits)  */
+       .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
+-      .quirks = 0,
++      .quirks = FSPI_QUIRK_DISABLE_DTR,
+       .lut_num = 32,
+       .little_endian = true,  /* little-endian    */
+ };
+@@ -1157,6 +1159,13 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
+ };
+ static const struct spi_controller_mem_caps nxp_fspi_mem_caps = {
++      .dtr = true,
++      .swap16 = false,
++      .per_op_freq = true,
++};
++
++static const struct spi_controller_mem_caps nxp_fspi_mem_caps_disable_dtr = {
++      .dtr = false,
+       .per_op_freq = true,
+ };
+@@ -1245,7 +1254,12 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       ctlr->bus_num = -1;
+       ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
+       ctlr->mem_ops = &nxp_fspi_mem_ops;
+-      ctlr->mem_caps = &nxp_fspi_mem_caps;
++
++      if (f->devtype_data->quirks & FSPI_QUIRK_DISABLE_DTR)
++              ctlr->mem_caps = &nxp_fspi_mem_caps_disable_dtr;
++      else
++              ctlr->mem_caps = &nxp_fspi_mem_caps;
++
+       ctlr->dev.of_node = np;
+       return devm_spi_register_controller(&pdev->dev, ctlr);
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-spi-nxp-fspi-remove-the-goto-in-probe.patch b/queue-6.12/spi-spi-nxp-fspi-remove-the-goto-in-probe.patch
new file mode 100644 (file)
index 0000000..a7a4eaf
--- /dev/null
@@ -0,0 +1,179 @@
+From ffd2b6a6c136c1b564b92e73b16fe33191e7ab72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 18:06:43 +0800
+Subject: spi: spi-nxp-fspi: remove the goto in probe
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 48900813abd2730a35c6e3afd1609bafac5271cc ]
+
+Remove all the goto in probe to simplify the driver.
+
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250428-flexspipatch-v3-1-61d5e8f591bc@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 87 ++++++++++++--------------------------
+ 1 file changed, 27 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 78afef8851fc9..825b2a36377c2 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -1167,10 +1167,10 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       struct device_node *np = dev->of_node;
+       struct resource *res;
+       struct nxp_fspi *f;
+-      int ret;
++      int ret, irq;
+       u32 reg;
+-      ctlr = spi_alloc_host(&pdev->dev, sizeof(*f));
++      ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*f));
+       if (!ctlr)
+               return -ENOMEM;
+@@ -1180,10 +1180,8 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       f = spi_controller_get_devdata(ctlr);
+       f->dev = dev;
+       f->devtype_data = (struct nxp_fspi_devtype_data *)device_get_match_data(dev);
+-      if (!f->devtype_data) {
+-              ret = -ENODEV;
+-              goto err_put_ctrl;
+-      }
++      if (!f->devtype_data)
++              return -ENODEV;
+       platform_set_drvdata(pdev, f);
+@@ -1192,11 +1190,8 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+               f->iobase = devm_platform_ioremap_resource(pdev, 0);
+       else
+               f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base");
+-
+-      if (IS_ERR(f->iobase)) {
+-              ret = PTR_ERR(f->iobase);
+-              goto err_put_ctrl;
+-      }
++      if (IS_ERR(f->iobase))
++              return PTR_ERR(f->iobase);
+       /* find the resources - controller memory mapped space */
+       if (is_acpi_node(dev_fwnode(f->dev)))
+@@ -1204,11 +1199,8 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       else
+               res = platform_get_resource_byname(pdev,
+                               IORESOURCE_MEM, "fspi_mmap");
+-
+-      if (!res) {
+-              ret = -ENODEV;
+-              goto err_put_ctrl;
+-      }
++      if (!res)
++              return -ENODEV;
+       /* assign memory mapped starting address and mapped size. */
+       f->memmap_phy = res->start;
+@@ -1217,69 +1209,46 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       /* find the clocks */
+       if (dev_of_node(&pdev->dev)) {
+               f->clk_en = devm_clk_get(dev, "fspi_en");
+-              if (IS_ERR(f->clk_en)) {
+-                      ret = PTR_ERR(f->clk_en);
+-                      goto err_put_ctrl;
+-              }
++              if (IS_ERR(f->clk_en))
++                      return PTR_ERR(f->clk_en);
+               f->clk = devm_clk_get(dev, "fspi");
+-              if (IS_ERR(f->clk)) {
+-                      ret = PTR_ERR(f->clk);
+-                      goto err_put_ctrl;
+-              }
+-
+-              ret = nxp_fspi_clk_prep_enable(f);
+-              if (ret) {
+-                      dev_err(dev, "can not enable the clock\n");
+-                      goto err_put_ctrl;
+-              }
++              if (IS_ERR(f->clk))
++                      return PTR_ERR(f->clk);
+       }
++      /* find the irq */
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return dev_err_probe(dev, irq, "Failed to get irq source");
++
++      ret = nxp_fspi_clk_prep_enable(f);
++      if (ret)
++              return dev_err_probe(dev, ret, "Can't enable the clock\n");
++
+       /* Clear potential interrupts */
+       reg = fspi_readl(f, f->iobase + FSPI_INTR);
+       if (reg)
+               fspi_writel(f, reg, f->iobase + FSPI_INTR);
+-      /* find the irq */
+-      ret = platform_get_irq(pdev, 0);
+-      if (ret < 0)
+-              goto err_disable_clk;
++      nxp_fspi_default_setup(f);
+-      ret = devm_request_irq(dev, ret,
++      ret = devm_request_irq(dev, irq,
+                       nxp_fspi_irq_handler, 0, pdev->name, f);
+       if (ret) {
+-              dev_err(dev, "failed to request irq: %d\n", ret);
+-              goto err_disable_clk;
++              nxp_fspi_clk_disable_unprep(f);
++              return dev_err_probe(dev, ret, "Failed to request irq\n");
+       }
+-      mutex_init(&f->lock);
++      devm_mutex_init(dev, &f->lock);
+       ctlr->bus_num = -1;
+       ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
+       ctlr->mem_ops = &nxp_fspi_mem_ops;
+       ctlr->mem_caps = &nxp_fspi_mem_caps;
+-
+-      nxp_fspi_default_setup(f);
+-
+       ctlr->dev.of_node = np;
+-      ret = devm_spi_register_controller(&pdev->dev, ctlr);
+-      if (ret)
+-              goto err_destroy_mutex;
+-
+-      return 0;
+-
+-err_destroy_mutex:
+-      mutex_destroy(&f->lock);
+-
+-err_disable_clk:
+-      nxp_fspi_clk_disable_unprep(f);
+-
+-err_put_ctrl:
+-      spi_controller_put(ctlr);
+-
+-      dev_err(dev, "NXP FSPI probe failed\n");
+-      return ret;
++      return devm_spi_register_controller(&pdev->dev, ctlr);
+ }
+ static void nxp_fspi_remove(struct platform_device *pdev)
+@@ -1291,8 +1260,6 @@ static void nxp_fspi_remove(struct platform_device *pdev)
+       nxp_fspi_clk_disable_unprep(f);
+-      mutex_destroy(&f->lock);
+-
+       if (f->ahb_addr)
+               iounmap(f->ahb_addr);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch b/queue-6.12/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
new file mode 100644 (file)
index 0000000..1fc0029
--- /dev/null
@@ -0,0 +1,44 @@
+From ffb7737a66dce2f342fe6ad03cd56533927a7148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 10:50:27 +0100
+Subject: spi: tegra114: remove Kconfig dependency on TEGRA20_APB_DMA
+
+From: Francesco Lavra <flavra@baylibre.com>
+
+[ Upstream commit 3dcf44ab56e1d3ca3532083c0d5390b758e45b45 ]
+
+This driver runs also on Tegra SoCs without a Tegra20 APB DMA controller
+(e.g. Tegra234).
+Remove the Kconfig dependency on TEGRA20_APB_DMA; in addition, amend the
+help text to reflect the fact that this driver works on SoCs different from
+Tegra114.
+
+Fixes: bb9667d8187b ("arm64: tegra: Add SPI device tree nodes for Tegra234")
+Signed-off-by: Francesco Lavra <flavra@baylibre.com>
+Link: https://patch.msgid.link/20251126095027.4102004-1-flavra@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 8237972174048..06c740442fa73 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -1087,10 +1087,10 @@ config SPI_TEGRA210_QUAD
+ config SPI_TEGRA114
+       tristate "NVIDIA Tegra114 SPI Controller"
+-      depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
++      depends on ARCH_TEGRA || COMPILE_TEST
+       depends on RESET_CONTROLLER
+       help
+-        SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
++        SPI controller driver for NVIDIA Tegra114 and later SoCs. This controller
+         is different than the older SoCs SPI controller and also register interface
+         get changed with this controller.
+-- 
+2.51.0
+
diff --git a/queue-6.12/team-move-team-device-type-change-at-the-end-of-team.patch b/queue-6.12/team-move-team-device-type-change-at-the-end-of-team.patch
new file mode 100644 (file)
index 0000000..30d91ab
--- /dev/null
@@ -0,0 +1,118 @@
+From fa35338f2e45e461afacbedf698b6a190886d63c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 02:20:27 +0200
+Subject: team: Move team device type change at the end of team_port_add
+
+From: Nikola Z. Ivanov <zlatistiv@gmail.com>
+
+[ Upstream commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef ]
+
+Attempting to add a port device that is already up will expectedly fail,
+but not before modifying the team device header_ops.
+
+In the case of the syzbot reproducer the gre0 device is
+already in state UP when it attempts to add it as a
+port device of team0, this fails but before that
+header_ops->create of team0 is changed from eth_header to ipgre_header
+in the call to team_dev_type_check_change.
+
+Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense
+as the private data of the device still holds a struct team.
+
+Example sequence of iproute2 commands to reproduce the hang/BUG():
+ip link add dev team0 type team
+ip link add dev gre0 type gre
+ip link set dev gre0 up
+ip link set dev gre0 master team0
+ip link set dev team0 up
+ping -I team0 1.1.1.1
+
+Move team_dev_type_check_change down where all other checks have passed
+as it changes the dev type with no way to restore it in case
+one of the checks that follow it fail.
+
+Also make sure to preserve the origial mtu assignment:
+  - If port_dev is not the same type as dev, dev takes mtu from port_dev
+  - If port_dev is the same type as dev, port_dev takes mtu from dev
+
+This is done by adding a conditional before the call to dev_set_mtu
+to prevent it from assigning port_dev->mtu = dev->mtu and instead
+letting team_dev_type_check_change assign dev->mtu = port_dev->mtu.
+The conditional is needed because the patch moves the call to
+team_dev_type_check_change past dev_set_mtu.
+
+Testing:
+  - team device driver in-tree selftests
+  - Add/remove various devices as slaves of team device
+  - syzbot
+
+Reported-by: syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a2a3b519de727b0f7903
+Fixes: 1d76efe1577b ("team: add support for non-ethernet devices")
+Signed-off-by: Nikola Z. Ivanov <zlatistiv@gmail.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20251122002027.695151-1-zlatistiv@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team_core.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
+index 6cfafaac1b4fb..94c40c5cebdd6 100644
+--- a/drivers/net/team/team_core.c
++++ b/drivers/net/team/team_core.c
+@@ -1190,10 +1190,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+               return -EPERM;
+       }
+-      err = team_dev_type_check_change(dev, port_dev);
+-      if (err)
+-              return err;
+-
+       if (port_dev->flags & IFF_UP) {
+               NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port");
+               netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
+@@ -1211,10 +1207,16 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+       INIT_LIST_HEAD(&port->qom_list);
+       port->orig.mtu = port_dev->mtu;
+-      err = dev_set_mtu(port_dev, dev->mtu);
+-      if (err) {
+-              netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
+-              goto err_set_mtu;
++      /*
++       * MTU assignment will be handled in team_dev_type_check_change
++       * if dev and port_dev are of different types
++       */
++      if (dev->type == port_dev->type) {
++              err = dev_set_mtu(port_dev, dev->mtu);
++              if (err) {
++                      netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
++                      goto err_set_mtu;
++              }
+       }
+       memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
+@@ -1289,6 +1291,10 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+               }
+       }
++      err = team_dev_type_check_change(dev, port_dev);
++      if (err)
++              goto err_set_dev_type;
++
+       if (dev->flags & IFF_UP) {
+               netif_addr_lock_bh(dev);
+               dev_uc_sync_multiple(port_dev, dev);
+@@ -1307,6 +1313,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+       return 0;
++err_set_dev_type:
+ err_set_slave_promisc:
+       __team_option_inst_del_port(team, port);
+-- 
+2.51.0
+
diff --git a/queue-6.12/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch b/queue-6.12/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
new file mode 100644 (file)
index 0000000..a22b7a9
--- /dev/null
@@ -0,0 +1,45 @@
+From b74ff16217d90201f5d841083c794592d293b8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:22:15 +0800
+Subject: usb: gadget: renesas_usbf: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 74851fbb6d647304f8a7dc491434d3a335ef4b8d ]
+
+devm_pm_runtime_enable() can fail due to memory allocation.
+The current code ignores its return value, potentially causing
+pm_runtime_resume_and_get() to operate on uninitialized runtime
+PM state.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 3e6e14ffdea4 ("usb: gadget: udc: add Renesas RZ/N1 USBF controller support")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Acked-by: Herve Codina <herve.codina@bootlin.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/20251124022215.1619-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/renesas_usbf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c
+index 657f265ac7cc5..8463f681ae673 100644
+--- a/drivers/usb/gadget/udc/renesas_usbf.c
++++ b/drivers/usb/gadget/udc/renesas_usbf.c
+@@ -3262,7 +3262,9 @@ static int usbf_probe(struct platform_device *pdev)
+       if (IS_ERR(udc->regs))
+               return PTR_ERR(udc->regs);
+-      devm_pm_runtime_enable(&pdev->dev);
++      ret = devm_pm_runtime_enable(&pdev->dev);
++      if (ret)
++              return ret;
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.12/veth-apply-qdisc-backpressure-on-full-ptr_ring-to-re.patch b/queue-6.12/veth-apply-qdisc-backpressure-on-full-ptr_ring-to-re.patch
new file mode 100644 (file)
index 0000000..28789f0
--- /dev/null
@@ -0,0 +1,175 @@
+From 679f02e5c3b8813daceb030ef0824c6de9163cb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 16:55:40 +0200
+Subject: veth: apply qdisc backpressure on full ptr_ring to reduce TX drops
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit dc82a33297fc2c58cb0b2b008d728668d45c0f6a ]
+
+In production, we're seeing TX drops on veth devices when the ptr_ring
+fills up. This can occur when NAPI mode is enabled, though it's
+relatively rare. However, with threaded NAPI - which we use in
+production - the drops become significantly more frequent.
+
+The underlying issue is that with threaded NAPI, the consumer often runs
+on a different CPU than the producer. This increases the likelihood of
+the ring filling up before the consumer gets scheduled, especially under
+load, leading to drops in veth_xmit() (ndo_start_xmit()).
+
+This patch introduces backpressure by returning NETDEV_TX_BUSY when the
+ring is full, signaling the qdisc layer to requeue the packet. The txq
+(netdev queue) is stopped in this condition and restarted once
+veth_poll() drains entries from the ring, ensuring coordination between
+NAPI and qdisc.
+
+Backpressure is only enabled when a qdisc is attached. Without a qdisc,
+the driver retains its original behavior - dropping packets immediately
+when the ring is full. This avoids unexpected behavior changes in setups
+without a configured qdisc.
+
+With a qdisc in place (e.g. fq, sfq) this allows Active Queue Management
+(AQM) to fairly schedule packets across flows and reduce collateral
+damage from elephant flows.
+
+A known limitation of this approach is that the full ring sits in front
+of the qdisc layer, effectively forming a FIFO buffer that introduces
+base latency. While AQM still improves fairness and mitigates flow
+dominance, the latency impact is measurable.
+
+In hardware drivers, this issue is typically addressed using BQL (Byte
+Queue Limits), which tracks in-flight bytes needed based on physical link
+rate. However, for virtual drivers like veth, there is no fixed bandwidth
+constraint - the bottleneck is CPU availability and the scheduler's ability
+to run the NAPI thread. It is unclear how effective BQL would be in this
+context.
+
+This patch serves as a first step toward addressing TX drops. Future work
+may explore adapting a BQL-like mechanism to better suit virtual devices
+like veth.
+
+Reported-by: Yan Zhai <yan@cloudflare.com>
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Reviewed-by: Toshiaki Makita <toshiaki.makita1@gmail.com>
+Link: https://patch.msgid.link/174559294022.827981.1282809941662942189.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a14602fcae17 ("veth: reduce XDP no_direct return section to fix race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/veth.c | 57 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 47 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 18148e068aa00..44903e2b0925e 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -306,12 +306,10 @@ static void __veth_xdp_flush(struct veth_rq *rq)
+ static int veth_xdp_rx(struct veth_rq *rq, struct sk_buff *skb)
+ {
+-      if (unlikely(ptr_ring_produce(&rq->xdp_ring, skb))) {
+-              dev_kfree_skb_any(skb);
+-              return NET_RX_DROP;
+-      }
++      if (unlikely(ptr_ring_produce(&rq->xdp_ring, skb)))
++              return NETDEV_TX_BUSY; /* signal qdisc layer */
+-      return NET_RX_SUCCESS;
++      return NET_RX_SUCCESS; /* same as NETDEV_TX_OK */
+ }
+ static int veth_forward_skb(struct net_device *dev, struct sk_buff *skb,
+@@ -345,11 +343,11 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct veth_priv *rcv_priv, *priv = netdev_priv(dev);
+       struct veth_rq *rq = NULL;
+-      int ret = NETDEV_TX_OK;
++      struct netdev_queue *txq;
+       struct net_device *rcv;
+       int length = skb->len;
+       bool use_napi = false;
+-      int rxq;
++      int ret, rxq;
+       rcu_read_lock();
+       rcv = rcu_dereference(priv->peer);
+@@ -372,17 +370,45 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
+       }
+       skb_tx_timestamp(skb);
+-      if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) {
++
++      ret = veth_forward_skb(rcv, skb, rq, use_napi);
++      switch (ret) {
++      case NET_RX_SUCCESS: /* same as NETDEV_TX_OK */
+               if (!use_napi)
+                       dev_sw_netstats_tx_add(dev, 1, length);
+               else
+                       __veth_xdp_flush(rq);
+-      } else {
++              break;
++      case NETDEV_TX_BUSY:
++              /* If a qdisc is attached to our virtual device, returning
++               * NETDEV_TX_BUSY is allowed.
++               */
++              txq = netdev_get_tx_queue(dev, rxq);
++
++              if (qdisc_txq_has_no_queue(txq)) {
++                      dev_kfree_skb_any(skb);
++                      goto drop;
++              }
++              /* Restore Eth hdr pulled by dev_forward_skb/eth_type_trans */
++              __skb_push(skb, ETH_HLEN);
++              /* Depend on prior success packets started NAPI consumer via
++               * __veth_xdp_flush(). Cancel TXQ stop if consumer stopped,
++               * paired with empty check in veth_poll().
++               */
++              netif_tx_stop_queue(txq);
++              smp_mb__after_atomic();
++              if (unlikely(__ptr_ring_empty(&rq->xdp_ring)))
++                      netif_tx_wake_queue(txq);
++              break;
++      case NET_RX_DROP: /* same as NET_XMIT_DROP */
+ drop:
+               atomic64_inc(&priv->dropped);
+               ret = NET_XMIT_DROP;
++              break;
++      default:
++              net_crit_ratelimited("%s(%s): Invalid return code(%d)",
++                                   __func__, dev->name, ret);
+       }
+-
+       rcu_read_unlock();
+       return ret;
+@@ -874,9 +900,17 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+                       struct veth_xdp_tx_bq *bq,
+                       struct veth_stats *stats)
+ {
++      struct veth_priv *priv = netdev_priv(rq->dev);
++      int queue_idx = rq->xdp_rxq.queue_index;
++      struct netdev_queue *peer_txq;
++      struct net_device *peer_dev;
+       int i, done = 0, n_xdpf = 0;
+       void *xdpf[VETH_XDP_BATCH];
++      /* NAPI functions as RCU section */
++      peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
++      peer_txq = netdev_get_tx_queue(peer_dev, queue_idx);
++
+       for (i = 0; i < budget; i++) {
+               void *ptr = __ptr_ring_consume(&rq->xdp_ring);
+@@ -925,6 +959,9 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+       rq->stats.vs.xdp_packets += done;
+       u64_stats_update_end(&rq->stats.syncp);
++      if (unlikely(netif_tx_queue_stopped(peer_txq)))
++              netif_tx_wake_queue(peer_txq);
++
+       return done;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/veth-more-robust-handing-of-race-to-avoid-txq-gettin.patch b/queue-6.12/veth-more-robust-handing-of-race-to-avoid-txq-gettin.patch
new file mode 100644 (file)
index 0000000..2b7ec07
--- /dev/null
@@ -0,0 +1,152 @@
+From 0e606f973813464604e164463f8566abf583c982 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Nov 2025 14:13:52 +0100
+Subject: veth: more robust handing of race to avoid txq getting stuck
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit 5442a9da69789741bfda39f34ee7f69552bf0c56 ]
+
+Commit dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to
+reduce TX drops") introduced a race condition that can lead to a permanently
+stalled TXQ. This was observed in production on ARM64 systems (Ampere Altra
+Max).
+
+The race occurs in veth_xmit(). The producer observes a full ptr_ring and
+stops the queue (netif_tx_stop_queue()). The subsequent conditional logic,
+intended to re-wake the queue if the consumer had just emptied it (if
+(__ptr_ring_empty(...)) netif_tx_wake_queue()), can fail. This leads to a
+"lost wakeup" where the TXQ remains stopped (QUEUE_STATE_DRV_XOFF) and
+traffic halts.
+
+This failure is caused by an incorrect use of the __ptr_ring_empty() API
+from the producer side. As noted in kernel comments, this check is not
+guaranteed to be correct if a consumer is operating on another CPU. The
+empty test is based on ptr_ring->consumer_head, making it reliable only for
+the consumer. Using this check from the producer side is fundamentally racy.
+
+This patch fixes the race by adopting the more robust logic from an earlier
+version V4 of the patchset, which always flushed the peer:
+
+(1) In veth_xmit(), the racy conditional wake-up logic and its memory barrier
+are removed. Instead, after stopping the queue, we unconditionally call
+__veth_xdp_flush(rq). This guarantees that the NAPI consumer is scheduled,
+making it solely responsible for re-waking the TXQ.
+  This handles the race where veth_poll() consumes all packets and completes
+NAPI *before* veth_xmit() on the producer side has called netif_tx_stop_queue.
+The __veth_xdp_flush(rq) will observe rx_notify_masked is false and schedule
+NAPI.
+
+(2) On the consumer side, the logic for waking the peer TXQ is moved out of
+veth_xdp_rcv() and placed at the end of the veth_poll() function. This
+placement is part of fixing the race, as the netif_tx_queue_stopped() check
+must occur after rx_notify_masked is potentially set to false during NAPI
+completion.
+  This handles the race where veth_poll() consumes all packets, but haven't
+finished (rx_notify_masked is still true). The producer veth_xmit() stops the
+TXQ and __veth_xdp_flush(rq) will observe rx_notify_masked is true, meaning
+not starting NAPI.  Then veth_poll() change rx_notify_masked to false and
+stops NAPI.  Before exiting veth_poll() will observe TXQ is stopped and wake
+it up.
+
+Fixes: dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops")
+Reviewed-by: Toshiaki Makita <toshiaki.makita1@gmail.com>
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/176295323282.307447.14790015927673763094.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a14602fcae17 ("veth: reduce XDP no_direct return section to fix race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/veth.c | 38 ++++++++++++++++++++------------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 25b43036cc08b..0f37e056b3dd7 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -391,14 +391,12 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
+               }
+               /* Restore Eth hdr pulled by dev_forward_skb/eth_type_trans */
+               __skb_push(skb, ETH_HLEN);
+-              /* Depend on prior success packets started NAPI consumer via
+-               * __veth_xdp_flush(). Cancel TXQ stop if consumer stopped,
+-               * paired with empty check in veth_poll().
+-               */
+               netif_tx_stop_queue(txq);
+-              smp_mb__after_atomic();
+-              if (unlikely(__ptr_ring_empty(&rq->xdp_ring)))
+-                      netif_tx_wake_queue(txq);
++              /* Makes sure NAPI peer consumer runs. Consumer is responsible
++               * for starting txq again, until then ndo_start_xmit (this
++               * function) will not be invoked by the netstack again.
++               */
++              __veth_xdp_flush(rq);
+               break;
+       case NET_RX_DROP: /* same as NET_XMIT_DROP */
+ drop:
+@@ -900,17 +898,9 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+                       struct veth_xdp_tx_bq *bq,
+                       struct veth_stats *stats)
+ {
+-      struct veth_priv *priv = netdev_priv(rq->dev);
+-      int queue_idx = rq->xdp_rxq.queue_index;
+-      struct netdev_queue *peer_txq;
+-      struct net_device *peer_dev;
+       int i, done = 0, n_xdpf = 0;
+       void *xdpf[VETH_XDP_BATCH];
+-      /* NAPI functions as RCU section */
+-      peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
+-      peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;
+-
+       for (i = 0; i < budget; i++) {
+               void *ptr = __ptr_ring_consume(&rq->xdp_ring);
+@@ -959,9 +949,6 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+       rq->stats.vs.xdp_packets += done;
+       u64_stats_update_end(&rq->stats.syncp);
+-      if (peer_txq && unlikely(netif_tx_queue_stopped(peer_txq)))
+-              netif_tx_wake_queue(peer_txq);
+-
+       return done;
+ }
+@@ -969,12 +956,20 @@ static int veth_poll(struct napi_struct *napi, int budget)
+ {
+       struct veth_rq *rq =
+               container_of(napi, struct veth_rq, xdp_napi);
++      struct veth_priv *priv = netdev_priv(rq->dev);
++      int queue_idx = rq->xdp_rxq.queue_index;
++      struct netdev_queue *peer_txq;
+       struct veth_stats stats = {};
++      struct net_device *peer_dev;
+       struct veth_xdp_tx_bq bq;
+       int done;
+       bq.count = 0;
++      /* NAPI functions as RCU section */
++      peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
++      peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;
++
+       xdp_set_return_frame_no_direct();
+       done = veth_xdp_rcv(rq, budget, &bq, &stats);
+@@ -996,6 +991,13 @@ static int veth_poll(struct napi_struct *napi, int budget)
+               veth_xdp_flush(rq, &bq);
+       xdp_clear_return_frame_no_direct();
++      /* Release backpressure per NAPI poll */
++      smp_rmb(); /* Paired with netif_tx_stop_queue set_bit */
++      if (peer_txq && netif_tx_queue_stopped(peer_txq)) {
++              txq_trans_cond_update(peer_txq);
++              netif_tx_wake_queue(peer_txq);
++      }
++
+       return done;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/veth-prevent-null-pointer-dereference-in-veth_xdp_rc.patch b/queue-6.12/veth-prevent-null-pointer-dereference-in-veth_xdp_rc.patch
new file mode 100644 (file)
index 0000000..033abc0
--- /dev/null
@@ -0,0 +1,61 @@
+From 0dbd072a3e139b6a818d01c693a0062eff92d65b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 14:40:04 +0200
+Subject: veth: prevent NULL pointer dereference in veth_xdp_rcv
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit 9337c54401a5bb6ac3c9f6c71dd2a9130cfba82e ]
+
+The veth peer device is RCU protected, but when the peer device gets
+deleted (veth_dellink) then the pointer is assigned NULL (via
+RCU_INIT_POINTER).
+
+This patch adds a necessary NULL check in veth_xdp_rcv when accessing
+the veth peer net_device.
+
+This fixes a bug introduced in commit dc82a33297fc ("veth: apply qdisc
+backpressure on full ptr_ring to reduce TX drops"). The bug is a race
+and only triggers when having inflight packets on a veth that is being
+deleted.
+
+Reported-by: Ihor Solodrai <ihor.solodrai@linux.dev>
+Closes: https://lore.kernel.org/all/fecfcad0-7a16-42b8-bff2-66ee83a6e5c4@linux.dev/
+Reported-by: syzbot+c4c7bf27f6b0c4bd97fe@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/683da55e.a00a0220.d8eae.0052.GAE@google.com/
+Fixes: dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops")
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
+Link: https://patch.msgid.link/174964557873.519608.10855046105237280978.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a14602fcae17 ("veth: reduce XDP no_direct return section to fix race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/veth.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 44903e2b0925e..25b43036cc08b 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -909,7 +909,7 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+       /* NAPI functions as RCU section */
+       peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
+-      peer_txq = netdev_get_tx_queue(peer_dev, queue_idx);
++      peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;
+       for (i = 0; i < budget; i++) {
+               void *ptr = __ptr_ring_consume(&rq->xdp_ring);
+@@ -959,7 +959,7 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
+       rq->stats.vs.xdp_packets += done;
+       u64_stats_update_end(&rq->stats.syncp);
+-      if (unlikely(netif_tx_queue_stopped(peer_txq)))
++      if (peer_txq && unlikely(netif_tx_queue_stopped(peer_txq)))
+               netif_tx_wake_queue(peer_txq);
+       return done;
+-- 
+2.51.0
+
diff --git a/queue-6.12/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch b/queue-6.12/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch
new file mode 100644 (file)
index 0000000..a1de255
--- /dev/null
@@ -0,0 +1,70 @@
+From 3d2864111cf8d7f7f0127896ce2ca4bebe23408b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 17:28:36 +0100
+Subject: veth: reduce XDP no_direct return section to fix race
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit a14602fcae17a3f1cb8a8521bedf31728f9e7e39 ]
+
+As explain in commit fa349e396e48 ("veth: Fix race with AF_XDP exposing
+old or uninitialized descriptors") for veth there is a chance after
+napi_complete_done() that another CPU can manage start another NAPI
+instance running veth_pool(). For NAPI this is correctly handled as the
+napi_schedule_prep() check will prevent multiple instances from getting
+scheduled, but for the remaining code in veth_pool() this can run
+concurrent with the newly started NAPI instance.
+
+The problem/race is that xdp_clear_return_frame_no_direct() isn't
+designed to be nested.
+
+Prior to commit 401cb7dae813 ("net: Reference bpf_redirect_info via
+task_struct on PREEMPT_RT.") the temporary BPF net context
+bpf_redirect_info was stored per CPU, where this wasn't an issue. Since
+this commit the BPF context is stored in 'current' task_struct. When
+running veth in threaded-NAPI mode, then the kthread becomes the storage
+area. Now a race exists between two concurrent veth_pool() function calls
+one exiting NAPI and one running new NAPI, both using the same BPF net
+context.
+
+Race is when another CPU gets within the xdp_set_return_frame_no_direct()
+section before exiting veth_pool() calls the clear-function
+xdp_clear_return_frame_no_direct().
+
+Fixes: 401cb7dae8130 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.")
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/176356963888.337072.4805242001928705046.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/veth.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 0f37e056b3dd7..4ff0d4232914f 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -975,6 +975,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
+       if (stats.xdp_redirect > 0)
+               xdp_do_flush();
++      if (stats.xdp_tx > 0)
++              veth_xdp_flush(rq, &bq);
++      xdp_clear_return_frame_no_direct();
+       if (done < budget && napi_complete_done(napi, done)) {
+               /* Write rx_notify_masked before reading ptr_ring */
+@@ -987,10 +990,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
+               }
+       }
+-      if (stats.xdp_tx > 0)
+-              veth_xdp_flush(rq, &bq);
+-      xdp_clear_return_frame_no_direct();
+-
+       /* Release backpressure per NAPI poll */
+       smp_rmb(); /* Paired with netif_tx_stop_queue set_bit */
+       if (peer_txq && netif_tx_queue_stopped(peer_txq)) {
+-- 
+2.51.0
+
diff --git a/queue-6.17/afs-fix-delayed-allocation-of-a-cell-s-anonymous-key.patch b/queue-6.17/afs-fix-delayed-allocation-of-a-cell-s-anonymous-key.patch
new file mode 100644 (file)
index 0000000..2cd87ce
--- /dev/null
@@ -0,0 +1,242 @@
+From cd9b0077a8fd60294951b9a8c1f846aa1e892b67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:05 +0000
+Subject: afs: Fix delayed allocation of a cell's anonymous key
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit d27c71257825dced46104eefe42e4d9964bd032e ]
+
+The allocation of a cell's anonymous key is done in a background thread
+along with other cell setup such as doing a DNS upcall.  In the reported
+bug, this is triggered by afs_parse_source() parsing the device name given
+to mount() and calling afs_lookup_cell() with the name of the cell.
+
+The normal key lookup then tries to use the key description on the
+anonymous authentication key as the reference for request_key() - but it
+may not yet be set and so an oops can happen.
+
+This has been made more likely to happen by the fix for dynamic lookup
+failure.
+
+Fix this by firstly allocating a reference name and attaching it to the
+afs_cell record when the record is created.  It can share the memory
+allocation with the cell name (unfortunately it can't just overlap the cell
+name by prepending it with "afs@" as the cell name already has a '.'
+prepended for other purposes).  This reference name is then passed to
+request_key().
+
+Secondly, the anon key is now allocated on demand at the point a key is
+requested in afs_request_key() if it is not already allocated.  A mutex is
+used to prevent multiple allocation for a cell.
+
+Thirdly, make afs_request_key_rcu() return NULL if the anonymous key isn't
+yet allocated (if we need it) and then the caller can return -ECHILD to
+drop out of RCU-mode and afs_request_key() can be called.
+
+Note that the anonymous key is kind of necessary to make the key lookup
+cache work as that doesn't currently cache a negative lookup, but it's
+probably worth some investigation to see if NULL can be used instead.
+
+Fixes: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure")
+Reported-by: syzbot+41c68824eefb67cdf00c@syzkaller.appspotmail.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://patch.msgid.link/800328.1764325145@warthog.procyon.org.uk
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/cell.c     | 43 ++++++++----------------------------------
+ fs/afs/internal.h |  1 +
+ fs/afs/security.c | 48 +++++++++++++++++++++++++++++++++++++++--------
+ 3 files changed, 49 insertions(+), 43 deletions(-)
+
+diff --git a/fs/afs/cell.c b/fs/afs/cell.c
+index d9b6fa1088b7b..71c10a05cebe5 100644
+--- a/fs/afs/cell.c
++++ b/fs/afs/cell.c
+@@ -140,7 +140,9 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
+               return ERR_PTR(-ENOMEM);
+       }
+-      cell->name = kmalloc(1 + namelen + 1, GFP_KERNEL);
++      /* Allocate the cell name and the key name in one go. */
++      cell->name = kmalloc(1 + namelen + 1 +
++                           4 + namelen + 1, GFP_KERNEL);
+       if (!cell->name) {
+               kfree(cell);
+               return ERR_PTR(-ENOMEM);
+@@ -151,7 +153,11 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
+       cell->name_len = namelen;
+       for (i = 0; i < namelen; i++)
+               cell->name[i] = tolower(name[i]);
+-      cell->name[i] = 0;
++      cell->name[i++] = 0;
++
++      cell->key_desc = cell->name + i;
++      memcpy(cell->key_desc, "afs@", 4);
++      memcpy(cell->key_desc + 4, cell->name, cell->name_len + 1);
+       cell->net = net;
+       refcount_set(&cell->ref, 1);
+@@ -710,33 +716,6 @@ void afs_set_cell_timer(struct afs_cell *cell, unsigned int delay_secs)
+       timer_reduce(&cell->management_timer, jiffies + delay_secs * HZ);
+ }
+-/*
+- * Allocate a key to use as a placeholder for anonymous user security.
+- */
+-static int afs_alloc_anon_key(struct afs_cell *cell)
+-{
+-      struct key *key;
+-      char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp;
+-
+-      /* Create a key to represent an anonymous user. */
+-      memcpy(keyname, "afs@", 4);
+-      dp = keyname + 4;
+-      cp = cell->name;
+-      do {
+-              *dp++ = tolower(*cp);
+-      } while (*cp++);
+-
+-      key = rxrpc_get_null_key(keyname);
+-      if (IS_ERR(key))
+-              return PTR_ERR(key);
+-
+-      cell->anonymous_key = key;
+-
+-      _debug("anon key %p{%x}",
+-             cell->anonymous_key, key_serial(cell->anonymous_key));
+-      return 0;
+-}
+-
+ /*
+  * Activate a cell.
+  */
+@@ -746,12 +725,6 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
+       struct afs_cell *pcell;
+       int ret;
+-      if (!cell->anonymous_key) {
+-              ret = afs_alloc_anon_key(cell);
+-              if (ret < 0)
+-                      return ret;
+-      }
+-
+       ret = afs_proc_cell_setup(cell);
+       if (ret < 0)
+               return ret;
+diff --git a/fs/afs/internal.h b/fs/afs/internal.h
+index 87828d685293f..470e6eef8bd49 100644
+--- a/fs/afs/internal.h
++++ b/fs/afs/internal.h
+@@ -413,6 +413,7 @@ struct afs_cell {
+       u8                      name_len;       /* Length of name */
+       char                    *name;          /* Cell name, case-flattened and NUL-padded */
++      char                    *key_desc;      /* Authentication key description */
+ };
+ /*
+diff --git a/fs/afs/security.c b/fs/afs/security.c
+index 6a7744c9e2a2d..ff8830e6982fb 100644
+--- a/fs/afs/security.c
++++ b/fs/afs/security.c
+@@ -16,6 +16,30 @@
+ static DEFINE_HASHTABLE(afs_permits_cache, 10);
+ static DEFINE_SPINLOCK(afs_permits_lock);
++static DEFINE_MUTEX(afs_key_lock);
++
++/*
++ * Allocate a key to use as a placeholder for anonymous user security.
++ */
++static int afs_alloc_anon_key(struct afs_cell *cell)
++{
++      struct key *key;
++
++      mutex_lock(&afs_key_lock);
++      if (!cell->anonymous_key) {
++              key = rxrpc_get_null_key(cell->key_desc);
++              if (!IS_ERR(key))
++                      cell->anonymous_key = key;
++      }
++      mutex_unlock(&afs_key_lock);
++
++      if (IS_ERR(key))
++              return PTR_ERR(key);
++
++      _debug("anon key %p{%x}",
++             cell->anonymous_key, key_serial(cell->anonymous_key));
++      return 0;
++}
+ /*
+  * get a key
+@@ -23,11 +47,12 @@ static DEFINE_SPINLOCK(afs_permits_lock);
+ struct key *afs_request_key(struct afs_cell *cell)
+ {
+       struct key *key;
++      int ret;
+-      _enter("{%x}", key_serial(cell->anonymous_key));
++      _enter("{%s}", cell->key_desc);
+-      _debug("key %s", cell->anonymous_key->description);
+-      key = request_key_net(&key_type_rxrpc, cell->anonymous_key->description,
++      _debug("key %s", cell->key_desc);
++      key = request_key_net(&key_type_rxrpc, cell->key_desc,
+                             cell->net->net, NULL);
+       if (IS_ERR(key)) {
+               if (PTR_ERR(key) != -ENOKEY) {
+@@ -35,6 +60,12 @@ struct key *afs_request_key(struct afs_cell *cell)
+                       return key;
+               }
++              if (!cell->anonymous_key) {
++                      ret = afs_alloc_anon_key(cell);
++                      if (ret < 0)
++                              return ERR_PTR(ret);
++              }
++
+               /* act as anonymous user */
+               _leave(" = {%x} [anon]", key_serial(cell->anonymous_key));
+               return key_get(cell->anonymous_key);
+@@ -52,11 +83,10 @@ struct key *afs_request_key_rcu(struct afs_cell *cell)
+ {
+       struct key *key;
+-      _enter("{%x}", key_serial(cell->anonymous_key));
++      _enter("{%s}", cell->key_desc);
+-      _debug("key %s", cell->anonymous_key->description);
+-      key = request_key_net_rcu(&key_type_rxrpc,
+-                                cell->anonymous_key->description,
++      _debug("key %s", cell->key_desc);
++      key = request_key_net_rcu(&key_type_rxrpc, cell->key_desc,
+                                 cell->net->net);
+       if (IS_ERR(key)) {
+               if (PTR_ERR(key) != -ENOKEY) {
+@@ -65,6 +95,8 @@ struct key *afs_request_key_rcu(struct afs_cell *cell)
+               }
+               /* act as anonymous user */
++              if (!cell->anonymous_key)
++                      return NULL; /* Need to allocate */
+               _leave(" = {%x} [anon]", key_serial(cell->anonymous_key));
+               return key_get(cell->anonymous_key);
+       } else {
+@@ -408,7 +440,7 @@ int afs_permission(struct mnt_idmap *idmap, struct inode *inode,
+       if (mask & MAY_NOT_BLOCK) {
+               key = afs_request_key_rcu(vnode->volume->cell);
+-              if (IS_ERR(key))
++              if (IS_ERR_OR_NULL(key))
+                       return -ECHILD;
+               ret = -ECHILD;
+-- 
+2.51.0
+
diff --git a/queue-6.17/afs-fix-uninit-var-in-afs_alloc_anon_key.patch b/queue-6.17/afs-fix-uninit-var-in-afs_alloc_anon_key.patch
new file mode 100644 (file)
index 0000000..783c1c3
--- /dev/null
@@ -0,0 +1,50 @@
+From 8b819d95114ef5f39787f9dd8822141c0d2a426d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 00:40:11 +0000
+Subject: afs: Fix uninit var in afs_alloc_anon_key()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 19eef1d98eeda3745df35839190b7d4a4adea656 ]
+
+Fix an uninitialised variable (key) in afs_alloc_anon_key() by setting it
+to cell->anonymous_key.  Without this change, the error check may return a
+false failure with a bad error number.
+
+Most of the time this is unlikely to happen because the first encounter
+with afs_alloc_anon_key() will usually be from (auto)mount, for which all
+subsequent operations must wait - apart from other (auto)mounts.  Once the
+call->anonymous_key is allocated, all further calls to afs_request_key()
+will skip the call to afs_alloc_anon_key() for that cell.
+
+Fixes: d27c71257825 ("afs: Fix delayed allocation of a cell's anonymous key")
+Reported-by: Paulo Alcantra <pc@manguebit.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Paulo Alcantara <pc@manguebit.org>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: syzbot+41c68824eefb67cdf00c@syzkaller.appspotmail.com
+cc: linux-afs@lists.infradead.org
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/security.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/afs/security.c b/fs/afs/security.c
+index ff8830e6982fb..55ddce94af031 100644
+--- a/fs/afs/security.c
++++ b/fs/afs/security.c
+@@ -26,7 +26,8 @@ static int afs_alloc_anon_key(struct afs_cell *cell)
+       struct key *key;
+       mutex_lock(&afs_key_lock);
+-      if (!cell->anonymous_key) {
++      key = cell->anonymous_key;
++      if (!key) {
+               key = rxrpc_get_null_key(cell->key_desc);
+               if (!IS_ERR(key))
+                       cell->anonymous_key = key;
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch b/queue-6.17/bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch
new file mode 100644 (file)
index 0000000..d136f27
--- /dev/null
@@ -0,0 +1,132 @@
+From 720403fe3ad2eefe049efbbc546795cc0edde709 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Nov 2025 15:53:34 +0800
+Subject: Bluetooth: btusb: mediatek: Fix kernel crash when releasing mtk iso
+ interface
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 4015b979767125cf8a2233a145a3b3af78bfd8fb ]
+
+When performing reset tests and encountering abnormal card drop issues
+that lead to a kernel crash, it is necessary to perform a null check
+before releasing resources to avoid attempting to release a null pointer.
+
+<4>[   29.158070] Hardware name: Google Quigon sku196612/196613 board (DT)
+<4>[   29.158076] Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+<4>[   29.158154] pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+<4>[   29.158162] pc : klist_remove+0x90/0x158
+<4>[   29.158174] lr : klist_remove+0x88/0x158
+<4>[   29.158180] sp : ffffffc0846b3c00
+<4>[   29.158185] pmr_save: 000000e0
+<4>[   29.158188] x29: ffffffc0846b3c30 x28: ffffff80cd31f880 x27: ffffff80c1bdc058
+<4>[   29.158199] x26: dead000000000100 x25: ffffffdbdc624ea3 x24: ffffff80c1bdc4c0
+<4>[   29.158209] x23: ffffffdbdc62a3e6 x22: ffffff80c6c07000 x21: ffffffdbdc829290
+<4>[   29.158219] x20: 0000000000000000 x19: ffffff80cd3e0648 x18: 000000031ec97781
+<4>[   29.158229] x17: ffffff80c1bdc4a8 x16: ffffffdc10576548 x15: ffffff80c1180428
+<4>[   29.158238] x14: 0000000000000000 x13: 000000000000e380 x12: 0000000000000018
+<4>[   29.158248] x11: ffffff80c2a7fd10 x10: 0000000000000000 x9 : 0000000100000000
+<4>[   29.158257] x8 : 0000000000000000 x7 : 7f7f7f7f7f7f7f7f x6 : 2d7223ff6364626d
+<4>[   29.158266] x5 : 0000008000000000 x4 : 0000000000000020 x3 : 2e7325006465636e
+<4>[   29.158275] x2 : ffffffdc11afeff8 x1 : 0000000000000000 x0 : ffffffdc11be4d0c
+<4>[   29.158285] Call trace:
+<4>[   29.158290]  klist_remove+0x90/0x158
+<4>[   29.158298]  device_release_driver_internal+0x20c/0x268
+<4>[   29.158308]  device_release_driver+0x1c/0x30
+<4>[   29.158316]  usb_driver_release_interface+0x70/0x88
+<4>[   29.158325]  btusb_mtk_release_iso_intf+0x68/0xd8 [btusb (HASH:e8b6 5)]
+<4>[   29.158347]  btusb_mtk_reset+0x5c/0x480 [btusb (HASH:e8b6 5)]
+<4>[   29.158361]  hci_cmd_sync_work+0x10c/0x188 [bluetooth (HASH:a4fa 6)]
+<4>[   29.158430]  process_scheduled_works+0x258/0x4e8
+<4>[   29.158441]  worker_thread+0x300/0x428
+<4>[   29.158448]  kthread+0x108/0x1d0
+<4>[   29.158455]  ret_from_fork+0x10/0x20
+<0>[   29.158467] Code: 91343000 940139d1 f9400268 927ff914 (f9401297)
+<4>[   29.158474] ---[ end trace 0000000000000000 ]---
+<0>[   29.167129] Kernel panic - not syncing: Oops: Fatal exception
+<2>[   29.167144] SMP: stopping secondary CPUs
+<4>[   29.167158] ------------[ cut here ]------------
+
+Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions")
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c        | 34 +++++++++++++++++++++++++-------
+ include/net/bluetooth/hci_core.h |  1 -
+ 2 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a722446ec73dd..202a845e0236f 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2711,9 +2711,16 @@ static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb)
+ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
+ {
+-      struct btmtk_data *btmtk_data = hci_get_priv(data->hdev);
++      struct btmtk_data *btmtk_data;
+       int err;
++      if (!data->hdev)
++              return;
++
++      btmtk_data = hci_get_priv(data->hdev);
++      if (!btmtk_data)
++              return;
++
+       /*
+        * The function usb_driver_claim_interface() is documented to need
+        * locks held if it's not called from a probe routine. The code here
+@@ -2735,17 +2742,30 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
+ static void btusb_mtk_release_iso_intf(struct hci_dev *hdev)
+ {
+-      struct btmtk_data *btmtk_data = hci_get_priv(hdev);
++      struct btmtk_data *btmtk_data;
++
++      if (!hdev)
++              return;
++
++      btmtk_data = hci_get_priv(hdev);
++      if (!btmtk_data)
++              return;
+       if (test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) {
+               usb_kill_anchored_urbs(&btmtk_data->isopkt_anchor);
+               clear_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags);
+-              dev_kfree_skb_irq(btmtk_data->isopkt_skb);
+-              btmtk_data->isopkt_skb = NULL;
+-              usb_set_intfdata(btmtk_data->isopkt_intf, NULL);
+-              usb_driver_release_interface(&btusb_driver,
+-                                           btmtk_data->isopkt_intf);
++              if (btmtk_data->isopkt_skb) {
++                      dev_kfree_skb_irq(btmtk_data->isopkt_skb);
++                      btmtk_data->isopkt_skb = NULL;
++              }
++
++              if (btmtk_data->isopkt_intf) {
++                      usb_set_intfdata(btmtk_data->isopkt_intf, NULL);
++                      usb_driver_release_interface(&btusb_driver,
++                                                   btmtk_data->isopkt_intf);
++                      btmtk_data->isopkt_intf = NULL;
++              }
+       }
+       clear_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags);
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 8d78cb2b9f1ab..4ccb462a0a4b8 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -748,7 +748,6 @@ struct hci_conn {
+       __u8            remote_cap;
+       __u8            remote_auth;
+-      __u8            remote_id;
+       unsigned int    sent;
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch b/queue-6.17/bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch
new file mode 100644 (file)
index 0000000..2ddef62
--- /dev/null
@@ -0,0 +1,85 @@
+From 183129f38bfb3671a983e5d649a1790a940407cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 09:49:27 -0500
+Subject: Bluetooth: hci_core: Fix triggering cmd_timer for HCI_OP_NOP
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 275ddfeb3fdc274050c2173ffd985b1e80a9aa37 ]
+
+HCI_OP_NOP means no command was actually sent so there is no point in
+triggering cmd_timer which may cause a hdev->reset in the process since
+it is assumed that the controller is stuck processing a command.
+
+Fixes: e2d471b7806b ("Bluetooth: ISO: Fix not using SID from adv report")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 55e0722fd0662..72c7607aac209 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4093,7 +4093,7 @@ static void hci_rx_work(struct work_struct *work)
+       }
+ }
+-static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
++static int hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+       int err;
+@@ -4105,16 +4105,19 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+       if (!hdev->sent_cmd) {
+               skb_queue_head(&hdev->cmd_q, skb);
+               queue_work(hdev->workqueue, &hdev->cmd_work);
+-              return;
++              return -EINVAL;
+       }
+       if (hci_skb_opcode(skb) != HCI_OP_NOP) {
+               err = hci_send_frame(hdev, skb);
+               if (err < 0) {
+                       hci_cmd_sync_cancel_sync(hdev, -err);
+-                      return;
++                      return err;
+               }
+               atomic_dec(&hdev->cmd_cnt);
++      } else {
++              err = -ENODATA;
++              kfree_skb(skb);
+       }
+       if (hdev->req_status == HCI_REQ_PEND &&
+@@ -4122,12 +4125,15 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+               kfree_skb(hdev->req_skb);
+               hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
+       }
++
++      return err;
+ }
+ static void hci_cmd_work(struct work_struct *work)
+ {
+       struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
+       struct sk_buff *skb;
++      int err;
+       BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
+              atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
+@@ -4138,7 +4144,9 @@ static void hci_cmd_work(struct work_struct *work)
+               if (!skb)
+                       return;
+-              hci_send_cmd_sync(hdev, skb);
++              err = hci_send_cmd_sync(hdev, skb);
++              if (err)
++                      return;
+               rcu_read_lock();
+               if (test_bit(HCI_RESET, &hdev->flags) ||
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-hci_core-lookup-hci_conn-on-rx-path-on-pro.patch b/queue-6.17/bluetooth-hci_core-lookup-hci_conn-on-rx-path-on-pro.patch
new file mode 100644 (file)
index 0000000..6b39f96
--- /dev/null
@@ -0,0 +1,417 @@
+From 16486fe11c98ab223348a2dc1429a5a6b87bb51e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Nov 2025 18:43:55 +0200
+Subject: Bluetooth: hci_core: lookup hci_conn on RX path on protocol side
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 79a2d4678ba90bdba577dc3af88cc900d6dcd5ee ]
+
+The hdev lock/lookup/unlock/use pattern in the packet RX path doesn't
+ensure hci_conn* is not concurrently modified/deleted. This locking
+appears to be leftover from before conn_hash started using RCU
+commit bf4c63252490b ("Bluetooth: convert conn hash to RCU")
+and not clear if it had purpose since then.
+
+Currently, there are code paths that delete hci_conn* from elsewhere
+than the ordered hdev->workqueue where the RX work runs in. E.g.
+commit 5af1f84ed13a ("Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync")
+introduced some of these, and there probably were a few others before
+it.  It's better to do the locking so that even if these run
+concurrently no UAF is possible.
+
+Move the lookup of hci_conn and associated socket-specific conn to
+protocol recv handlers, and do them within a single critical section
+to cover hci_conn* usage and lookup.
+
+syzkaller has reported a crash that appears to be this issue:
+
+    [Task hdev->workqueue]          [Task 2]
+                                    hci_disconnect_all_sync
+    l2cap_recv_acldata(hcon)
+                                      hci_conn_get(hcon)
+                                      hci_abort_conn_sync(hcon)
+                                        hci_dev_lock
+      hci_dev_lock
+                                        hci_conn_del(hcon)
+      v-------------------------------- hci_dev_unlock
+                                      hci_conn_put(hcon)
+      conn = hcon->l2cap_data (UAF)
+
+Fixes: 5af1f84ed13a ("Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync")
+Reported-by: syzbot+d32d77220b92eddd89ad@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d32d77220b92eddd89ad
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 20 ++++++---
+ net/bluetooth/hci_core.c         | 73 +++++++++++---------------------
+ net/bluetooth/iso.c              | 30 ++++++++++---
+ net/bluetooth/l2cap_core.c       | 23 +++++++---
+ net/bluetooth/sco.c              | 35 +++++++++++----
+ 5 files changed, 108 insertions(+), 73 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 4ccb462a0a4b8..b020ce30929e6 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -855,11 +855,12 @@ extern struct mutex hci_cb_list_lock;
+ /* ----- HCI interface to upper protocols ----- */
+ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
+ int l2cap_disconn_ind(struct hci_conn *hcon);
+-void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags);
++int l2cap_recv_acldata(struct hci_dev *hdev, u16 handle, struct sk_buff *skb,
++                     u16 flags);
+ #if IS_ENABLED(CONFIG_BT_BREDR)
+ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
+-void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
++int sco_recv_scodata(struct hci_dev *hdev, u16 handle, struct sk_buff *skb);
+ #else
+ static inline int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                                 __u8 *flags)
+@@ -867,23 +868,30 @@ static inline int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+       return 0;
+ }
+-static inline void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
++static inline int sco_recv_scodata(struct hci_dev *hdev, u16 handle,
++                                 struct sk_buff *skb)
+ {
++      kfree_skb(skb);
++      return -ENOENT;
+ }
+ #endif
+ #if IS_ENABLED(CONFIG_BT_LE)
+ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
+-void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags);
++int iso_recv(struct hci_dev *hdev, u16 handle, struct sk_buff *skb,
++           u16 flags);
+ #else
+ static inline int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                                 __u8 *flags)
+ {
+       return 0;
+ }
+-static inline void iso_recv(struct hci_conn *hcon, struct sk_buff *skb,
+-                          u16 flags)
++
++static inline int iso_recv(struct hci_dev *hdev, u16 handle,
++                         struct sk_buff *skb, u16 flags)
+ {
++      kfree_skb(skb);
++      return -ENOENT;
+ }
+ #endif
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 72c7607aac209..057ec1a5230d9 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -3804,13 +3804,14 @@ static void hci_tx_work(struct work_struct *work)
+ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+       struct hci_acl_hdr *hdr;
+-      struct hci_conn *conn;
+       __u16 handle, flags;
++      int err;
+       hdr = skb_pull_data(skb, sizeof(*hdr));
+       if (!hdr) {
+               bt_dev_err(hdev, "ACL packet too small");
+-              goto drop;
++              kfree_skb(skb);
++              return;
+       }
+       handle = __le16_to_cpu(hdr->handle);
+@@ -3822,36 +3823,27 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+       hdev->stat.acl_rx++;
+-      hci_dev_lock(hdev);
+-      conn = hci_conn_hash_lookup_handle(hdev, handle);
+-      hci_dev_unlock(hdev);
+-
+-      if (conn) {
+-              hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
+-
+-              /* Send to upper protocol */
+-              l2cap_recv_acldata(conn, skb, flags);
+-              return;
+-      } else {
++      err = l2cap_recv_acldata(hdev, handle, skb, flags);
++      if (err == -ENOENT)
+               bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
+                          handle);
+-      }
+-
+-drop:
+-      kfree_skb(skb);
++      else if (err)
++              bt_dev_dbg(hdev, "ACL packet recv for handle %d failed: %d",
++                         handle, err);
+ }
+ /* SCO data packet */
+ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+       struct hci_sco_hdr *hdr;
+-      struct hci_conn *conn;
+       __u16 handle, flags;
++      int err;
+       hdr = skb_pull_data(skb, sizeof(*hdr));
+       if (!hdr) {
+               bt_dev_err(hdev, "SCO packet too small");
+-              goto drop;
++              kfree_skb(skb);
++              return;
+       }
+       handle = __le16_to_cpu(hdr->handle);
+@@ -3863,34 +3855,28 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+       hdev->stat.sco_rx++;
+-      hci_dev_lock(hdev);
+-      conn = hci_conn_hash_lookup_handle(hdev, handle);
+-      hci_dev_unlock(hdev);
++      hci_skb_pkt_status(skb) = flags & 0x03;
+-      if (conn) {
+-              /* Send to upper protocol */
+-              hci_skb_pkt_status(skb) = flags & 0x03;
+-              sco_recv_scodata(conn, skb);
+-              return;
+-      } else {
++      err = sco_recv_scodata(hdev, handle, skb);
++      if (err == -ENOENT)
+               bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
+                                      handle);
+-      }
+-
+-drop:
+-      kfree_skb(skb);
++      else if (err)
++              bt_dev_dbg(hdev, "SCO packet recv for handle %d failed: %d",
++                         handle, err);
+ }
+ static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+       struct hci_iso_hdr *hdr;
+-      struct hci_conn *conn;
+       __u16 handle, flags;
++      int err;
+       hdr = skb_pull_data(skb, sizeof(*hdr));
+       if (!hdr) {
+               bt_dev_err(hdev, "ISO packet too small");
+-              goto drop;
++              kfree_skb(skb);
++              return;
+       }
+       handle = __le16_to_cpu(hdr->handle);
+@@ -3900,22 +3886,13 @@ static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+       bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
+                  handle, flags);
+-      hci_dev_lock(hdev);
+-      conn = hci_conn_hash_lookup_handle(hdev, handle);
+-      hci_dev_unlock(hdev);
+-
+-      if (!conn) {
++      err = iso_recv(hdev, handle, skb, flags);
++      if (err == -ENOENT)
+               bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
+                          handle);
+-              goto drop;
+-      }
+-
+-      /* Send to upper protocol */
+-      iso_recv(conn, skb, flags);
+-      return;
+-
+-drop:
+-      kfree_skb(skb);
++      else if (err)
++              bt_dev_dbg(hdev, "ISO packet recv for handle %d failed: %d",
++                         handle, err);
+ }
+ static bool hci_req_is_complete(struct hci_dev *hdev)
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 3d98cb6291da6..616c2fef91d24 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -2314,14 +2314,31 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+       iso_conn_del(hcon, bt_to_errno(reason));
+ }
+-void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
++int iso_recv(struct hci_dev *hdev, u16 handle, struct sk_buff *skb, u16 flags)
+ {
+-      struct iso_conn *conn = hcon->iso_data;
++      struct hci_conn *hcon;
++      struct iso_conn *conn;
+       struct skb_shared_hwtstamps *hwts;
+       __u16 pb, ts, len, sn;
+-      if (!conn)
+-              goto drop;
++      hci_dev_lock(hdev);
++
++      hcon = hci_conn_hash_lookup_handle(hdev, handle);
++      if (!hcon) {
++              hci_dev_unlock(hdev);
++              kfree_skb(skb);
++              return -ENOENT;
++      }
++
++      conn = iso_conn_hold_unless_zero(hcon->iso_data);
++      hcon = NULL;
++
++      hci_dev_unlock(hdev);
++
++      if (!conn) {
++              kfree_skb(skb);
++              return -EINVAL;
++      }
+       pb     = hci_iso_flags_pb(flags);
+       ts     = hci_iso_flags_ts(flags);
+@@ -2377,7 +2394,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+                       hci_skb_pkt_status(skb) = flags & 0x03;
+                       hci_skb_pkt_seqnum(skb) = sn;
+                       iso_recv_frame(conn, skb);
+-                      return;
++                      goto done;
+               }
+               if (pb == ISO_SINGLE) {
+@@ -2455,6 +2472,9 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+ drop:
+       kfree_skb(skb);
++done:
++      iso_conn_put(conn);
++      return 0;
+ }
+ static struct hci_cb iso_cb = {
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 35c57657bcf4e..07b493331fd78 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -7510,13 +7510,24 @@ struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
+       return c;
+ }
+-void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
++int l2cap_recv_acldata(struct hci_dev *hdev, u16 handle,
++                     struct sk_buff *skb, u16 flags)
+ {
++      struct hci_conn *hcon;
+       struct l2cap_conn *conn;
+       int len;
+-      /* Lock hdev to access l2cap_data to avoid race with l2cap_conn_del */
+-      hci_dev_lock(hcon->hdev);
++      /* Lock hdev for hci_conn, and race on l2cap_data vs. l2cap_conn_del */
++      hci_dev_lock(hdev);
++
++      hcon = hci_conn_hash_lookup_handle(hdev, handle);
++      if (!hcon) {
++              hci_dev_unlock(hdev);
++              kfree_skb(skb);
++              return -ENOENT;
++      }
++
++      hci_conn_enter_active_mode(hcon, BT_POWER_FORCE_ACTIVE_OFF);
+       conn = hcon->l2cap_data;
+@@ -7524,12 +7535,13 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+               conn = l2cap_conn_add(hcon);
+       conn = l2cap_conn_hold_unless_zero(conn);
++      hcon = NULL;
+-      hci_dev_unlock(hcon->hdev);
++      hci_dev_unlock(hdev);
+       if (!conn) {
+               kfree_skb(skb);
+-              return;
++              return -EINVAL;
+       }
+       BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags);
+@@ -7643,6 +7655,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+ unlock:
+       mutex_unlock(&conn->lock);
+       l2cap_conn_put(conn);
++      return 0;
+ }
+ static struct hci_cb l2cap_cb = {
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index ab0cf442d57b9..298c2a9ab4df8 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -1458,22 +1458,39 @@ static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+       sco_conn_del(hcon, bt_to_errno(reason));
+ }
+-void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
++int sco_recv_scodata(struct hci_dev *hdev, u16 handle, struct sk_buff *skb)
+ {
+-      struct sco_conn *conn = hcon->sco_data;
++      struct hci_conn *hcon;
++      struct sco_conn *conn;
+-      if (!conn)
+-              goto drop;
++      hci_dev_lock(hdev);
++
++      hcon = hci_conn_hash_lookup_handle(hdev, handle);
++      if (!hcon) {
++              hci_dev_unlock(hdev);
++              kfree_skb(skb);
++              return -ENOENT;
++      }
++
++      conn = sco_conn_hold_unless_zero(hcon->sco_data);
++      hcon = NULL;
++
++      hci_dev_unlock(hdev);
++
++      if (!conn) {
++              kfree_skb(skb);
++              return -EINVAL;
++      }
+       BT_DBG("conn %p len %u", conn, skb->len);
+-      if (skb->len) {
++      if (skb->len)
+               sco_recv_frame(conn, skb);
+-              return;
+-      }
++      else
++              kfree_skb(skb);
+-drop:
+-      kfree_skb(skb);
++      sco_conn_put(conn);
++      return 0;
+ }
+ static struct hci_cb sco_cb = {
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch b/queue-6.17/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
new file mode 100644 (file)
index 0000000..283300e
--- /dev/null
@@ -0,0 +1,72 @@
+From 0970cdaa84350f65d1366fbbc3886989ce95a20a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Nov 2025 17:04:43 +0800
+Subject: Bluetooth: hci_sock: Prevent race in socket write iter and sock bind
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 89bb613511cc21ed5ba6bddc1c9b9ae9c0dad392 ]
+
+There is a potential race condition between sock bind and socket write
+iter. bind may free the same cmd via mgmt_pending before write iter sends
+the cmd, just as syzbot reported in UAF[1].
+
+Here we use hci_dev_lock to synchronize the two, thereby avoiding the
+UAF mentioned in [1].
+
+[1]
+syzbot reported:
+BUG: KASAN: slab-use-after-free in mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+Read of size 8 at addr ffff888077164818 by task syz.0.17/5989
+Call Trace:
+ mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+ set_link_security+0x5c2/0x710 net/bluetooth/mgmt.c:1918
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Allocated by task 5989:
+ mgmt_pending_add+0x35/0x140 net/bluetooth/mgmt_util.c:296
+ set_link_security+0x557/0x710 net/bluetooth/mgmt.c:1910
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Freed by task 5991:
+ mgmt_pending_free net/bluetooth/mgmt_util.c:311 [inline]
+ mgmt_pending_foreach+0x30d/0x380 net/bluetooth/mgmt_util.c:257
+ mgmt_index_removed+0x112/0x2f0 net/bluetooth/mgmt.c:9477
+ hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314
+
+Fixes: 6fe26f694c82 ("Bluetooth: MGMT: Protect mgmt_pending list with its own lock")
+Reported-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=9aa47cd4633a3cf92a80
+Tested-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index fc866759910d9..ad19022ae127a 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -1311,7 +1311,9 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+                       goto done;
+               }
++              hci_dev_lock(hdev);
+               mgmt_index_removed(hdev);
++              hci_dev_unlock(hdev);
+               err = hci_dev_open(hdev->id);
+               if (err) {
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-6.17/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..9445e70
--- /dev/null
@@ -0,0 +1,87 @@
+From f3b3b3d18fab81e61e22c6d0ea6ccb95f376710e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index 45512b2ba951c..3a1ce04a7a536 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2136,7 +2136,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2188,24 +2188,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2226,11 +2208,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch b/queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
new file mode 100644 (file)
index 0000000..de07a27
--- /dev/null
@@ -0,0 +1,92 @@
+From 983a287813f8200f17100df3337f21f2acdd1de1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:02 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing header
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf ]
+
+The driver expects to receive a struct gs_host_frame in
+gs_usb_receive_bulk_callback().
+
+Use struct_group to describe the header of the struct gs_host_frame and
+check that we have at least received the header before accessing any
+members of it.
+
+To resubmit the URB, do not dereference the pointer chain
+"dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since
+"urb->context" contains "parent", it is always defined, while "dev" is not
+defined if the URB it too short.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-2-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index fa9bab8c89aea..51f8d694104d9 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -262,13 +262,15 @@ struct canfd_quirk {
+ } __packed;
+ struct gs_host_frame {
+-      u32 echo_id;
+-      __le32 can_id;
++      struct_group(header,
++              u32 echo_id;
++              __le32 can_id;
+-      u8 can_dlc;
+-      u8 channel;
+-      u8 flags;
+-      u8 reserved;
++              u8 can_dlc;
++              u8 channel;
++              u8 flags;
++              u8 reserved;
++      );
+       union {
+               DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
+@@ -576,6 +578,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
++      unsigned int minimum_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -594,6 +597,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+               return;
+       }
++      minimum_length = sizeof(hf->header);
++      if (urb->actual_length < minimum_length) {
++              dev_err_ratelimited(&parent->udev->dev,
++                                  "short read (actual_length=%u, minimum_length=%u)\n",
++                                  urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
+       /* device reports out of range channel id */
+       if (hf->channel >= parent->channel_cnt)
+               goto device_detach;
+@@ -687,7 +699,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ resubmit_urb:
+       usb_fill_bulk_urb(urb, parent->udev,
+                         parent->pipe_in,
+-                        hf, dev->parent->hf_size_rx,
++                        hf, parent->hf_size_rx,
+                         gs_usb_receive_bulk_callback, parent);
+       rc = usb_submit_urb(urb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-24056 b/queue-6.17/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-24056
new file mode 100644 (file)
index 0000000..ccc72b7
--- /dev/null
@@ -0,0 +1,140 @@
+From 55152876a57052fae02003905df6bc971af434d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:03 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing data
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 395d988f93861101ec89d0dd9e3b876ae9392a5b ]
+
+The URB received in gs_usb_receive_bulk_callback() contains a struct
+gs_host_frame. The length of the data after the header depends on the
+gs_host_frame hf::flags and the active device features (e.g. time
+stamping).
+
+Introduce a new function gs_usb_get_minimum_length() and check that we have
+at least received the required amount of data before accessing it. Only
+copy the data to that skb that has actually been received.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-3-a29b42eacada@pengutronix.de
+[mkl: rename gs_usb_get_minimum_length() -> +gs_usb_get_minimum_rx_length()]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 59 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 51f8d694104d9..8d8a610f91441 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -261,6 +261,11 @@ struct canfd_quirk {
+       u8 quirk;
+ } __packed;
++/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates
++ * a regular RX'ed CAN frame
++ */
++#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff
++
+ struct gs_host_frame {
+       struct_group(header,
+               u32 echo_id;
+@@ -570,6 +575,37 @@ gs_usb_get_echo_skb(struct gs_can *dev, struct sk_buff *skb,
+       return len;
+ }
++static unsigned int
++gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf,
++                           unsigned int *data_length_p)
++{
++      unsigned int minimum_length, data_length = 0;
++
++      if (hf->flags & GS_CAN_FLAG_FD) {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX)
++                      data_length = can_fd_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, canfd_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      } else {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX &&
++                  !(hf->can_id & cpu_to_le32(CAN_RTR_FLAG)))
++                      data_length = can_cc_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, classic_can_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      }
++
++      *data_length_p = data_length;
++      return minimum_length;
++}
++
+ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ {
+       struct gs_usb *parent = urb->context;
+@@ -578,7 +614,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
+-      unsigned int minimum_length;
++      unsigned int minimum_length, data_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -621,20 +657,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       if (!netif_running(netdev))
+               goto resubmit_urb;
+-      if (hf->echo_id == -1) { /* normal rx */
++      minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length);
++      if (urb->actual_length < minimum_length) {
++              stats->rx_errors++;
++              stats->rx_length_errors++;
++
++              if (net_ratelimit())
++                      netdev_err(netdev,
++                                 "short read (actual_length=%u, minimum_length=%u)\n",
++                                 urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
++      if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */
+               if (hf->flags & GS_CAN_FLAG_FD) {
+                       skb = alloc_canfd_skb(netdev, &cfd);
+                       if (!skb)
+                               return;
+                       cfd->can_id = le32_to_cpu(hf->can_id);
+-                      cfd->len = can_fd_dlc2len(hf->can_dlc);
++                      cfd->len = data_length;
+                       if (hf->flags & GS_CAN_FLAG_BRS)
+                               cfd->flags |= CANFD_BRS;
+                       if (hf->flags & GS_CAN_FLAG_ESI)
+                               cfd->flags |= CANFD_ESI;
+-                      memcpy(cfd->data, hf->canfd->data, cfd->len);
++                      memcpy(cfd->data, hf->canfd->data, data_length);
+               } else {
+                       skb = alloc_can_skb(netdev, &cf);
+                       if (!skb)
+@@ -643,7 +692,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+                       cf->can_id = le32_to_cpu(hf->can_id);
+                       can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
+-                      memcpy(cf->data, hf->classic_can->data, 8);
++                      memcpy(cf->data, hf->classic_can->data, data_length);
+                       /* ERROR frames tell us information about the controller */
+                       if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
+-- 
+2.51.0
+
diff --git a/queue-6.17/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch b/queue-6.17/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
new file mode 100644 (file)
index 0000000..949e05f
--- /dev/null
@@ -0,0 +1,60 @@
+From 73a7c20c979b8ed358ac3d15a4a0a122b5cdeeb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:01 +0100
+Subject: can: gs_usb: gs_usb_xmit_callback(): fix handling of failed
+ transmitted URBs
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 ]
+
+The driver lacks the cleanup of failed transfers of URBs. This reduces the
+number of available URBs per error by 1. This leads to reduced performance
+and ultimately to a complete stop of the transmission.
+
+If the sending of a bulk URB fails do proper cleanup:
+- increase netdev stats
+- mark the echo_sbk as free
+- free the driver's context and do accounting
+- wake the send queue
+
+Closes: https://github.com/candle-usb/candleLight_fw/issues/187
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-1-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 69b8d6da651bf..fa9bab8c89aea 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -750,8 +750,21 @@ static void gs_usb_xmit_callback(struct urb *urb)
+       struct gs_can *dev = txc->dev;
+       struct net_device *netdev = dev->netdev;
+-      if (urb->status)
+-              netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
++      if (!urb->status)
++              return;
++
++      if (urb->status != -ESHUTDOWN && net_ratelimit())
++              netdev_info(netdev, "failed to xmit URB %u: %pe\n",
++                          txc->echo_id, ERR_PTR(urb->status));
++
++      netdev->stats.tx_dropped++;
++      netdev->stats.tx_errors++;
++
++      can_free_echo_skb(netdev, txc->echo_id, NULL);
++      gs_free_tx_context(txc);
++      atomic_dec(&dev->active_tx_urbs);
++
++      netif_wake_queue(netdev);
+ }
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+-- 
+2.51.0
+
diff --git a/queue-6.17/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-6.17/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..29079fe
--- /dev/null
@@ -0,0 +1,62 @@
+From 33c13d92da6b54dbf988b0ac828db00dadf08e88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index c29828a94ad0e..1167d38344f1d 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -685,7 +685,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1732,7 +1732,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-6.17/dma-direct-fix-missing-sg_dma_len-assignment-in-p2pd.patch b/queue-6.17/dma-direct-fix-missing-sg_dma_len-assignment-in-p2pd.patch
new file mode 100644 (file)
index 0000000..70e5828
--- /dev/null
@@ -0,0 +1,65 @@
+From 93e0fa80961761bb76e8134f8f72a3b0b4085d8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:41:12 +0000
+Subject: dma-direct: Fix missing sg_dma_len assignment in P2PDMA bus mappings
+
+From: Pranjal Shrivastava <praan@google.com>
+
+[ Upstream commit d0d08f4bd7f667dc7a65cd7133c0a94a6f02aca3 ]
+
+Prior to commit a25e7962db0d7 ("PCI/P2PDMA: Refactor the p2pdma mapping
+helpers"), P2P segments were mapped using the pci_p2pdma_map_segment()
+helper. This helper was responsible for populating sg->dma_address,
+marking the bus address, and also setting sg_dma_len(sg).
+
+The refactor[1] removed this helper and moved the mapping logic directly
+into the callers. While iommu_dma_map_sg() was correctly updated to set
+the length in the new flow, it was missed in dma_direct_map_sg().
+
+Thus, in dma_direct_map_sg(), the PCI_P2PDMA_MAP_BUS_ADDR case sets the
+dma_address and marks the segment, but immediately executes 'continue',
+which causes the loop to skip the standard assignment logic at the end:
+
+    sg_dma_len(sg) = sg->length;
+
+As a result, when CONFIG_NEED_SG_DMA_LENGTH is enabled, the dma_length
+field remains uninitialized (zero) for P2P bus address mappings. This
+breaks upper-layer drivers (for e.g. RDMA/IB) that rely on sg_dma_len()
+to determine the transfer size.
+
+Fix this by explicitly setting the DMA length in the
+PCI_P2PDMA_MAP_BUS_ADDR case before continuing to the next scatterlist
+entry.
+
+Fixes: a25e7962db0d7 ("PCI/P2PDMA: Refactor the p2pdma mapping helpers")
+Reported-by: Jacob Moroni <jmoroni@google.com>
+Signed-off-by: Pranjal Shrivastava <praan@google.com>
+
+[1]
+https://lore.kernel.org/all/ac14a0e94355bf898de65d023ccf8a2ad22a3ece.1746424934.git.leon@kernel.org/
+
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Shivaji Kant <shivajikant@google.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20251126114112.3694469-1-praan@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/direct.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index 24c359d9c8799..95f37028032df 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -486,6 +486,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+               case PCI_P2PDMA_MAP_BUS_ADDR:
+                       sg->dma_address = pci_p2pdma_bus_addr_map(&p2pdma_state,
+                                       sg_phys(sg));
++                      sg_dma_len(sg) = sg->length;
+                       sg_dma_mark_bus_address(sg);
+                       continue;
+               default:
+-- 
+2.51.0
+
diff --git a/queue-6.17/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch b/queue-6.17/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
new file mode 100644 (file)
index 0000000..c0ffa55
--- /dev/null
@@ -0,0 +1,39 @@
+From 7ee18e074e4edf6272b7fba54bcb291d4942e65c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 09:40:31 -0500
+Subject: drm/amdgpu: fix cyan_skillfish2 gpu info fw handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 ]
+
+If the board supports IP discovery, we don't need to
+parse the gpu info firmware.
+
+Backport to 6.18.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4721
+Fixes: fa819e3a7c1e ("drm/amdgpu: add support for cyan skillfish gpu_info")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5427e32fa3a0ba9a016db83877851ed277b065fb)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index aaee97cd9a109..a713d5e6e4012 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2604,6 +2604,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
+               chip_name = "navi12";
+               break;
+       case CHIP_CYAN_SKILLFISH:
++              if (adev->mman.discovery_bin)
++                      return 0;
+               chip_name = "cyan_skillfish";
+               break;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.17/drm-bridge-sii902x-fix-hdmi-detection-with-drm_bridg.patch b/queue-6.17/drm-bridge-sii902x-fix-hdmi-detection-with-drm_bridg.patch
new file mode 100644 (file)
index 0000000..c740eaa
--- /dev/null
@@ -0,0 +1,118 @@
+From 2e16f286f9c5109051146eccf91b6a51b4ca3c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Oct 2025 20:46:35 +0530
+Subject: drm/bridge: sii902x: Fix HDMI detection with
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR
+
+From: Devarsh Thakkar <devarsht@ti.com>
+
+[ Upstream commit d6732ef4ab252e5753be7acad87b0a91cfd06953 ]
+
+The sii902x driver was caching HDMI detection state in a sink_is_hdmi field
+and checking it in mode_set() to determine whether to set HDMI or DVI
+output mode. This approach had two problems:
+
+1. With DRM_BRIDGE_ATTACH_NO_CONNECTOR (used by modern display drivers like
+TIDSS), the bridge's get_modes() is never called. Instead, the
+drm_bridge_connector helper calls the bridge's edid_read() and updates the
+connector itself. This meant sink_is_hdmi was never populated, causing the
+driver to default to DVI mode and breaking HDMI audio.
+
+2. The mode_set() callback doesn't receive atomic state or connector
+pointer, making it impossible to check connector->display_info.is_hdmi
+directly at that point.
+
+Fix this by moving the HDMI vs DVI decision from mode_set() to
+atomic_enable(), where we can access the connector via
+drm_atomic_get_new_connector_for_encoder(). This works for both connector
+models:
+
+- With DRM_BRIDGE_ATTACH_NO_CONNECTOR: Returns the drm_bridge_connector
+  created by the display driver, which has already been updated by the
+helper's call to drm_edid_connector_update()
+
+- Without DRM_BRIDGE_ATTACH_NO_CONNECTOR (legacy): Returns the connector
+  embedded in sii902x struct, which gets updated by the bridge's own
+get_modes()
+
+Fixes: 3de47e1309c2 ("drm/bridge: sii902x: use display info is_hdmi")
+Signed-off-by: Devarsh Thakkar <devarsht@ti.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patch.msgid.link/20251030151635.3019864-1-devarsht@ti.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/sii902x.c | 20 ++++++++------------
+ 1 file changed, 8 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
+index d537b1d036fb0..1f0aba28ad1e1 100644
+--- a/drivers/gpu/drm/bridge/sii902x.c
++++ b/drivers/gpu/drm/bridge/sii902x.c
+@@ -179,7 +179,6 @@ struct sii902x {
+       struct drm_connector connector;
+       struct gpio_desc *reset_gpio;
+       struct i2c_mux_core *i2cmux;
+-      bool sink_is_hdmi;
+       u32 bus_width;
+       /*
+@@ -315,8 +314,6 @@ static int sii902x_get_modes(struct drm_connector *connector)
+               drm_edid_free(drm_edid);
+       }
+-      sii902x->sink_is_hdmi = connector->display_info.is_hdmi;
+-
+       return num;
+ }
+@@ -342,9 +339,17 @@ static void sii902x_bridge_atomic_enable(struct drm_bridge *bridge,
+                                        struct drm_atomic_state *state)
+ {
+       struct sii902x *sii902x = bridge_to_sii902x(bridge);
++      struct drm_connector *connector;
++      u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
++
++      connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
++      if (connector && connector->display_info.is_hdmi)
++              output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
+       mutex_lock(&sii902x->mutex);
++      regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
++                         SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
+       regmap_update_bits(sii902x->regmap, SII902X_PWR_STATE_CTRL,
+                          SII902X_AVI_POWER_STATE_MSK,
+                          SII902X_AVI_POWER_STATE_D(0));
+@@ -359,16 +364,12 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
+                                   const struct drm_display_mode *adj)
+ {
+       struct sii902x *sii902x = bridge_to_sii902x(bridge);
+-      u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
+       struct regmap *regmap = sii902x->regmap;
+       u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
+       struct hdmi_avi_infoframe frame;
+       u16 pixel_clock_10kHz = adj->clock / 10;
+       int ret;
+-      if (sii902x->sink_is_hdmi)
+-              output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
+-
+       buf[0] = pixel_clock_10kHz & 0xff;
+       buf[1] = pixel_clock_10kHz >> 8;
+       buf[2] = drm_mode_vrefresh(adj);
+@@ -384,11 +385,6 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
+       mutex_lock(&sii902x->mutex);
+-      ret = regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
+-                               SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
+-      if (ret)
+-              goto out;
+-
+       ret = regmap_bulk_write(regmap, SII902X_TPI_VIDEO_DATA, buf, 10);
+       if (ret)
+               goto out;
+-- 
+2.51.0
+
diff --git a/queue-6.17/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch b/queue-6.17/drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch
new file mode 100644 (file)
index 0000000..6880080
--- /dev/null
@@ -0,0 +1,54 @@
+From 159a51be38e048c106ba0e8d5d6b3378bab57f11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 11:48:43 -0800
+Subject: drm/xe: Fix conversion from clock ticks to milliseconds
+
+From: Harish Chegondi <harish.chegondi@intel.com>
+
+[ Upstream commit 7276878b069c57d9a9cca5db01d2f7a427b73456 ]
+
+When tick counts are large and multiplication by MSEC_PER_SEC is larger
+than 64 bits, the conversion from clock ticks to milliseconds can go bad.
+
+Use mul_u64_u32_div() instead.
+
+Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Signed-off-by: Harish Chegondi <harish.chegondi@intel.com>
+Suggested-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+Fixes: 49cc215aad7f ("drm/xe: Add xe_gt_clock_interval_to_ms helper")
+Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Link: https://patch.msgid.link/1562f1b62d5be3fbaee100f09107f3cc49e40dd1.1763408584.git.harish.chegondi@intel.com
+(cherry picked from commit 96b93ac214f9dd66294d975d86c5dee256faef91)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt_clock.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_clock.c b/drivers/gpu/drm/xe/xe_gt_clock.c
+index 4f011d1573c65..f65d1edd05671 100644
+--- a/drivers/gpu/drm/xe/xe_gt_clock.c
++++ b/drivers/gpu/drm/xe/xe_gt_clock.c
+@@ -93,11 +93,6 @@ int xe_gt_clock_init(struct xe_gt *gt)
+       return 0;
+ }
+-static u64 div_u64_roundup(u64 n, u32 d)
+-{
+-      return div_u64(n + d - 1, d);
+-}
+-
+ /**
+  * xe_gt_clock_interval_to_ms - Convert sampled GT clock ticks to msec
+  *
+@@ -108,5 +103,5 @@ static u64 div_u64_roundup(u64 n, u32 d)
+  */
+ u64 xe_gt_clock_interval_to_ms(struct xe_gt *gt, u64 count)
+ {
+-      return div_u64_roundup(count * MSEC_PER_SEC, gt->info.reference_clock);
++      return mul_u64_u32_div(count, MSEC_PER_SEC, gt->info.reference_clock);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/eth-fbnic-fix-counter-roll-over-issue.patch b/queue-6.17/eth-fbnic-fix-counter-roll-over-issue.patch
new file mode 100644 (file)
index 0000000..40c63d1
--- /dev/null
@@ -0,0 +1,43 @@
+From 990942516145fa85c3f5427a60ec5943b26be0ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 13:17:04 -0800
+Subject: eth: fbnic: Fix counter roll-over issue
+
+From: Mohsin Bashir <mohsin.bashr@gmail.com>
+
+[ Upstream commit 6d66e093e0740d39a36ef742c60eec247df26f41 ]
+
+Fix a potential counter roll-over issue in fbnic_mbx_alloc_rx_msgs()
+when calculating descriptor slots. The issue occurs when head - tail
+results in a large positive value (unsigned) and the compiler interprets
+head - tail - 1 as a signed value.
+
+Since FBNIC_IPC_MBX_DESC_LEN is a power of two, use a masking operation,
+which is a common way of avoiding this problem when dealing with these
+sort of ring space calculations.
+
+Fixes: da3cde08209e ("eth: fbnic: Add FW communication mechanism")
+Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20251125211704.3222413-1-mohsin.bashr@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+index 0c55be7d25476..acc1ad91b0c3a 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+@@ -201,7 +201,7 @@ static int fbnic_mbx_alloc_rx_msgs(struct fbnic_dev *fbd)
+               return -ENODEV;
+       /* Fill all but 1 unused descriptors in the Rx queue. */
+-      count = (head - tail - 1) % FBNIC_IPC_MBX_DESC_LEN;
++      count = (head - tail - 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
+       while (!err && count--) {
+               struct fbnic_tlv_msg *msg;
+-- 
+2.51.0
+
diff --git a/queue-6.17/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch b/queue-6.17/fs-namespace-fix-reference-leak-in-grab_requested_mn.patch
new file mode 100644 (file)
index 0000000..8a4ae08
--- /dev/null
@@ -0,0 +1,53 @@
+From b1b8dd2b1c34a47d18db09438cf385205d8f93d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 07:19:53 +0000
+Subject: fs/namespace: fix reference leak in grab_requested_mnt_ns
+
+From: Andrei Vagin <avagin@google.com>
+
+[ Upstream commit 7b6dcd9bfd869eee7693e45b1817dac8c56e5f86 ]
+
+lookup_mnt_ns() already takes a reference on mnt_ns.
+grab_requested_mnt_ns() doesn't need to take an extra reference.
+
+Fixes: 78f0e33cd6c93 ("fs/namespace: correctly handle errors returned by grab_requested_mnt_ns")
+Signed-off-by: Andrei Vagin <avagin@google.com>
+Link: https://patch.msgid.link/20251122071953.3053755-1-avagin@google.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index fd988bc759bd3..e059c2c9867f0 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -5901,6 +5901,8 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
+       if (kreq->mnt_ns_id) {
+               mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id);
++              if (!mnt_ns)
++                      return ERR_PTR(-ENOENT);
+       } else if (kreq->mnt_ns_fd) {
+               struct ns_common *ns;
+@@ -5916,13 +5918,12 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
+                       return ERR_PTR(-EINVAL);
+               mnt_ns = to_mnt_ns(ns);
++              refcount_inc(&mnt_ns->passive);
+       } else {
+               mnt_ns = current->nsproxy->mnt_ns;
++              refcount_inc(&mnt_ns->passive);
+       }
+-      if (!mnt_ns)
+-              return ERR_PTR(-ENOENT);
+-      refcount_inc(&mnt_ns->passive);
+       return mnt_ns;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch b/queue-6.17/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
new file mode 100644 (file)
index 0000000..1590680
--- /dev/null
@@ -0,0 +1,132 @@
+From 6ec900978604cc3ba958356ba123f4bf2b4cb613 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 18:16:19 +0200
+Subject: iio: st_lsm6dsx: Fixed calibrated timestamp calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Tesi <martepisa@gmail.com>
+
+[ Upstream commit 8abbf45fcda028c2c05ba38eb14ede9fa9e7341b ]
+
+The calibrated timestamp is calculated from the nominal value using the
+formula:
+  ts_gain[ns] â‰ˆ ts_sensitivity - (ts_trim_coeff * val) / 1000.
+
+The values of ts_sensitivity and ts_trim_coeff are not the same for all
+devices, so it is necessary to differentiate them based on the part name.
+For the correct values please consult the relevant AN.
+
+Fixes: cb3b6b8e1bc0 ("iio: imu: st_lsm6dsx: add odr calibration feature")
+Signed-off-by: Mario Tesi <mario.tesi@st.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h      | 18 ++++++++++++++++++
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 19 ++++++++-----------
+ 2 files changed, 26 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+index c225b246c8a55..f8486a1b02d07 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+@@ -192,6 +192,22 @@ struct st_lsm6dsx_fifo_ops {
+  * @fifo_en: Hw timer FIFO enable register info (addr + mask).
+  * @decimator: Hw timer FIFO decimator register info (addr + mask).
+  * @freq_fine: Difference in % of ODR with respect to the typical.
++ * @ts_sensitivity: Nominal timestamp sensitivity.
++ * @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
++ *                 This coefficient comes into play when linearizing the formula
++ *                 used to calculate the calibrated timestamp (please see the
++ *                 relevant formula in the AN for the specific IMU).
++ *                 For example, in the case of LSM6DSO we have:
++ *
++ *                  1 / (1 + x) ~= 1 - x (Taylor’s Series)
++ *                  ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
++ *                  ttrim[ns] ~= 25000 - 37.5 * val
++ *                  ttrim[ns] ~= 25000 - (37500 * val) / 1000
++ *
++ *                  so, replacing ts_sensitivity = 25000 and
++ *                  ts_trim_coeff = 37500
++ *
++ *                  ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
+  */
+ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg timer_en;
+@@ -199,6 +215,8 @@ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg fifo_en;
+       struct st_lsm6dsx_reg decimator;
+       u8 freq_fine;
++      u16 ts_sensitivity;
++      u16 ts_trim_coeff;
+ };
+ /**
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index c65ad49829e7d..72d8af39a9535 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -94,8 +94,6 @@
+ #define ST_LSM6DSX_REG_WHOAMI_ADDR            0x0f
+-#define ST_LSM6DSX_TS_SENSITIVITY             25000UL /* 25us */
+-
+ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+@@ -983,6 +981,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -1196,6 +1196,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .event_settings = {
+                       .enable_reg = {
+@@ -1371,6 +1373,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x4f,
++                      .ts_sensitivity = 21701,
++                      .ts_trim_coeff = 28212,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -2248,20 +2252,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
+       }
+       /* calibrate timestamp sensitivity */
+-      hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
++      hw->ts_gain = ts_settings->ts_sensitivity;
+       if (ts_settings->freq_fine) {
+               err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
+               if (err < 0)
+                       return err;
+-              /*
+-               * linearize the AN5192 formula:
+-               * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
+-               * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
+-               * ttrim[ns] ~= 25000 - 37.5 * val
+-               * ttrim[ns] ~= 25000 - (37500 * val) / 1000
+-               */
+-              hw->ts_gain -= ((s8)val * 37500) / 1000;
++              hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000;
+       }
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-6.17/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..be219f5
--- /dev/null
@@ -0,0 +1,38 @@
+From 7eb2c9d3a1fdde48cd0ec0912d7e2bbe5f1272a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index c9dd8c42c0cdf..3a28ab5c42e57 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -268,7 +268,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.17/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch b/queue-6.17/mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch
new file mode 100644 (file)
index 0000000..18ee48f
--- /dev/null
@@ -0,0 +1,169 @@
+From a2f5d24e27777a586ebf0e0155257d947c3240bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 01:16:30 +0800
+Subject: mailbox: mtk-cmdq: Refine DMA address handling for the command buffer
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit a195c7ccfb7a21b8118139835e25936ec8722596 ]
+
+GCE can only fetch the command buffer address from a 32-bit register.
+Some SoCs support a 35-bit command buffer address for GCE, which
+requires a right shift of 3 bits before setting the address into
+the 32-bit register. A comment has been added to the header of
+cmdq_get_shift_pa() to explain this requirement.
+
+To prevent the GCE command buffer address from being DMA mapped beyond
+its supported bit range, the DMA bit mask for the device is set during
+initialization.
+
+Additionally, to ensure the correct shift is applied when setting or
+reading the register that stores the GCE command buffer address,
+new APIs, cmdq_convert_gce_addr() and cmdq_revert_gce_addr(), have
+been introduced for consistent operations on this register.
+
+The variable type for the command buffer address has been standardized
+to dma_addr_t to prevent handling issues caused by type mismatches.
+
+Fixes: 0858fde496f8 ("mailbox: cmdq: variablize address shift in platform")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mtk-cmdq-mailbox.c       | 45 ++++++++++++++++--------
+ include/linux/mailbox/mtk-cmdq-mailbox.h | 10 ++++++
+ 2 files changed, 41 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
+index 654a60f63756a..5791f80f995ab 100644
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c
+@@ -92,6 +92,18 @@ struct gce_plat {
+       u32 gce_num;
+ };
++static inline u32 cmdq_convert_gce_addr(dma_addr_t addr, const struct gce_plat *pdata)
++{
++      /* Convert DMA addr (PA or IOVA) to GCE readable addr */
++      return addr >> pdata->shift;
++}
++
++static inline dma_addr_t cmdq_revert_gce_addr(u32 addr, const struct gce_plat *pdata)
++{
++      /* Revert GCE readable addr to DMA addr (PA or IOVA) */
++      return (dma_addr_t)addr << pdata->shift;
++}
++
+ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+ {
+       struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+@@ -188,13 +200,12 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
+       struct cmdq_task *prev_task = list_last_entry(
+                       &thread->task_busy_list, typeof(*task), list_entry);
+       u64 *prev_task_base = prev_task->pkt->va_base;
++      u32 gce_addr = cmdq_convert_gce_addr(task->pa_base, task->cmdq->pdata);
+       /* let previous task jump to this task */
+       dma_sync_single_for_cpu(dev, prev_task->pa_base,
+                               prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+-      prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
+-              (u64)CMDQ_JUMP_BY_PA << 32 |
+-              (task->pa_base >> task->cmdq->pdata->shift);
++      prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] = (u64)CMDQ_JUMP_BY_PA << 32 | gce_addr;
+       dma_sync_single_for_device(dev, prev_task->pa_base,
+                                  prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+@@ -237,7 +248,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+                                   struct cmdq_thread *thread)
+ {
+       struct cmdq_task *task, *tmp, *curr_task = NULL;
+-      u32 curr_pa, irq_flag, task_end_pa;
++      u32 irq_flag, gce_addr;
++      dma_addr_t curr_pa, task_end_pa;
+       bool err;
+       irq_flag = readl(thread->base + CMDQ_THR_IRQ_STATUS);
+@@ -259,7 +271,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+       else
+               return;
+-      curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
++      gce_addr = readl(thread->base + CMDQ_THR_CURR_ADDR);
++      curr_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
+       list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+                                list_entry) {
+@@ -378,7 +391,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+       struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+       struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+       struct cmdq_task *task;
+-      unsigned long curr_pa, end_pa;
++      u32 gce_addr;
++      dma_addr_t curr_pa, end_pa;
+       /* Client should not flush new tasks if suspended. */
+       WARN_ON(cmdq->suspended);
+@@ -402,20 +416,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+                */
+               WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
+-              writel(task->pa_base >> cmdq->pdata->shift,
+-                     thread->base + CMDQ_THR_CURR_ADDR);
+-              writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
+-                     thread->base + CMDQ_THR_END_ADDR);
++              gce_addr = cmdq_convert_gce_addr(task->pa_base, cmdq->pdata);
++              writel(gce_addr, thread->base + CMDQ_THR_CURR_ADDR);
++              gce_addr = cmdq_convert_gce_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata);
++              writel(gce_addr, thread->base + CMDQ_THR_END_ADDR);
+               writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
+               writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
+               writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+       } else {
+               WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+-              curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+-                      cmdq->pdata->shift;
+-              end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+-                      cmdq->pdata->shift;
++              gce_addr = readl(thread->base + CMDQ_THR_CURR_ADDR);
++              curr_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
++              gce_addr = readl(thread->base + CMDQ_THR_END_ADDR);
++              end_pa = cmdq_revert_gce_addr(gce_addr, cmdq->pdata);
+               /* check boundary */
+               if (curr_pa == end_pa - CMDQ_INST_SIZE ||
+                   curr_pa == end_pa) {
+@@ -646,6 +660,9 @@ static int cmdq_probe(struct platform_device *pdev)
+       if (err)
+               return err;
++      dma_set_coherent_mask(dev,
++                            DMA_BIT_MASK(sizeof(u32) * BITS_PER_BYTE + cmdq->pdata->shift));
++
+       cmdq->mbox.dev = dev;
+       cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr,
+                                       sizeof(*cmdq->mbox.chans), GFP_KERNEL);
+diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
+index 4c1a91b07de39..e1555e06e7e55 100644
+--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
++++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
+@@ -77,6 +77,16 @@ struct cmdq_pkt {
+       size_t                  buf_size; /* real buffer size */
+ };
++/**
++ * cmdq_get_shift_pa() - get the shift bits of physical address
++ * @chan: mailbox channel
++ *
++ * GCE can only fetch the command buffer address from a 32-bit register.
++ * Some SOCs support more than 32-bit command buffer address for GCE, which
++ * requires some shift bits to make the address fit into the 32-bit register.
++ *
++ * Return: the shift bits of physical address
++ */
+ u8 cmdq_get_shift_pa(struct mbox_chan *chan);
+ #endif /* __MTK_CMDQ_MAILBOX_H__ */
+-- 
+2.51.0
+
diff --git a/queue-6.17/mailbox-pcc-don-t-zero-error-register.patch b/queue-6.17/mailbox-pcc-don-t-zero-error-register.patch
new file mode 100644 (file)
index 0000000..74a2790
--- /dev/null
@@ -0,0 +1,57 @@
+From 6e0b5c86b230decae3b67f282797e659f4931068 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:42:29 +0000
+Subject: mailbox: pcc: don't zero error register
+
+From: Jamie Iles <jamie.iles@oss.qualcomm.com>
+
+[ Upstream commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 ]
+
+The error status mask for a type 3/4 subspace is used for reading the
+error status, and the bitwise inverse is used for clearing the error
+with the intent being to preserve any of the non-error bits.  However,
+we were previously applying the mask to extract the status and then
+applying the inverse to the result which ended up clearing all bits.
+
+Instead, store the inverse mask in the preserve mask and then use that
+on the original value read from the error status so that only the error
+is cleared.
+
+Fixes: c45ded7e1135 ("mailbox: pcc: Add support for PCCT extended PCC subspaces(type 3/4)")
+Signed-off-by: Jamie Iles <jamie.iles@oss.qualcomm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@oss.qualcomm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 0a00719b24827..ff292b9e0be9e 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -276,9 +276,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
+       if (ret)
+               return ret;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
++      if (val & pchan->error.status_mask) {
++              val &= pchan->error.preserve_mask;
+               pcc_chan_reg_write(&pchan->error, val);
+               return -EIO;
+       }
+@@ -745,7 +744,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
+               ret = pcc_chan_reg_init(&pchan->error,
+                                       &pcct_ext->error_status_register,
+-                                      0, 0, pcct_ext->error_status_mask,
++                                      ~pcct_ext->error_status_mask, 0,
++                                      pcct_ext->error_status_mask,
+                                       "Error Status");
+       }
+       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-6.17/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..6b3be43
--- /dev/null
@@ -0,0 +1,144 @@
+From f9d66bf8f2bc1fc45070941b05fb5814dc50da0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 493432d036b9a..c7895bfb2ecf8 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index b0ed572e88c67..0ce9caae8799c 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-6.17/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..e8937fa
--- /dev/null
@@ -0,0 +1,93 @@
+From 676b0c8ffde531e31764c12559a89a3f60925777 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index f21de0c21e524..d23d23bed39fe 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch b/queue-6.17/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
new file mode 100644 (file)
index 0000000..f28736a
--- /dev/null
@@ -0,0 +1,73 @@
+From 9cfbd94ace102d9cbb15152dd5b8461442ff0fa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 13:13:24 +0200
+Subject: net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing
+ traffic
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
+
+When using the SGMII PCS as a fixed-link chip-to-chip connection, it is
+easy to miss the fact that traffic passes only at 1G, since that's what
+any normal such connection would use.
+
+When using the SGMII PCS connected towards an on-board PHY or an SFP
+module, it is immediately noticeable that when the link resolves to a
+speed other than 1G, traffic from the MAC fails to pass: TX counters
+increase, but nothing gets decoded by the other end, and no local RX
+counters increase either.
+
+Artificially lowering a fixed-link rate to speed = <100> makes us able
+to see the same issue as in the case of having an SGMII PHY.
+
+Some debugging shows that the XPCS configuration is A-OK, but that the
+MAC Configuration Table entry for the port has the SPEED bits still set
+to 1000Mbps, due to a special condition in the driver. Deleting that
+condition, and letting the resolved link speed be programmed directly
+into the MAC speed field, results in a functional link at all 3 speeds.
+
+This piece of evidence, based on testing on both generations with SGMII
+support (SJA1105S and SJA1110A) directly contradicts the statement from
+the blamed commit that "the MAC is fixed at 1 Gbps and we need to
+configure the PCS only (if even that)". Worse, that statement is not
+backed by any documentation, and no one from NXP knows what it might
+refer to.
+
+I am unable to recall sufficient context regarding my testing from March
+2020 to understand what led me to draw such a braindead and factually
+incorrect conclusion. Yet, there is nothing of value regarding forcing
+the MAC speed, either for SGMII or 2500Base-X (introduced at a later
+stage), so remove all such logic.
+
+Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index f674c400f05b2..aa2145cf29a67 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1302,14 +1302,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
+        * table, since this will be used for the clocking setup, and we no
+        * longer need to store it in the static config (already told hardware
+        * we want auto during upload phase).
+-       * Actually for the SGMII port, the MAC is fixed at 1 Gbps and
+-       * we need to configure the PCS only (if even that).
+        */
+-      if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+-      else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-
+       mac[port].speed = speed;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-fec-cancel-perout_timer-when-perout-is-disabled.patch b/queue-6.17/net-fec-cancel-perout_timer-when-perout-is-disabled.patch
new file mode 100644 (file)
index 0000000..22b2db7
--- /dev/null
@@ -0,0 +1,42 @@
+From 1167763a1a9b2779391ed74c75eca6abdb4ed95d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:07 +0800
+Subject: net: fec: cancel perout_timer when PEROUT is disabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 50caa744689e505414673c20359b04aa918439e3 ]
+
+The PEROUT allows the user to set a specified future time to output the
+periodic signal. If the future time is far from the current time, the FEC
+driver will use hrtimer to configure PEROUT one second before the future
+time. However, the hrtimer will not be canceled if the PEROUT is disabled
+before the hrtimer expires. So the PEROUT will be configured when the
+hrtimer expires, which is not as expected. Therefore, cancel the hrtimer
+in fec_ptp_pps_disable() to fix this issue.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-2-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index fa88b47d526c0..7a5367ea94101 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -497,6 +497,8 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+ {
+       unsigned long flags;
++      hrtimer_cancel(&fep->perout_timer);
++
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch b/queue-6.17/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
new file mode 100644 (file)
index 0000000..9e3c90e
--- /dev/null
@@ -0,0 +1,58 @@
+From ec2aaace8584afe9eafcba76c95caff7d8f56fbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:09 +0800
+Subject: net: fec: do not allow enabling PPS and PEROUT simultaneously
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit c0a1f3d7e128e8d1b6c0fe09c68eac5ebcf677c8 ]
+
+In the current driver, PPS and PEROUT use the same channel to generate
+the events, so they cannot be enabled at the same time. Otherwise, the
+later configuration will overwrite the earlier configuration. Therefore,
+when configuring PPS, the driver will check whether PEROUT is enabled.
+Similarly, when configuring PEROUT, the driver will check whether PPS
+is enabled.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-4-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index f31b1626c12f7..ed5d59abeb537 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -128,6 +128,12 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      if (fep->perout_enable) {
++              spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++              dev_err(&fep->pdev->dev, "PEROUT is running");
++              return -EBUSY;
++      }
++
+       if (fep->pps_enable == enable) {
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return 0;
+@@ -571,6 +577,12 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++                      if (fep->pps_enable) {
++                              dev_err(&fep->pdev->dev, "PPS is running");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       if (fep->perout_enable) {
+                               dev_err(&fep->pdev->dev,
+                                       "PEROUT has been enabled\n");
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-fec-do-not-register-pps-event-for-perout.patch b/queue-6.17/net-fec-do-not-register-pps-event-for-perout.patch
new file mode 100644 (file)
index 0000000..f843f95
--- /dev/null
@@ -0,0 +1,48 @@
+From e88d4903d313fca971622f6beb5e280f76aab188 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:10 +0800
+Subject: net: fec: do not register PPS event for PEROUT
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 9a060d0fac9e75524f72864adec6d8cdb70a5bca ]
+
+There are currently two situations that can trigger the PTP interrupt,
+one is the PPS event, the other is the PEROUT event. However, the irq
+handler fec_pps_interrupt() does not check the irq event type and
+directly registers a PPS event into the system, but the event may be
+a PEROUT event. This is incorrect because PEROUT is an output signal,
+while PPS is the input of the kernel PPS system. Therefore, add a check
+for the event type, if pps_enable is true, it means that the current
+event is a PPS event, and then the PPS event is registered.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-5-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index ed5d59abeb537..4b7bad9a485df 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -718,8 +718,11 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id)
+               fep->next_counter = (fep->next_counter + fep->reload_period) &
+                               fep->cc.mask;
+-              event.type = PTP_CLOCK_PPS;
+-              ptp_clock_event(fep->ptp_clock, &event);
++              if (fep->pps_enable) {
++                      event.type = PTP_CLOCK_PPS;
++                      ptp_clock_event(fep->ptp_clock, &event);
++              }
++
+               return IRQ_HANDLED;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-fec-do-not-update-perout-if-it-is-enabled.patch b/queue-6.17/net-fec-do-not-update-perout-if-it-is-enabled.patch
new file mode 100644 (file)
index 0000000..ce6cd1a
--- /dev/null
@@ -0,0 +1,137 @@
+From 53cd1a9a31fff9c37d5df6945309100d130617fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:08 +0800
+Subject: net: fec: do not update PEROUT if it is enabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e97faa0c20ea8840f45569ba434e30538fff8fc9 ]
+
+If the previously set PEROUT is already active, updating it will cause
+the new PEROUT to start immediately instead of at the specified time.
+This is because fep->reload_period is updated whithout check whether
+the PEROUT is enabled, and the old PEROUT is not disabled. Therefore,
+the pulse period will be updated immediately in the pulse interrupt
+handler fec_pps_interrupt().
+
+Currently, the driver does not support directly updating PEROUT and it
+will make the logic be more complicated. To fix the current issue, add
+a check before enabling the PEROUT, the driver will return an error if
+PEROUT is enabled. If users wants to update a new PEROUT, they should
+disable the old PEROUT first.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-3-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec.h     |  1 +
+ drivers/net/ethernet/freescale/fec_ptp.c | 43 ++++++++++++++++++------
+ 2 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 5c8fdcef759ba..2601e0b074dd6 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -680,6 +680,7 @@ struct fec_enet_private {
+       unsigned int reload_period;
+       int pps_enable;
+       unsigned int next_counter;
++      bool perout_enable;
+       struct hrtimer perout_timer;
+       u64 perout_stime;
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index 7a5367ea94101..f31b1626c12f7 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -243,6 +243,7 @@ static int fec_ptp_pps_perout(struct fec_enet_private *fep)
+        * the FEC_TCCR register in time and missed the start time.
+        */
+       if (fep->perout_stime < curr_time + 100 * NSEC_PER_MSEC) {
++              fep->perout_enable = false;
+               dev_err(&fep->pdev->dev, "Current time is too close to the start time!\n");
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return -1;
+@@ -500,6 +501,7 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+       hrtimer_cancel(&fep->perout_timer);
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      fep->perout_enable = false;
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+@@ -531,6 +533,8 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+               return ret;
+       } else if (rq->type == PTP_CLK_REQ_PEROUT) {
++              u32 reload_period;
++
+               /* Reject requests with unsupported flags */
+               if (rq->perout.flags)
+                       return -EOPNOTSUPP;
+@@ -550,12 +554,14 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       return -EOPNOTSUPP;
+               }
+-              fep->reload_period = div_u64(period_ns, 2);
+-              if (on && fep->reload_period) {
++              reload_period = div_u64(period_ns, 2);
++              if (on && reload_period) {
++                      u64 perout_stime;
++
+                       /* Convert 1588 timestamp to ns*/
+                       start_time.tv_sec = rq->perout.start.sec;
+                       start_time.tv_nsec = rq->perout.start.nsec;
+-                      fep->perout_stime = timespec64_to_ns(&start_time);
++                      perout_stime = timespec64_to_ns(&start_time);
+                       mutex_lock(&fep->ptp_clk_mutex);
+                       if (!fep->ptp_clk_on) {
+@@ -564,18 +570,35 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                               return -EOPNOTSUPP;
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++
++                      if (fep->perout_enable) {
++                              dev_err(&fep->pdev->dev,
++                                      "PEROUT has been enabled\n");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       /* Read current timestamp */
+                       curr_time = timecounter_read(&fep->tc);
+-                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-                      mutex_unlock(&fep->ptp_clk_mutex);
++                      if (perout_stime <= curr_time) {
++                              dev_err(&fep->pdev->dev,
++                                      "Start time must be greater than current time\n");
++                              ret = -EINVAL;
++                              goto unlock;
++                      }
+                       /* Calculate time difference */
+-                      delta = fep->perout_stime - curr_time;
++                      delta = perout_stime - curr_time;
++                      fep->reload_period = reload_period;
++                      fep->perout_stime = perout_stime;
++                      fep->perout_enable = true;
+-                      if (fep->perout_stime <= curr_time) {
+-                              dev_err(&fep->pdev->dev, "Start time must larger than current time!\n");
+-                              return -EINVAL;
+-                      }
++unlock:
++                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++                      mutex_unlock(&fep->ptp_clk_mutex);
++
++                      if (ret)
++                              return ret;
+                       /* Because the timer counter of FEC only has 31-bits, correspondingly,
+                        * the time comparison register FEC_TCCR also only low 31 bits can be
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-lan966x-fix-the-initialization-of-taprio.patch b/queue-6.17/net-lan966x-fix-the-initialization-of-taprio.patch
new file mode 100644 (file)
index 0000000..15c7056
--- /dev/null
@@ -0,0 +1,56 @@
+From 14208465038283a11780d2c216b53aa11c9893f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 07:14:11 +0100
+Subject: net: lan966x: Fix the initialization of taprio
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 ]
+
+To initialize the taprio block in lan966x, it is required to configure
+the register REVISIT_DLY. The purpose of this register is to set the
+delay before revisit the next gate and the value of this register depends
+on the system clock. The problem is that the we calculated wrong the value
+of the system clock period in picoseconds. The actual system clock is
+~165.617754MHZ and this correspond to a period of 6038 pico seconds and
+not 15125 as currently set.
+
+Fixes: e462b2717380b4 ("net: lan966x: Add offload support for taprio")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121061411.810571-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index b4377b8613c3a..8c40db90ee8f6 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -1,11 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/ptp_classify.h>
++#include <linux/units.h>
+ #include "lan966x_main.h"
+ #include "vcap_api.h"
+ #include "vcap_api_client.h"
++#define LAN9X66_CLOCK_RATE    165617754
++
+ #define LAN966X_MAX_PTP_ID    512
+ /* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
+@@ -1126,5 +1129,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u32 lan966x_ptp_get_period_ps(void)
+ {
+       /* This represents the system clock period in picoseconds */
+-      return 15125;
++      return PICO / LAN9X66_CLOCK_RATE;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mctp-unconditionally-set-skb-dev-on-dst-output.patch b/queue-6.17/net-mctp-unconditionally-set-skb-dev-on-dst-output.patch
new file mode 100644 (file)
index 0000000..a34eae8
--- /dev/null
@@ -0,0 +1,46 @@
+From 325afd0b13d76d93dc4c38c5e7f138a334334270 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 14:48:54 +0800
+Subject: net: mctp: unconditionally set skb->dev on dst output
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit b3e528a5811bbc8246dbdb962f0812dc9b721681 ]
+
+On transmit, we are currently relying on skb->dev being set by
+mctp_local_output() when we first set up the skb destination fields.
+However, forwarded skbs do not use the local_output path, so will retain
+their incoming netdev as their ->dev on tx. This does not work when
+we're forwarding between interfaces.
+
+Set skb->dev unconditionally in the transmit path, to allow for proper
+forwarding.
+
+We keep the skb->dev initialisation in mctp_local_output(), as we use it
+for fragmentation.
+
+Fixes: 269936db5eb3 ("net: mctp: separate routing database from routing operations")
+Suggested-by: Vince Chang <vince_chang@aspeedtech.com>
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20251125-dev-forward-v1-1-54ecffcd0616@codeconstruct.com.au
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mctp/route.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 4d314e062ba9c..2ac4011a953ff 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -623,6 +623,7 @@ static int mctp_dst_output(struct mctp_dst *dst, struct sk_buff *skb)
+       skb->protocol = htons(ETH_P_MCTP);
+       skb->pkt_type = PACKET_OUTGOING;
++      skb->dev = dst->dev->dev;
+       if (skb->len > dst->mtu) {
+               kfree_skb(skb);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-6.17/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..6070c5e
--- /dev/null
@@ -0,0 +1,63 @@
+From 72c301752b56dedd9521231a80fb677a7a065f92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 9b93da4d52f64..cf8f14ce4cd50 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -627,7 +627,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch b/queue-6.17/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
new file mode 100644 (file)
index 0000000..e36d353
--- /dev/null
@@ -0,0 +1,42 @@
+From 8e41d31997f805165ac96ff12fedf8069a5a9271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 14:17:13 +0000
+Subject: net: phy: mxl-gpy: fix bogus error on USXGMII and integrated PHY
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit ec3803b5917b6ff2f86ea965d0985c95d8a85119 ]
+
+As the interface mode doesn't need to be updated on PHYs connected with
+USXGMII and integrated PHYs, gpy_update_interface() should just return 0
+in these cases rather than -EINVAL which has wrongly been introduced by
+commit 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface()
+function return type"), as this breaks support for those PHYs.
+
+Fixes: 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface() function return type")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/f744f721a1fcc5e2e936428c62ff2c7d94d2a293.1763648168.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mxl-gpy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index 0c8dc16ee7bde..221b315203d06 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -540,7 +540,7 @@ static int gpy_update_interface(struct phy_device *phydev)
+       /* Interface mode is fixed for USXGMII and integrated PHY */
+       if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
+           phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
+-              return -EINVAL;
++              return 0;
+       /* Automatically switch SERDES interface between SGMII and 2500-BaseX
+        * according to speed. Disable ANEG in 2500-BaseX mode.
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-phy-mxl-gpy-fix-link-properties-on-usxgmii-and-i.patch b/queue-6.17/net-phy-mxl-gpy-fix-link-properties-on-usxgmii-and-i.patch
new file mode 100644 (file)
index 0000000..a228360
--- /dev/null
@@ -0,0 +1,65 @@
+From 528a61ad10c14ffaf78deddaa4f96704f42351dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 15:02:19 +0000
+Subject: net: phy: mxl-gpy: fix link properties on USXGMII and internal PHYs
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 081156ce13f8fa4e97b5148dc54d8c0ddf02117b ]
+
+gpy_update_interface() returns early in case the PHY is internal or
+connected via USXGMII. In this case the gigabit master/slave property
+as well as MDI/MDI-X status also won't be read which seems wrong.
+Always read those properties by moving the logic to retrieve them to
+gpy_read_status().
+
+Fixes: fd8825cd8c6fc ("net: phy: mxl-gpy: Add PHY Auto/MDI/MDI-X set driver for GPY211 chips")
+Fixes: 311abcdddc00a ("net: phy: add support to get Master-Slave configuration")
+Suggested-by: "Russell King (Oracle)" <linux@armlinux.org.uk>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/71fccf3f56742116eb18cc070d2a9810479ea7f9.1763650701.git.daniel@makrotopia.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mxl-gpy.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index 221b315203d06..2a873f791733a 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -578,13 +578,7 @@ static int gpy_update_interface(struct phy_device *phydev)
+               break;
+       }
+-      if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
+-              ret = genphy_read_master_slave(phydev);
+-              if (ret < 0)
+-                      return ret;
+-      }
+-
+-      return gpy_update_mdix(phydev);
++      return 0;
+ }
+ static int gpy_read_status(struct phy_device *phydev)
+@@ -639,6 +633,16 @@ static int gpy_read_status(struct phy_device *phydev)
+               ret = gpy_update_interface(phydev);
+               if (ret < 0)
+                       return ret;
++
++              if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
++                      ret = genphy_read_master_slave(phydev);
++                      if (ret < 0)
++                              return ret;
++              }
++
++              ret = gpy_update_mdix(phydev);
++              if (ret < 0)
++                      return ret;
+       }
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-6.17/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..a2b1602
--- /dev/null
@@ -0,0 +1,47 @@
+From 816f7a6e37ce885f81ee19a84418eb3f190e341c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index 75bad561b3525..849c5a6c2af1e 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1521,8 +1521,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch b/queue-6.17/net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch
new file mode 100644 (file)
index 0000000..dc214f9
--- /dev/null
@@ -0,0 +1,39 @@
+From 51ad1881a6b15a28ef54c2ff651b4d4ab72880f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 15:09:00 +0800
+Subject: net: wwan: mhi: Keep modem name match with Foxconn T99W640
+
+From: Slark Xiao <slark_xiao@163.com>
+
+[ Upstream commit 4fcb8ab4a09b1855dbfd7062605dd13abd64c086 ]
+
+Correct it since M.2 device T99W640 has updated from T99W515.
+We need to align it with MHI side otherwise this modem can't
+get the network.
+
+Fixes: ae5a34264354 ("bus: mhi: host: pci_generic: Fix the modem name of Foxconn T99W640")
+Signed-off-by: Slark Xiao <slark_xiao@163.com>
+Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251125070900.33324-1-slark_xiao@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wwan/mhi_wwan_mbim.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
+index c814fbd756a1e..f8bc9a39bfa30 100644
+--- a/drivers/net/wwan/mhi_wwan_mbim.c
++++ b/drivers/net/wwan/mhi_wwan_mbim.c
+@@ -98,7 +98,7 @@ static struct mhi_mbim_link *mhi_mbim_get_link_rcu(struct mhi_mbim_context *mbim
+ static int mhi_mbim_get_link_mux_id(struct mhi_controller *cntrl)
+ {
+       if (strcmp(cntrl->name, "foxconn-dw5934e") == 0 ||
+-          strcmp(cntrl->name, "foxconn-t99w515") == 0)
++          strcmp(cntrl->name, "foxconn-t99w640") == 0)
+               return WDS_BIND_MUX_DATA_PORT_MUX_ID;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/ovl-fail-ovl_lock_rename_workdir-if-either-target-is.patch b/queue-6.17/ovl-fail-ovl_lock_rename_workdir-if-either-target-is.patch
new file mode 100644 (file)
index 0000000..7b4386c
--- /dev/null
@@ -0,0 +1,44 @@
+From 886f8e95661e175c01b8abb1971a06ce258936aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 12:22:35 +1100
+Subject: ovl: fail ovl_lock_rename_workdir() if either target is unhashed
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit e9c70084a64e51b65bb68f810692a03dc8bedffa ]
+
+As well as checking that the parent hasn't changed after getting the
+lock we need to check that the dentry hasn't been unhashed.
+Otherwise we might try to rename something that has been removed.
+
+Reported-by: syzbot+bfc9a0ccf0de47d04e8c@syzkaller.appspotmail.com
+Fixes: d2c995581c7c ("ovl: Call ovl_create_temp() without lock held.")
+Signed-off-by: NeilBrown <neil@brown.name>
+Link: https://patch.msgid.link/176429295510.634289.1552337113663461690@noble.neil.brown.name
+Tested-by: syzbot+bfc9a0ccf0de47d04e8c@syzkaller.appspotmail.com
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/util.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index 41033bac96cbb..ab652164ffc90 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -1234,9 +1234,9 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *work,
+               goto err;
+       if (trap)
+               goto err_unlock;
+-      if (work && work->d_parent != workdir)
++      if (work && (work->d_parent != workdir || d_unhashed(work)))
+               goto err_unlock;
+-      if (upper && upper->d_parent != upperdir)
++      if (upper && (upper->d_parent != upperdir || d_unhashed(upper)))
+               goto err_unlock;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/platform-x86-intel-punit_ipc-fix-memory-corruption.patch b/queue-6.17/platform-x86-intel-punit_ipc-fix-memory-corruption.patch
new file mode 100644 (file)
index 0000000..efe7c90
--- /dev/null
@@ -0,0 +1,46 @@
+From 6716124e0974ae8d44a6c7e323067e4e731f5e4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 20:51:28 +0300
+Subject: platform/x86: intel: punit_ipc: fix memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
+
+This passes the address of the pointer "&punit_ipcdev" when the intent
+was to pass the pointer itself "punit_ipcdev" (without the ampersand).
+This means that the:
+
+       complete(&ipcdev->cmd_complete);
+
+in intel_punit_ioc() will write to a wrong memory address corrupting it.
+
+Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/punit_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
+index bafac8aa2baf6..14513010daadf 100644
+--- a/drivers/platform/x86/intel/punit_ipc.c
++++ b/drivers/platform/x86/intel/punit_ipc.c
+@@ -250,7 +250,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
+       } else {
+               ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+                                      IRQF_NO_SUSPEND, "intel_punit_ipc",
+-                                     &punit_ipcdev);
++                                     punit_ipcdev);
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.17/riscv-dts-allwinner-d1-fix-vlenb-property.patch b/queue-6.17/riscv-dts-allwinner-d1-fix-vlenb-property.patch
new file mode 100644 (file)
index 0000000..f3add53
--- /dev/null
@@ -0,0 +1,40 @@
+From 44cb1109a21c44c2534eaf80e69157b8a0eabdd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 23:35:06 +0300
+Subject: riscv: dts: allwinner: d1: fix vlenb property
+
+From: Sergey Matyukevich <geomatsi@gmail.com>
+
+[ Upstream commit 9f393d8e757f79060baf4b2e703bd6b2d0d8d323 ]
+
+According to [1], the C906 vector registers are 128 bits wide.
+The 'thead,vlenb' property specifies the vector register length
+in bytes, so its value must be set to 16.
+
+[1] https://dl.linux-sunxi.org/D1/Xuantie_C906_R1S0_User_Manual.pdf
+
+Fixes: ce1daeeba600 ("riscv: dts: allwinner: Add xtheadvector to the D1/D1s devicetree")
+Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>
+Link: https://patch.msgid.link/20251119203508.1032716-1-geomatsi@gmail.com
+Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
+index 6367112e614a1..a7442a508433d 100644
+--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
++++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
+@@ -28,7 +28,7 @@
+                       riscv,isa-base = "rv64i";
+                       riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+                                              "zifencei", "zihpm", "xtheadvector";
+-                      thead,vlenb = <128>;
++                      thead,vlenb = <16>;
+                       #cooling-cells = <2>;
+                       cpu0_intc: interrupt-controller {
+-- 
+2.51.0
+
diff --git a/queue-6.17/series b/queue-6.17/series
new file mode 100644 (file)
index 0000000..3edb53d
--- /dev/null
@@ -0,0 +1,52 @@
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-24056
+bluetooth-btusb-mediatek-fix-kernel-crash-when-relea.patch
+bluetooth-hci_core-fix-triggering-cmd_timer-for-hci_.patch
+bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
+bluetooth-hci_core-lookup-hci_conn-on-rx-path-on-pro.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+veth-reduce-xdp-no_direct-return-section-to-fix-race.patch
+drm-bridge-sii902x-fix-hdmi-detection-with-drm_bridg.patch
+net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
+platform-x86-intel-punit_ipc-fix-memory-corruption.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-phy-mxl-gpy-fix-link-properties-on-usxgmii-and-i.patch
+net-lan966x-fix-the-initialization-of-taprio.patch
+drm-xe-fix-conversion-from-clock-ticks-to-millisecon.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+team-move-team-device-type-change-at-the-end-of-team.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+xsk-avoid-overwriting-skb-fields-for-multi-buffer-tr.patch
+xsk-avoid-data-corruption-on-cq-descriptor-number.patch
+drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
+dma-direct-fix-missing-sg_dma_len-assignment-in-p2pd.patch
+net-wwan-mhi-keep-modem-name-match-with-foxconn-t99w.patch
+net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
+eth-fbnic-fix-counter-roll-over-issue.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+net-mctp-unconditionally-set-skb-dev-on-dst-output.patch
+net-fec-cancel-perout_timer-when-perout-is-disabled.patch
+net-fec-do-not-update-perout-if-it-is-enabled.patch
+net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
+net-fec-do-not-register-pps-event-for-perout.patch
+iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
+xhci-sideband-add-api-to-trace-sideband-usage.patch
+xhci-sideband-fix-race-condition-in-sideband-unregis.patch
+usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+mailbox-mtk-cmdq-refine-dma-address-handling-for-the.patch
+mailbox-pcc-don-t-zero-error-register.patch
+spi-spi-cadence-quadspi-remove-duplicate-pm_runtime_.patch
+spi-spi-cadence-quadspi-enable-pm-runtime-earlier-to.patch
+fs-namespace-fix-reference-leak-in-grab_requested_mn.patch
+afs-fix-delayed-allocation-of-a-cell-s-anonymous-key.patch
+ovl-fail-ovl_lock_rename_workdir-if-either-target-is.patch
+riscv-dts-allwinner-d1-fix-vlenb-property.patch
+spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
+spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
+spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch
+spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
+afs-fix-uninit-var-in-afs_alloc_anon_key.patch
diff --git a/queue-6.17/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch b/queue-6.17/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
new file mode 100644 (file)
index 0000000..85cf773
--- /dev/null
@@ -0,0 +1,42 @@
+From 24bf9126ca51b4d12eaf5d5ad3c77409d23db7de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 09:58:52 +0800
+Subject: spi: amlogic-spifc-a1: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit a90903c2a3c38bce475f46ea3f93dbf6a9971553 ]
+
+devm_pm_runtime_enable() can fail due to memory allocation. The current
+code ignores its return value, potentially causing runtime PM operations
+to fail silently after autosuspend configuration.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 909fac05b926 ("spi: add support for Amlogic A1 SPI Flash Controller")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20251124015852.937-1-vulab@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-amlogic-spifc-a1.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c
+index 18c9aa2cbc290..eb503790017b2 100644
+--- a/drivers/spi/spi-amlogic-spifc-a1.c
++++ b/drivers/spi/spi-amlogic-spifc-a1.c
+@@ -353,7 +353,9 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
+       pm_runtime_set_autosuspend_delay(spifc->dev, 500);
+       pm_runtime_use_autosuspend(spifc->dev);
+-      devm_pm_runtime_enable(spifc->dev);
++      ret = devm_pm_runtime_enable(spifc->dev);
++      if (ret)
++              return ret;
+       ctrl->num_chipselect = 1;
+       ctrl->dev.of_node = pdev->dev.of_node;
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-6.17/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..a156afa
--- /dev/null
@@ -0,0 +1,68 @@
+From ffe3e2eceaff6a3425916658b4d249e302ed2745 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index b56210734caaf..2e3c62f12bef9 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch b/queue-6.17/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
new file mode 100644 (file)
index 0000000..63caee9
--- /dev/null
@@ -0,0 +1,78 @@
+From 0cbdad79d645ad14c27615674a1a49a28bac77be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:25:01 +0100
+Subject: spi: nxp-fspi: Propagate fwnode in ACPI case as well
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 40ad64ac25bb736740f895d99a4aebbda9b80991 ]
+
+Propagate fwnode of the ACPI device to the SPI controller Linux device.
+Currently only OF case propagates fwnode to the controller.
+
+While at it, replace several calls to dev_fwnode() with a single one
+cached in a local variable, and unify checks for fwnode type by using
+is_*_node() APIs.
+
+Fixes: 55ab8487e01d ("spi: spi-nxp-fspi: Add ACPI support")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20251126202501.2319679-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index fcf10be66d391..f96638cae1d94 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -1270,7 +1270,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctlr;
+       struct device *dev = &pdev->dev;
+-      struct device_node *np = dev->of_node;
++      struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct resource *res;
+       struct nxp_fspi *f;
+       int ret, irq;
+@@ -1292,7 +1292,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, f);
+       /* find the resources - configuration register address space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               f->iobase = devm_platform_ioremap_resource(pdev, 0);
+       else
+               f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base");
+@@ -1300,7 +1300,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+               return PTR_ERR(f->iobase);
+       /* find the resources - controller memory mapped space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               res = platform_get_resource_byname(pdev,
+@@ -1313,7 +1313,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       f->memmap_phy_size = resource_size(res);
+       /* find the clocks */
+-      if (dev_of_node(&pdev->dev)) {
++      if (is_of_node(fwnode)) {
+               f->clk_en = devm_clk_get(dev, "fspi_en");
+               if (IS_ERR(f->clk_en))
+                       return PTR_ERR(f->clk_en);
+@@ -1366,7 +1366,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       else
+               ctlr->mem_caps = &nxp_fspi_mem_caps;
+-      ctlr->dev.of_node = np;
++      device_set_node(&ctlr->dev, fwnode);
+       ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f);
+       if (ret)
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-spi-cadence-quadspi-enable-pm-runtime-earlier-to.patch b/queue-6.17/spi-spi-cadence-quadspi-enable-pm-runtime-earlier-to.patch
new file mode 100644 (file)
index 0000000..f608a38
--- /dev/null
@@ -0,0 +1,64 @@
+From fef97a3086e4ed7ab8550257a9236d845d6f4db4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 21:41:45 +0530
+Subject: spi: spi-cadence-quadspi: Enable pm runtime earlier to avoid
+ imbalance
+
+From: Anurag Dutta <a-dutta@ti.com>
+
+[ Upstream commit f1eb4e792bb1ee3dcdffa66f8a83a4867cda2dd3 ]
+
+The "probe_setup_failed" label calls pm_runtime_disable(), but
+pm_runtime_enable() was placed after a possible jump to this label.
+When cqspi_setup_flash() fails, control jumps to the label without
+pm_runtime_enable() being called, leading to unbalanced PM runtime
+reference counting.
+
+Move pm_runtime_enable() and associated calls above the first
+possible branch to "probe_setup_failed" to ensure balanced
+enable/disable calls across all error paths.
+
+Fixes: 30dbc1c8d50f ("spi: cadence-qspi: defer runtime support on socfpga if reset bit is enabled")
+Signed-off-by: Anurag Dutta <a-dutta@ti.com>
+Link: https://patch.msgid.link/20251105161146.2019090-2-a-dutta@ti.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-cadence-quadspi.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index d7720931403c2..4a5a83dc8fe37 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1981,6 +1981,13 @@ static int cqspi_probe(struct platform_device *pdev)
+       cqspi->current_cs = -1;
+       cqspi->sclk = 0;
++      if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
++              pm_runtime_enable(dev);
++              pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
++              pm_runtime_use_autosuspend(dev);
++              pm_runtime_get_noresume(dev);
++      }
++
+       ret = cqspi_setup_flash(cqspi);
+       if (ret) {
+               dev_err(dev, "failed to setup flash parameters %d\n", ret);
+@@ -1998,13 +2005,6 @@ static int cqspi_probe(struct platform_device *pdev)
+                       goto probe_dma_failed;
+       }
+-      if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
+-              pm_runtime_enable(dev);
+-              pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
+-              pm_runtime_use_autosuspend(dev);
+-              pm_runtime_get_noresume(dev);
+-      }
+-
+       ret = spi_register_controller(host);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-spi-cadence-quadspi-remove-duplicate-pm_runtime_.patch b/queue-6.17/spi-spi-cadence-quadspi-remove-duplicate-pm_runtime_.patch
new file mode 100644 (file)
index 0000000..e55866a
--- /dev/null
@@ -0,0 +1,42 @@
+From fd7c7f7167b22dd1eaaabcea3643ba2802943067 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 21:41:46 +0530
+Subject: spi: spi-cadence-quadspi: Remove duplicate
+ pm_runtime_put_autosuspend() call
+
+From: Anurag Dutta <a-dutta@ti.com>
+
+[ Upstream commit 10eaa4c4a257944e9b30d13fda7d09164a70866d ]
+
+Fix runtime PM usage count underflow caused by calling
+pm_runtime_put_autosuspend() twice with only one corresponding
+pm_runtime_get_noresume() call. This triggers the warning:
+"Runtime PM usage count underflow!"
+
+Remove the duplicate put call to balance the runtime PM reference
+counting.
+
+Fixes: 30dbc1c8d50f ("spi: cadence-qspi: defer runtime support on socfpga if reset bit is enabled")
+Signed-off-by: Anurag Dutta <a-dutta@ti.com>
+Link: https://patch.msgid.link/20251105161146.2019090-3-a-dutta@ti.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-cadence-quadspi.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index ce0f605ab688b..d7720931403c2 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -2012,7 +2012,6 @@ static int cqspi_probe(struct platform_device *pdev)
+       }
+       if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
+-              pm_runtime_put_autosuspend(dev);
+               pm_runtime_mark_last_busy(dev);
+               pm_runtime_put_autosuspend(dev);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch b/queue-6.17/spi-spi-nxp-fspi-add-oct-dtr-mode-support.patch
new file mode 100644 (file)
index 0000000..e7cacda
--- /dev/null
@@ -0,0 +1,79 @@
+From edeac5ea6317a394d6d398c545105ead4a259d7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 15:27:10 +0800
+Subject: spi: spi-nxp-fspi: Add OCT-DTR mode support
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 0f67557763accbdd56681f17ed5350735198c57b ]
+
+Add OCT-DTR mode support in default, since flexspi do not supports
+swapping bytes on a 16 bit boundary in OCT-DTR mode, so mark swap16
+as false.
+
+lx2160a do not support DQS, so add a quirk to disable DTR mode for this
+platform.
+
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20250917-flexspi-ddr-v2-5-bb9fe2a01889@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index ab13f11242c3c..fcf10be66d391 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -330,6 +330,8 @@
+ /* Access flash memory using IP bus only */
+ #define FSPI_QUIRK_USE_IP_ONLY        BIT(0)
++/* Disable DTR */
++#define FSPI_QUIRK_DISABLE_DTR        BIT(1)
+ struct nxp_fspi_devtype_data {
+       unsigned int rxfifo;
+@@ -344,7 +346,7 @@ static struct nxp_fspi_devtype_data lx2160a_data = {
+       .rxfifo = SZ_512,       /* (64  * 64 bits)  */
+       .txfifo = SZ_1K,        /* (128 * 64 bits)  */
+       .ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
+-      .quirks = 0,
++      .quirks = FSPI_QUIRK_DISABLE_DTR,
+       .lut_num = 32,
+       .little_endian = true,  /* little-endian    */
+ };
+@@ -1236,6 +1238,13 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
+ };
+ static const struct spi_controller_mem_caps nxp_fspi_mem_caps = {
++      .dtr = true,
++      .swap16 = false,
++      .per_op_freq = true,
++};
++
++static const struct spi_controller_mem_caps nxp_fspi_mem_caps_disable_dtr = {
++      .dtr = false,
+       .per_op_freq = true,
+ };
+@@ -1351,7 +1360,12 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       ctlr->bus_num = -1;
+       ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
+       ctlr->mem_ops = &nxp_fspi_mem_ops;
+-      ctlr->mem_caps = &nxp_fspi_mem_caps;
++
++      if (f->devtype_data->quirks & FSPI_QUIRK_DISABLE_DTR)
++              ctlr->mem_caps = &nxp_fspi_mem_caps_disable_dtr;
++      else
++              ctlr->mem_caps = &nxp_fspi_mem_caps;
++
+       ctlr->dev.of_node = np;
+       ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f);
+-- 
+2.51.0
+
diff --git a/queue-6.17/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch b/queue-6.17/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
new file mode 100644 (file)
index 0000000..7a9b845
--- /dev/null
@@ -0,0 +1,44 @@
+From 4b44046410101ea85b613578a0f31da808ba0c56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 10:50:27 +0100
+Subject: spi: tegra114: remove Kconfig dependency on TEGRA20_APB_DMA
+
+From: Francesco Lavra <flavra@baylibre.com>
+
+[ Upstream commit 3dcf44ab56e1d3ca3532083c0d5390b758e45b45 ]
+
+This driver runs also on Tegra SoCs without a Tegra20 APB DMA controller
+(e.g. Tegra234).
+Remove the Kconfig dependency on TEGRA20_APB_DMA; in addition, amend the
+help text to reflect the fact that this driver works on SoCs different from
+Tegra114.
+
+Fixes: bb9667d8187b ("arm64: tegra: Add SPI device tree nodes for Tegra234")
+Signed-off-by: Francesco Lavra <flavra@baylibre.com>
+Link: https://patch.msgid.link/20251126095027.4102004-1-flavra@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 891729c9c5642..9f20cb75bb856 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -1170,10 +1170,10 @@ config SPI_TEGRA210_QUAD
+ config SPI_TEGRA114
+       tristate "NVIDIA Tegra114 SPI Controller"
+-      depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
++      depends on ARCH_TEGRA || COMPILE_TEST
+       depends on RESET_CONTROLLER
+       help
+-        SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
++        SPI controller driver for NVIDIA Tegra114 and later SoCs. This controller
+         is different than the older SoCs SPI controller and also register interface
+         get changed with this controller.
+-- 
+2.51.0
+
diff --git a/queue-6.17/team-move-team-device-type-change-at-the-end-of-team.patch b/queue-6.17/team-move-team-device-type-change-at-the-end-of-team.patch
new file mode 100644 (file)
index 0000000..96cd899
--- /dev/null
@@ -0,0 +1,118 @@
+From b93ffa9bed3f9a03fe675480dbbf1c6040180d3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 02:20:27 +0200
+Subject: team: Move team device type change at the end of team_port_add
+
+From: Nikola Z. Ivanov <zlatistiv@gmail.com>
+
+[ Upstream commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef ]
+
+Attempting to add a port device that is already up will expectedly fail,
+but not before modifying the team device header_ops.
+
+In the case of the syzbot reproducer the gre0 device is
+already in state UP when it attempts to add it as a
+port device of team0, this fails but before that
+header_ops->create of team0 is changed from eth_header to ipgre_header
+in the call to team_dev_type_check_change.
+
+Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense
+as the private data of the device still holds a struct team.
+
+Example sequence of iproute2 commands to reproduce the hang/BUG():
+ip link add dev team0 type team
+ip link add dev gre0 type gre
+ip link set dev gre0 up
+ip link set dev gre0 master team0
+ip link set dev team0 up
+ping -I team0 1.1.1.1
+
+Move team_dev_type_check_change down where all other checks have passed
+as it changes the dev type with no way to restore it in case
+one of the checks that follow it fail.
+
+Also make sure to preserve the origial mtu assignment:
+  - If port_dev is not the same type as dev, dev takes mtu from port_dev
+  - If port_dev is the same type as dev, port_dev takes mtu from dev
+
+This is done by adding a conditional before the call to dev_set_mtu
+to prevent it from assigning port_dev->mtu = dev->mtu and instead
+letting team_dev_type_check_change assign dev->mtu = port_dev->mtu.
+The conditional is needed because the patch moves the call to
+team_dev_type_check_change past dev_set_mtu.
+
+Testing:
+  - team device driver in-tree selftests
+  - Add/remove various devices as slaves of team device
+  - syzbot
+
+Reported-by: syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a2a3b519de727b0f7903
+Fixes: 1d76efe1577b ("team: add support for non-ethernet devices")
+Signed-off-by: Nikola Z. Ivanov <zlatistiv@gmail.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20251122002027.695151-1-zlatistiv@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team_core.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
+index 17f07eb0ee52a..25562b17debe1 100644
+--- a/drivers/net/team/team_core.c
++++ b/drivers/net/team/team_core.c
+@@ -1191,10 +1191,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+               return -EPERM;
+       }
+-      err = team_dev_type_check_change(dev, port_dev);
+-      if (err)
+-              return err;
+-
+       if (port_dev->flags & IFF_UP) {
+               NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port");
+               netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
+@@ -1212,10 +1208,16 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+       INIT_LIST_HEAD(&port->qom_list);
+       port->orig.mtu = port_dev->mtu;
+-      err = dev_set_mtu(port_dev, dev->mtu);
+-      if (err) {
+-              netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
+-              goto err_set_mtu;
++      /*
++       * MTU assignment will be handled in team_dev_type_check_change
++       * if dev and port_dev are of different types
++       */
++      if (dev->type == port_dev->type) {
++              err = dev_set_mtu(port_dev, dev->mtu);
++              if (err) {
++                      netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
++                      goto err_set_mtu;
++              }
+       }
+       memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
+@@ -1290,6 +1292,10 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+               }
+       }
++      err = team_dev_type_check_change(dev, port_dev);
++      if (err)
++              goto err_set_dev_type;
++
+       if (dev->flags & IFF_UP) {
+               netif_addr_lock_bh(dev);
+               dev_uc_sync_multiple(port_dev, dev);
+@@ -1308,6 +1314,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
+       return 0;
++err_set_dev_type:
+ err_set_slave_promisc:
+       __team_option_inst_del_port(team, port);
+-- 
+2.51.0
+
diff --git a/queue-6.17/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch b/queue-6.17/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
new file mode 100644 (file)
index 0000000..26efa95
--- /dev/null
@@ -0,0 +1,45 @@
+From 4050504e9b34c44f3411c0057459d9695836084a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:22:15 +0800
+Subject: usb: gadget: renesas_usbf: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 74851fbb6d647304f8a7dc491434d3a335ef4b8d ]
+
+devm_pm_runtime_enable() can fail due to memory allocation.
+The current code ignores its return value, potentially causing
+pm_runtime_resume_and_get() to operate on uninitialized runtime
+PM state.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 3e6e14ffdea4 ("usb: gadget: udc: add Renesas RZ/N1 USBF controller support")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Acked-by: Herve Codina <herve.codina@bootlin.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/20251124022215.1619-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/renesas_usbf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c
+index 14f4b2cf05a48..4c201574a0af8 100644
+--- a/drivers/usb/gadget/udc/renesas_usbf.c
++++ b/drivers/usb/gadget/udc/renesas_usbf.c
+@@ -3262,7 +3262,9 @@ static int usbf_probe(struct platform_device *pdev)
+       if (IS_ERR(udc->regs))
+               return PTR_ERR(udc->regs);
+-      devm_pm_runtime_enable(&pdev->dev);
++      ret = devm_pm_runtime_enable(&pdev->dev);
++      if (ret)
++              return ret;
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.17/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch b/queue-6.17/veth-reduce-xdp-no_direct-return-section-to-fix-race.patch
new file mode 100644 (file)
index 0000000..223bb64
--- /dev/null
@@ -0,0 +1,70 @@
+From e10f87a144bcf4ce35d186f37263fbcc60f6703d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 17:28:36 +0100
+Subject: veth: reduce XDP no_direct return section to fix race
+
+From: Jesper Dangaard Brouer <hawk@kernel.org>
+
+[ Upstream commit a14602fcae17a3f1cb8a8521bedf31728f9e7e39 ]
+
+As explain in commit fa349e396e48 ("veth: Fix race with AF_XDP exposing
+old or uninitialized descriptors") for veth there is a chance after
+napi_complete_done() that another CPU can manage start another NAPI
+instance running veth_pool(). For NAPI this is correctly handled as the
+napi_schedule_prep() check will prevent multiple instances from getting
+scheduled, but for the remaining code in veth_pool() this can run
+concurrent with the newly started NAPI instance.
+
+The problem/race is that xdp_clear_return_frame_no_direct() isn't
+designed to be nested.
+
+Prior to commit 401cb7dae813 ("net: Reference bpf_redirect_info via
+task_struct on PREEMPT_RT.") the temporary BPF net context
+bpf_redirect_info was stored per CPU, where this wasn't an issue. Since
+this commit the BPF context is stored in 'current' task_struct. When
+running veth in threaded-NAPI mode, then the kthread becomes the storage
+area. Now a race exists between two concurrent veth_pool() function calls
+one exiting NAPI and one running new NAPI, both using the same BPF net
+context.
+
+Race is when another CPU gets within the xdp_set_return_frame_no_direct()
+section before exiting veth_pool() calls the clear-function
+xdp_clear_return_frame_no_direct().
+
+Fixes: 401cb7dae8130 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.")
+Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/176356963888.337072.4805242001928705046.stgit@firesoul
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/veth.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 35dd89aff4a94..cc502bf022d55 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -975,6 +975,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
+       if (stats.xdp_redirect > 0)
+               xdp_do_flush();
++      if (stats.xdp_tx > 0)
++              veth_xdp_flush(rq, &bq);
++      xdp_clear_return_frame_no_direct();
+       if (done < budget && napi_complete_done(napi, done)) {
+               /* Write rx_notify_masked before reading ptr_ring */
+@@ -987,10 +990,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
+               }
+       }
+-      if (stats.xdp_tx > 0)
+-              veth_xdp_flush(rq, &bq);
+-      xdp_clear_return_frame_no_direct();
+-
+       /* Release backpressure per NAPI poll */
+       smp_rmb(); /* Paired with netif_tx_stop_queue set_bit */
+       if (peer_txq && netif_tx_queue_stopped(peer_txq)) {
+-- 
+2.51.0
+
diff --git a/queue-6.17/xhci-sideband-add-api-to-trace-sideband-usage.patch b/queue-6.17/xhci-sideband-add-api-to-trace-sideband-usage.patch
new file mode 100644 (file)
index 0000000..dd8ffe8
--- /dev/null
@@ -0,0 +1,131 @@
+From a9e52c49125fe55a68d3b5dedec3fe61e2d19464 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Sep 2025 14:20:15 +0000
+Subject: xhci: sideband: add api to trace sideband usage
+
+From: Guan-Yu Lin <guanyulin@google.com>
+
+[ Upstream commit ef82a4803aabaf623bfcae07981406f1386eabf9 ]
+
+The existing sideband driver only registers sidebands without tracking
+their active usage. To address this, sideband will now record its active
+usage when it creates/removes interrupters. In addition, a new api is
+introduced to provide a means for other dirvers to fetch sideband
+activity information on a USB host controller.
+
+Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
+Link: https://lore.kernel.org/r/20250911142051.90822-4-guanyulin@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20250911142051.90822-4-guanyulin@google.com
+Stable-dep-of: 8c13a7323b84 ("xhci: sideband: Fix race condition in sideband unregister")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-sideband.c  | 36 +++++++++++++++++++++++++++++++
+ include/linux/usb/xhci-sideband.h |  9 ++++++++
+ 2 files changed, 45 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
+index d49f9886dd848..e771a476fef2e 100644
+--- a/drivers/usb/host/xhci-sideband.c
++++ b/drivers/usb/host/xhci-sideband.c
+@@ -266,6 +266,31 @@ xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
+ }
+ EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
++/**
++ * xhci_sideband_check - check the existence of active sidebands
++ * @hcd: the host controller driver associated with the target host controller
++ *
++ * Allow other drivers, such as usb controller driver, to check if there are
++ * any sideband activity on the host controller. This information could be used
++ * for power management or other forms of resource management. The caller should
++ * ensure downstream usb devices are all either suspended or marked as
++ * "offload_at_suspend" to ensure the correctness of the return value.
++ *
++ * Returns true on any active sideband existence, false otherwise.
++ */
++bool xhci_sideband_check(struct usb_hcd *hcd)
++{
++      struct usb_device *udev = hcd->self.root_hub;
++      bool active;
++
++      usb_lock_device(udev);
++      active = usb_offload_check(udev);
++      usb_unlock_device(udev);
++
++      return active;
++}
++EXPORT_SYMBOL_GPL(xhci_sideband_check);
++
+ /**
+  * xhci_sideband_create_interrupter - creates a new interrupter for this sideband
+  * @sb: sideband instance for this usb device
+@@ -286,6 +311,7 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+                                bool ip_autoclear, u32 imod_interval, int intr_num)
+ {
+       int ret = 0;
++      struct usb_device *udev;
+       if (!sb || !sb->xhci)
+               return -ENODEV;
+@@ -304,6 +330,9 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+               goto out;
+       }
++      udev = sb->vdev->udev;
++      ret = usb_offload_get(udev);
++
+       sb->ir->ip_autoclear = ip_autoclear;
+ out:
+@@ -323,6 +352,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
+ void
+ xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
+ {
++      struct usb_device *udev;
++
+       if (!sb || !sb->ir)
+               return;
+@@ -330,6 +361,11 @@ xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
+       xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
+       sb->ir = NULL;
++      udev = sb->vdev->udev;
++
++      if (udev->state != USB_STATE_NOTATTACHED)
++              usb_offload_put(udev);
++
+       mutex_unlock(&sb->mutex);
+ }
+ EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
+diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sideband.h
+index 45288c392f6e0..005257085dcbd 100644
+--- a/include/linux/usb/xhci-sideband.h
++++ b/include/linux/usb/xhci-sideband.h
+@@ -11,6 +11,7 @@
+ #include <linux/scatterlist.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #define       EP_CTX_PER_DEV          31      /* FIXME defined twice, from xhci.h */
+@@ -83,6 +84,14 @@ xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
+                                 struct usb_host_endpoint *host_ep);
+ struct sg_table *
+ xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
++
++#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
++bool xhci_sideband_check(struct usb_hcd *hcd);
++#else
++static inline bool xhci_sideband_check(struct usb_hcd *hcd)
++{ return false; }
++#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
++
+ int
+ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+                                bool ip_autoclear, u32 imod_interval, int intr_num);
+-- 
+2.51.0
+
diff --git a/queue-6.17/xhci-sideband-fix-race-condition-in-sideband-unregis.patch b/queue-6.17/xhci-sideband-fix-race-condition-in-sideband-unregis.patch
new file mode 100644 (file)
index 0000000..a26ddf7
--- /dev/null
@@ -0,0 +1,247 @@
+From 4281c3b2ba2dd298a105d49d2698ac542aecc278 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 18:28:18 +0200
+Subject: xhci: sideband: Fix race condition in sideband unregister
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 8c13a7323b847c0370aec66f655e2596a2174a17 ]
+
+Uttkarsh Aggarwal observed a kernel panic during sideband un-register
+and found it was caused by a race condition between sideband unregister,
+and creating sideband interrupters.
+The issue occurrs when thread T1 runs uaudio_disconnect() and released
+sb->xhci via sideband_unregister, while thread T2 simultaneously accessed
+the now-NULL sb->xhci in xhci_sideband_create_interrupter() resulting in
+a crash.
+
+Ensure new endpoints or interrupter can't be added to a sidenband after
+xhci_sideband_unregister() cleared the existing ones, and unlocked the
+sideband mutex.
+Reorganize code so that mutex is only taken and released once in
+xhci_sideband_unregister(), and clear sb->vdev while mutex is taken.
+
+Use mutex guards to reduce human unlock errors in code
+
+Refuse to add endpoints or interrupter if sb->vdev is not set.
+sb->vdev is set when sideband is created and registered.
+
+Reported-by: Uttkarsh Aggarwal <uttkarsh.aggarwal@oss.qualcomm.com>
+Closes: https://lore.kernel.org/linux-usb/20251028080043.27760-1-uttkarsh.aggarwal@oss.qualcomm.com
+Fixes: de66754e9f80 ("xhci: sideband: add initial api to register a secondary interrupter entity")
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://patch.msgid.link/20251107162819.1362579-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-sideband.c | 102 ++++++++++++++++++-------------
+ 1 file changed, 58 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
+index e771a476fef2e..a85f62a73313a 100644
+--- a/drivers/usb/host/xhci-sideband.c
++++ b/drivers/usb/host/xhci-sideband.c
+@@ -73,9 +73,12 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
+       return NULL;
+ }
++/* Caller must hold sb->mutex */
+ static void
+ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *ep)
+ {
++      lockdep_assert_held(&sb->mutex);
++
+       /*
+        * Issue a stop endpoint command when an endpoint is removed.
+        * The stop ep cmd handler will handle the ring cleanup.
+@@ -86,6 +89,25 @@ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *e
+       sb->eps[ep->ep_index] = NULL;
+ }
++/* Caller must hold sb->mutex */
++static void
++__xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
++{
++      struct usb_device *udev;
++
++      lockdep_assert_held(&sb->mutex);
++
++      if (!sb->ir)
++              return;
++
++      xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
++      sb->ir = NULL;
++      udev = sb->vdev->udev;
++
++      if (udev->state != USB_STATE_NOTATTACHED)
++              usb_offload_put(udev);
++}
++
+ /* sideband api functions */
+ /**
+@@ -131,14 +153,16 @@ xhci_sideband_add_endpoint(struct xhci_sideband *sb,
+       struct xhci_virt_ep *ep;
+       unsigned int ep_index;
+-      mutex_lock(&sb->mutex);
++      guard(mutex)(&sb->mutex);
++
++      if (!sb->vdev)
++              return -ENODEV;
++
+       ep_index = xhci_get_endpoint_index(&host_ep->desc);
+       ep = &sb->vdev->eps[ep_index];
+-      if (ep->ep_state & EP_HAS_STREAMS) {
+-              mutex_unlock(&sb->mutex);
++      if (ep->ep_state & EP_HAS_STREAMS)
+               return -EINVAL;
+-      }
+       /*
+        * Note, we don't know the DMA mask of the audio DSP device, if its
+@@ -148,14 +172,11 @@ xhci_sideband_add_endpoint(struct xhci_sideband *sb,
+        * and let this function add the endpoint and allocate the ring buffer
+        * with the smallest common DMA mask
+        */
+-      if (sb->eps[ep_index] || ep->sideband) {
+-              mutex_unlock(&sb->mutex);
++      if (sb->eps[ep_index] || ep->sideband)
+               return -EBUSY;
+-      }
+       ep->sideband = sb;
+       sb->eps[ep_index] = ep;
+-      mutex_unlock(&sb->mutex);
+       return 0;
+ }
+@@ -180,18 +201,16 @@ xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
+       struct xhci_virt_ep *ep;
+       unsigned int ep_index;
+-      mutex_lock(&sb->mutex);
++      guard(mutex)(&sb->mutex);
++
+       ep_index = xhci_get_endpoint_index(&host_ep->desc);
+       ep = sb->eps[ep_index];
+-      if (!ep || !ep->sideband || ep->sideband != sb) {
+-              mutex_unlock(&sb->mutex);
++      if (!ep || !ep->sideband || ep->sideband != sb)
+               return -ENODEV;
+-      }
+       __xhci_sideband_remove_endpoint(sb, ep);
+       xhci_initialize_ring_info(ep->ring);
+-      mutex_unlock(&sb->mutex);
+       return 0;
+ }
+@@ -316,28 +335,25 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+       if (!sb || !sb->xhci)
+               return -ENODEV;
+-      mutex_lock(&sb->mutex);
+-      if (sb->ir) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
++      guard(mutex)(&sb->mutex);
++
++      if (!sb->vdev)
++              return -ENODEV;
++
++      if (sb->ir)
++              return -EBUSY;
+       sb->ir = xhci_create_secondary_interrupter(xhci_to_hcd(sb->xhci),
+                                                  num_seg, imod_interval,
+                                                  intr_num);
+-      if (!sb->ir) {
+-              ret = -ENOMEM;
+-              goto out;
+-      }
++      if (!sb->ir)
++              return -ENOMEM;
+       udev = sb->vdev->udev;
+       ret = usb_offload_get(udev);
+       sb->ir->ip_autoclear = ip_autoclear;
+-out:
+-      mutex_unlock(&sb->mutex);
+-
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
+@@ -352,21 +368,12 @@ EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
+ void
+ xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
+ {
+-      struct usb_device *udev;
+-
+-      if (!sb || !sb->ir)
++      if (!sb)
+               return;
+-      mutex_lock(&sb->mutex);
+-      xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
+-
+-      sb->ir = NULL;
+-      udev = sb->vdev->udev;
++      guard(mutex)(&sb->mutex);
+-      if (udev->state != USB_STATE_NOTATTACHED)
+-              usb_offload_put(udev);
+-
+-      mutex_unlock(&sb->mutex);
++      __xhci_sideband_remove_interrupter(sb);
+ }
+ EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
+@@ -465,6 +472,7 @@ EXPORT_SYMBOL_GPL(xhci_sideband_register);
+ void
+ xhci_sideband_unregister(struct xhci_sideband *sb)
+ {
++      struct xhci_virt_device *vdev;
+       struct xhci_hcd *xhci;
+       int i;
+@@ -473,17 +481,23 @@ xhci_sideband_unregister(struct xhci_sideband *sb)
+       xhci = sb->xhci;
+-      mutex_lock(&sb->mutex);
+-      for (i = 0; i < EP_CTX_PER_DEV; i++)
+-              if (sb->eps[i])
+-                      __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
+-      mutex_unlock(&sb->mutex);
++      scoped_guard(mutex, &sb->mutex) {
++              vdev = sb->vdev;
++              if (!vdev)
++                      return;
++
++              for (i = 0; i < EP_CTX_PER_DEV; i++)
++                      if (sb->eps[i])
++                              __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
+-      xhci_sideband_remove_interrupter(sb);
++              __xhci_sideband_remove_interrupter(sb);
++
++              sb->vdev = NULL;
++      }
+       spin_lock_irq(&xhci->lock);
+       sb->xhci = NULL;
+-      sb->vdev->sideband = NULL;
++      vdev->sideband = NULL;
+       spin_unlock_irq(&xhci->lock);
+       kfree(sb);
+-- 
+2.51.0
+
diff --git a/queue-6.17/xsk-avoid-data-corruption-on-cq-descriptor-number.patch b/queue-6.17/xsk-avoid-data-corruption-on-cq-descriptor-number.patch
new file mode 100644 (file)
index 0000000..884de80
--- /dev/null
@@ -0,0 +1,340 @@
+From 0617068bae90aeaaa11d1fdb3cc3b277c3a567a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 18:14:09 +0100
+Subject: xsk: avoid data corruption on cq descriptor number
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 0ebc27a4c67d44e5ce88d21cdad8201862b78837 ]
+
+Since commit 30f241fcf52a ("xsk: Fix immature cq descriptor
+production"), the descriptor number is stored in skb control block and
+xsk_cq_submit_addr_locked() relies on it to put the umem addrs onto
+pool's completion queue.
+
+skb control block shouldn't be used for this purpose as after transmit
+xsk doesn't have control over it and other subsystems could use it. This
+leads to the following kernel panic due to a NULL pointer dereference.
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ #PF: supervisor read access in kernel mode
+ #PF: error_code(0x0000) - not-present page
+ PGD 0 P4D 0
+ Oops: Oops: 0000 [#1] SMP NOPTI
+ CPU: 2 UID: 1 PID: 927 Comm: p4xsk.bin Not tainted 6.16.12+deb14-cloud-amd64 #1 PREEMPT(lazy)  Debian 6.16.12-1
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
+ RIP: 0010:xsk_destruct_skb+0xd0/0x180
+ [...]
+ Call Trace:
+  <IRQ>
+  ? napi_complete_done+0x7a/0x1a0
+  ip_rcv_core+0x1bb/0x340
+  ip_rcv+0x30/0x1f0
+  __netif_receive_skb_one_core+0x85/0xa0
+  process_backlog+0x87/0x130
+  __napi_poll+0x28/0x180
+  net_rx_action+0x339/0x420
+  handle_softirqs+0xdc/0x320
+  ? handle_edge_irq+0x90/0x1e0
+  do_softirq.part.0+0x3b/0x60
+  </IRQ>
+  <TASK>
+  __local_bh_enable_ip+0x60/0x70
+  __dev_direct_xmit+0x14e/0x1f0
+  __xsk_generic_xmit+0x482/0xb70
+  ? __remove_hrtimer+0x41/0xa0
+  ? __xsk_generic_xmit+0x51/0xb70
+  ? _raw_spin_unlock_irqrestore+0xe/0x40
+  xsk_sendmsg+0xda/0x1c0
+  __sys_sendto+0x1ee/0x200
+  __x64_sys_sendto+0x24/0x30
+  do_syscall_64+0x84/0x2f0
+  ? __pfx_pollwake+0x10/0x10
+  ? __rseq_handle_notify_resume+0xad/0x4c0
+  ? restore_fpregs_from_fpstate+0x3c/0x90
+  ? switch_fpu_return+0x5b/0xe0
+  ? do_syscall_64+0x204/0x2f0
+  ? do_syscall_64+0x204/0x2f0
+  ? do_syscall_64+0x204/0x2f0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+ [...]
+ Kernel panic - not syncing: Fatal exception in interrupt
+ Kernel Offset: 0x1c000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
+
+Instead use the skb destructor_arg pointer along with pointer tagging.
+As pointers are always aligned to 8B, use the bottom bit to indicate
+whether this a single address or an allocated struct containing several
+addresses.
+
+Fixes: 30f241fcf52a ("xsk: Fix immature cq descriptor production")
+Closes: https://lore.kernel.org/netdev/0435b904-f44f-48f8-afb0-68868474bf1c@nop.hu/
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Link: https://patch.msgid.link/20251124171409.3845-1-fmancera@suse.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk.c | 143 +++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 88 insertions(+), 55 deletions(-)
+
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 01f258894faeb..78fc25e88d7c3 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -36,20 +36,13 @@
+ #define TX_BATCH_SIZE 32
+ #define MAX_PER_SOCKET_BUDGET 32
+-struct xsk_addr_node {
+-      u64 addr;
+-      struct list_head addr_node;
+-};
+-
+-struct xsk_addr_head {
++struct xsk_addrs {
+       u32 num_descs;
+-      struct list_head addrs_list;
++      u64 addrs[MAX_SKB_FRAGS + 1];
+ };
+ static struct kmem_cache *xsk_tx_generic_cache;
+-#define XSKCB(skb) ((struct xsk_addr_head *)((skb)->cb))
+-
+ void xsk_set_rx_need_wakeup(struct xsk_buff_pool *pool)
+ {
+       if (pool->cached_need_wakeup & XDP_WAKEUP_RX)
+@@ -558,29 +551,68 @@ static int xsk_cq_reserve_locked(struct xsk_buff_pool *pool)
+       return ret;
+ }
++static bool xsk_skb_destructor_is_addr(struct sk_buff *skb)
++{
++      return (uintptr_t)skb_shinfo(skb)->destructor_arg & 0x1UL;
++}
++
++static u64 xsk_skb_destructor_get_addr(struct sk_buff *skb)
++{
++      return (u64)((uintptr_t)skb_shinfo(skb)->destructor_arg & ~0x1UL);
++}
++
++static void xsk_skb_destructor_set_addr(struct sk_buff *skb, u64 addr)
++{
++      skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
++}
++
++static void xsk_inc_num_desc(struct sk_buff *skb)
++{
++      struct xsk_addrs *xsk_addr;
++
++      if (!xsk_skb_destructor_is_addr(skb)) {
++              xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
++              xsk_addr->num_descs++;
++      }
++}
++
++static u32 xsk_get_num_desc(struct sk_buff *skb)
++{
++      struct xsk_addrs *xsk_addr;
++
++      if (xsk_skb_destructor_is_addr(skb))
++              return 1;
++
++      xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
++
++      return xsk_addr->num_descs;
++}
++
+ static void xsk_cq_submit_addr_locked(struct xsk_buff_pool *pool,
+                                     struct sk_buff *skb)
+ {
+-      struct xsk_addr_node *pos, *tmp;
++      u32 num_descs = xsk_get_num_desc(skb);
++      struct xsk_addrs *xsk_addr;
+       u32 descs_processed = 0;
+       unsigned long flags;
+-      u32 idx;
++      u32 idx, i;
+       spin_lock_irqsave(&pool->cq_lock, flags);
+       idx = xskq_get_prod(pool->cq);
+-      xskq_prod_write_addr(pool->cq, idx,
+-                           (u64)(uintptr_t)skb_shinfo(skb)->destructor_arg);
+-      descs_processed++;
++      if (unlikely(num_descs > 1)) {
++              xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
+-      if (unlikely(XSKCB(skb)->num_descs > 1)) {
+-              list_for_each_entry_safe(pos, tmp, &XSKCB(skb)->addrs_list, addr_node) {
++              for (i = 0; i < num_descs; i++) {
+                       xskq_prod_write_addr(pool->cq, idx + descs_processed,
+-                                           pos->addr);
++                                           xsk_addr->addrs[i]);
+                       descs_processed++;
+-                      list_del(&pos->addr_node);
+-                      kmem_cache_free(xsk_tx_generic_cache, pos);
+               }
++              kmem_cache_free(xsk_tx_generic_cache, xsk_addr);
++      } else {
++              xskq_prod_write_addr(pool->cq, idx,
++                                   xsk_skb_destructor_get_addr(skb));
++              descs_processed++;
+       }
+       xskq_prod_submit_n(pool->cq, descs_processed);
+       spin_unlock_irqrestore(&pool->cq_lock, flags);
+@@ -595,16 +627,6 @@ static void xsk_cq_cancel_locked(struct xsk_buff_pool *pool, u32 n)
+       spin_unlock_irqrestore(&pool->cq_lock, flags);
+ }
+-static void xsk_inc_num_desc(struct sk_buff *skb)
+-{
+-      XSKCB(skb)->num_descs++;
+-}
+-
+-static u32 xsk_get_num_desc(struct sk_buff *skb)
+-{
+-      return XSKCB(skb)->num_descs;
+-}
+-
+ static void xsk_destruct_skb(struct sk_buff *skb)
+ {
+       struct xsk_tx_metadata_compl *compl = &skb_shinfo(skb)->xsk_meta;
+@@ -621,27 +643,22 @@ static void xsk_destruct_skb(struct sk_buff *skb)
+ static void xsk_skb_init_misc(struct sk_buff *skb, struct xdp_sock *xs,
+                             u64 addr)
+ {
+-      BUILD_BUG_ON(sizeof(struct xsk_addr_head) > sizeof(skb->cb));
+-      INIT_LIST_HEAD(&XSKCB(skb)->addrs_list);
+       skb->dev = xs->dev;
+       skb->priority = READ_ONCE(xs->sk.sk_priority);
+       skb->mark = READ_ONCE(xs->sk.sk_mark);
+-      XSKCB(skb)->num_descs = 0;
+       skb->destructor = xsk_destruct_skb;
+-      skb_shinfo(skb)->destructor_arg = (void *)(uintptr_t)addr;
++      xsk_skb_destructor_set_addr(skb, addr);
+ }
+ static void xsk_consume_skb(struct sk_buff *skb)
+ {
+       struct xdp_sock *xs = xdp_sk(skb->sk);
+       u32 num_descs = xsk_get_num_desc(skb);
+-      struct xsk_addr_node *pos, *tmp;
++      struct xsk_addrs *xsk_addr;
+       if (unlikely(num_descs > 1)) {
+-              list_for_each_entry_safe(pos, tmp, &XSKCB(skb)->addrs_list, addr_node) {
+-                      list_del(&pos->addr_node);
+-                      kmem_cache_free(xsk_tx_generic_cache, pos);
+-              }
++              xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
++              kmem_cache_free(xsk_tx_generic_cache, xsk_addr);
+       }
+       skb->destructor = sock_wfree;
+@@ -662,7 +679,6 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
+ {
+       struct xsk_buff_pool *pool = xs->pool;
+       u32 hr, len, ts, offset, copy, copied;
+-      struct xsk_addr_node *xsk_addr;
+       struct sk_buff *skb = xs->skb;
+       struct page *page;
+       void *buffer;
+@@ -680,16 +696,26 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
+               xsk_skb_init_misc(skb, xs, desc->addr);
+       } else {
+-              xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
+-              if (!xsk_addr)
+-                      return ERR_PTR(-ENOMEM);
++              struct xsk_addrs *xsk_addr;
++
++              if (xsk_skb_destructor_is_addr(skb)) {
++                      xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache,
++                                                   GFP_KERNEL);
++                      if (!xsk_addr)
++                              return ERR_PTR(-ENOMEM);
++
++                      xsk_addr->num_descs = 1;
++                      xsk_addr->addrs[0] = xsk_skb_destructor_get_addr(skb);
++                      skb_shinfo(skb)->destructor_arg = (void *)xsk_addr;
++              } else {
++                      xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
++              }
+               /* in case of -EOVERFLOW that could happen below,
+                * xsk_consume_skb() will release this node as whole skb
+                * would be dropped, which implies freeing all list elements
+                */
+-              xsk_addr->addr = desc->addr;
+-              list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
++              xsk_addr->addrs[xsk_addr->num_descs] = desc->addr;
+       }
+       addr = desc->addr;
+@@ -765,10 +791,25 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                       xsk_skb_init_misc(skb, xs, desc->addr);
+               } else {
+                       int nr_frags = skb_shinfo(skb)->nr_frags;
+-                      struct xsk_addr_node *xsk_addr;
++                      struct xsk_addrs *xsk_addr;
+                       struct page *page;
+                       u8 *vaddr;
++                      if (xsk_skb_destructor_is_addr(skb)) {
++                              xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache,
++                                                           GFP_KERNEL);
++                              if (!xsk_addr) {
++                                      err = -ENOMEM;
++                                      goto free_err;
++                              }
++
++                              xsk_addr->num_descs = 1;
++                              xsk_addr->addrs[0] = xsk_skb_destructor_get_addr(skb);
++                              skb_shinfo(skb)->destructor_arg = (void *)xsk_addr;
++                      } else {
++                              xsk_addr = (struct xsk_addrs *)skb_shinfo(skb)->destructor_arg;
++                      }
++
+                       if (unlikely(nr_frags == (MAX_SKB_FRAGS - 1) && xp_mb_desc(desc))) {
+                               err = -EOVERFLOW;
+                               goto free_err;
+@@ -780,13 +821,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                               goto free_err;
+                       }
+-                      xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
+-                      if (!xsk_addr) {
+-                              __free_page(page);
+-                              err = -ENOMEM;
+-                              goto free_err;
+-                      }
+-
+                       vaddr = kmap_local_page(page);
+                       memcpy(vaddr, buffer, len);
+                       kunmap_local(vaddr);
+@@ -794,8 +828,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                       skb_add_rx_frag(skb, nr_frags, page, 0, len, PAGE_SIZE);
+                       refcount_add(PAGE_SIZE, &xs->sk.sk_wmem_alloc);
+-                      xsk_addr->addr = desc->addr;
+-                      list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
++                      xsk_addr->addrs[xsk_addr->num_descs] = desc->addr;
+               }
+               if (first_frag && desc->options & XDP_TX_METADATA) {
+@@ -1892,7 +1925,7 @@ static int __init xsk_init(void)
+               goto out_pernet;
+       xsk_tx_generic_cache = kmem_cache_create("xsk_generic_xmit_cache",
+-                                               sizeof(struct xsk_addr_node),
++                                               sizeof(struct xsk_addrs),
+                                                0, SLAB_HWCACHE_ALIGN, NULL);
+       if (!xsk_tx_generic_cache) {
+               err = -ENOMEM;
+-- 
+2.51.0
+
diff --git a/queue-6.17/xsk-avoid-overwriting-skb-fields-for-multi-buffer-tr.patch b/queue-6.17/xsk-avoid-overwriting-skb-fields-for-multi-buffer-tr.patch
new file mode 100644 (file)
index 0000000..9c132a0
--- /dev/null
@@ -0,0 +1,87 @@
+From b18fcd7cceaef3858d237bec0395cde9fd13362f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Sep 2025 18:00:07 +0200
+Subject: xsk: avoid overwriting skb fields for multi-buffer traffic
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit c30d084960cf316c95fbf145d39974ce1ff7889c ]
+
+We are unnecessarily setting a bunch of skb fields per each processed
+descriptor, which is redundant for fragmented frames.
+
+Let us set these respective members for first fragment only. To address
+both paths that we have within xsk_build_skb(), move assignments onto
+xsk_set_destructor_arg() and rename it to xsk_skb_init_misc().
+
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
+Link: https://patch.msgid.link/20250925160009.2474816-2-maciej.fijalkowski@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0ebc27a4c67d ("xsk: avoid data corruption on cq descriptor number")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 72e34bd2d925c..01f258894faeb 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -618,11 +618,16 @@ static void xsk_destruct_skb(struct sk_buff *skb)
+       sock_wfree(skb);
+ }
+-static void xsk_set_destructor_arg(struct sk_buff *skb, u64 addr)
++static void xsk_skb_init_misc(struct sk_buff *skb, struct xdp_sock *xs,
++                            u64 addr)
+ {
+       BUILD_BUG_ON(sizeof(struct xsk_addr_head) > sizeof(skb->cb));
+       INIT_LIST_HEAD(&XSKCB(skb)->addrs_list);
++      skb->dev = xs->dev;
++      skb->priority = READ_ONCE(xs->sk.sk_priority);
++      skb->mark = READ_ONCE(xs->sk.sk_mark);
+       XSKCB(skb)->num_descs = 0;
++      skb->destructor = xsk_destruct_skb;
+       skb_shinfo(skb)->destructor_arg = (void *)(uintptr_t)addr;
+ }
+@@ -673,7 +678,7 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
+               skb_reserve(skb, hr);
+-              xsk_set_destructor_arg(skb, desc->addr);
++              xsk_skb_init_misc(skb, xs, desc->addr);
+       } else {
+               xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
+               if (!xsk_addr)
+@@ -757,7 +762,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                       if (unlikely(err))
+                               goto free_err;
+-                      xsk_set_destructor_arg(skb, desc->addr);
++                      xsk_skb_init_misc(skb, xs, desc->addr);
+               } else {
+                       int nr_frags = skb_shinfo(skb)->nr_frags;
+                       struct xsk_addr_node *xsk_addr;
+@@ -826,14 +831,10 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                       if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
+                               skb->skb_mstamp_ns = meta->request.launch_time;
++                      xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
+               }
+       }
+-      skb->dev = dev;
+-      skb->priority = READ_ONCE(xs->sk.sk_priority);
+-      skb->mark = READ_ONCE(xs->sk.sk_mark);
+-      skb->destructor = xsk_destruct_skb;
+-      xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
+       xsk_inc_num_desc(skb);
+       return skb;
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch b/queue-6.6/bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
new file mode 100644 (file)
index 0000000..2b7383c
--- /dev/null
@@ -0,0 +1,72 @@
+From 6868aa21003bfbddc1d87c8dcb220c6f6eb1d64e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Nov 2025 17:04:43 +0800
+Subject: Bluetooth: hci_sock: Prevent race in socket write iter and sock bind
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 89bb613511cc21ed5ba6bddc1c9b9ae9c0dad392 ]
+
+There is a potential race condition between sock bind and socket write
+iter. bind may free the same cmd via mgmt_pending before write iter sends
+the cmd, just as syzbot reported in UAF[1].
+
+Here we use hci_dev_lock to synchronize the two, thereby avoiding the
+UAF mentioned in [1].
+
+[1]
+syzbot reported:
+BUG: KASAN: slab-use-after-free in mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+Read of size 8 at addr ffff888077164818 by task syz.0.17/5989
+Call Trace:
+ mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316
+ set_link_security+0x5c2/0x710 net/bluetooth/mgmt.c:1918
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Allocated by task 5989:
+ mgmt_pending_add+0x35/0x140 net/bluetooth/mgmt_util.c:296
+ set_link_security+0x557/0x710 net/bluetooth/mgmt.c:1910
+ hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
+ hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:742
+ sock_write_iter+0x279/0x360 net/socket.c:1195
+
+Freed by task 5991:
+ mgmt_pending_free net/bluetooth/mgmt_util.c:311 [inline]
+ mgmt_pending_foreach+0x30d/0x380 net/bluetooth/mgmt_util.c:257
+ mgmt_index_removed+0x112/0x2f0 net/bluetooth/mgmt.c:9477
+ hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314
+
+Fixes: 6fe26f694c82 ("Bluetooth: MGMT: Protect mgmt_pending list with its own lock")
+Reported-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=9aa47cd4633a3cf92a80
+Tested-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index d2613bd3e6db0..8b3ef088ed14e 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -1304,7 +1304,9 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+                       goto done;
+               }
++              hci_dev_lock(hdev);
+               mgmt_index_removed(hdev);
++              hci_dev_unlock(hdev);
+               err = hci_dev_open(hdev->id);
+               if (err) {
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch b/queue-6.6/bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
new file mode 100644 (file)
index 0000000..f45bdcf
--- /dev/null
@@ -0,0 +1,87 @@
+From de8be4a98c74fac3d59e4d3904249f64984c3a3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 13:45:13 -0500
+Subject: Bluetooth: SMP: Fix not generating mackey and ltk when repairing
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
+
+The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+introduced a goto that bypasses the creation of temporary mackey and ltk
+which are later used by the likes of DHKey Check step.
+
+Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for
+Just Works (LE SC)") which means confirm_hint is always set in case
+JUST_WORKS so the branch checking for an existing LTK becomes pointless
+as confirm_hint will always be set, so this just merge both cases of
+malicious or legitimate devices to be confirmed before continuing with the
+pairing procedure.
+
+Link: https://github.com/bluez/bluez/issues/1622
+Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index 4c00bc50de811..e7ee13fe83a74 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2137,7 +2137,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb, confirm_hint;
+-      u32 passkey;
++      u32 passkey = 0;
+       int err;
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
+@@ -2189,24 +2189,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+-
+-              /* Only Just-Works pairing requires extra checks */
+-              if (smp->method != JUST_WORKS)
+-                      goto mackey_and_ltk;
+-
+-              /* If there already exists long term key in local host, leave
+-               * the decision to user space since the remote device could
+-               * be legitimate or malicious.
+-               */
+-              if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
+-                               hcon->role)) {
+-                      /* Set passkey to 0. The value can be any number since
+-                       * it'll be ignored anyway.
+-                       */
+-                      passkey = 0;
+-                      confirm_hint = 1;
+-                      goto confirm;
+-              }
+       }
+ mackey_and_ltk:
+@@ -2227,11 +2209,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+       if (err)
+               return SMP_UNSPECIFIED;
+-      confirm_hint = 0;
+-
+-confirm:
+-      if (smp->method == JUST_WORKS)
+-              confirm_hint = 1;
++      /* Always require user confirmation for Just-Works pairing to prevent
++       * impersonation attacks, or in case of a legitimate device that is
++       * repairing use the confirmation as acknowledgment to proceed with the
++       * creation of new keys.
++       */
++      confirm_hint = smp->method == JUST_WORKS ? 1 : 0;
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
+                                       hcon->dst_type, passkey, confirm_hint);
+-- 
+2.51.0
+
diff --git a/queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch b/queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
new file mode 100644 (file)
index 0000000..16c117f
--- /dev/null
@@ -0,0 +1,92 @@
+From b0e7b67bfb17560ce3e97df77fbaae7a7800029a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:02 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing header
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf ]
+
+The driver expects to receive a struct gs_host_frame in
+gs_usb_receive_bulk_callback().
+
+Use struct_group to describe the header of the struct gs_host_frame and
+check that we have at least received the header before accessing any
+members of it.
+
+To resubmit the URB, do not dereference the pointer chain
+"dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since
+"urb->context" contains "parent", it is always defined, while "dev" is not
+defined if the URB it too short.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-2-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 1ba6395a5a667..e786616d167b8 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -259,13 +259,15 @@ struct canfd_quirk {
+ } __packed;
+ struct gs_host_frame {
+-      u32 echo_id;
+-      __le32 can_id;
++      struct_group(header,
++              u32 echo_id;
++              __le32 can_id;
+-      u8 can_dlc;
+-      u8 channel;
+-      u8 flags;
+-      u8 reserved;
++              u8 can_dlc;
++              u8 channel;
++              u8 flags;
++              u8 reserved;
++      );
+       union {
+               DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
+@@ -573,6 +575,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
++      unsigned int minimum_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -591,6 +594,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+               return;
+       }
++      minimum_length = sizeof(hf->header);
++      if (urb->actual_length < minimum_length) {
++              dev_err_ratelimited(&parent->udev->dev,
++                                  "short read (actual_length=%u, minimum_length=%u)\n",
++                                  urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
+       /* device reports out of range channel id */
+       if (hf->channel >= parent->channel_cnt)
+               goto device_detach;
+@@ -684,7 +696,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ resubmit_urb:
+       usb_fill_bulk_urb(urb, parent->udev,
+                         parent->pipe_in,
+-                        hf, dev->parent->hf_size_rx,
++                        hf, parent->hf_size_rx,
+                         gs_usb_receive_bulk_callback, parent);
+       rc = usb_submit_urb(urb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-2290 b/queue-6.6/can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-2290
new file mode 100644 (file)
index 0000000..1defd8e
--- /dev/null
@@ -0,0 +1,140 @@
+From da34234948b26d1abb80e061227382ad2e1d8928 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:03 +0100
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length
+ before accessing data
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 395d988f93861101ec89d0dd9e3b876ae9392a5b ]
+
+The URB received in gs_usb_receive_bulk_callback() contains a struct
+gs_host_frame. The length of the data after the header depends on the
+gs_host_frame hf::flags and the active device features (e.g. time
+stamping).
+
+Introduce a new function gs_usb_get_minimum_length() and check that we have
+at least received the required amount of data before accessing it. Only
+copy the data to that skb that has actually been received.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-3-a29b42eacada@pengutronix.de
+[mkl: rename gs_usb_get_minimum_length() -> +gs_usb_get_minimum_rx_length()]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 59 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index e786616d167b8..72997312c9567 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -258,6 +258,11 @@ struct canfd_quirk {
+       u8 quirk;
+ } __packed;
++/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates
++ * a regular RX'ed CAN frame
++ */
++#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff
++
+ struct gs_host_frame {
+       struct_group(header,
+               u32 echo_id;
+@@ -567,6 +572,37 @@ gs_usb_get_echo_skb(struct gs_can *dev, struct sk_buff *skb,
+       return len;
+ }
++static unsigned int
++gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf,
++                           unsigned int *data_length_p)
++{
++      unsigned int minimum_length, data_length = 0;
++
++      if (hf->flags & GS_CAN_FLAG_FD) {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX)
++                      data_length = can_fd_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, canfd_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      } else {
++              if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX &&
++                  !(hf->can_id & cpu_to_le32(CAN_RTR_FLAG)))
++                      data_length = can_cc_dlc2len(hf->can_dlc);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      /* timestamp follows data field of max size */
++                      minimum_length = struct_size(hf, classic_can_ts, 1);
++              else
++                      minimum_length = sizeof(hf->header) + data_length;
++      }
++
++      *data_length_p = data_length;
++      return minimum_length;
++}
++
+ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ {
+       struct gs_usb *parent = urb->context;
+@@ -575,7 +611,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       int rc;
+       struct net_device_stats *stats;
+       struct gs_host_frame *hf = urb->transfer_buffer;
+-      unsigned int minimum_length;
++      unsigned int minimum_length, data_length;
+       struct gs_tx_context *txc;
+       struct can_frame *cf;
+       struct canfd_frame *cfd;
+@@ -618,20 +654,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+       if (!netif_running(netdev))
+               goto resubmit_urb;
+-      if (hf->echo_id == -1) { /* normal rx */
++      minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length);
++      if (urb->actual_length < minimum_length) {
++              stats->rx_errors++;
++              stats->rx_length_errors++;
++
++              if (net_ratelimit())
++                      netdev_err(netdev,
++                                 "short read (actual_length=%u, minimum_length=%u)\n",
++                                 urb->actual_length, minimum_length);
++
++              goto resubmit_urb;
++      }
++
++      if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */
+               if (hf->flags & GS_CAN_FLAG_FD) {
+                       skb = alloc_canfd_skb(netdev, &cfd);
+                       if (!skb)
+                               return;
+                       cfd->can_id = le32_to_cpu(hf->can_id);
+-                      cfd->len = can_fd_dlc2len(hf->can_dlc);
++                      cfd->len = data_length;
+                       if (hf->flags & GS_CAN_FLAG_BRS)
+                               cfd->flags |= CANFD_BRS;
+                       if (hf->flags & GS_CAN_FLAG_ESI)
+                               cfd->flags |= CANFD_ESI;
+-                      memcpy(cfd->data, hf->canfd->data, cfd->len);
++                      memcpy(cfd->data, hf->canfd->data, data_length);
+               } else {
+                       skb = alloc_can_skb(netdev, &cf);
+                       if (!skb)
+@@ -640,7 +689,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+                       cf->can_id = le32_to_cpu(hf->can_id);
+                       can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
+-                      memcpy(cf->data, hf->classic_can->data, 8);
++                      memcpy(cf->data, hf->classic_can->data, data_length);
+                       /* ERROR frames tell us information about the controller */
+                       if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
+-- 
+2.51.0
+
diff --git a/queue-6.6/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch b/queue-6.6/can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
new file mode 100644 (file)
index 0000000..36a2faf
--- /dev/null
@@ -0,0 +1,60 @@
+From 75ce03b6fdb4d1c5a87de7875f1c083094fefd7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 10:01:01 +0100
+Subject: can: gs_usb: gs_usb_xmit_callback(): fix handling of failed
+ transmitted URBs
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 ]
+
+The driver lacks the cleanup of failed transfers of URBs. This reduces the
+number of available URBs per error by 1. This leads to reduced performance
+and ultimately to a complete stop of the transmission.
+
+If the sending of a bulk URB fails do proper cleanup:
+- increase netdev stats
+- mark the echo_sbk as free
+- free the driver's context and do accounting
+- wake the send queue
+
+Closes: https://github.com/candle-usb/candleLight_fw/issues/187
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-1-a29b42eacada@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 9bd61fd8e5013..1ba6395a5a667 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -747,8 +747,21 @@ static void gs_usb_xmit_callback(struct urb *urb)
+       struct gs_can *dev = txc->dev;
+       struct net_device *netdev = dev->netdev;
+-      if (urb->status)
+-              netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
++      if (!urb->status)
++              return;
++
++      if (urb->status != -ESHUTDOWN && net_ratelimit())
++              netdev_info(netdev, "failed to xmit URB %u: %pe\n",
++                          txc->echo_id, ERR_PTR(urb->status));
++
++      netdev->stats.tx_dropped++;
++      netdev->stats.tx_errors++;
++
++      can_free_echo_skb(netdev, txc->echo_id, NULL);
++      gs_free_tx_context(txc);
++      atomic_dec(&dev->active_tx_urbs);
++
++      netif_wake_queue(netdev);
+ }
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+-- 
+2.51.0
+
diff --git a/queue-6.6/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch b/queue-6.6/can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
new file mode 100644 (file)
index 0000000..e33e132
--- /dev/null
@@ -0,0 +1,62 @@
+From 007a8ceaabb8f5466ef14be9ed4e6cfb3d2acecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 12:27:09 -0400
+Subject: can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
+
+From: Seungjin Bae <eeodqql09@gmail.com>
+
+[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
+
+The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback`
+functions contain logic to zero-length commands. These commands are used
+to align data to the USB endpoint's wMaxPacketSize boundary.
+
+The driver attempts to skip these placeholders by aligning the buffer
+position `pos` to the next packet boundary using `round_up()` function.
+
+However, if zero-length command is found exactly on a packet boundary
+(i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up`
+function will return the unchanged value of `pos`. This prevents `pos`
+to be increased, causing an infinite loop in the parsing logic.
+
+This patch fixes this in the function by using `pos + 1` instead.
+This ensures that even if `pos` is on a boundary, the calculation is
+based on `pos + 1`, forcing `round_up()` to always return the next
+aligned boundary.
+
+Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
+Reviewed-by: Jimmy Assarsson <extja@kvaser.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com>
+Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 23bd7574b1c7e..7b931953dadc4 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -611,7 +611,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+                        * for further details.
+                        */
+                       if (tmp->len == 0) {
+-                              pos = round_up(pos,
++                              pos = round_up(pos + 1,
+                                              le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                               continue;
+@@ -1590,7 +1590,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
+                * number of events in case of a heavy rx load on the bus.
+                */
+               if (cmd->len == 0) {
+-                      pos = round_up(pos, le16_to_cpu
++                      pos = round_up(pos + 1, le16_to_cpu
+                                               (dev->bulk_in->wMaxPacketSize));
+                       continue;
+               }
+-- 
+2.51.0
+
diff --git a/queue-6.6/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch b/queue-6.6/drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
new file mode 100644 (file)
index 0000000..64f5f44
--- /dev/null
@@ -0,0 +1,39 @@
+From 6bf3d331c975ee81ff800b9dd0287957255b33ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 09:40:31 -0500
+Subject: drm/amdgpu: fix cyan_skillfish2 gpu info fw handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 ]
+
+If the board supports IP discovery, we don't need to
+parse the gpu info firmware.
+
+Backport to 6.18.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4721
+Fixes: fa819e3a7c1e ("drm/amdgpu: add support for cyan skillfish gpu_info")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5427e32fa3a0ba9a016db83877851ed277b065fb)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index b2a1dc193cb8f..c1b9333d7b78a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -1941,6 +1941,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
+               chip_name = "navi12";
+               break;
+       case CHIP_CYAN_SKILLFISH:
++              if (adev->mman.discovery_bin)
++                      return 0;
+               chip_name = "cyan_skillfish";
+               break;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch b/queue-6.6/iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
new file mode 100644 (file)
index 0000000..5530a7d
--- /dev/null
@@ -0,0 +1,132 @@
+From a423c1846b5aa8684b95834f2f65cbcdedb67f86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 18:16:19 +0200
+Subject: iio: st_lsm6dsx: Fixed calibrated timestamp calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Tesi <martepisa@gmail.com>
+
+[ Upstream commit 8abbf45fcda028c2c05ba38eb14ede9fa9e7341b ]
+
+The calibrated timestamp is calculated from the nominal value using the
+formula:
+  ts_gain[ns] â‰ˆ ts_sensitivity - (ts_trim_coeff * val) / 1000.
+
+The values of ts_sensitivity and ts_trim_coeff are not the same for all
+devices, so it is necessary to differentiate them based on the part name.
+For the correct values please consult the relevant AN.
+
+Fixes: cb3b6b8e1bc0 ("iio: imu: st_lsm6dsx: add odr calibration feature")
+Signed-off-by: Mario Tesi <mario.tesi@st.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h      | 18 ++++++++++++++++++
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 19 ++++++++-----------
+ 2 files changed, 26 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+index c19237717e812..0f347684f6fc9 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+@@ -190,6 +190,22 @@ struct st_lsm6dsx_fifo_ops {
+  * @fifo_en: Hw timer FIFO enable register info (addr + mask).
+  * @decimator: Hw timer FIFO decimator register info (addr + mask).
+  * @freq_fine: Difference in % of ODR with respect to the typical.
++ * @ts_sensitivity: Nominal timestamp sensitivity.
++ * @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
++ *                 This coefficient comes into play when linearizing the formula
++ *                 used to calculate the calibrated timestamp (please see the
++ *                 relevant formula in the AN for the specific IMU).
++ *                 For example, in the case of LSM6DSO we have:
++ *
++ *                  1 / (1 + x) ~= 1 - x (Taylor’s Series)
++ *                  ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
++ *                  ttrim[ns] ~= 25000 - 37.5 * val
++ *                  ttrim[ns] ~= 25000 - (37500 * val) / 1000
++ *
++ *                  so, replacing ts_sensitivity = 25000 and
++ *                  ts_trim_coeff = 37500
++ *
++ *                  ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
+  */
+ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg timer_en;
+@@ -197,6 +213,8 @@ struct st_lsm6dsx_hw_ts_settings {
+       struct st_lsm6dsx_reg fifo_en;
+       struct st_lsm6dsx_reg decimator;
+       u8 freq_fine;
++      u16 ts_sensitivity;
++      u16 ts_trim_coeff;
+ };
+ /**
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index b6e6b1df8a618..6e42e0c659e0c 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -77,8 +77,6 @@
+ #define ST_LSM6DSX_REG_WHOAMI_ADDR            0x0f
+-#define ST_LSM6DSX_TS_SENSITIVITY             25000UL /* 25us */
+-
+ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+       ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+@@ -962,6 +960,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -1175,6 +1175,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x63,
++                      .ts_sensitivity = 25000,
++                      .ts_trim_coeff = 37500,
+               },
+               .event_settings = {
+                       .enable_reg = {
+@@ -1350,6 +1352,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+                               .mask = GENMASK(7, 6),
+                       },
+                       .freq_fine = 0x4f,
++                      .ts_sensitivity = 21701,
++                      .ts_trim_coeff = 28212,
+               },
+               .shub_settings = {
+                       .page_mux = {
+@@ -2243,20 +2247,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
+       }
+       /* calibrate timestamp sensitivity */
+-      hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
++      hw->ts_gain = ts_settings->ts_sensitivity;
+       if (ts_settings->freq_fine) {
+               err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
+               if (err < 0)
+                       return err;
+-              /*
+-               * linearize the AN5192 formula:
+-               * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
+-               * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
+-               * ttrim[ns] ~= 25000 - 37.5 * val
+-               * ttrim[ns] ~= 25000 - (37500 * val) / 1000
+-               */
+-              hw->ts_gain -= ((s8)val * 37500) / 1000;
++              hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000;
+       }
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.6/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch b/queue-6.6/mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
new file mode 100644 (file)
index 0000000..dfd6beb
--- /dev/null
@@ -0,0 +1,38 @@
+From 1ce4753ea297b48e491adfb643bcb75fb3118d80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 10:40:39 +0800
+Subject: mailbox: mailbox-test: Fix debugfs_create_dir error checking
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
+
+The debugfs_create_dir() function returns ERR_PTR() on error, not NULL.
+The current null-check fails to catch errors.
+
+Use IS_ERR() to correctly check for errors.
+
+Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mailbox-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
+index 22d6018ceec3c..6bdee87f30836 100644
+--- a/drivers/mailbox/mailbox-test.c
++++ b/drivers/mailbox/mailbox-test.c
+@@ -268,7 +268,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,
+               return 0;
+       tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
+-      if (!tdev->root_debugfs_dir) {
++      if (IS_ERR(tdev->root_debugfs_dir)) {
+               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+               return -EINVAL;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/mailbox-pcc-don-t-zero-error-register.patch b/queue-6.6/mailbox-pcc-don-t-zero-error-register.patch
new file mode 100644 (file)
index 0000000..b90390d
--- /dev/null
@@ -0,0 +1,57 @@
+From ac5da2a5fc97a9cd4b51dce0ba21032d6bff45e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:42:29 +0000
+Subject: mailbox: pcc: don't zero error register
+
+From: Jamie Iles <jamie.iles@oss.qualcomm.com>
+
+[ Upstream commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 ]
+
+The error status mask for a type 3/4 subspace is used for reading the
+error status, and the bitwise inverse is used for clearing the error
+with the intent being to preserve any of the non-error bits.  However,
+we were previously applying the mask to extract the status and then
+applying the inverse to the result which ended up clearing all bits.
+
+Instead, store the inverse mask in the preserve mask and then use that
+on the original value read from the error status so that only the error
+is cleared.
+
+Fixes: c45ded7e1135 ("mailbox: pcc: Add support for PCCT extended PCC subspaces(type 3/4)")
+Signed-off-by: Jamie Iles <jamie.iles@oss.qualcomm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@oss.qualcomm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index bb977cf8ad423..2b7d0bc920726 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -278,9 +278,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
+       if (ret)
+               return ret;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
++      if (val & pchan->error.status_mask) {
++              val &= pchan->error.preserve_mask;
+               pcc_chan_reg_write(&pchan->error, val);
+               return -EIO;
+       }
+@@ -673,7 +672,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
+               ret = pcc_chan_reg_init(&pchan->error,
+                                       &pcct_ext->error_status_register,
+-                                      0, 0, pcct_ext->error_status_mask,
++                                      ~pcct_ext->error_status_mask, 0,
++                                      pcct_ext->error_status_mask,
+                                       "Error Status");
+       }
+       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.6/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch b/queue-6.6/mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
new file mode 100644 (file)
index 0000000..2c10326
--- /dev/null
@@ -0,0 +1,92 @@
+From 2ed84f02a5c3a92b88c0fc9c7b27a46bfa6a4739 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 15:28:52 +0000
+Subject: mailbox: pcc: Refactor error handling in irq handler into separate
+ function
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 3a675f50415b95f2ae10bfd932e2154ba1a08ee7 ]
+
+The existing error handling logic in pcc_mbox_irq() is intermixed with the
+main flow of the function. The command complete check and the complete
+complete update/acknowledgment are nicely factored into separate functions.
+
+Moves error detection and clearing logic into a separate function called:
+pcc_mbox_error_check_and_clear() by extracting error-handling logic from
+pcc_mbox_irq().
+
+This ensures error checking and clearing are handled separately and it
+improves maintainability by keeping the IRQ handler focused on processing
+events.
+
+Acked-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Huisong Li <lihuisong@huawei.com>
+Tested-by: Adam Young <admiyo@os.amperecomputing.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 49254d99a8ad6..bb977cf8ad423 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -269,6 +269,25 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+       return !!val;
+ }
++static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)
++{
++      u64 val;
++      int ret;
++
++      ret = pcc_chan_reg_read(&pchan->error, &val);
++      if (ret)
++              return ret;
++
++      val &= pchan->error.status_mask;
++      if (val) {
++              val &= ~pchan->error.status_mask;
++              pcc_chan_reg_write(&pchan->error, val);
++              return -EIO;
++      }
++
++      return 0;
++}
++
+ static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
+ {
+       struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
+@@ -309,8 +328,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+ {
+       struct pcc_chan_info *pchan;
+       struct mbox_chan *chan = p;
+-      u64 val;
+-      int ret;
+       pchan = chan->con_priv;
+@@ -324,15 +341,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+-      ret = pcc_chan_reg_read(&pchan->error, &val);
+-      if (ret)
++      if (pcc_mbox_error_check_and_clear(pchan))
+               return IRQ_NONE;
+-      val &= pchan->error.status_mask;
+-      if (val) {
+-              val &= ~pchan->error.status_mask;
+-              pcc_chan_reg_write(&pchan->error, val);
+-              return IRQ_NONE;
+-      }
+       /*
+        * Clear this flag after updating interrupt ack register and just
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-aquantia-add-missing-descriptor-cache-invalidati.patch b/queue-6.6/net-aquantia-add-missing-descriptor-cache-invalidati.patch
new file mode 100644 (file)
index 0000000..f42b893
--- /dev/null
@@ -0,0 +1,144 @@
+From f7e6996e4bd04d599e40464c28ce806d29e7d713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 12:15:33 +0800
+Subject: net: aquantia: Add missing descriptor cache invalidation on ATL2
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
+
+ATL2 hardware was missing descriptor cache invalidation in hw_stop(),
+causing SMMU translation faults during device shutdown and module removal:
+[   70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received:
+[   70.361893] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0002060000000010
+[   70.367948] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000020000000000
+[   70.374002] arm-smmu-v3 arm-smmu-v3.5.auto:  0x00000000ff9bc000
+[   70.380055] arm-smmu-v3 arm-smmu-v3.5.auto:  0x0000000000000000
+[   70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0
+[   70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
+
+Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after
+driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning
+hw cache it should be toggled") fixed cache invalidation for ATL B0, but
+ATL2 was left with only interrupt disabling. This allowed hardware to
+write to cached descriptors after DMA memory was unmapped, triggering
+SMMU faults. Once cache invalidation is applied to ATL2, the translation
+fault can't be observed anymore.
+
+Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both
+ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
+
+Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops")
+Tested-by: Carol Soto <csoto@nvidia.com>
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/aquantia/atlantic/aq_hw_utils.c  | 22 +++++++++++++++++++
+ .../ethernet/aquantia/atlantic/aq_hw_utils.h  |  1 +
+ .../aquantia/atlantic/hw_atl/hw_atl_b0.c      | 19 +---------------
+ .../aquantia/atlantic/hw_atl2/hw_atl2.c       |  2 +-
+ 4 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+index 1921741f7311d..18b08277d2e1a 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+@@ -15,6 +15,7 @@
+ #include "aq_hw.h"
+ #include "aq_nic.h"
++#include "hw_atl/hw_atl_llh.h"
+ void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
+                        u32 shift, u32 val)
+@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+               lo_hi_writeq(value, hw->mmio + reg);
+ }
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw)
++{
++      int err;
++      u32 val;
++
++      /* Invalidate Descriptor Cache to prevent writing to the cached
++       * descriptors and to the data pointer of those descriptors
++       */
++      hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw);
++
++      err = aq_hw_err_from_flags(hw);
++      if (err)
++              goto err_exit;
++
++      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
++                                hw, val, val == 1, 1000U, 10000U);
++
++err_exit:
++      return err;
++}
++
+ int aq_hw_err_from_flags(struct aq_hw_s *hw)
+ {
+       int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+index ffa6e4067c211..d89c63d88e4a4 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
+ u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
++int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw);
+ int aq_hw_err_from_flags(struct aq_hw_s *hw);
+ int aq_hw_num_tcs(struct aq_hw_s *hw);
+ int aq_hw_q_per_tc(struct aq_hw_s *hw);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+index 54e70f07b5734..7b4814b3ba442 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
+ static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
+ {
+-      int err;
+-      u32 val;
+-
+       hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+-      /* Invalidate Descriptor Cache to prevent writing to the cached
+-       * descriptors and to the data pointer of those descriptors
+-       */
+-      hw_atl_rdm_rx_dma_desc_cache_init_tgl(self);
+-
+-      err = aq_hw_err_from_flags(self);
+-
+-      if (err)
+-              goto err_exit;
+-
+-      readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get,
+-                                self, val, val == 1, 1000U, 10000U);
+-
+-err_exit:
+-      return err;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
+diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+index 220400a633f5e..a7bef9da823da 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self)
+ {
+       hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
+-      return 0;
++      return aq_hw_invalidate_descriptor_cache(self);
+ }
+ static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch b/queue-6.6/net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
new file mode 100644 (file)
index 0000000..3258e18
--- /dev/null
@@ -0,0 +1,93 @@
+From fe8b7626622ee197fd4721fc67f21e62a31d10a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 11:22:49 +0800
+Subject: net: atlantic: fix fragment overflow handling in RX path
+
+From: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+
+[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
+
+The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17)
+fragments when handling large multi-descriptor packets. This causes an
+out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
+
+The issue occurs because the driver doesn't check the total number of
+fragments before calling skb_add_rx_frag(). When a packet requires more
+than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
+
+Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+then all fragments are accounted for. And reusing the existing check to
+prevent the overflow earlier in the code path.
+
+This crash occurred in production with an Aquantia AQC113 10G NIC.
+
+Stack trace from production environment:
+```
+RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0
+Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89
+ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90
+c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48
+89 fa 83
+RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287
+RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX:
+fffffffe0a0c8000
+RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI:
+0000000000037a40
+RBP: 0000000000000024 R08: 0000000000000000 R09:
+0000000000000021
+R10: 0000000000000848 R11: 0000000000000000 R12:
+ffffa9bec02a8e24
+R13: ffff925ad8615570 R14: 0000000000000000 R15:
+ffff925b22e80a00
+FS: 0000000000000000(0000)
+GS:ffff925e47880000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4:
+0000000000f72ef0
+PKRU: 55555554
+Call Trace:
+<IRQ>
+aq_ring_rx_clean+0x175/0xe60 [atlantic]
+? aq_ring_rx_clean+0x14d/0xe60 [atlantic]
+? aq_ring_tx_clean+0xdf/0x190 [atlantic]
+? kmem_cache_free+0x348/0x450
+? aq_vec_poll+0x81/0x1d0 [atlantic]
+? __napi_poll+0x28/0x1c0
+? net_rx_action+0x337/0x420
+```
+
+Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS")
+Changes in v4:
+- Add Fixes: tag to satisfy patch validation requirements.
+
+Changes in v3:
+- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE,
+  then all fragments are accounted for.
+
+Signed-off-by: Jiefeng Zhang <jiefeng.z.zhang@gmail.com>
+Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+index f7433abd65915..3f004d08307fb 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+@@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
+               if (!buff->is_eop) {
+                       unsigned int frag_cnt = 0U;
++
++                      /* There will be an extra fragment */
++                      if (buff->len > AQ_CFG_RX_HDR_SIZE)
++                              frag_cnt++;
++
+                       buff_ = buff;
+                       do {
+                               bool is_rsc_completed = true;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch b/queue-6.6/net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
new file mode 100644 (file)
index 0000000..30ef7c2
--- /dev/null
@@ -0,0 +1,73 @@
+From 0531a52c763c06ccc21ace6f636a48ff5d12a0c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Nov 2025 13:13:24 +0200
+Subject: net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing
+ traffic
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
+
+When using the SGMII PCS as a fixed-link chip-to-chip connection, it is
+easy to miss the fact that traffic passes only at 1G, since that's what
+any normal such connection would use.
+
+When using the SGMII PCS connected towards an on-board PHY or an SFP
+module, it is immediately noticeable that when the link resolves to a
+speed other than 1G, traffic from the MAC fails to pass: TX counters
+increase, but nothing gets decoded by the other end, and no local RX
+counters increase either.
+
+Artificially lowering a fixed-link rate to speed = <100> makes us able
+to see the same issue as in the case of having an SGMII PHY.
+
+Some debugging shows that the XPCS configuration is A-OK, but that the
+MAC Configuration Table entry for the port has the SPEED bits still set
+to 1000Mbps, due to a special condition in the driver. Deleting that
+condition, and letting the resolved link speed be programmed directly
+into the MAC speed field, results in a functional link at all 3 speeds.
+
+This piece of evidence, based on testing on both generations with SGMII
+support (SJA1105S and SJA1110A) directly contradicts the statement from
+the blamed commit that "the MAC is fixed at 1 Gbps and we need to
+configure the PCS only (if even that)". Worse, that statement is not
+backed by any documentation, and no one from NXP knows what it might
+refer to.
+
+I am unable to recall sufficient context regarding my testing from March
+2020 to understand what led me to draw such a braindead and factually
+incorrect conclusion. Yet, there is nothing of value regarding forcing
+the MAC speed, either for SGMII or 2500Base-X (introduced at a later
+stage), so remove all such logic.
+
+Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index 0de73a6257f9a..1acc5d912d161 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1307,14 +1307,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
+        * table, since this will be used for the clocking setup, and we no
+        * longer need to store it in the static config (already told hardware
+        * we want auto during upload phase).
+-       * Actually for the SGMII port, the MAC is fixed at 1 Gbps and
+-       * we need to configure the PCS only (if even that).
+        */
+-      if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+-      else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-
+       mac[port].speed = speed;
+       return 0;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-dsa-sja1105-simplify-static-configuration-reload.patch b/queue-6.6/net-dsa-sja1105-simplify-static-configuration-reload.patch
new file mode 100644 (file)
index 0000000..5f794a2
--- /dev/null
@@ -0,0 +1,159 @@
+From b868b4fbe230d28bb168a69bf9003fc1af18abd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 17:04:36 +0100
+Subject: net: dsa: sja1105: simplify static configuration reload
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit a18891b55703a45b700618ef40edd5e9aaecc345 ]
+
+The static configuration reload saves the port speed in the static
+configuration tables by first converting it from the internal
+respresentation to the SPEED_xxx ethtool representation, and then
+converts it back to restore the setting. This is because
+sja1105_adjust_port_config() takes the speed as SPEED_xxx.
+
+However, this is unnecessarily complex. If we split
+sja1105_adjust_port_config() up, we can simply save and restore the
+mac[port].speed member in the static configuration tables.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------
+ 1 file changed, 34 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index 843e50b5a0ec5..0de73a6257f9a 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1261,29 +1261,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)
+       return rc;
+ }
+-/* Convert link speed from SJA1105 to ethtool encoding */
+-static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv,
+-                                       u64 speed)
+-{
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS])
+-              return SPEED_10;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS])
+-              return SPEED_100;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS])
+-              return SPEED_1000;
+-      if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS])
+-              return SPEED_2500;
+-      return SPEED_UNKNOWN;
+-}
+-
+-/* Set link speed in the MAC configuration for a specific port. */
+-static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+-                                    int speed_mbps)
++static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
++                                int speed_mbps)
+ {
+       struct sja1105_mac_config_entry *mac;
+-      struct device *dev = priv->ds->dev;
+       u64 speed;
+-      int rc;
+       /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
+        * tables. On E/T, MAC reconfig tables are not readable, only writable.
+@@ -1317,7 +1299,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+               speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+               break;
+       default:
+-              dev_err(dev, "Invalid speed %iMbps\n", speed_mbps);
++              dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps);
+               return -EINVAL;
+       }
+@@ -1329,11 +1311,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
+        * we need to configure the PCS only (if even that).
+        */
+       if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
++              speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
+       else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
+-              mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
+-      else
+-              mac[port].speed = speed;
++              speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
++
++      mac[port].speed = speed;
++
++      return 0;
++}
++
++/* Write the MAC Configuration Table entry and, if necessary, the CGU settings,
++ * after a link speedchange for this port.
++ */
++static int sja1105_set_port_config(struct sja1105_private *priv, int port)
++{
++      struct sja1105_mac_config_entry *mac;
++      struct device *dev = priv->ds->dev;
++      int rc;
++
++      /* On P/Q/R/S, one can read from the device via the MAC reconfiguration
++       * tables. On E/T, MAC reconfig tables are not readable, only writable.
++       * We have to *know* what the MAC looks like.  For the sake of keeping
++       * the code common, we'll use the static configuration tables as a
++       * reasonable approximation for both E/T and P/Q/R/S.
++       */
++      mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+       /* Write to the dynamic reconfiguration tables */
+       rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+@@ -1383,7 +1385,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
+ {
+       struct sja1105_private *priv = ds->priv;
+-      sja1105_adjust_port_config(priv, port, speed);
++      if (!sja1105_set_port_speed(priv, port, speed))
++              sja1105_set_port_config(priv, port);
+       sja1105_inhibit_tx(priv, BIT(port), false);
+ }
+@@ -2284,8 +2287,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+ {
+       struct ptp_system_timestamp ptp_sts_before;
+       struct ptp_system_timestamp ptp_sts_after;
+-      int speed_mbps[SJA1105_MAX_NUM_PORTS];
+       u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0};
++      u64 mac_speed[SJA1105_MAX_NUM_PORTS];
+       struct sja1105_mac_config_entry *mac;
+       struct dsa_switch *ds = priv->ds;
+       s64 t1, t2, t3, t4;
+@@ -2298,14 +2301,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+       mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+-      /* Back up the dynamic link speed changed by sja1105_adjust_port_config
++      /* Back up the dynamic link speed changed by sja1105_set_port_speed()
+        * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the
+        * switch wants to see in the static config in order to allow us to
+        * change it through the dynamic interface later.
+        */
+       for (i = 0; i < ds->num_ports; i++) {
+-              speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
+-                                                            mac[i].speed);
++              mac_speed[i] = mac[i].speed;
+               mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];
+               if (priv->xpcs[i])
+@@ -2368,7 +2370,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
+               struct dw_xpcs *xpcs = priv->xpcs[i];
+               unsigned int neg_mode;
+-              rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
++              mac[i].speed = mac_speed[i];
++              rc = sja1105_set_port_config(priv, i);
+               if (rc < 0)
+                       goto out;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-cancel-perout_timer-when-perout-is-disabled.patch b/queue-6.6/net-fec-cancel-perout_timer-when-perout-is-disabled.patch
new file mode 100644 (file)
index 0000000..eea1d85
--- /dev/null
@@ -0,0 +1,42 @@
+From 154dff42240b04b4495c96630f197d71e3fc2cb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:07 +0800
+Subject: net: fec: cancel perout_timer when PEROUT is disabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 50caa744689e505414673c20359b04aa918439e3 ]
+
+The PEROUT allows the user to set a specified future time to output the
+periodic signal. If the future time is far from the current time, the FEC
+driver will use hrtimer to configure PEROUT one second before the future
+time. However, the hrtimer will not be canceled if the PEROUT is disabled
+before the hrtimer expires. So the PEROUT will be configured when the
+hrtimer expires, which is not as expected. Therefore, cancel the hrtimer
+in fec_ptp_pps_disable() to fix this issue.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-2-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index 7f6b574320716..cb3f05da3eee6 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -498,6 +498,8 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+ {
+       unsigned long flags;
++      hrtimer_cancel(&fep->perout_timer);
++
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch b/queue-6.6/net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
new file mode 100644 (file)
index 0000000..85329a0
--- /dev/null
@@ -0,0 +1,58 @@
+From 0fce626b2b228fb1699019cbc3e3de4010092f04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:09 +0800
+Subject: net: fec: do not allow enabling PPS and PEROUT simultaneously
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit c0a1f3d7e128e8d1b6c0fe09c68eac5ebcf677c8 ]
+
+In the current driver, PPS and PEROUT use the same channel to generate
+the events, so they cannot be enabled at the same time. Otherwise, the
+later configuration will overwrite the earlier configuration. Therefore,
+when configuring PPS, the driver will check whether PEROUT is enabled.
+Similarly, when configuring PEROUT, the driver will check whether PPS
+is enabled.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-4-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index a3853fccdc7b6..beb1d98fa741a 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -129,6 +129,12 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      if (fep->perout_enable) {
++              spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++              dev_err(&fep->pdev->dev, "PEROUT is running");
++              return -EBUSY;
++      }
++
+       if (fep->pps_enable == enable) {
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return 0;
+@@ -572,6 +578,12 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++                      if (fep->pps_enable) {
++                              dev_err(&fep->pdev->dev, "PPS is running");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       if (fep->perout_enable) {
+                               dev_err(&fep->pdev->dev,
+                                       "PEROUT has been enabled\n");
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-do-not-register-pps-event-for-perout.patch b/queue-6.6/net-fec-do-not-register-pps-event-for-perout.patch
new file mode 100644 (file)
index 0000000..1d3170e
--- /dev/null
@@ -0,0 +1,48 @@
+From 315ef572f3f8dfb7fefc6c95f8c69aabb557f3c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:10 +0800
+Subject: net: fec: do not register PPS event for PEROUT
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 9a060d0fac9e75524f72864adec6d8cdb70a5bca ]
+
+There are currently two situations that can trigger the PTP interrupt,
+one is the PPS event, the other is the PEROUT event. However, the irq
+handler fec_pps_interrupt() does not check the irq event type and
+directly registers a PPS event into the system, but the event may be
+a PEROUT event. This is incorrect because PEROUT is an output signal,
+while PPS is the input of the kernel PPS system. Therefore, add a check
+for the event type, if pps_enable is true, it means that the current
+event is a PPS event, and then the PPS event is registered.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-5-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_ptp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index beb1d98fa741a..4bb894b5afcb9 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -719,8 +719,11 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id)
+               fep->next_counter = (fep->next_counter + fep->reload_period) &
+                               fep->cc.mask;
+-              event.type = PTP_CLOCK_PPS;
+-              ptp_clock_event(fep->ptp_clock, &event);
++              if (fep->pps_enable) {
++                      event.type = PTP_CLOCK_PPS;
++                      ptp_clock_event(fep->ptp_clock, &event);
++              }
++
+               return IRQ_HANDLED;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-do-not-update-perout-if-it-is-enabled.patch b/queue-6.6/net-fec-do-not-update-perout-if-it-is-enabled.patch
new file mode 100644 (file)
index 0000000..2ffdb35
--- /dev/null
@@ -0,0 +1,137 @@
+From bcc78467e4709dccd613569f78ca5871b4343149 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:52:08 +0800
+Subject: net: fec: do not update PEROUT if it is enabled
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e97faa0c20ea8840f45569ba434e30538fff8fc9 ]
+
+If the previously set PEROUT is already active, updating it will cause
+the new PEROUT to start immediately instead of at the specified time.
+This is because fep->reload_period is updated whithout check whether
+the PEROUT is enabled, and the old PEROUT is not disabled. Therefore,
+the pulse period will be updated immediately in the pulse interrupt
+handler fec_pps_interrupt().
+
+Currently, the driver does not support directly updating PEROUT and it
+will make the logic be more complicated. To fix the current issue, add
+a check before enabling the PEROUT, the driver will return an error if
+PEROUT is enabled. If users wants to update a new PEROUT, they should
+disable the old PEROUT first.
+
+Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251125085210.1094306-3-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec.h     |  1 +
+ drivers/net/ethernet/freescale/fec_ptp.c | 43 ++++++++++++++++++------
+ 2 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 733af928caffc..d80a8c07c0200 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -683,6 +683,7 @@ struct fec_enet_private {
+       unsigned int reload_period;
+       int pps_enable;
+       unsigned int next_counter;
++      bool perout_enable;
+       struct hrtimer perout_timer;
+       u64 perout_stime;
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index cb3f05da3eee6..a3853fccdc7b6 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -244,6 +244,7 @@ static int fec_ptp_pps_perout(struct fec_enet_private *fep)
+        * the FEC_TCCR register in time and missed the start time.
+        */
+       if (fep->perout_stime < curr_time + 100 * NSEC_PER_MSEC) {
++              fep->perout_enable = false;
+               dev_err(&fep->pdev->dev, "Current time is too close to the start time!\n");
+               spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+               return -1;
+@@ -501,6 +502,7 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
+       hrtimer_cancel(&fep->perout_timer);
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
++      fep->perout_enable = false;
+       writel(0, fep->hwp + FEC_TCSR(channel));
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+@@ -532,6 +534,8 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+               return ret;
+       } else if (rq->type == PTP_CLK_REQ_PEROUT) {
++              u32 reload_period;
++
+               /* Reject requests with unsupported flags */
+               if (rq->perout.flags)
+                       return -EOPNOTSUPP;
+@@ -551,12 +555,14 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                       return -EOPNOTSUPP;
+               }
+-              fep->reload_period = div_u64(period_ns, 2);
+-              if (on && fep->reload_period) {
++              reload_period = div_u64(period_ns, 2);
++              if (on && reload_period) {
++                      u64 perout_stime;
++
+                       /* Convert 1588 timestamp to ns*/
+                       start_time.tv_sec = rq->perout.start.sec;
+                       start_time.tv_nsec = rq->perout.start.nsec;
+-                      fep->perout_stime = timespec64_to_ns(&start_time);
++                      perout_stime = timespec64_to_ns(&start_time);
+                       mutex_lock(&fep->ptp_clk_mutex);
+                       if (!fep->ptp_clk_on) {
+@@ -565,18 +571,35 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
+                               return -EOPNOTSUPP;
+                       }
+                       spin_lock_irqsave(&fep->tmreg_lock, flags);
++
++                      if (fep->perout_enable) {
++                              dev_err(&fep->pdev->dev,
++                                      "PEROUT has been enabled\n");
++                              ret = -EBUSY;
++                              goto unlock;
++                      }
++
+                       /* Read current timestamp */
+                       curr_time = timecounter_read(&fep->tc);
+-                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+-                      mutex_unlock(&fep->ptp_clk_mutex);
++                      if (perout_stime <= curr_time) {
++                              dev_err(&fep->pdev->dev,
++                                      "Start time must be greater than current time\n");
++                              ret = -EINVAL;
++                              goto unlock;
++                      }
+                       /* Calculate time difference */
+-                      delta = fep->perout_stime - curr_time;
++                      delta = perout_stime - curr_time;
++                      fep->reload_period = reload_period;
++                      fep->perout_stime = perout_stime;
++                      fep->perout_enable = true;
+-                      if (fep->perout_stime <= curr_time) {
+-                              dev_err(&fep->pdev->dev, "Start time must larger than current time!\n");
+-                              return -EINVAL;
+-                      }
++unlock:
++                      spin_unlock_irqrestore(&fep->tmreg_lock, flags);
++                      mutex_unlock(&fep->ptp_clk_mutex);
++
++                      if (ret)
++                              return ret;
+                       /* Because the timer counter of FEC only has 31-bits, correspondingly,
+                        * the time comparison register FEC_TCCR also only low 31 bits can be
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-lan966x-fix-the-initialization-of-taprio.patch b/queue-6.6/net-lan966x-fix-the-initialization-of-taprio.patch
new file mode 100644 (file)
index 0000000..75dba22
--- /dev/null
@@ -0,0 +1,56 @@
+From 966b8ac6e88ccb0e7da6f8de124b58de479e6581 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 07:14:11 +0100
+Subject: net: lan966x: Fix the initialization of taprio
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 ]
+
+To initialize the taprio block in lan966x, it is required to configure
+the register REVISIT_DLY. The purpose of this register is to set the
+delay before revisit the next gate and the value of this register depends
+on the system clock. The problem is that the we calculated wrong the value
+of the system clock period in picoseconds. The actual system clock is
+~165.617754MHZ and this correspond to a period of 6038 pico seconds and
+not 15125 as currently set.
+
+Fixes: e462b2717380b4 ("net: lan966x: Add offload support for taprio")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121061411.810571-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index 87e5e81d40dc6..84f5b4410e48e 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -1,11 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/ptp_classify.h>
++#include <linux/units.h>
+ #include "lan966x_main.h"
+ #include "vcap_api.h"
+ #include "vcap_api_client.h"
++#define LAN9X66_CLOCK_RATE    165617754
++
+ #define LAN966X_MAX_PTP_ID    512
+ /* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
+@@ -1132,5 +1135,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
+ u32 lan966x_ptp_get_period_ps(void)
+ {
+       /* This represents the system clock period in picoseconds */
+-      return 15125;
++      return PICO / LAN9X66_CLOCK_RATE;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5e-fix-validation-logic-in-rate-limiting.patch b/queue-6.6/net-mlx5e-fix-validation-logic-in-rate-limiting.patch
new file mode 100644 (file)
index 0000000..0b8dceb
--- /dev/null
@@ -0,0 +1,63 @@
+From 19d7956379623190125df62a066356f6dcf60a7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:00:43 -0800
+Subject: net/mlx5e: Fix validation logic in rate limiting
+
+From: Danielle Costantino <dcostantino@meta.com>
+
+[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
+
+The rate limiting validation condition currently checks the output
+variable max_bw_value[i] instead of the input value
+maxrate->tc_maxrate[i]. This causes the validation to compare an
+uninitialized or stale value rather than the actual requested rate.
+
+The condition should check the input rate to properly validate against
+the upper limit:
+
+    } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+
+This aligns with the pattern used in the first branch, which correctly
+checks maxrate->tc_maxrate[i] against upper_limit_mbps.
+
+The current implementation can lead to unreliable validation behavior:
+
+- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0
+  from initialization, the GBPS path may be taken regardless of whether
+  the actual rate is within bounds
+
+- When processing multiple TCs (i > 0), max_bw_value[i] contains the
+  value computed for the previous TC, affecting the validation logic
+
+- The overflow check for rates exceeding 255 Gbps may not trigger
+  consistently depending on previous array values
+
+This patch ensures the validation correctly examines the requested rate
+value for proper bounds checking.
+
+Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps")
+Signed-off-by: Danielle Costantino <dcostantino@meta.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 29e633e6dd3f0..e29a8ed7e7ac1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -619,7 +619,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else if (max_bw_value[i] <= upper_limit_gbps) {
++              } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch b/queue-6.6/net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
new file mode 100644 (file)
index 0000000..c9c8e2e
--- /dev/null
@@ -0,0 +1,42 @@
+From 9966de5088b4b34f1db3d0efa433368dc7f953d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Nov 2025 14:17:13 +0000
+Subject: net: phy: mxl-gpy: fix bogus error on USXGMII and integrated PHY
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit ec3803b5917b6ff2f86ea965d0985c95d8a85119 ]
+
+As the interface mode doesn't need to be updated on PHYs connected with
+USXGMII and integrated PHYs, gpy_update_interface() should just return 0
+in these cases rather than -EINVAL which has wrongly been introduced by
+commit 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface()
+function return type"), as this breaks support for those PHYs.
+
+Fixes: 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface() function return type")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/f744f721a1fcc5e2e936428c62ff2c7d94d2a293.1763648168.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mxl-gpy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index 034f5c4d03377..5868a0747097f 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -515,7 +515,7 @@ static int gpy_update_interface(struct phy_device *phydev)
+       /* Interface mode is fixed for USXGMII and integrated PHY */
+       if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
+           phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
+-              return -EINVAL;
++              return 0;
+       /* Automatically switch SERDES interface between SGMII and 2500-BaseX
+        * according to speed. Disable ANEG in 2500-BaseX mode.
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch b/queue-6.6/net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
new file mode 100644 (file)
index 0000000..5d4297e
--- /dev/null
@@ -0,0 +1,47 @@
+From 2d112a7540c0bdbd79c80d508df148132877ed72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 12:38:34 +0000
+Subject: net: sxgbe: fix potential NULL dereference in sxgbe_rx()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
+
+Currently, when skb is null, the driver prints an error and then
+dereferences skb on the next line.
+
+To fix this, let's add a 'break' after the error message to switch
+to sxgbe_rx_refill(), which is similar to the approach taken by the
+other drivers in this particular case, e.g. calxeda with xgmac_rx().
+
+Found during a code review.
+
+Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+index 71439825ea4e0..d662679c29832 100644
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+@@ -1521,8 +1521,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
+               skb = priv->rxq[qnum]->rx_skbuff[entry];
+-              if (unlikely(!skb))
++              if (unlikely(!skb)) {
+                       netdev_err(priv->dev, "rx descriptor is not consistent\n");
++                      break;
++              }
+               prefetch(skb->data - NET_IP_ALIGN);
+               priv->rxq[qnum]->rx_skbuff[entry] = NULL;
+-- 
+2.51.0
+
diff --git a/queue-6.6/platform-x86-intel-punit_ipc-fix-memory-corruption.patch b/queue-6.6/platform-x86-intel-punit_ipc-fix-memory-corruption.patch
new file mode 100644 (file)
index 0000000..f1116bd
--- /dev/null
@@ -0,0 +1,46 @@
+From b011302d23bdf3a7d1b01c61606bbc1d8339e2b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 20:51:28 +0300
+Subject: platform/x86: intel: punit_ipc: fix memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
+
+This passes the address of the pointer "&punit_ipcdev" when the intent
+was to pass the pointer itself "punit_ipcdev" (without the ampersand).
+This means that the:
+
+       complete(&ipcdev->cmd_complete);
+
+in intel_punit_ioc() will write to a wrong memory address corrupting it.
+
+Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/punit_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
+index cd0ba84cc8e4a..9e48229538a5e 100644
+--- a/drivers/platform/x86/intel/punit_ipc.c
++++ b/drivers/platform/x86/intel/punit_ipc.c
+@@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
+       } else {
+               ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+                                      IRQF_NO_SUSPEND, "intel_punit_ipc",
+-                                     &punit_ipcdev);
++                                     punit_ipcdev);
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.6/series b/queue-6.6/series
new file mode 100644 (file)
index 0000000..c17fb07
--- /dev/null
@@ -0,0 +1,33 @@
+can-kvaser_usb-leaf-fix-potential-infinite-loop-in-c.patch
+can-gs_usb-gs_usb_xmit_callback-fix-handling-of-fail.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch
+can-gs_usb-gs_usb_receive_bulk_callback-check-actual.patch-2290
+bluetooth-hci_sock-prevent-race-in-socket-write-iter.patch
+bluetooth-smp-fix-not-generating-mackey-and-ltk-when.patch
+net-phy-mxl-gpy-fix-bogus-error-on-usxgmii-and-integ.patch
+platform-x86-intel-punit_ipc-fix-memory-corruption.patch
+net-aquantia-add-missing-descriptor-cache-invalidati.patch
+net-lan966x-fix-the-initialization-of-taprio.patch
+net-mlx5e-fix-validation-logic-in-rate-limiting.patch
+net-sxgbe-fix-potential-null-dereference-in-sxgbe_rx.patch
+drm-amdgpu-fix-cyan_skillfish2-gpu-info-fw-handling.patch
+net-dsa-sja1105-simplify-static-configuration-reload.patch
+net-dsa-sja1105-fix-sgmii-linking-at-10m-or-100m-but.patch
+net-atlantic-fix-fragment-overflow-handling-in-rx-pa.patch
+net-fec-cancel-perout_timer-when-perout-is-disabled.patch
+net-fec-do-not-update-perout-if-it-is-enabled.patch
+net-fec-do-not-allow-enabling-pps-and-perout-simulta.patch
+net-fec-do-not-register-pps-event-for-perout.patch
+iio-st_lsm6dsx-fixed-calibrated-timestamp-calculatio.patch
+usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
+mailbox-mailbox-test-fix-debugfs_create_dir-error-ch.patch
+mailbox-pcc-refactor-error-handling-in-irq-handler-i.patch
+mailbox-pcc-don-t-zero-error-register.patch
+spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
+spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
+spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch
+spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch
+spi-spi-mem-add-a-new-controller-capability.patch
+spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch
+spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
+spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
diff --git a/queue-6.6/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch b/queue-6.6/spi-amlogic-spifc-a1-handle-devm_pm_runtime_enable-e.patch
new file mode 100644 (file)
index 0000000..8909b8c
--- /dev/null
@@ -0,0 +1,42 @@
+From c93aa495cf3e15d9ebaf1e11e5a4fb4cbd1afb4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 09:58:52 +0800
+Subject: spi: amlogic-spifc-a1: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit a90903c2a3c38bce475f46ea3f93dbf6a9971553 ]
+
+devm_pm_runtime_enable() can fail due to memory allocation. The current
+code ignores its return value, potentially causing runtime PM operations
+to fail silently after autosuspend configuration.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 909fac05b926 ("spi: add support for Amlogic A1 SPI Flash Controller")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20251124015852.937-1-vulab@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-amlogic-spifc-a1.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c
+index fadf6667cd51c..b430bca4f8bce 100644
+--- a/drivers/spi/spi-amlogic-spifc-a1.c
++++ b/drivers/spi/spi-amlogic-spifc-a1.c
+@@ -349,7 +349,9 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
+       pm_runtime_set_autosuspend_delay(spifc->dev, 500);
+       pm_runtime_use_autosuspend(spifc->dev);
+-      devm_pm_runtime_enable(spifc->dev);
++      ret = devm_pm_runtime_enable(spifc->dev);
++      if (ret)
++              return ret;
+       ctrl->num_chipselect = 1;
+       ctrl->dev.of_node = pdev->dev.of_node;
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch b/queue-6.6/spi-bcm63xx-fix-premature-cs-deassertion-on-rx-only-.patch
new file mode 100644 (file)
index 0000000..42be2d3
--- /dev/null
@@ -0,0 +1,68 @@
+From 5fba3709d48bb6f2b350578042c9d78db1fdfeb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Nov 2025 01:08:35 +1100
+Subject: spi: bcm63xx: fix premature CS deassertion on RX-only transactions
+
+From: Hang Zhou <929513338@qq.com>
+
+[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
+
+On BCM6358 (and also observed on BCM6368) the controller appears to
+only generate as many SPI clocks as bytes that have been written into
+the TX FIFO. For RX-only transfers the driver programs the transfer
+length in SPI_MSG_CTL but does not write anything into the FIFO, so
+chip select is deasserted early and the RX transfer segment is never
+fully clocked in.
+
+A concrete failing case is a three-transfer MAC address read from
+SPI-NOR:
+  - TX 0x03 (read command)
+  - TX 3-byte address
+  - RX 6 bytes (MAC)
+
+In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works
+because the driver uses prepend_len and writes dummy bytes into the
+TX FIFO for the RX part.
+
+Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only
+segments so that the number of bytes written to the FIFO matches the
+total message length seen by the controller.
+
+Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up")
+
+Signed-off-by: Hang Zhou <929513338@qq.com>
+Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index a95badb7b7114..ba66fe9f1f543 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+               if (t->rx_buf) {
+                       do_rx = true;
++
++                      /*
++                       * In certain hardware implementations, there appears to be a
++                       * hidden accumulator that tracks the number of bytes written into
++                       * the hardware FIFO, and this accumulator overrides the length in
++                       * the SPI_MSG_CTL register.
++                       *
++                       * Therefore, for read-only transfers, we need to write some dummy
++                       * value into the FIFO to keep the accumulator tracking the correct
++                       * length.
++                       */
++                      if (!t->tx_buf)
++                              memset_io(bs->tx_io + len, 0xFF, t->len);
++
+                       /* prepend is half-duplex write only */
+                       if (t == first)
+                               prepend_len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch b/queue-6.6/spi-nxp-fspi-propagate-fwnode-in-acpi-case-as-well.patch
new file mode 100644 (file)
index 0000000..f1193a9
--- /dev/null
@@ -0,0 +1,78 @@
+From c8cac72655f936f3e80bbfe12c6a829e8e3ab8cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:25:01 +0100
+Subject: spi: nxp-fspi: Propagate fwnode in ACPI case as well
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 40ad64ac25bb736740f895d99a4aebbda9b80991 ]
+
+Propagate fwnode of the ACPI device to the SPI controller Linux device.
+Currently only OF case propagates fwnode to the controller.
+
+While at it, replace several calls to dev_fwnode() with a single one
+cached in a local variable, and unify checks for fwnode type by using
+is_*_node() APIs.
+
+Fixes: 55ab8487e01d ("spi: spi-nxp-fspi: Add ACPI support")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20251126202501.2319679-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 5d631f8c593e3..ce110035a3597 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -1165,7 +1165,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctlr;
+       struct device *dev = &pdev->dev;
+-      struct device_node *np = dev->of_node;
++      struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct resource *res;
+       struct nxp_fspi *f;
+       int ret;
+@@ -1189,7 +1189,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, f);
+       /* find the resources - configuration register address space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               f->iobase = devm_platform_ioremap_resource(pdev, 0);
+       else
+               f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base");
+@@ -1200,7 +1200,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       }
+       /* find the resources - controller memory mapped space */
+-      if (is_acpi_node(dev_fwnode(f->dev)))
++      if (is_acpi_node(fwnode))
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               res = platform_get_resource_byname(pdev,
+@@ -1216,7 +1216,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       f->memmap_phy_size = resource_size(res);
+       /* find the clocks */
+-      if (dev_of_node(&pdev->dev)) {
++      if (is_of_node(fwnode)) {
+               f->clk_en = devm_clk_get(dev, "fspi_en");
+               if (IS_ERR(f->clk_en)) {
+                       ret = PTR_ERR(f->clk_en);
+@@ -1262,7 +1262,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       nxp_fspi_default_setup(f);
+-      ctlr->dev.of_node = np;
++      device_set_node(&ctlr->dev, fwnode);
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+       if (ret)
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch b/queue-6.6/spi-nxp-fspi-support-per-spi-mem-operation-frequency.patch
new file mode 100644 (file)
index 0000000..225deb8
--- /dev/null
@@ -0,0 +1,77 @@
+From e124bfb79ff92599a5f34d3d0e45e73893c9a2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:57 +0100
+Subject: spi: nxp-fspi: Support per spi-mem operation frequency switches
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 26851cf65ffca2d3a8d529a125e54cf0084d69e7 ]
+
+Every ->exec_op() call correctly configures the spi bus speed to the
+maximum allowed frequency for the memory using the constant spi default
+parameter. Since we can now have per-operation constraints, let's use
+the value that comes from the spi-mem operation structure instead. In
+case there is no specific limitation for this operation, the default spi
+device value will be given anyway.
+
+The per-operation frequency capability is thus advertised to the spi-mem
+core.
+
+Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-12-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 731504ec7ef8b..5d631f8c593e3 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -711,9 +711,10 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+  * Value for rest of the CS FLSHxxCR0 register would be zero.
+  *
+  */
+-static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
++static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
++                              const struct spi_mem_op *op)
+ {
+-      unsigned long rate = spi->max_speed_hz;
++      unsigned long rate = op->max_freq;
+       int ret;
+       uint64_t size_kb;
+@@ -938,7 +939,7 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+                                  FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true);
+       WARN_ON(err);
+-      nxp_fspi_select_mem(f, mem->spi);
++      nxp_fspi_select_mem(f, mem->spi, op);
+       nxp_fspi_prepare_lut(f, op);
+       /*
+@@ -1156,6 +1157,10 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
+       .get_name = nxp_fspi_get_name,
+ };
++static const struct spi_controller_mem_caps nxp_fspi_mem_caps = {
++      .per_op_freq = true,
++};
++
+ static int nxp_fspi_probe(struct platform_device *pdev)
+ {
+       struct spi_controller *ctlr;
+@@ -1253,6 +1258,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
+       ctlr->bus_num = -1;
+       ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
+       ctlr->mem_ops = &nxp_fspi_mem_ops;
++      ctlr->mem_caps = &nxp_fspi_mem_caps;
+       nxp_fspi_default_setup(f);
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-spi-mem-add-a-new-controller-capability.patch b/queue-6.6/spi-spi-mem-add-a-new-controller-capability.patch
new file mode 100644 (file)
index 0000000..a51356a
--- /dev/null
@@ -0,0 +1,73 @@
+From 9af862094c74f1d895a710035a18e6b6d8039bc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:47 +0100
+Subject: spi: spi-mem: Add a new controller capability
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 1248c9b8d54120950fda10fbeb98fb8932b4d45c ]
+
+There are spi devices with multiple frequency limitations depending on
+the invoked command. We probably do not want to afford running at the
+lowest supported frequency all the time, so if we want to get the most
+of our hardware, we need to allow per-operation frequency limitations.
+
+Among all the SPI memory controllers, I believe all are capable of
+changing the spi frequency on the fly. Some of the drivers do not make
+any frequency setup though. And some others will derive a per chip
+prescaler value which will be used forever.
+
+Actually changing the frequency on the fly is something new in Linux, so
+we need to carefully flag the drivers which do and do not support it. A
+controller capability is created for that, and the presence for this
+capability will always be checked before accepting such pattern.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-2-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mem.c       | 6 ++++++
+ include/linux/spi/spi-mem.h | 2 ++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index b73a659e268d6..c581aa5fbf7cf 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -191,6 +191,12 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+           op->max_freq < mem->spi->controller->min_speed_hz)
+               return false;
++      if (op->max_freq &&
++          op->max_freq < mem->spi->max_speed_hz) {
++              if (!spi_mem_controller_is_capable(ctlr, per_op_freq))
++                      return false;
++      }
++
+       return spi_mem_check_buswidth(mem, op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index cceebf8c78ba9..6bd0b548bd1e9 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -309,11 +309,13 @@ struct spi_controller_mem_ops {
+  * @ecc: Supports operations with error correction
+  * @swap16: Supports swapping bytes on a 16 bit boundary when configured in
+  *        Octal DTR
++ * @per_op_freq: Supports per operation frequency switching
+  */
+ struct spi_controller_mem_caps {
+       bool dtr;
+       bool ecc;
+       bool swap16;
++      bool per_op_freq;
+ };
+ #define spi_mem_controller_is_capable(ctlr, cap)      \
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch b/queue-6.6/spi-spi-mem-allow-specifying-the-byte-order-in-octal.patch
new file mode 100644 (file)
index 0000000..75dd809
--- /dev/null
@@ -0,0 +1,93 @@
+From 3b80fa87abc28da890346bfa1eb0f5d090ae4f83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Sep 2024 22:19:52 +0800
+Subject: spi: spi-mem: Allow specifying the byte order in Octal DTR mode
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 030ace430afcf847f537227afceb22dfe8fb8fc8 ]
+
+There are NOR flashes (Macronix) that swap the bytes on a 16-bit
+boundary when configured in Octal DTR mode. The byte order of
+16-bit words is swapped when read or written in Octal Double
+Transfer Rate (DTR) mode compared to Single Transfer Rate (STR)
+modes. If one writes D0 D1 D2 D3 bytes using 1-1-1 mode, and uses
+8D-8D-8D SPI mode for reading, it will read back D1 D0 D3 D2.
+Swapping the bytes may introduce some endianness problems. It can
+affect the boot sequence if the entire boot sequence is not handled
+in either 8D-8D-8D mode or 1-1-1 mode. Therefore, it is necessary
+to swap the bytes back to ensure the same byte order as in STR modes.
+Fortunately there are controllers that could swap the bytes back at
+runtime, addressing the flash's endianness requirements. Provide a
+way for the upper layers to specify the byte order in Octal DTR mode.
+
+Merge Tudor's patch and add modifications for suiting newer version
+of Linux kernel.
+
+Suggested-by: Michael Walle <mwalle@kernel.org>
+Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
+Signed-off-by: AlvinZhou <alvinzhou@mxic.com.tw>
+Acked-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240926141956.2386374-3-alvinzhou.tw@gmail.com
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mem.c       | 3 +++
+ include/linux/spi/spi-mem.h | 8 +++++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index edd7430d4c052..84b250703e138 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -172,6 +172,9 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+               if (!spi_mem_controller_is_capable(ctlr, dtr))
+                       return false;
++              if (op->data.swap16 && !spi_mem_controller_is_capable(ctlr, swap16))
++                      return false;
++
+               if (op->cmd.nbytes != 2)
+                       return false;
+       } else {
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index 6b0a7dc48a4b7..eed6e016d69cc 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -90,6 +90,8 @@ enum spi_mem_data_dir {
+  * @data.buswidth: number of IO lanes used to send/receive the data
+  * @data.dtr: whether the data should be sent in DTR mode or not
+  * @data.ecc: whether error correction is required or not
++ * @data.swap16: whether the byte order of 16-bit words is swapped when read
++ *             or written in Octal DTR mode compared to STR mode.
+  * @data.dir: direction of the transfer
+  * @data.nbytes: number of data bytes to send/receive. Can be zero if the
+  *             operation does not involve transferring data
+@@ -124,7 +126,8 @@ struct spi_mem_op {
+               u8 buswidth;
+               u8 dtr : 1;
+               u8 ecc : 1;
+-              u8 __pad : 6;
++              u8 swap16 : 1;
++              u8 __pad : 5;
+               enum spi_mem_data_dir dir;
+               unsigned int nbytes;
+               union {
+@@ -295,10 +298,13 @@ struct spi_controller_mem_ops {
+  * struct spi_controller_mem_caps - SPI memory controller capabilities
+  * @dtr: Supports DTR operations
+  * @ecc: Supports operations with error correction
++ * @swap16: Supports swapping bytes on a 16 bit boundary when configured in
++ *        Octal DTR
+  */
+ struct spi_controller_mem_caps {
+       bool dtr;
+       bool ecc;
++      bool swap16;
+ };
+ #define spi_mem_controller_is_capable(ctlr, cap)      \
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch b/queue-6.6/spi-spi-mem-extend-spi-mem-operations-with-a-per-ope.patch
new file mode 100644 (file)
index 0000000..72b16fa
--- /dev/null
@@ -0,0 +1,221 @@
+From b509ac741343a10723ed1ab07a942bc9a2783713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 18:05:46 +0100
+Subject: spi: spi-mem: Extend spi-mem operations with a per-operation maximum
+ frequency
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 0fefeade90e74bc8f40ab0e460f483565c492e28 ]
+
+In the spi subsystem, the bus frequency is derived as follows:
+- the controller may expose a minimum and maximum operating frequency
+- the hardware description, through the spi peripheral properties,
+  advise what is the maximum acceptable frequency from a device/wiring
+  point of view.
+Transfers must be observed at a frequency which fits both (so in
+practice, the lowest maximum).
+
+Actually, this second point mixes two information and already takes the
+lowest frequency among:
+- what the spi device is capable of (what is written in the component
+  datasheet)
+- what the wiring allows (electromagnetic sensibility, crossovers,
+  terminations, antenna effect, etc).
+
+This logic works until spi devices are no longer capable of sustaining
+their highest frequency regardless of the operation. Spi memories are
+typically subject to such variation. Some devices are capable of
+spitting their internally stored data (essentially in read mode) at a
+very fast rate, typically up to 166MHz on Winbond SPI-NAND chips, using
+"fast" commands. However, some of the low-end operations, such as
+regular page read-from-cache commands, are more limited and can only be
+executed at 54MHz at most. This is currently a problem in the SPI-NAND
+subsystem. Another situation, even if not yet supported, will be with
+DTR commands, when the data is latched on both edges of the clock. The
+same chips as mentioned previously are in this case limited to
+80MHz. Yet another example might be continuous reads, which, under
+certain circumstances, can also run at most at 104 or 120MHz.
+
+As a matter of fact, the "one frequency per chip" policy is outdated and
+more fine grain configuration is needed: we need to allow per-operation
+frequency limitations. So far, all datasheets I encountered advertise a
+maximum default frequency, which need to be lowered for certain specific
+operations. So based on the current infrastructure, we can still expect
+firmware (device trees in general) to continued advertising the same
+maximum speed which is a mix between the PCB limitations and the chip
+maximum capability, and expect per-operation lower frequencies when this
+is relevant.
+
+Add a `struct spi_mem_op` member to carry this information. Not
+providing this field explicitly from upper layers means that there is no
+further constraint and the default spi device maximum speed will be
+carried instead. The SPI_MEM_OP() macro is also expanded with an
+optional frequency argument, because virtually all operations can be
+subject to such a limitation, and this will allow for a smooth and
+discrete transition.
+
+For controller drivers which do not implement the spi-mem interface, the
+per-transfer speed is also set acordingly to a lower (than the maximum
+default) speed when relevant.
+
+Acked-by: Pratyush Yadav <pratyush@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-1-ad218dbc406f@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/spi/core.c |  2 ++
+ drivers/spi/spi-mem.c       | 28 ++++++++++++++++++++++++++++
+ include/linux/spi/spi-mem.h | 12 +++++++++++-
+ 3 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index ee61b2d882320..4c2776f52fee5 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1044,6 +1044,8 @@ spinand_select_op_variant(struct spinand_device *spinand,
+                       if (ret)
+                               break;
++                      spi_mem_adjust_op_freq(spinand->spimem, &op);
++
+                       if (!spi_mem_supports_op(spinand->spimem, &op))
+                               break;
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index 84b250703e138..b73a659e268d6 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -187,6 +187,10 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+                       return false;
+       }
++      if (op->max_freq && mem->spi->controller->min_speed_hz &&
++          op->max_freq < mem->spi->controller->min_speed_hz)
++              return false;
++
+       return spi_mem_check_buswidth(mem, op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+@@ -321,6 +325,9 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+       u8 *tmpbuf;
+       int ret;
++      /* Make sure the operation frequency is correct before going futher */
++      spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op);
++
+       ret = spi_mem_check_op(op);
+       if (ret)
+               return ret;
+@@ -363,6 +370,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+       xfers[xferpos].tx_buf = tmpbuf;
+       xfers[xferpos].len = op->cmd.nbytes;
+       xfers[xferpos].tx_nbits = op->cmd.buswidth;
++      xfers[xferpos].speed_hz = op->max_freq;
+       spi_message_add_tail(&xfers[xferpos], &msg);
+       xferpos++;
+       totalxferlen++;
+@@ -377,6 +385,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               xfers[xferpos].tx_buf = tmpbuf + 1;
+               xfers[xferpos].len = op->addr.nbytes;
+               xfers[xferpos].tx_nbits = op->addr.buswidth;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->addr.nbytes;
+@@ -388,6 +397,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               xfers[xferpos].len = op->dummy.nbytes;
+               xfers[xferpos].tx_nbits = op->dummy.buswidth;
+               xfers[xferpos].dummy_data = 1;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->dummy.nbytes;
+@@ -403,6 +413,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+               }
+               xfers[xferpos].len = op->data.nbytes;
++              xfers[xferpos].speed_hz = op->max_freq;
+               spi_message_add_tail(&xfers[xferpos], &msg);
+               xferpos++;
+               totalxferlen += op->data.nbytes;
+@@ -481,6 +492,23 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
++/**
++ * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation to
++ *                          match controller, PCB and chip limitations
++ * @mem: the SPI memory
++ * @op: the operation to adjust
++ *
++ * Some chips have per-op frequency limitations and must adapt the maximum
++ * speed. This function allows SPI mem drivers to set @op->max_freq to the
++ * maximum supported value.
++ */
++void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
++{
++      if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
++              op->max_freq = mem->spi->max_speed_hz;
++}
++EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
++
+ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+                                     u64 offs, size_t len, void *buf)
+ {
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index eed6e016d69cc..cceebf8c78ba9 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -68,6 +68,9 @@ enum spi_mem_data_dir {
+       SPI_MEM_DATA_OUT,
+ };
++#define SPI_MEM_OP_MAX_FREQ(__freq)                           \
++      .max_freq = __freq
++
+ /**
+  * struct spi_mem_op - describes a SPI memory operation
+  * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
+@@ -97,6 +100,9 @@ enum spi_mem_data_dir {
+  *             operation does not involve transferring data
+  * @data.buf.in: input buffer (must be DMA-able)
+  * @data.buf.out: output buffer (must be DMA-able)
++ * @max_freq: frequency limitation wrt this operation. 0 means there is no
++ *          specific constraint and the highest achievable frequency can be
++ *          attempted.
+  */
+ struct spi_mem_op {
+       struct {
+@@ -135,14 +141,17 @@ struct spi_mem_op {
+                       const void *out;
+               } buf;
+       } data;
++
++      unsigned int max_freq;
+ };
+-#define SPI_MEM_OP(__cmd, __addr, __dummy, __data)            \
++#define SPI_MEM_OP(__cmd, __addr, __dummy, __data, ...)               \
+       {                                                       \
+               .cmd = __cmd,                                   \
+               .addr = __addr,                                 \
+               .dummy = __dummy,                               \
+               .data = __data,                                 \
++              __VA_ARGS__                                     \
+       }
+ /**
+@@ -369,6 +378,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ #endif /* CONFIG_SPI_MEM */
+ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
++void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op);
+ bool spi_mem_supports_op(struct spi_mem *mem,
+                        const struct spi_mem_op *op);
+-- 
+2.51.0
+
diff --git a/queue-6.6/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch b/queue-6.6/spi-tegra114-remove-kconfig-dependency-on-tegra20_ap.patch
new file mode 100644 (file)
index 0000000..f1e7cac
--- /dev/null
@@ -0,0 +1,44 @@
+From 20eba44098ce715314df88a6bfab48c7819972d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 10:50:27 +0100
+Subject: spi: tegra114: remove Kconfig dependency on TEGRA20_APB_DMA
+
+From: Francesco Lavra <flavra@baylibre.com>
+
+[ Upstream commit 3dcf44ab56e1d3ca3532083c0d5390b758e45b45 ]
+
+This driver runs also on Tegra SoCs without a Tegra20 APB DMA controller
+(e.g. Tegra234).
+Remove the Kconfig dependency on TEGRA20_APB_DMA; in addition, amend the
+help text to reflect the fact that this driver works on SoCs different from
+Tegra114.
+
+Fixes: bb9667d8187b ("arm64: tegra: Add SPI device tree nodes for Tegra234")
+Signed-off-by: Francesco Lavra <flavra@baylibre.com>
+Link: https://patch.msgid.link/20251126095027.4102004-1-flavra@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 3ce0fd5df8e9c..cda333f226b66 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -1059,10 +1059,10 @@ config SPI_TEGRA210_QUAD
+ config SPI_TEGRA114
+       tristate "NVIDIA Tegra114 SPI Controller"
+-      depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
++      depends on ARCH_TEGRA || COMPILE_TEST
+       depends on RESET_CONTROLLER
+       help
+-        SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
++        SPI controller driver for NVIDIA Tegra114 and later SoCs. This controller
+         is different than the older SoCs SPI controller and also register interface
+         get changed with this controller.
+-- 
+2.51.0
+
diff --git a/queue-6.6/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch b/queue-6.6/usb-gadget-renesas_usbf-handle-devm_pm_runtime_enabl.patch
new file mode 100644 (file)
index 0000000..99443bb
--- /dev/null
@@ -0,0 +1,45 @@
+From 205f18c43f82f5c174c77c4ef6f0c8d6de616fec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 10:22:15 +0800
+Subject: usb: gadget: renesas_usbf: Handle devm_pm_runtime_enable() errors
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 74851fbb6d647304f8a7dc491434d3a335ef4b8d ]
+
+devm_pm_runtime_enable() can fail due to memory allocation.
+The current code ignores its return value, potentially causing
+pm_runtime_resume_and_get() to operate on uninitialized runtime
+PM state.
+
+Check the return value of devm_pm_runtime_enable() and return on failure.
+
+Fixes: 3e6e14ffdea4 ("usb: gadget: udc: add Renesas RZ/N1 USBF controller support")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Acked-by: Herve Codina <herve.codina@bootlin.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/20251124022215.1619-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/renesas_usbf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c
+index 657f265ac7cc5..8463f681ae673 100644
+--- a/drivers/usb/gadget/udc/renesas_usbf.c
++++ b/drivers/usb/gadget/udc/renesas_usbf.c
+@@ -3262,7 +3262,9 @@ static int usbf_probe(struct platform_device *pdev)
+       if (IS_ERR(udc->regs))
+               return PTR_ERR(udc->regs);
+-      devm_pm_runtime_enable(&pdev->dev);
++      ret = devm_pm_runtime_enable(&pdev->dev);
++      if (ret)
++              return ret;
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.51.0
+