--- /dev/null
+From 7cc981f9ddefe79879847bdb5635a8030fc4d43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 12:26:16 +0200
+Subject: accel/ivpu: Correct DCT interrupt handling
+
+From: Karol Wachowski <karol.wachowski@intel.com>
+
+[ Upstream commit e53e004e346062e15df9511bd4b5a19e34701384 ]
+
+Fix improper use of dct_active_percent field in DCT interrupt handler
+causing DCT to never get enabled. Set dct_active_percent internally before
+IPC to ensure correct driver value even if IPC fails.
+Set default DCT value to 30 accordingly to HW architecture specification.
+
+Fixes: a19bffb10c46 ("accel/ivpu: Implement DCT handling")
+Signed-off-by: Karol Wachowski <karol.wachowski@intel.com>
+Signed-off-by: Maciej Falkowski <maciej.falkowski@linux.intel.com>
+Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
+Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+Link: https://lore.kernel.org/r/20250416102616.384577-1-maciej.falkowski@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +-
+ drivers/accel/ivpu/ivpu_pm.c | 18 ++++++++++--------
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h
+index 71792dab3c210..3855e2df1e0c8 100644
+--- a/drivers/accel/ivpu/ivpu_hw_btrs.h
++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h
+@@ -14,7 +14,7 @@
+ #define PLL_PROFILING_FREQ_DEFAULT 38400000
+ #define PLL_PROFILING_FREQ_HIGH 400000000
+
+-#define DCT_DEFAULT_ACTIVE_PERCENT 15u
++#define DCT_DEFAULT_ACTIVE_PERCENT 30u
+ #define DCT_PERIOD_US 35300u
+
+ int ivpu_hw_btrs_info_init(struct ivpu_device *vdev);
+diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c
+index 5060c5dd40d1f..7acf78aeb3800 100644
+--- a/drivers/accel/ivpu/ivpu_pm.c
++++ b/drivers/accel/ivpu/ivpu_pm.c
+@@ -433,16 +433,17 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent)
+ active_us = (DCT_PERIOD_US * active_percent) / 100;
+ inactive_us = DCT_PERIOD_US - active_us;
+
++ vdev->pm->dct_active_percent = active_percent;
++
++ ivpu_dbg(vdev, PM, "DCT requested %u%% (D0: %uus, D0i2: %uus)\n",
++ active_percent, active_us, inactive_us);
++
+ ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us);
+ if (ret) {
+ ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret);
+ return ret;
+ }
+
+- vdev->pm->dct_active_percent = active_percent;
+-
+- ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n",
+- active_percent, active_us, inactive_us);
+ return 0;
+ }
+
+@@ -450,15 +451,16 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev)
+ {
+ int ret;
+
++ vdev->pm->dct_active_percent = 0;
++
++ ivpu_dbg(vdev, PM, "DCT requested to be disabled\n");
++
+ ret = ivpu_jsm_dct_disable(vdev);
+ if (ret) {
+ ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret);
+ return ret;
+ }
+
+- vdev->pm->dct_active_percent = 0;
+-
+- ivpu_dbg(vdev, PM, "DCT disabled\n");
+ return 0;
+ }
+
+@@ -470,7 +472,7 @@ void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev)
+ if (ivpu_hw_btrs_dct_get_request(vdev, &enable))
+ return;
+
+- if (vdev->pm->dct_active_percent)
++ if (enable)
+ ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT);
+ else
+ ret = ivpu_pm_dct_disable(vdev);
+--
+2.39.5
+
--- /dev/null
+From c925e39096a8c7ffbf65b9640cd2ba1f21e42b18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 15:04:02 +0800
+Subject: ALSA: hda/realtek - Enable speaker for HP platform
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit 494d0939b1bda4d4ddca7d52a6ce6f808ff2c9a5 ]
+
+The speaker doesn't mute when plugged headphone.
+This platform support 4ch speakers.
+The speaker pin 0x14 wasn't fill verb table.
+After assigned model ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX.
+The speaker can mute when headphone was plugged.
+
+Fixes: aa8e3ef4fe53 ("ALSA: hda/realtek: Add quirks for various HP ENVY models")
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/eb4c14a4d85740069c909e756bbacb0e@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 35c1128ea6b67..263c7be1d4e29 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -440,6 +440,10 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
+ fallthrough;
+ case 0x10ec0215:
++ case 0x10ec0236:
++ case 0x10ec0245:
++ case 0x10ec0256:
++ case 0x10ec0257:
+ case 0x10ec0285:
+ case 0x10ec0289:
+ alc_update_coef_idx(codec, 0x36, 1<<13, 0);
+@@ -447,12 +451,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ case 0x10ec0230:
+ case 0x10ec0233:
+ case 0x10ec0235:
+- case 0x10ec0236:
+- case 0x10ec0245:
+ case 0x10ec0255:
+- case 0x10ec0256:
+ case 0x19e58326:
+- case 0x10ec0257:
+ case 0x10ec0282:
+ case 0x10ec0283:
+ case 0x10ec0286:
+@@ -10713,8 +10713,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8caf, "HP Elite mt645 G8 Mobile Thin Client", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8cbd, "HP Pavilion Aero Laptop 13-bg0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS),
+- SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2),
+- SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2),
++ SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
++ SND_PCI_QUIRK(0x103c, 0x8cde, "HP OmniBook Ultra Flip Laptop 14t", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
+ SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
+--
+2.39.5
+
--- /dev/null
+From bdf2aa2ec88dd5aabba224dfcf229cc3e7b971c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 07:31:41 +0200
+Subject: ALSA: hda/realtek: Fix built-mic regression on other ASUS models
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 4d5b71b487291da9f92e352c0a7e39f256d60db8 ]
+
+A few ASUS models use the ALC256_FIXUP_ASUS_HEADSET_MODE although they
+have no built-in mic pin on NID 0x13, as found in the commit
+c1732ede5e80 ("ALSA: hda/realtek - Fix headset and mic on several Asus
+laptops with ALC256"). This was relatively harmless in the past as
+NID 0x13 was assigned as the secondary mic. But since the fix for the
+pin sort order, this pin became the primary one, hence user started
+noticing the broken input, and we've fixed already for a few ASUS
+models to switch to ALC256_FIXUP_ASUS_MIC_NO_PRESENCE.
+
+This patch corrects the other ASUS models to use the right quirk entry
+for fixing the built-in mic regression. Here we cover X541SA
+(1043:12e0), X541UV (1043:12f0), Z550SA (1043:13bf0) and X555UB
+(1043:1ccd).
+
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220058
+Link: https://patch.msgid.link/20250430053210.31776-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 263c7be1d4e29..2ff02fb6f7e94 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10774,10 +10774,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x12a3, "Asus N7691ZM", ALC269_FIXUP_ASUS_N7601ZM),
+ SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
+ SND_PCI_QUIRK(0x1043, 0x12b4, "ASUS B3405CCA / P3405CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2),
+- SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
+- SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
++ SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE),
+- SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
++ SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+ SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+@@ -10831,7 +10831,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
+ SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
+- SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
++ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JU/JV/JI", ALC245_FIXUP_CS35L41_SPI_2),
+ SND_PCI_QUIRK(0x1043, 0x1cdf, "ASUS G814JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2),
+ SND_PCI_QUIRK(0x1043, 0x1cef, "ASUS G834JY/JZ/JI/JG", ALC285_FIXUP_ASUS_HEADSET_MIC),
+--
+2.39.5
+
--- /dev/null
+From 4a3395f9f5ab4fcc97c08250b8dae27702ecefab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 14:48:41 +0200
+Subject: ALSA: ump: Fix buffer overflow at UMP SysEx message conversion
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 56f1f30e6795b890463d9b20b11e576adf5a2f77 ]
+
+The conversion function from MIDI 1.0 to UMP packet contains an
+internal buffer to keep the incoming MIDI bytes, and its size is 4, as
+it was supposed to be the max size for a MIDI1 UMP packet data.
+However, the implementation overlooked that SysEx is handled in a
+different format, and it can be up to 6 bytes, as found in
+do_convert_to_ump(). It leads eventually to a buffer overflow, and
+may corrupt the memory when a longer SysEx message is received.
+
+The fix is simply to extend the buffer size to 6 to fit with the SysEx
+UMP message.
+
+Fixes: 0b5288f5fe63 ("ALSA: ump: Add legacy raw MIDI support")
+Reported-by: Argusee <vr@darknavy.com>
+Link: https://patch.msgid.link/20250429124845.25128-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/ump_convert.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/sound/ump_convert.h b/include/sound/ump_convert.h
+index d099ae27f8491..682499b871eac 100644
+--- a/include/sound/ump_convert.h
++++ b/include/sound/ump_convert.h
+@@ -19,7 +19,7 @@ struct ump_cvt_to_ump_bank {
+ /* context for converting from MIDI1 byte stream to UMP packet */
+ struct ump_cvt_to_ump {
+ /* MIDI1 intermediate buffer */
+- unsigned char buf[4];
++ unsigned char buf[6]; /* up to 6 bytes for SysEx */
+ int len;
+ int cmd_bytes;
+
+--
+2.39.5
+
--- /dev/null
+From 78c9d2b7bd43d99cb5631044954676e775b4e60d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 11:31:40 +0530
+Subject: ASoC: amd: acp: Fix NULL pointer deref in acp_i2s_set_tdm_slot
+
+From: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+
+[ Upstream commit 6d9b64156d849e358cb49b6b899fb0b7d262bda8 ]
+
+Update chip data using dev_get_drvdata(dev->parent) to fix
+NULL pointer deref in acp_i2s_set_tdm_slot.
+
+Fixes: cd60dec8994c ("ASoC: amd: acp: Refactor TDM slots selction based on acp revision id")
+
+Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+Link: https://patch.msgid.link/20250425060144.1773265-2-venkataprasad.potturu@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/acp-i2s.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c
+index 89e99ed4275a2..f631147fc63bd 100644
+--- a/sound/soc/amd/acp/acp-i2s.c
++++ b/sound/soc/amd/acp/acp-i2s.c
+@@ -101,7 +101,7 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas
+ struct acp_stream *stream;
+ int slot_len, no_of_slots;
+
+- chip = dev_get_platdata(dev);
++ chip = dev_get_drvdata(dev->parent);
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+--
+2.39.5
+
--- /dev/null
+From bc036ee644e6050fad94dc4a09d2471b47137381 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 13:36:07 +0100
+Subject: ASoC: cs-amp-lib-test: Don't select SND_SOC_CS_AMP_LIB
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 96014d91cffb335d3b396771524ff2aba3549865 ]
+
+Depend on SND_SOC_CS_AMP_LIB instead of selecting it.
+
+KUNIT_ALL_TESTS should only build tests for components that are
+already being built, it should not cause other stuff to be added
+to the build.
+
+Fixes: 177862317a98 ("ASoC: cs-amp-lib: Add KUnit test for calibration helpers")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250411123608.1676462-3-rf@opensource.cirrus.com
+Reviewed-by: David Gow <davidgow@google.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/Kconfig | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index ee35f3aa55216..0138cfabbb038 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -763,10 +763,9 @@ config SND_SOC_CS_AMP_LIB
+ tristate
+
+ config SND_SOC_CS_AMP_LIB_TEST
+- tristate "KUnit test for Cirrus Logic cs-amp-lib"
+- depends on KUNIT
++ tristate "KUnit test for Cirrus Logic cs-amp-lib" if !KUNIT_ALL_TESTS
++ depends on SND_SOC_CS_AMP_LIB && KUNIT
+ default KUNIT_ALL_TESTS
+- select SND_SOC_CS_AMP_LIB
+ help
+ This builds KUnit tests for the Cirrus Logic common
+ amplifier library.
+--
+2.39.5
+
--- /dev/null
+From ab76ea450ebb73b2622cdbfe01837c25c9e252f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 14:41:34 -0500
+Subject: ASoC: Intel: sof_sdw: Add NULL check in asoc_sdw_rt_dmic_rtd_init()
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 68715cb5c0e00284d93f976c6368809f64131b0b ]
+
+mic_name returned by devm_kasprintf() could be NULL.
+Add a check for it.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: bee2fe44679f ("ASoC: Intel: sof_sdw: use generic rtd_init function for Realtek SDW DMICs")
+Link: https://patch.msgid.link/20250415194134.292830-1-chenyuan0y@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sdw_utils/soc_sdw_rt_dmic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c
+index 46d917a99c51d..97be110a59b63 100644
+--- a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c
++++ b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c
+@@ -29,6 +29,8 @@ int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da
+ mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "rt715-sdca");
+ else
+ mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s", component->name_prefix);
++ if (!mic_name)
++ return -ENOMEM;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL,
+ "%s mic:%s", card->components,
+--
+2.39.5
+
--- /dev/null
+From 02ba48d82dfd7db60c299fcc8003a168b43be4df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 11:49:10 +0200
+Subject: ASoC: simple-card-utils: Fix pointer check in
+ graph_util_parse_link_direction
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 3cc393d2232ec770b5f79bf0673d67702a3536c3 ]
+
+Actually check if the passed pointers are valid, before writing to them.
+This also fixes a USBAN warning:
+UBSAN: invalid-load in ../sound/soc/fsl/imx-card.c:687:25
+load of value 255 is not a valid value for type '_Bool'
+
+This is because playback_only is uninitialized and is not written to, as
+the playback-only property is absent.
+
+Fixes: 844de7eebe97 ("ASoC: audio-graph-card2: expand dai_link property part")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://patch.msgid.link/20250429094910.1150970-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/simple-card-utils.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
+index 32efb30c55d69..8bd5b93f34576 100644
+--- a/sound/soc/generic/simple-card-utils.c
++++ b/sound/soc/generic/simple-card-utils.c
+@@ -1146,9 +1146,9 @@ void graph_util_parse_link_direction(struct device_node *np,
+ bool is_playback_only = of_property_read_bool(np, "playback-only");
+ bool is_capture_only = of_property_read_bool(np, "capture-only");
+
+- if (is_playback_only)
++ if (playback_only)
+ *playback_only = is_playback_only;
+- if (is_capture_only)
++ if (capture_only)
+ *capture_only = is_capture_only;
+ }
+ EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
+--
+2.39.5
+
--- /dev/null
+From 56fbbe46f174ddb85833bedfc564044df85a488f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 10:59:53 +0000
+Subject: ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence
+
+From: Sheetal <sheetal@nvidia.com>
+
+[ Upstream commit 9aff2e8df240e84a36f2607f98a0a9924a24e65d ]
+
+Issue:
+ When multiple audio streams share a common BE DAI, the BE DAI
+ widget can be powered up before its hardware parameters are configured.
+ This incorrect sequence leads to intermittent pcm_write errors.
+
+ For example, the below Tegra use-case throws an error:
+ aplay(2 streams) -> AMX(mux) -> ADX(demux) -> arecord(2 streams),
+ here, 'AMX TX' and 'ADX RX' are common BE DAIs.
+
+For above usecase when failure happens below sequence is observed:
+ aplay(1) FE open()
+ - BE DAI callbacks added to the list
+ - BE DAI state = SND_SOC_DPCM_STATE_OPEN
+ aplay(2) FE open()
+ - BE DAI callbacks are not added to the list as the state is
+ already SND_SOC_DPCM_STATE_OPEN during aplay(1) FE open().
+ aplay(2) FE hw_params()
+ - BE DAI hw_params() callback ignored
+ aplay(2) FE prepare()
+ - Widget is powered ON without BE DAI hw_params() call
+ aplay(1) FE hw_params()
+ - BE DAI hw_params() is now called
+
+Fix:
+ Add BE DAIs in the list if its state is either SND_SOC_DPCM_STATE_OPEN
+ or SND_SOC_DPCM_STATE_HW_PARAMS as well.
+
+It ensures the widget is powered ON after BE DAI hw_params() callback.
+
+Fixes: 0c25db3f7621 ("ASoC: soc-pcm: Don't reconnect an already active BE")
+Signed-off-by: Sheetal <sheetal@nvidia.com>
+Link: https://patch.msgid.link/20250404105953.2784819-1-sheetal@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-pcm.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 88b3ad5a25520..53b0ea68b939f 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1618,10 +1618,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
+ /*
+ * Filter for systems with 'component_chaining' enabled.
+ * This helps to avoid unnecessary re-configuration of an
+- * already active BE on such systems.
++ * already active BE on such systems and ensures the BE DAI
++ * widget is powered ON after hw_params() BE DAI callback.
+ */
+ if (fe->card->component_chaining &&
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
+ continue;
+
+--
+2.39.5
+
--- /dev/null
+From af76111bd263d358a494b1e692c6101e0c2c606a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 18:52:09 +0200
+Subject: ASoC: stm32: sai: add a check on minimal kernel frequency
+
+From: Olivier Moysan <olivier.moysan@foss.st.com>
+
+[ Upstream commit cce34d113e2a592806abcdc02c7f8513775d8b20 ]
+
+On MP2 SoCs SAI kernel clock rate is managed through
+stm32_sai_set_parent_rate() function.
+If the kernel clock rate was set previously to a low frequency, this
+frequency may be too low to support the newly requested audio stream rate.
+However the stm32_sai_rate_accurate() will only check accuracy against
+the maximum kernel clock rate. The function will return leaving the kernel
+clock rate unchanged.
+Add a check on minimal frequency requirement, to avoid this.
+
+Fixes: 2cfe1ff22555 ("ASoC: stm32: sai: add stm32mp25 support")
+Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
+Link: https://patch.msgid.link/20250430165210.321273-3-olivier.moysan@foss.st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/stm/stm32_sai_sub.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
+index 5a5acc67569fe..d9c4266c8150d 100644
+--- a/sound/soc/stm/stm32_sai_sub.c
++++ b/sound/soc/stm/stm32_sai_sub.c
+@@ -447,7 +447,10 @@ static int stm32_sai_set_parent_rate(struct stm32_sai_sub_data *sai,
+ * return immediately.
+ */
+ sai_curr_rate = clk_get_rate(sai->sai_ck);
+- if (stm32_sai_rate_accurate(sai_ck_max_rate, sai_curr_rate))
++ dev_dbg(&pdev->dev, "kernel clock rate: min [%u], max [%u], current [%u]",
++ sai_ck_min_rate, sai_ck_max_rate, sai_curr_rate);
++ if (stm32_sai_rate_accurate(sai_ck_max_rate, sai_curr_rate) &&
++ sai_curr_rate >= sai_ck_min_rate)
+ return 0;
+
+ /*
+--
+2.39.5
+
--- /dev/null
+From bf50f3b32fc51500b4ca518977203fc9ef06fd12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 18:52:08 +0200
+Subject: ASoC: stm32: sai: skip useless iterations on kernel rate loop
+
+From: Olivier Moysan <olivier.moysan@foss.st.com>
+
+[ Upstream commit edea92770a3b6454dc796fc5436a3315bb402181 ]
+
+the frequency of the kernel clock must be greater than or equal to the
+bitclock rate. When searching for a convenient kernel clock rate in
+stm32_sai_set_parent_rate() function, it is useless to continue the loop
+below bitclock rate, as it will result in a invalid kernel clock rate.
+Change the loop output condition.
+
+Fixes: 2cfe1ff22555 ("ASoC: stm32: sai: add stm32mp25 support")
+Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
+Link: https://patch.msgid.link/20250430165210.321273-2-olivier.moysan@foss.st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/stm/stm32_sai_sub.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
+index 3efbf4aaf9654..5a5acc67569fe 100644
+--- a/sound/soc/stm/stm32_sai_sub.c
++++ b/sound/soc/stm/stm32_sai_sub.c
+@@ -409,11 +409,11 @@ static int stm32_sai_set_parent_rate(struct stm32_sai_sub_data *sai,
+ unsigned int rate)
+ {
+ struct platform_device *pdev = sai->pdev;
+- unsigned int sai_ck_rate, sai_ck_max_rate, sai_curr_rate, sai_new_rate;
++ unsigned int sai_ck_rate, sai_ck_max_rate, sai_ck_min_rate, sai_curr_rate, sai_new_rate;
+ int div, ret;
+
+ /*
+- * Set maximum expected kernel clock frequency
++ * Set minimum and maximum expected kernel clock frequency
+ * - mclk on or spdif:
+ * f_sai_ck = MCKDIV * mclk-fs * fs
+ * Here typical 256 ratio is assumed for mclk-fs
+@@ -423,13 +423,16 @@ static int stm32_sai_set_parent_rate(struct stm32_sai_sub_data *sai,
+ * Set constraint MCKDIV * FRL <= 256, to ensure MCKDIV is in available range
+ * f_sai_ck = sai_ck_max_rate * pow_of_two(FRL) / 256
+ */
++ sai_ck_min_rate = rate * 256;
+ if (!(rate % SAI_RATE_11K))
+ sai_ck_max_rate = SAI_MAX_SAMPLE_RATE_11K * 256;
+ else
+ sai_ck_max_rate = SAI_MAX_SAMPLE_RATE_8K * 256;
+
+- if (!sai->sai_mclk && !STM_SAI_PROTOCOL_IS_SPDIF(sai))
++ if (!sai->sai_mclk && !STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
++ sai_ck_min_rate = rate * sai->fs_length;
+ sai_ck_max_rate /= DIV_ROUND_CLOSEST(256, roundup_pow_of_two(sai->fs_length));
++ }
+
+ /*
+ * Request exclusivity, as the clock is shared by SAI sub-blocks and by
+@@ -472,7 +475,7 @@ static int stm32_sai_set_parent_rate(struct stm32_sai_sub_data *sai,
+ /* Try a lower frequency */
+ div++;
+ sai_ck_rate = sai_ck_max_rate / div;
+- } while (sai_ck_rate > rate);
++ } while (sai_ck_rate >= sai_ck_min_rate);
+
+ /* No accurate rate found */
+ dev_err(&pdev->dev, "Failed to find an accurate rate");
+--
+2.39.5
+
--- /dev/null
+From 9bd1c3ce36bca85e0f3deeb2a16a99ccba6e17e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Apr 2025 07:21:56 +0530
+Subject: Bluetooth: btintel_pcie: Add additional to checks to clear TX/RX
+ paths
+
+From: Kiran K <kiran.k@intel.com>
+
+[ Upstream commit 1c7664957e4edb234c69de2db4be1f740d2df564 ]
+
+Due to a hardware issue, there is a possibility that the driver may miss
+an MSIx interrupt on the RX/TX data path. Since the TX and RX paths are
+independent, when a TX MSIx interrupt occurs, the driver can check the
+RX queue for any pending data and process it if present. The same
+approach applies to the RX path.
+
+Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
+Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
+Signed-off-by: Kiran K <kiran.k@intel.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btintel_pcie.c | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
+index ea9b137b1491c..1636f636fbef0 100644
+--- a/drivers/bluetooth/btintel_pcie.c
++++ b/drivers/bluetooth/btintel_pcie.c
+@@ -773,10 +773,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
+ bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia);
+
+ /* Check CR_TIA and CR_HIA for change */
+- if (cr_tia == cr_hia) {
+- bt_dev_warn(hdev, "RXQ: no new CD found");
++ if (cr_tia == cr_hia)
+ return;
+- }
+
+ rxq = &data->rxq;
+
+@@ -812,6 +810,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data)
+ return IRQ_WAKE_THREAD;
+ }
+
++static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data)
++{
++ return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
++}
++
++static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data)
++{
++ return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
++}
++
+ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
+ {
+ struct msix_entry *entry = dev_id;
+@@ -839,12 +847,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
+ btintel_pcie_msix_gp0_handler(data);
+
+ /* For TX */
+- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0)
++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
+ btintel_pcie_msix_tx_handle(data);
++ if (!btintel_pcie_is_rxq_empty(data))
++ btintel_pcie_msix_rx_handle(data);
++ }
+
+ /* For RX */
+- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1)
++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) {
+ btintel_pcie_msix_rx_handle(data);
++ if (!btintel_pcie_is_txackq_empty(data))
++ btintel_pcie_msix_tx_handle(data);
++ }
+
+ /*
+ * Before sending the interrupt the HW disables it to prevent a nested
+--
+2.39.5
+
--- /dev/null
+From 3244a325c3c8fdea8b5764d0970e82600ac3de36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 09:18:42 +0530
+Subject: Bluetooth: btintel_pcie: Avoid redundant buffer allocation
+
+From: Kiran K <kiran.k@intel.com>
+
+[ Upstream commit d1af1f02ef8653dea4573e444136c8331189cd59 ]
+
+Reuse the skb buffer provided by the PCIe driver to pass it onto the
+stack, instead of copying it to a new skb.
+
+Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
+Signed-off-by: Kiran K <kiran.k@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btintel_pcie.c | 33 ++++++++++++--------------------
+ 1 file changed, 12 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
+index 6130854b6658a..ea9b137b1491c 100644
+--- a/drivers/bluetooth/btintel_pcie.c
++++ b/drivers/bluetooth/btintel_pcie.c
+@@ -595,8 +595,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+ /* This is a debug event that comes from IML and OP image when it
+ * starts execution. There is no need pass this event to stack.
+ */
+- if (skb->data[2] == 0x97)
++ if (skb->data[2] == 0x97) {
++ hci_recv_diag(hdev, skb);
+ return 0;
++ }
+ }
+
+ return hci_recv_frame(hdev, skb);
+@@ -612,7 +614,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
+ u8 pkt_type;
+ u16 plen;
+ u32 pcie_pkt_type;
+- struct sk_buff *new_skb;
+ void *pdata;
+ struct hci_dev *hdev = data->hdev;
+
+@@ -689,24 +690,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
+
+ bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen);
+
+- new_skb = bt_skb_alloc(plen, GFP_ATOMIC);
+- if (!new_skb) {
+- bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u",
+- skb->len);
+- ret = -ENOMEM;
+- goto exit_error;
+- }
+-
+- hci_skb_pkt_type(new_skb) = pkt_type;
+- skb_put_data(new_skb, skb->data, plen);
++ hci_skb_pkt_type(skb) = pkt_type;
+ hdev->stat.byte_rx += plen;
++ skb_trim(skb, plen);
+
+ if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT)
+- ret = btintel_pcie_recv_event(hdev, new_skb);
++ ret = btintel_pcie_recv_event(hdev, skb);
+ else
+- ret = hci_recv_frame(hdev, new_skb);
++ ret = hci_recv_frame(hdev, skb);
++ skb = NULL; /* skb is freed in the callee */
+
+ exit_error:
++ if (skb)
++ kfree_skb(skb);
++
+ if (ret)
+ hdev->stat.err_rx++;
+
+@@ -720,16 +717,10 @@ static void btintel_pcie_rx_work(struct work_struct *work)
+ struct btintel_pcie_data *data = container_of(work,
+ struct btintel_pcie_data, rx_work);
+ struct sk_buff *skb;
+- int err;
+- struct hci_dev *hdev = data->hdev;
+
+ /* Process the sk_buf in queue and send to the HCI layer */
+ while ((skb = skb_dequeue(&data->rx_skb_q))) {
+- err = btintel_pcie_recv_frame(data, skb);
+- if (err)
+- bt_dev_err(hdev, "Failed to send received frame: %d",
+- err);
+- kfree_skb(skb);
++ btintel_pcie_recv_frame(data, skb);
+ }
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 839c4be34b6b56f54a2ccff47a2afcc7c8955b5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 21:00:37 +0800
+Subject: Bluetooth: btusb: avoid NULL pointer dereference in skb_dequeue()
+
+From: En-Wei Wu <en-wei.wu@canonical.com>
+
+[ Upstream commit 0317b033abcd1d8dd2798f0e2de5e84543d0bd22 ]
+
+A NULL pointer dereference can occur in skb_dequeue() when processing a
+QCA firmware crash dump on WCN7851 (0489:e0f3).
+
+[ 93.672166] Bluetooth: hci0: ACL memdump size(589824)
+
+[ 93.672475] BUG: kernel NULL pointer dereference, address: 0000000000000008
+[ 93.672517] Workqueue: hci0 hci_devcd_rx [bluetooth]
+[ 93.672598] RIP: 0010:skb_dequeue+0x50/0x80
+
+The issue stems from handle_dump_pkt_qca() returning 0 even when a dump
+packet is successfully processed. This is because it incorrectly
+forwards the return value of hci_devcd_init() (which returns 0 on
+success). As a result, the caller (btusb_recv_acl_qca() or
+btusb_recv_evt_qca()) assumes the packet was not handled and passes it
+to hci_recv_frame(), leading to premature kfree() of the skb.
+
+Later, hci_devcd_rx() attempts to dequeue the same skb from the dump
+queue, resulting in a NULL pointer dereference.
+
+Fix this by:
+1. Making handle_dump_pkt_qca() return 0 on success and negative errno
+ on failure, consistent with kernel conventions.
+2. Splitting dump packet detection into separate functions for ACL
+ and event packets for better structure and readability.
+
+This ensures dump packets are properly identified and consumed, avoiding
+double handling and preventing NULL pointer access.
+
+Fixes: 20981ce2d5a5 ("Bluetooth: btusb: Add WCN6855 devcoredump support")
+Signed-off-by: En-Wei Wu <en-wei.wu@canonical.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 | 101 +++++++++++++++++++++++++++-----------
+ 1 file changed, 73 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index bfd769f2026b3..ccd0a21da3955 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -3010,22 +3010,16 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
+ bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err);
+ }
+
+-/*
+- * ==0: not a dump pkt.
+- * < 0: fails to handle a dump pkt
+- * > 0: otherwise.
+- */
++/* Return: 0 on success, negative errno on failure. */
+ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+- int ret = 1;
++ int ret = 0;
+ u8 pkt_type;
+ u8 *sk_ptr;
+ unsigned int sk_len;
+ u16 seqno;
+ u32 dump_size;
+
+- struct hci_event_hdr *event_hdr;
+- struct hci_acl_hdr *acl_hdr;
+ struct qca_dump_hdr *dump_hdr;
+ struct btusb_data *btdata = hci_get_drvdata(hdev);
+ struct usb_device *udev = btdata->udev;
+@@ -3035,30 +3029,14 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
+ sk_len = skb->len;
+
+ if (pkt_type == HCI_ACLDATA_PKT) {
+- acl_hdr = hci_acl_hdr(skb);
+- if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
+- return 0;
+ sk_ptr += HCI_ACL_HDR_SIZE;
+ sk_len -= HCI_ACL_HDR_SIZE;
+- event_hdr = (struct hci_event_hdr *)sk_ptr;
+- } else {
+- event_hdr = hci_event_hdr(skb);
+ }
+
+- if ((event_hdr->evt != HCI_VENDOR_PKT)
+- || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
+- return 0;
+-
+ sk_ptr += HCI_EVENT_HDR_SIZE;
+ sk_len -= HCI_EVENT_HDR_SIZE;
+
+ dump_hdr = (struct qca_dump_hdr *)sk_ptr;
+- if ((sk_len < offsetof(struct qca_dump_hdr, data))
+- || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS)
+- || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
+- return 0;
+-
+- /*it is dump pkt now*/
+ seqno = le16_to_cpu(dump_hdr->seqno);
+ if (seqno == 0) {
+ set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags);
+@@ -3132,17 +3110,84 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
+ return ret;
+ }
+
++/* Return: true if the ACL packet is a dump packet, false otherwise. */
++static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ u8 *sk_ptr;
++ unsigned int sk_len;
++
++ struct hci_event_hdr *event_hdr;
++ struct hci_acl_hdr *acl_hdr;
++ struct qca_dump_hdr *dump_hdr;
++
++ sk_ptr = skb->data;
++ sk_len = skb->len;
++
++ acl_hdr = hci_acl_hdr(skb);
++ if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
++ return false;
++
++ sk_ptr += HCI_ACL_HDR_SIZE;
++ sk_len -= HCI_ACL_HDR_SIZE;
++ event_hdr = (struct hci_event_hdr *)sk_ptr;
++
++ if ((event_hdr->evt != HCI_VENDOR_PKT) ||
++ (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
++ return false;
++
++ sk_ptr += HCI_EVENT_HDR_SIZE;
++ sk_len -= HCI_EVENT_HDR_SIZE;
++
++ dump_hdr = (struct qca_dump_hdr *)sk_ptr;
++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
++ return false;
++
++ return true;
++}
++
++/* Return: true if the event packet is a dump packet, false otherwise. */
++static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ u8 *sk_ptr;
++ unsigned int sk_len;
++
++ struct hci_event_hdr *event_hdr;
++ struct qca_dump_hdr *dump_hdr;
++
++ sk_ptr = skb->data;
++ sk_len = skb->len;
++
++ event_hdr = hci_event_hdr(skb);
++
++ if ((event_hdr->evt != HCI_VENDOR_PKT)
++ || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
++ return false;
++
++ sk_ptr += HCI_EVENT_HDR_SIZE;
++ sk_len -= HCI_EVENT_HDR_SIZE;
++
++ dump_hdr = (struct qca_dump_hdr *)sk_ptr;
++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
++ return false;
++
++ return true;
++}
++
+ static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+- if (handle_dump_pkt_qca(hdev, skb))
+- return 0;
++ if (acl_pkt_is_dump_qca(hdev, skb))
++ return handle_dump_pkt_qca(hdev, skb);
+ return hci_recv_frame(hdev, skb);
+ }
+
+ static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb)
+ {
+- if (handle_dump_pkt_qca(hdev, skb))
+- return 0;
++ if (evt_pkt_is_dump_qca(hdev, skb))
++ return handle_dump_pkt_qca(hdev, skb);
+ return hci_recv_frame(hdev, skb);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 685678ddbdd926bf72b9254fbfd86de838335e51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 16:08:48 -0400
+Subject: Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast
+ Receiver
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 6d0417e4e1cf66fd917f06f0454958362714ef7d ]
+
+Broadcast Receiver requires creating PA sync but the command just
+generates a status so this makes use of __hci_cmd_sync_status_sk to wait
+for HCI_EV_LE_PA_SYNC_ESTABLISHED, also because of this chance it is not
+longer necessary to use a custom method to serialize the process of
+creating the PA sync since the cmd_work_sync itself ensures only one
+command would be pending which now awaits for
+HCI_EV_LE_PA_SYNC_ESTABLISHED before proceeding to next connection.
+
+Fixes: 4a5e0ba68676 ("Bluetooth: ISO: Do not emit LE PA Create Sync if previous is pending")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 2 +
+ include/net/bluetooth/hci_core.h | 13 +++--
+ include/net/bluetooth/hci_sync.h | 2 +
+ net/bluetooth/hci_conn.c | 92 +-------------------------------
+ net/bluetooth/hci_event.c | 6 +--
+ net/bluetooth/hci_sync.c | 87 ++++++++++++++++++++++++++++--
+ 6 files changed, 95 insertions(+), 107 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index a8586c3058c7c..8ea7a063cc651 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -1931,6 +1931,8 @@ struct hci_cp_le_pa_create_sync {
+ __u8 sync_cte_type;
+ } __packed;
+
++#define HCI_OP_LE_PA_CREATE_SYNC_CANCEL 0x2045
++
+ #define HCI_OP_LE_PA_TERM_SYNC 0x2046
+ struct hci_cp_le_pa_term_sync {
+ __le16 handle;
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index f0b49aad519eb..49f51877988d8 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1105,10 +1105,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
+ return NULL;
+ }
+
+-static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev,
+- __u8 sid,
+- bdaddr_t *dst,
+- __u8 dst_type)
++static inline struct hci_conn *
++hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
+ {
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *c;
+@@ -1116,8 +1114,10 @@ static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev,
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(c, &h->list, list) {
+- if (c->type != ISO_LINK || bacmp(&c->dst, dst) ||
+- c->dst_type != dst_type || c->sid != sid)
++ if (c->type != ISO_LINK)
++ continue;
++
++ if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags))
+ continue;
+
+ rcu_read_unlock();
+@@ -1516,7 +1516,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
+ void hci_sco_setup(struct hci_conn *conn, __u8 status);
+ bool hci_iso_setup_path(struct hci_conn *conn);
+ int hci_le_create_cis_pending(struct hci_dev *hdev);
+-int hci_pa_create_sync_pending(struct hci_dev *hdev);
+ int hci_le_big_create_sync_pending(struct hci_dev *hdev);
+ int hci_conn_check_create_cis(struct hci_conn *conn);
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 7e2cf0cca939a..93dac4c7f9e3e 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -185,3 +185,5 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn);
+ int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn);
+ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ struct hci_conn_params *params);
++
++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn);
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index d097e308a7554..badaa6c199204 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2061,95 +2061,6 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
+ return hci_le_create_big(conn, &conn->iso_qos);
+ }
+
+-static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
+-{
+- bt_dev_dbg(hdev, "");
+-
+- if (err)
+- bt_dev_err(hdev, "Unable to create PA: %d", err);
+-}
+-
+-static bool hci_conn_check_create_pa_sync(struct hci_conn *conn)
+-{
+- if (conn->type != ISO_LINK || conn->sid == HCI_SID_INVALID)
+- return false;
+-
+- return true;
+-}
+-
+-static int create_pa_sync(struct hci_dev *hdev, void *data)
+-{
+- struct hci_cp_le_pa_create_sync cp = {0};
+- struct hci_conn *conn;
+- int err = 0;
+-
+- hci_dev_lock(hdev);
+-
+- rcu_read_lock();
+-
+- /* The spec allows only one pending LE Periodic Advertising Create
+- * Sync command at a time. If the command is pending now, don't do
+- * anything. We check for pending connections after each PA Sync
+- * Established event.
+- *
+- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+- * page 2493:
+- *
+- * If the Host issues this command when another HCI_LE_Periodic_
+- * Advertising_Create_Sync command is pending, the Controller shall
+- * return the error code Command Disallowed (0x0C).
+- */
+- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+- if (test_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags))
+- goto unlock;
+- }
+-
+- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+- if (hci_conn_check_create_pa_sync(conn)) {
+- struct bt_iso_qos *qos = &conn->iso_qos;
+-
+- cp.options = qos->bcast.options;
+- cp.sid = conn->sid;
+- cp.addr_type = conn->dst_type;
+- bacpy(&cp.addr, &conn->dst);
+- cp.skip = cpu_to_le16(qos->bcast.skip);
+- cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout);
+- cp.sync_cte_type = qos->bcast.sync_cte_type;
+-
+- break;
+- }
+- }
+-
+-unlock:
+- rcu_read_unlock();
+-
+- hci_dev_unlock(hdev);
+-
+- if (bacmp(&cp.addr, BDADDR_ANY)) {
+- hci_dev_set_flag(hdev, HCI_PA_SYNC);
+- set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
+-
+- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC,
+- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+- if (!err)
+- err = hci_update_passive_scan_sync(hdev);
+-
+- if (err) {
+- hci_dev_clear_flag(hdev, HCI_PA_SYNC);
+- clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
+- }
+- }
+-
+- return err;
+-}
+-
+-int hci_pa_create_sync_pending(struct hci_dev *hdev)
+-{
+- /* Queue start pa_create_sync and scan */
+- return hci_cmd_sync_queue(hdev, create_pa_sync,
+- NULL, create_pa_complete);
+-}
+-
+ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+ __u8 dst_type, __u8 sid,
+ struct bt_iso_qos *qos)
+@@ -2164,10 +2075,11 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+ conn->dst_type = dst_type;
+ conn->sid = sid;
+ conn->state = BT_LISTEN;
++ conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
+
+ hci_conn_hold(conn);
+
+- hci_pa_create_sync_pending(hdev);
++ hci_connect_pa_sync(hdev, conn);
+
+ return conn;
+ }
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 20d3cdcb14f6c..216db540e502c 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6371,8 +6371,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
+
+ hci_dev_clear_flag(hdev, HCI_PA_SYNC);
+
+- conn = hci_conn_hash_lookup_sid(hdev, ev->sid, &ev->bdaddr,
+- ev->bdaddr_type);
++ conn = hci_conn_hash_lookup_create_pa_sync(hdev);
+ if (!conn) {
+ bt_dev_err(hdev,
+ "Unable to find connection for dst %pMR sid 0x%2.2x",
+@@ -6411,9 +6410,6 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
+ }
+
+ unlock:
+- /* Handle any other pending PA sync command */
+- hci_pa_create_sync_pending(hdev);
+-
+ hci_dev_unlock(hdev);
+ }
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 14c3ee5c6a1e8..9d03717263bf8 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -2693,16 +2693,16 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+
+ /* Force address filtering if PA Sync is in progress */
+ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
+- struct hci_cp_le_pa_create_sync *sent;
++ struct hci_conn *conn;
+
+- sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC);
+- if (sent) {
++ conn = hci_conn_hash_lookup_create_pa_sync(hdev);
++ if (conn) {
+ struct conn_params pa;
+
+ memset(&pa, 0, sizeof(pa));
+
+- bacpy(&pa.addr, &sent->addr);
+- pa.addr_type = sent->addr_type;
++ bacpy(&pa.addr, &conn->dst);
++ pa.addr_type = conn->dst_type;
+
+ /* Clear first since there could be addresses left
+ * behind.
+@@ -6895,3 +6895,80 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_CONN_UPDATE,
+ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ }
++
++static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
++{
++ bt_dev_dbg(hdev, "err %d", err);
++
++ if (!err)
++ return;
++
++ hci_dev_clear_flag(hdev, HCI_PA_SYNC);
++
++ if (err == -ECANCELED)
++ return;
++
++ hci_dev_lock(hdev);
++
++ hci_update_passive_scan_sync(hdev);
++
++ hci_dev_unlock(hdev);
++}
++
++static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)
++{
++ struct hci_cp_le_pa_create_sync cp;
++ struct hci_conn *conn = data;
++ struct bt_iso_qos *qos = &conn->iso_qos;
++ int err;
++
++ if (!hci_conn_valid(hdev, conn))
++ return -ECANCELED;
++
++ if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
++ return -EBUSY;
++
++ /* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can
++ * program the address in the allow list so PA advertisements can be
++ * received.
++ */
++ set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
++
++ hci_update_passive_scan_sync(hdev);
++
++ memset(&cp, 0, sizeof(cp));
++ cp.options = qos->bcast.options;
++ cp.sid = conn->sid;
++ cp.addr_type = conn->dst_type;
++ bacpy(&cp.addr, &conn->dst);
++ cp.skip = cpu_to_le16(qos->bcast.skip);
++ cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout);
++ cp.sync_cte_type = qos->bcast.sync_cte_type;
++
++ /* The spec allows only one pending LE Periodic Advertising Create
++ * Sync command at a time so we forcefully wait for PA Sync Established
++ * event since cmd_work can only schedule one command at a time.
++ *
++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
++ * page 2493:
++ *
++ * If the Host issues this command when another HCI_LE_Periodic_
++ * Advertising_Create_Sync command is pending, the Controller shall
++ * return the error code Command Disallowed (0x0C).
++ */
++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_PA_CREATE_SYNC,
++ sizeof(cp), &cp,
++ HCI_EV_LE_PA_SYNC_ESTABLISHED,
++ conn->conn_timeout, NULL);
++ if (err == -ETIMEDOUT)
++ __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC_CANCEL,
++ 0, NULL, HCI_CMD_TIMEOUT);
++
++ return err;
++}
++
++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn)
++{
++ return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn,
++ create_pa_complete);
++}
+--
+2.39.5
+
--- /dev/null
+From fa3f19bd6e421e93044b0a6f3f72c4673e3a1dd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 15:43:32 -0400
+Subject: Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 024421cf39923927ab2b5fe895d1d922b9abe67f ]
+
+BIG Create Sync requires the command to just generates a status so this
+makes use of __hci_cmd_sync_status_sk to wait for
+HCI_EVT_LE_BIG_SYNC_ESTABLISHED, also because of this chance it is not
+longer necessary to use a custom method to serialize the process of
+creating the BIG sync since the cmd_work_sync itself ensures only one
+command would be pending which now awaits for
+HCI_EVT_LE_BIG_SYNC_ESTABLISHED before proceeding to next connection.
+
+Fixes: 42ecf1947135 ("Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 2 +-
+ include/net/bluetooth/hci_core.h | 7 ++-
+ include/net/bluetooth/hci_sync.h | 1 +
+ net/bluetooth/hci_conn.c | 89 ++------------------------------
+ net/bluetooth/hci_event.c | 9 ++--
+ net/bluetooth/hci_sync.c | 63 ++++++++++++++++++++++
+ net/bluetooth/iso.c | 26 +++++-----
+ 7 files changed, 88 insertions(+), 109 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 8ea7a063cc651..797992019f9ee 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -2832,7 +2832,7 @@ struct hci_evt_le_create_big_complete {
+ __le16 bis_handle[];
+ } __packed;
+
+-#define HCI_EVT_LE_BIG_SYNC_ESTABILISHED 0x1d
++#define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d
+ struct hci_evt_le_big_sync_estabilished {
+ __u8 status;
+ __u8 handle;
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 49f51877988d8..7d8bab892154e 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1516,7 +1516,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
+ void hci_sco_setup(struct hci_conn *conn, __u8 status);
+ bool hci_iso_setup_path(struct hci_conn *conn);
+ int hci_le_create_cis_pending(struct hci_dev *hdev);
+-int hci_le_big_create_sync_pending(struct hci_dev *hdev);
+ int hci_conn_check_create_cis(struct hci_conn *conn);
+
+ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+@@ -1557,9 +1556,9 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
+ __u8 data_len, __u8 *data);
+ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+ __u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
+-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
+- struct bt_iso_qos *qos,
+- __u16 sync_handle, __u8 num_bis, __u8 bis[]);
++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
++ struct bt_iso_qos *qos, __u16 sync_handle,
++ __u8 num_bis, __u8 bis[]);
+ int hci_conn_check_link_mode(struct hci_conn *conn);
+ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
+ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 93dac4c7f9e3e..72558c826aa1b 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -187,3 +187,4 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ struct hci_conn_params *params);
+
+ int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn);
++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn);
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index badaa6c199204..ae66fa0a5fb58 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2084,89 +2084,9 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+ return conn;
+ }
+
+-static bool hci_conn_check_create_big_sync(struct hci_conn *conn)
+-{
+- if (!conn->num_bis)
+- return false;
+-
+- return true;
+-}
+-
+-static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err)
+-{
+- bt_dev_dbg(hdev, "");
+-
+- if (err)
+- bt_dev_err(hdev, "Unable to create BIG sync: %d", err);
+-}
+-
+-static int big_create_sync(struct hci_dev *hdev, void *data)
+-{
+- DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11);
+- struct hci_conn *conn;
+-
+- rcu_read_lock();
+-
+- pdu->num_bis = 0;
+-
+- /* The spec allows only one pending LE BIG Create Sync command at
+- * a time. If the command is pending now, don't do anything. We
+- * check for pending connections after each BIG Sync Established
+- * event.
+- *
+- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+- * page 2586:
+- *
+- * If the Host sends this command when the Controller is in the
+- * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_
+- * Established event has not been generated, the Controller shall
+- * return the error code Command Disallowed (0x0C).
+- */
+- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+- if (test_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags))
+- goto unlock;
+- }
+-
+- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+- if (hci_conn_check_create_big_sync(conn)) {
+- struct bt_iso_qos *qos = &conn->iso_qos;
+-
+- set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
+-
+- pdu->handle = qos->bcast.big;
+- pdu->sync_handle = cpu_to_le16(conn->sync_handle);
+- pdu->encryption = qos->bcast.encryption;
+- memcpy(pdu->bcode, qos->bcast.bcode,
+- sizeof(pdu->bcode));
+- pdu->mse = qos->bcast.mse;
+- pdu->timeout = cpu_to_le16(qos->bcast.timeout);
+- pdu->num_bis = conn->num_bis;
+- memcpy(pdu->bis, conn->bis, conn->num_bis);
+-
+- break;
+- }
+- }
+-
+-unlock:
+- rcu_read_unlock();
+-
+- if (!pdu->num_bis)
+- return 0;
+-
+- return hci_send_cmd(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
+- struct_size(pdu, bis, pdu->num_bis), pdu);
+-}
+-
+-int hci_le_big_create_sync_pending(struct hci_dev *hdev)
+-{
+- /* Queue big_create_sync */
+- return hci_cmd_sync_queue_once(hdev, big_create_sync,
+- NULL, big_create_sync_complete);
+-}
+-
+-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
+- struct bt_iso_qos *qos,
+- __u16 sync_handle, __u8 num_bis, __u8 bis[])
++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
++ struct bt_iso_qos *qos, __u16 sync_handle,
++ __u8 num_bis, __u8 bis[])
+ {
+ int err;
+
+@@ -2183,9 +2103,10 @@ int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
+
+ hcon->num_bis = num_bis;
+ memcpy(hcon->bis, bis, num_bis);
++ hcon->conn_timeout = msecs_to_jiffies(qos->bcast.timeout * 10);
+ }
+
+- return hci_le_big_create_sync_pending(hdev);
++ return hci_connect_big_sync(hdev, hcon);
+ }
+
+ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 216db540e502c..ab940ec698c0f 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6921,7 +6921,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+
+- if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
++ if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
+ flex_array_size(ev, bis, ev->num_bis)))
+ return;
+
+@@ -6992,9 +6992,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+ }
+
+ unlock:
+- /* Handle any other pending BIG sync command */
+- hci_le_big_create_sync_pending(hdev);
+-
+ hci_dev_unlock(hdev);
+ }
+
+@@ -7116,8 +7113,8 @@ static const struct hci_le_ev {
+ hci_le_create_big_complete_evt,
+ sizeof(struct hci_evt_le_create_big_complete),
+ HCI_MAX_EVENT_SIZE),
+- /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
+- HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
++ /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */
++ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
+ hci_le_big_sync_established_evt,
+ sizeof(struct hci_evt_le_big_sync_estabilished),
+ HCI_MAX_EVENT_SIZE),
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 9d03717263bf8..85c6ac082bfcd 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6972,3 +6972,66 @@ int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn)
+ return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn,
+ create_pa_complete);
+ }
++
++static void create_big_complete(struct hci_dev *hdev, void *data, int err)
++{
++ struct hci_conn *conn = data;
++
++ bt_dev_dbg(hdev, "err %d", err);
++
++ if (err == -ECANCELED)
++ return;
++
++ if (hci_conn_valid(hdev, conn))
++ clear_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
++}
++
++static int hci_le_big_create_sync(struct hci_dev *hdev, void *data)
++{
++ DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11);
++ struct hci_conn *conn = data;
++ struct bt_iso_qos *qos = &conn->iso_qos;
++ int err;
++
++ if (!hci_conn_valid(hdev, conn))
++ return -ECANCELED;
++
++ set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
++
++ memset(cp, 0, sizeof(*cp));
++ cp->handle = qos->bcast.big;
++ cp->sync_handle = cpu_to_le16(conn->sync_handle);
++ cp->encryption = qos->bcast.encryption;
++ memcpy(cp->bcode, qos->bcast.bcode, sizeof(cp->bcode));
++ cp->mse = qos->bcast.mse;
++ cp->timeout = cpu_to_le16(qos->bcast.timeout);
++ cp->num_bis = conn->num_bis;
++ memcpy(cp->bis, conn->bis, conn->num_bis);
++
++ /* The spec allows only one pending LE BIG Create Sync command at
++ * a time, so we forcefully wait for BIG Sync Established event since
++ * cmd_work can only schedule one command at a time.
++ *
++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
++ * page 2586:
++ *
++ * If the Host sends this command when the Controller is in the
++ * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_
++ * Established event has not been generated, the Controller shall
++ * return the error code Command Disallowed (0x0C).
++ */
++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
++ struct_size(cp, bis, cp->num_bis), cp,
++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
++ conn->conn_timeout, NULL);
++ if (err == -ETIMEDOUT)
++ hci_le_big_terminate_sync(hdev, cp->handle);
++
++ return err;
++}
++
++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn)
++{
++ return hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync, conn,
++ create_big_complete);
++}
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 0cb52a3308bae..491efb327b5b5 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1450,14 +1450,13 @@ static void iso_conn_big_sync(struct sock *sk)
+ lock_sock(sk);
+
+ if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
+- err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
+- &iso_pi(sk)->qos,
+- iso_pi(sk)->sync_handle,
+- iso_pi(sk)->bc_num_bis,
+- iso_pi(sk)->bc_bis);
++ err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
++ &iso_pi(sk)->qos,
++ iso_pi(sk)->sync_handle,
++ iso_pi(sk)->bc_num_bis,
++ iso_pi(sk)->bc_bis);
+ if (err)
+- bt_dev_err(hdev, "hci_le_big_create_sync: %d",
+- err);
++ bt_dev_err(hdev, "hci_big_create_sync: %d", err);
+ }
+
+ release_sock(sk);
+@@ -1906,7 +1905,7 @@ static void iso_conn_ready(struct iso_conn *conn)
+ hcon);
+ } else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
+ ev = hci_recv_event_data(hcon->hdev,
+- HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
+
+ /* Get reference to PA sync parent socket, if it exists */
+ parent = iso_get_sock(&hcon->src, &hcon->dst,
+@@ -2097,12 +2096,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+
+ if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
+ !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
+- err = hci_le_big_create_sync(hdev,
+- hcon,
+- &iso_pi(sk)->qos,
+- iso_pi(sk)->sync_handle,
+- iso_pi(sk)->bc_num_bis,
+- iso_pi(sk)->bc_bis);
++ err = hci_conn_big_create_sync(hdev, hcon,
++ &iso_pi(sk)->qos,
++ iso_pi(sk)->sync_handle,
++ iso_pi(sk)->bc_num_bis,
++ iso_pi(sk)->bc_bis);
+ if (err) {
+ bt_dev_err(hdev, "hci_le_big_create_sync: %d",
+ err);
+--
+2.39.5
+
--- /dev/null
+From f809edfa758f765b3c246794548c126ad97d97a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 22:51:03 +0300
+Subject: Bluetooth: L2CAP: copy RX timestamp to new fragments
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3908feb1bd7f319a10e18d84369a48163264cc7d ]
+
+Copy timestamp too when allocating new skb for received fragment.
+Fixes missing RX timestamps with fragmentation.
+
+Fixes: 4d7ea8ee90e4 ("Bluetooth: L2CAP: Fix handling fragmented length")
+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>
+---
+ net/bluetooth/l2cap_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index a55388fbf07c8..c219a8c596d3e 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -7380,6 +7380,9 @@ static int l2cap_recv_frag(struct l2cap_conn *conn, struct sk_buff *skb,
+ return -ENOMEM;
+ /* Init rx_len */
+ conn->rx_len = len;
++
++ skb_set_delivery_time(conn->rx_skb, skb->tstamp,
++ skb->tstamp_type);
+ }
+
+ /* Copy as much as the rx_skb can hold */
+--
+2.39.5
+
--- /dev/null
+From 4f26fb2c6ad52c7e7b344929c225cc443116f2b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:58:58 -0700
+Subject: bnxt_en: Add missing skb_mark_for_recycle() in bnxt_rx_vlan()
+
+From: Somnath Kotur <somnath.kotur@broadcom.com>
+
+[ Upstream commit a63db07e4ecd45b027718168faf7d798bb47bf58 ]
+
+If bnxt_rx_vlan() fails because the VLAN protocol ID is invalid,
+the SKB is freed but we're missing the call to recycle it. This
+may cause the warning:
+
+"page_pool_release_retry() stalled pool shutdown"
+
+Add the missing skb_mark_for_recycle() in bnxt_rx_vlan().
+
+Fixes: 86b05508f775 ("bnxt_en: Use the unified RX page pool buffers for XDP and non-XDP")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index da837866c02f8..174bb33432d13 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -2011,6 +2011,7 @@ static struct sk_buff *bnxt_rx_vlan(struct sk_buff *skb, u8 cmp_type,
+ }
+ return skb;
+ vlan_err:
++ skb_mark_for_recycle(skb);
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+--
+2.39.5
+
--- /dev/null
+From bfc50fedc292b0c5b33641888cc3064f8de5d132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:58:59 -0700
+Subject: bnxt_en: call pci_alloc_irq_vectors() after bnxt_reserve_rings()
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 1ae04e489dd757e1e61999362f33e7c554c3b9e3 ]
+
+On some architectures (e.g. ARM), calling pci_alloc_irq_vectors()
+will immediately cause the MSIX table to be written. This will not
+work if we haven't called bnxt_reserve_rings() to properly map
+the MSIX table to the MSIX vectors reserved by FW.
+
+Fix the FW error recovery path to delay the bnxt_init_int_mode() ->
+pci_alloc_irq_vectors() call by removing it from bnxt_hwrm_if_change().
+bnxt_request_irq() later in the code path will call it and by then the
+MSIX table is properly mapped.
+
+Fixes: 4343838ca5eb ("bnxt_en: Replace deprecated PCI MSIX APIs")
+Suggested-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 174bb33432d13..a414d7d721b20 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12172,13 +12172,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
+ set_bit(BNXT_STATE_ABORT_ERR, &bp->state);
+ return rc;
+ }
++ /* IRQ will be initialized later in bnxt_request_irq()*/
+ bnxt_clear_int_mode(bp);
+- rc = bnxt_init_int_mode(bp);
+- if (rc) {
+- clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state);
+- netdev_err(bp->dev, "init int mode failed\n");
+- return rc;
+- }
+ }
+ rc = bnxt_cancel_reservations(bp, fw_reset);
+ }
+--
+2.39.5
+
--- /dev/null
+From b783c5564756319b70504305b0e6a66d47554d9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:59:01 -0700
+Subject: bnxt_en: Fix coredump logic to free allocated buffer
+
+From: Shruti Parab <shruti.parab@broadcom.com>
+
+[ Upstream commit ea9376cf68230e05492f22ca45d329f16e262c7b ]
+
+When handling HWRM_DBG_COREDUMP_LIST FW command in
+bnxt_hwrm_dbg_dma_data(), the allocated buffer info->dest_buf is
+not freed in the error path. In the normal path, info->dest_buf
+is assigned to coredump->data and it will eventually be freed after
+the coredump is collected.
+
+Free info->dest_buf immediately inside bnxt_hwrm_dbg_dma_data() in
+the error path.
+
+Fixes: c74751f4c392 ("bnxt_en: Return error if FW returns more data than dump length")
+Reported-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Shruti Parab <shruti.parab@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
+index 7236d8e548ab5..0c0d833d19342 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
+@@ -116,6 +116,11 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
+ memcpy(info->dest_buf + off, dma_buf, len);
+ } else {
+ rc = -ENOBUFS;
++ if (cmn_req->req_type ==
++ cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) {
++ kfree(info->dest_buf);
++ info->dest_buf = NULL;
++ }
+ break;
+ }
+ }
+--
+2.39.5
+
--- /dev/null
+From 0aba37a3aca37e1a3624146425467777dba7cd7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:58:56 -0700
+Subject: bnxt_en: Fix error handling path in bnxt_init_chip()
+
+From: Shravya KN <shravya.k-n@broadcom.com>
+
+[ Upstream commit 9ab7a709c926c16b4433cf02d04fcbcf35aaab2b ]
+
+WARN_ON() is triggered in __flush_work() if bnxt_init_chip() fails
+because we call cancel_work_sync() on dim work that has not been
+initialized.
+
+WARNING: CPU: 37 PID: 5223 at kernel/workqueue.c:4201 __flush_work.isra.0+0x212/0x230
+
+The driver relies on the BNXT_STATE_NAPI_DISABLED bit to check if dim
+work has already been cancelled. But in the bnxt_open() path,
+BNXT_STATE_NAPI_DISABLED is not set and this causes the error
+path to think that it needs to cancel the uninitalized dim work.
+Fix it by setting BNXT_STATE_NAPI_DISABLED during initialization.
+The bit will be cleared when we enable NAPI and initialize dim work.
+
+Fixes: 40452969a506 ("bnxt_en: Fix DIM shutdown")
+Suggested-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index e44f9692dc2ee..da837866c02f8 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -11379,6 +11379,9 @@ static void bnxt_init_napi(struct bnxt *bp)
+ poll_fn = bnxt_poll_p5;
+ else if (BNXT_CHIP_TYPE_NITRO_A0(bp))
+ cp_nr_rings--;
++
++ set_bit(BNXT_STATE_NAPI_DISABLED, &bp->state);
++
+ for (i = 0; i < cp_nr_rings; i++) {
+ bnapi = bp->bnapi[i];
+ netif_napi_add_config(bp->dev, &bnapi->napi, poll_fn,
+--
+2.39.5
+
--- /dev/null
+From b024233bd747180fae933091dc9bbc72e135b7a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:59:03 -0700
+Subject: bnxt_en: Fix ethtool -d byte order for 32-bit values
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 02e8be5a032cae0f4ca33c6053c44d83cf4acc93 ]
+
+For version 1 register dump that includes the PCIe stats, the existing
+code incorrectly assumes that all PCIe stats are 64-bit values. Fix it
+by using an array containing the starting and ending index of the 32-bit
+values. The loop in bnxt_get_regs() will use the array to do proper
+endian swap for the 32-bit values.
+
+Fixes: b5d600b027eb ("bnxt_en: Add support for 'ethtool -d'")
+Reviewed-by: Shruti Parab <shruti.parab@broadcom.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 38 ++++++++++++++++---
+ 1 file changed, 32 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index d974f71074a76..54208e0495983 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -2062,6 +2062,17 @@ static int bnxt_get_regs_len(struct net_device *dev)
+ return reg_len;
+ }
+
++#define BNXT_PCIE_32B_ENTRY(start, end) \
++ { offsetof(struct pcie_ctx_hw_stats, start), \
++ offsetof(struct pcie_ctx_hw_stats, end) }
++
++static const struct {
++ u16 start;
++ u16 end;
++} bnxt_pcie_32b_entries[] = {
++ BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]),
++};
++
+ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *_p)
+ {
+@@ -2094,12 +2105,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
+ rc = hwrm_req_send(bp, req);
+ if (!rc) {
+- __le64 *src = (__le64 *)hw_pcie_stats;
+- u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
+- int i;
+-
+- for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
+- dst[i] = le64_to_cpu(src[i]);
++ u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN);
++ u8 *src = (u8 *)hw_pcie_stats;
++ int i, j;
++
++ for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) {
++ if (i >= bnxt_pcie_32b_entries[j].start &&
++ i <= bnxt_pcie_32b_entries[j].end) {
++ u32 *dst32 = (u32 *)(dst + i);
++
++ *dst32 = le32_to_cpu(*(__le32 *)(src + i));
++ i += 4;
++ if (i > bnxt_pcie_32b_entries[j].end &&
++ j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1)
++ j++;
++ } else {
++ u64 *dst64 = (u64 *)(dst + i);
++
++ *dst64 = le64_to_cpu(*(__le64 *)(src + i));
++ i += 8;
++ }
++ }
+ }
+ hwrm_req_drop(bp, req);
+ }
+--
+2.39.5
+
--- /dev/null
+From 81f7fe6813ff816817b4dc953fc5fe715bfbc1b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:58:57 -0700
+Subject: bnxt_en: Fix ethtool selftest output in one of the failure cases
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit 8e6cc9045380f3f0c48ebda2bda5e1abe263388d ]
+
+When RDMA driver is loaded, running offline self test is not
+supported and driver returns failure early. But it is not clearing
+the input buffer and hence the application prints some junk
+characters for individual test results.
+
+Fix it by clearing the buffer before returning.
+
+Fixes: 895621f1c816 ("bnxt_en: Don't support offline self test when RoCE driver is loaded")
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 9c58208395144..d974f71074a76 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -4922,6 +4922,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
+ if (!bp->num_tests || !BNXT_PF(bp))
+ return;
+
++ memset(buf, 0, sizeof(u64) * bp->num_tests);
+ if (etest->flags & ETH_TEST_FL_OFFLINE &&
+ bnxt_ulp_registered(bp->edev)) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+@@ -4929,7 +4930,6 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
+ return;
+ }
+
+- memset(buf, 0, sizeof(u64) * bp->num_tests);
+ if (!netif_running(dev)) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ return;
+--
+2.39.5
+
--- /dev/null
+From 1cd098738a2dccd3eb870f5460ee66e245af2af7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 10:03:43 -0700
+Subject: bnxt_en: fix module unload sequence
+
+From: Vadim Fedorenko <vadfed@meta.com>
+
+[ Upstream commit 927069d5c40c1cfa7b2d13cfc6d7d58bc6f85c50 ]
+
+Recent updates to the PTP part of bnxt changed the way PTP FIFO is
+cleared, skbs waiting for TX timestamps are now cleared during
+ndo_close() call. To do clearing procedure, the ptp structure must
+exist and point to a valid address. Module destroy sequence had ptp
+clear code running before netdev close causing invalid memory access and
+kernel crash. Change the sequence to destroy ptp structure after device
+close.
+
+Fixes: 8f7ae5a85137 ("bnxt_en: improve TX timestamping FIFO configuration")
+Reported-by: Taehee Yoo <ap420073@gmail.com>
+Closes: https://lore.kernel.org/netdev/CAMArcTWDe2cd41=ub=zzvYifaYcYv-N-csxfqxUvejy_L0D6UQ@mail.gmail.com/
+Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Tested-by: Taehee Yoo <ap420073@gmail.com>
+Link: https://patch.msgid.link/20250430170343.759126-1-vadfed@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index a414d7d721b20..bd8b9cb05ae98 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -15731,8 +15731,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
+
+ bnxt_rdma_aux_device_del(bp);
+
+- bnxt_ptp_clear(bp);
+ unregister_netdev(dev);
++ bnxt_ptp_clear(bp);
+
+ bnxt_rdma_aux_device_uninit(bp);
+
+--
+2.39.5
+
--- /dev/null
+From 91a2f4312dfcfb505b6a0eaaa97961e2dab3c047 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:59:02 -0700
+Subject: bnxt_en: Fix out-of-bound memcpy() during ethtool -w
+
+From: Shruti Parab <shruti.parab@broadcom.com>
+
+[ Upstream commit 6b87bd94f34370bbf1dfa59352bed8efab5bf419 ]
+
+When retrieving the FW coredump using ethtool, it can sometimes cause
+memory corruption:
+
+BUG: KFENCE: memory corruption in __bnxt_get_coredump+0x3ef/0x670 [bnxt_en]
+Corrupted memory at 0x000000008f0f30e8 [ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] (in kfence-#45):
+__bnxt_get_coredump+0x3ef/0x670 [bnxt_en]
+ethtool_get_dump_data+0xdc/0x1a0
+__dev_ethtool+0xa1e/0x1af0
+dev_ethtool+0xa8/0x170
+dev_ioctl+0x1b5/0x580
+sock_do_ioctl+0xab/0xf0
+sock_ioctl+0x1ce/0x2e0
+__x64_sys_ioctl+0x87/0xc0
+do_syscall_64+0x5c/0xf0
+entry_SYSCALL_64_after_hwframe+0x78/0x80
+
+...
+
+This happens when copying the coredump segment list in
+bnxt_hwrm_dbg_dma_data() with the HWRM_DBG_COREDUMP_LIST FW command.
+The info->dest_buf buffer is allocated based on the number of coredump
+segments returned by the FW. The segment list is then DMA'ed by
+the FW and the length of the DMA is returned by FW. The driver then
+copies this DMA'ed segment list to info->dest_buf.
+
+In some cases, this DMA length may exceed the info->dest_buf length
+and cause the above BUG condition. Fix it by capping the copy
+length to not exceed the length of info->dest_buf. The extra
+DMA data contains no useful information.
+
+This code path is shared for the HWRM_DBG_COREDUMP_LIST and the
+HWRM_DBG_COREDUMP_RETRIEVE FW commands. The buffering is different
+for these 2 FW commands. To simplify the logic, we need to move
+the line to adjust the buffer length for HWRM_DBG_COREDUMP_RETRIEVE
+up, so that the new check to cap the copy length will work for both
+commands.
+
+Fixes: c74751f4c392 ("bnxt_en: Return error if FW returns more data than dump length")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Shruti Parab <shruti.parab@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/broadcom/bnxt/bnxt_coredump.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
+index 0c0d833d19342..a73398c4a3e98 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
+@@ -110,10 +110,19 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
+ }
+ }
+
++ if (cmn_req->req_type ==
++ cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE))
++ info->dest_buf_size += len;
++
+ if (info->dest_buf) {
+ if ((info->seg_start + off + len) <=
+ BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
+- memcpy(info->dest_buf + off, dma_buf, len);
++ u16 copylen = min_t(u16, len,
++ info->dest_buf_size - off);
++
++ memcpy(info->dest_buf + off, dma_buf, copylen);
++ if (copylen < len)
++ break;
+ } else {
+ rc = -ENOBUFS;
+ if (cmn_req->req_type ==
+@@ -125,10 +134,6 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
+ }
+ }
+
+- if (cmn_req->req_type ==
+- cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE))
+- info->dest_buf_size += len;
+-
+ if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE))
+ break;
+
+--
+2.39.5
+
--- /dev/null
+From 818038a92a298c17ecef472a48489d575c86d961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 05:55:47 -0700
+Subject: bnxt_en: improve TX timestamping FIFO configuration
+
+From: Vadim Fedorenko <vadfed@meta.com>
+
+[ Upstream commit 8f7ae5a85137b913cb97e2d24409d36548d0bab1 ]
+
+Reconfiguration of netdev may trigger close/open procedure which can
+break FIFO status by adjusting the amount of empty slots for TX
+timestamps. But it is not really needed because timestamps for the
+packets sent over the wire still can be retrieved. On the other side,
+during netdev close procedure any skbs waiting for TX timestamps can be
+leaked because there is no cleaning procedure called. Free skbs waiting
+for TX timestamps when closing netdev.
+
+Fixes: 8aa2a79e9b95 ("bnxt_en: Increase the max total outstanding PTP TX packets to 4")
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
+Link: https://patch.msgid.link/20250424125547.460632-1-vadfed@meta.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 ++--
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 29 ++++++++++++++-----
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h | 1 +
+ 3 files changed, 25 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 1b39574e3fa22..e44f9692dc2ee 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -3403,6 +3403,9 @@ static void bnxt_free_tx_skbs(struct bnxt *bp)
+ }
+ netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i));
+ }
++
++ if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
++ bnxt_ptp_free_txts_skbs(bp->ptp_cfg);
+ }
+
+ static void bnxt_free_one_rx_ring(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
+@@ -12570,8 +12573,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ /* VF-reps may need to be re-opened after the PF is re-opened */
+ if (BNXT_PF(bp))
+ bnxt_vf_reps_open(bp);
+- if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
+- WRITE_ONCE(bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS);
+ bnxt_ptp_init_rtc(bp, true);
+ bnxt_ptp_cfg_tstamp_filters(bp);
+ if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+index 2d4e19b96ee74..0669d43472f51 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+@@ -794,6 +794,27 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
+ return HZ;
+ }
+
++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp)
++{
++ struct bnxt_ptp_tx_req *txts_req;
++ u16 cons = ptp->txts_cons;
++
++ /* make sure ptp aux worker finished with
++ * possible BNXT_STATE_OPEN set
++ */
++ ptp_cancel_worker_sync(ptp->ptp_clock);
++
++ ptp->tx_avail = BNXT_MAX_TX_TS;
++ while (cons != ptp->txts_prod) {
++ txts_req = &ptp->txts_req[cons];
++ if (!IS_ERR_OR_NULL(txts_req->tx_skb))
++ dev_kfree_skb_any(txts_req->tx_skb);
++ cons = NEXT_TXTS(cons);
++ }
++ ptp->txts_cons = cons;
++ ptp_schedule_worker(ptp->ptp_clock, 0);
++}
++
+ int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod)
+ {
+ spin_lock_bh(&ptp->ptp_tx_lock);
+@@ -1105,7 +1126,6 @@ int bnxt_ptp_init(struct bnxt *bp)
+ void bnxt_ptp_clear(struct bnxt *bp)
+ {
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+- int i;
+
+ if (!ptp)
+ return;
+@@ -1117,12 +1137,5 @@ void bnxt_ptp_clear(struct bnxt *bp)
+ kfree(ptp->ptp_info.pin_config);
+ ptp->ptp_info.pin_config = NULL;
+
+- for (i = 0; i < BNXT_MAX_TX_TS; i++) {
+- if (ptp->txts_req[i].tx_skb) {
+- dev_kfree_skb_any(ptp->txts_req[i].tx_skb);
+- ptp->txts_req[i].tx_skb = NULL;
+- }
+- }
+-
+ bnxt_unmap_ptp_regs(bp);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
+index a95f05e9c579b..0481161d26ef5 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
+@@ -162,6 +162,7 @@ int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp);
+ void bnxt_ptp_reapply_pps(struct bnxt *bp);
+ int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
+ int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp);
+ int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod);
+ void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod);
+ int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
+--
+2.39.5
+
--- /dev/null
+From f7ded002ce8260b3b5a5a76fa787acc0b231b12a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 07:44:10 -0500
+Subject: book3s64/radix : Align section vmemmap start address to PAGE_SIZE
+
+From: Donet Tom <donettom@linux.ibm.com>
+
+[ Upstream commit 9cf7e13fecbab0894f6986fc6986ab2eba8de52e ]
+
+A vmemmap altmap is a device-provided region used to provide
+backing storage for struct pages. For each namespace, the altmap
+should belong to that same namespace. If the namespaces are
+created unaligned, there is a chance that the section vmemmap
+start address could also be unaligned. If the section vmemmap
+start address is unaligned, the altmap page allocated from the
+current namespace might be used by the previous namespace also.
+During the free operation, since the altmap is shared between two
+namespaces, the previous namespace may detect that the page does
+not belong to its altmap and incorrectly assume that the page is a
+normal page. It then attempts to free the normal page, which leads
+to a kernel crash.
+
+Kernel attempted to read user page (18) - exploit attempt? (uid: 0)
+BUG: Kernel NULL pointer dereference on read at 0x00000018
+Faulting instruction address: 0xc000000000530c7c
+Oops: Kernel access of bad area, sig: 11 [#1]
+LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
+CPU: 32 PID: 2104 Comm: ndctl Kdump: loaded Tainted: G W
+NIP: c000000000530c7c LR: c000000000530e00 CTR: 0000000000007ffe
+REGS: c000000015e57040 TRAP: 0300 Tainted: G W
+MSR: 800000000280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 84482404
+CFAR: c000000000530dfc DAR: 0000000000000018 DSISR: 40000000 IRQMASK: 0
+GPR00: c000000000530e00 c000000015e572e0 c000000002c5cb00 c00c000101008040
+GPR04: 0000000000000000 0000000000000007 0000000000000001 000000000000001f
+GPR08: 0000000000000005 0000000000000000 0000000000000018 0000000000002000
+GPR12: c0000000001d2fb0 c0000060de6b0080 0000000000000000 c0000060dbf90020
+GPR16: c00c000101008000 0000000000000001 0000000000000000 c000000125b20f00
+GPR20: 0000000000000001 0000000000000000 ffffffffffffffff c00c000101007fff
+GPR24: 0000000000000001 0000000000000000 0000000000000000 0000000000000000
+GPR28: 0000000004040201 0000000000000001 0000000000000000 c00c000101008040
+NIP [c000000000530c7c] get_pfnblock_flags_mask+0x7c/0xd0
+LR [c000000000530e00] free_unref_page_prepare+0x130/0x4f0
+Call Trace:
+free_unref_page+0x50/0x1e0
+free_reserved_page+0x40/0x68
+free_vmemmap_pages+0x98/0xe0
+remove_pte_table+0x164/0x1e8
+remove_pmd_table+0x204/0x2c8
+remove_pud_table+0x1c4/0x288
+remove_pagetable+0x1c8/0x310
+vmemmap_free+0x24/0x50
+section_deactivate+0x28c/0x2a0
+__remove_pages+0x84/0x110
+arch_remove_memory+0x38/0x60
+memunmap_pages+0x18c/0x3d0
+devm_action_release+0x30/0x50
+release_nodes+0x68/0x140
+devres_release_group+0x100/0x190
+dax_pmem_compat_release+0x44/0x80 [dax_pmem_compat]
+device_for_each_child+0x8c/0x100
+[dax_pmem_compat_remove+0x2c/0x50 [dax_pmem_compat]
+nvdimm_bus_remove+0x78/0x140 [libnvdimm]
+device_remove+0x70/0xd0
+
+Another issue is that if there is no altmap, a PMD-sized vmemmap
+page will be allocated from RAM, regardless of the alignment of
+the section start address. If the section start address is not
+aligned to the PMD size, a VM_BUG_ON will be triggered when
+setting the PMD-sized page to page table.
+
+In this patch, we are aligning the section vmemmap start address
+to PAGE_SIZE. After alignment, the start address will not be
+part of the current namespace, and a normal page will be allocated
+for the vmemmap mapping of the current section. For the remaining
+sections, altmaps will be allocated. During the free operation,
+the normal page will be correctly freed.
+
+In the same way, a PMD_SIZE vmemmap page will be allocated only if
+the section start address is PMD_SIZE-aligned; otherwise, it will
+fall back to a PAGE-sized vmemmap allocation.
+
+Without this patch
+==================
+NS1 start NS2 start
+ _________________________________________________________
+| NS1 | NS2 |
+ ---------------------------------------------------------
+| Altmap| Altmap | .....|Altmap| Altmap | ...........
+| NS1 | NS1 | | NS2 | NS2 |
+
+In the above scenario, NS1 and NS2 are two namespaces. The vmemmap
+for NS1 comes from Altmap NS1, which belongs to NS1, and the
+vmemmap for NS2 comes from Altmap NS2, which belongs to NS2.
+
+The vmemmap start for NS2 is not aligned, so Altmap NS2 is shared
+by both NS1 and NS2. During the free operation in NS1, Altmap NS2
+is not part of NS1's altmap, causing it to attempt to free an
+invalid page.
+
+With this patch
+===============
+NS1 start NS2 start
+ _________________________________________________________
+| NS1 | NS2 |
+ ---------------------------------------------------------
+| Altmap| Altmap | .....| Normal | Altmap | Altmap |.......
+| NS1 | NS1 | | Page | NS2 | NS2 |
+
+If the vmemmap start for NS2 is not aligned then we are allocating
+a normal page. NS1 and NS2 vmemmap will be freed correctly.
+
+Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a different vmemmap handling function")
+Co-developed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Donet Tom <donettom@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/8f98ec2b442977c618f7256cec88eb17dde3f2b9.1741609795.git.donettom@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/book3s64/radix_pgtable.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
+index 311e2112d782e..128c011afc481 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -1120,6 +1120,19 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in
+ pmd_t *pmd;
+ pte_t *pte;
+
++ /*
++ * Make sure we align the start vmemmap addr so that we calculate
++ * the correct start_pfn in altmap boundary check to decided whether
++ * we should use altmap or RAM based backing memory allocation. Also
++ * the address need to be aligned for set_pte operation.
++
++ * If the start addr is already PMD_SIZE aligned we will try to use
++ * a pmd mapping. We don't want to be too aggressive here beacause
++ * that will cause more allocations in RAM. So only if the namespace
++ * vmemmap start addr is PMD_SIZE aligned we will use PMD mapping.
++ */
++
++ start = ALIGN_DOWN(start, PAGE_SIZE);
+ for (addr = start; addr < end; addr = next) {
+ next = pmd_addr_end(addr, end);
+
+@@ -1145,8 +1158,8 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in
+ * in altmap block allocation failures, in which case
+ * we fallback to RAM for vmemmap allocation.
+ */
+- if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) ||
+- altmap_cross_boundary(altmap, addr, PMD_SIZE))) {
++ if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap &&
++ altmap_cross_boundary(altmap, addr, PMD_SIZE))) {
+ /*
+ * make sure we don't create altmap mappings
+ * covering things outside the device.
+--
+2.39.5
+
--- /dev/null
+From 8a7088de1b8bb994f154c559f3c03610ca71f973 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 21:50:14 +0530
+Subject: cpufreq: ACPI: Re-sync CPU boost state on system resume
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 3d59224947b024c9b2aa6e149a1537d449adb828 ]
+
+During CPU hotunplug events (such as those occurring during
+suspend/resume cycles), platform firmware may modify the CPU boost
+state.
+
+If boost was disabled prior to CPU removal, it correctly remains
+disabled upon re-plug. However, if firmware re-enables boost while the
+CPU is offline, the CPU may return with boost enabled—even if it was
+originally disabled—once it is hotplugged back in. This leads to
+inconsistent behavior and violates user or kernel policy expectations.
+
+To maintain consistency, ensure the boost state is re-synchronized with
+the kernel policy when a CPU is hotplugged back in.
+
+Note: This re-synchronization is not necessary during the initial call
+to ->init() for a CPU, as the cpufreq core handles it via
+cpufreq_online(). At that point, acpi_cpufreq_driver.boost_enabled is
+initialized to the value returned by boost_state(0).
+
+Fixes: 2b16c631832d ("cpufreq: ACPI: Remove set_boost in acpi_cpufreq_cpu_init()")
+Reported-by: Nicholas Chin <nic.c3.14@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220013
+Tested-by: Nicholas Chin <nic.c3.14@gmail.com>
+Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://patch.msgid.link/9c7de55fb06015c1b77e7dafd564b659838864e0.1745511526.git.viresh.kumar@linaro.org
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/acpi-cpufreq.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
+index ae0766b5a076b..453b629d3de65 100644
+--- a/drivers/cpufreq/acpi-cpufreq.c
++++ b/drivers/cpufreq/acpi-cpufreq.c
+@@ -909,8 +909,19 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
+ if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
+ pr_warn(FW_WARN "P-state 0 is not max freq\n");
+
+- if (acpi_cpufreq_driver.set_boost)
+- policy->boost_supported = true;
++ if (acpi_cpufreq_driver.set_boost) {
++ if (policy->boost_supported) {
++ /*
++ * The firmware may have altered boost state while the
++ * CPU was offline (for example during a suspend-resume
++ * cycle).
++ */
++ if (policy->boost_enabled != boost_state(cpu))
++ set_boost(policy, policy->boost_enabled);
++ } else {
++ policy->boost_supported = true;
++ }
++ }
+
+ return result;
+
+--
+2.39.5
+
--- /dev/null
+From dbf0e3ebb5beefa9026191b6793afa6f4d1c90a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 15:30:42 +0530
+Subject: cpufreq: acpi: Set policy->boost_supported
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit be6b8681a0e4c1477a2c1cb155f7b9188aa88acb ]
+
+With a later commit, the cpufreq core will call the ->set_boost()
+callback only if the policy supports boost frequency. The
+boost_supported flag is set by the cpufreq core if policy->freq_table is
+set and one or more boost frequencies are present.
+
+For other drivers, the flag must be set explicitly.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: 3d59224947b0 ("cpufreq: ACPI: Re-sync CPU boost state on system resume")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/acpi-cpufreq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
+index 463b69a2dff52..ae0766b5a076b 100644
+--- a/drivers/cpufreq/acpi-cpufreq.c
++++ b/drivers/cpufreq/acpi-cpufreq.c
+@@ -909,6 +909,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
+ if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
+ pr_warn(FW_WARN "P-state 0 is not max freq\n");
+
++ if (acpi_cpufreq_driver.set_boost)
++ policy->boost_supported = true;
++
+ return result;
+
+ err_unreg:
+--
+2.39.5
+
--- /dev/null
+From 26e5213be2816e03e00a4656e5643eb3cc2be899 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 11:04:25 +0530
+Subject: cpufreq: Introduce policy->boost_supported flag
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 1f7d1bab50e6ae517f8b6699e56d709d61ae13e5 ]
+
+It is possible to have a scenario where not all cpufreq policies support
+boost frequencies. And letting sysfs (or other parts of the kernel)
+enable boost feature for that policy isn't correct.
+
+Add a new flag, boost_supported, which will be set to true by the
+cpufreq core only if the freq table contains valid boost frequencies.
+
+Some cpufreq drivers though don't have boost frequencies in the
+freq-table, they can set this flag from their ->init() callbacks.
+
+Once all the drivers are updated to set the flag correctly, we can check
+it before enabling boost feature for a policy.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: 3d59224947b0 ("cpufreq: ACPI: Re-sync CPU boost state on system resume")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/freq_table.c | 4 ++++
+ include/linux/cpufreq.h | 3 +++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
+index 178e17009a16e..9db21ffc11979 100644
+--- a/drivers/cpufreq/freq_table.c
++++ b/drivers/cpufreq/freq_table.c
+@@ -367,6 +367,10 @@ int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy)
+ if (ret)
+ return ret;
+
++ /* Driver's may have set this field already */
++ if (policy_has_boost_freq(policy))
++ policy->boost_supported = true;
++
+ return set_freq_table_sorted(policy);
+ }
+
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index a604c54ae44da..73024830bd730 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -144,6 +144,9 @@ struct cpufreq_policy {
+ /* Per policy boost enabled flag. */
+ bool boost_enabled;
+
++ /* Per policy boost supported flag. */
++ bool boost_supported;
++
+ /* Cached frequency lookup from cpufreq_driver_resolve_freq. */
+ unsigned int cached_target_freq;
+ unsigned int cached_resolved_idx;
+--
+2.39.5
+
--- /dev/null
+From 067f4e8967e222afcaa566861d93614e426ebaf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 12:06:16 +0300
+Subject: drm/i915/pxp: fix undefined reference to
+ `intel_pxp_gsccs_is_ready_for_sessions'
+
+From: Chen Linxuan <chenlinxuan@uniontech.com>
+
+[ Upstream commit 7e21ea8149a0e41c3666ee52cc063a6f797a7a2a ]
+
+On x86_64 with gcc version 13.3.0, I compile kernel with:
+
+ make defconfig
+ ./scripts/kconfig/merge_config.sh .config <(
+ echo CONFIG_COMPILE_TEST=y
+ )
+ make KCFLAGS="-fno-inline-functions -fno-inline-small-functions -fno-inline-functions-called-once"
+
+Then I get a linker error:
+
+ ld: vmlinux.o: in function `pxp_fw_dependencies_completed':
+ kintel_pxp.c:(.text+0x95728f): undefined reference to `intel_pxp_gsccs_is_ready_for_sessions'
+
+This is caused by not having a intel_pxp_gsccs_is_ready_for_sessions()
+header stub for CONFIG_DRM_I915_PXP=n. Add it.
+
+Signed-off-by: Chen Linxuan <chenlinxuan@uniontech.com>
+Fixes: 99afb7cc8c44 ("drm/i915/pxp: Add ARB session creation and cleanup")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://lore.kernel.org/r/20250415090616.2649889-1-jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit b484c1e225a6a582fc78c4d7af7b286408bb7d41)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
+index 9aae779c4da31..4969d3de2bac3 100644
+--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
++++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
+@@ -23,6 +23,7 @@ int intel_pxp_gsccs_init(struct intel_pxp *pxp);
+
+ int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id);
+ void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
++bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
+
+ #else
+ static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
+@@ -34,8 +35,11 @@ static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp)
+ return 0;
+ }
+
+-#endif
++static inline bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp)
++{
++ return false;
++}
+
+-bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
++#endif
+
+ #endif /*__INTEL_PXP_GSCCS_H__ */
+--
+2.39.5
+
--- /dev/null
+From 1cace7ab8e5ed03f49ebd3a7cb69ef94a62d845b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 22:32:59 -0700
+Subject: drm/mipi-dbi: Fix blanking for non-16 bit formats
+
+From: Russell Cloran <rcloran@gmail.com>
+
+[ Upstream commit 1a8bc0fe8039e1e57f68c4a588f0403d98bfeb1f ]
+
+On r6x2b6x2g6x2 displays not enough blank data is sent to blank the
+entire screen. When support for these displays was added, the dirty
+function was updated to handle the different amount of data, but
+blanking was not, and remained hardcoded as 2 bytes per pixel.
+
+This change applies almost the same algorithm used in the dirty function
+to the blank function, but there is no fb available at that point, and
+no concern about having to transform any data, so the dbidev pixel
+format is always used for calculating the length.
+
+Fixes: 4aebb79021f3 ("drm/mipi-dbi: Add support for DRM_FORMAT_RGB888")
+Signed-off-by: Russell Cloran <rcloran@gmail.com>
+Link: https://lore.kernel.org/r/20250415053259.79572-1-rcloran@gmail.com
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dbi.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
+index 34bca75675766..3ea9f23b4f67a 100644
+--- a/drivers/gpu/drm/drm_mipi_dbi.c
++++ b/drivers/gpu/drm/drm_mipi_dbi.c
+@@ -404,12 +404,16 @@ static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev)
+ u16 height = drm->mode_config.min_height;
+ u16 width = drm->mode_config.min_width;
+ struct mipi_dbi *dbi = &dbidev->dbi;
+- size_t len = width * height * 2;
++ const struct drm_format_info *dst_format;
++ size_t len;
+ int idx;
+
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
++ dst_format = drm_format_info(dbidev->pixel_format);
++ len = drm_format_info_min_pitch(dst_format, 0, width) * height;
++
+ memset(dbidev->tx_buf, 0, len);
+
+ mipi_dbi_set_window_address(dbidev, 0, width - 1, 0, height - 1);
+--
+2.39.5
+
--- /dev/null
+From 80b548d6446cdfbaa436071d40aee8abc5262990 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 16:07:58 +0200
+Subject: drm/tests: shmem: Fix memleak
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 48ccf21fa8dc595c8aa4f1d347b593dcae0727d0 ]
+
+The drm_gem_shmem_test_get_pages_sgt() gets a scatter-gather table using
+the drm_gem_shmem_get_sg_table() function and rightfully calls
+sg_free_table() on it. However, it's also supposed to kfree() the
+returned sg_table, but doesn't.
+
+This leads to a memory leak, reported by kmemleak. Fix it by adding a
+kunit action to kfree the sgt when the test ends.
+
+Reported-by: Philipp Stanner <phasta@mailbox.org>
+Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/
+Fixes: 93032ae634d4 ("drm/test: add a test suite for GEM objects backed by shmem")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20250408140758.1831333-1-mripard@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_gem_shmem_test.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
+index fd4215e2f982d..925fbc2cda700 100644
+--- a/drivers/gpu/drm/tests/drm_gem_shmem_test.c
++++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
+@@ -216,6 +216,9 @@ static void drm_gem_shmem_test_get_pages_sgt(struct kunit *test)
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt);
+ KUNIT_EXPECT_NULL(test, shmem->sgt);
+
++ ret = kunit_add_action_or_reset(test, kfree_wrapper, sgt);
++ KUNIT_ASSERT_EQ(test, ret, 0);
++
+ ret = kunit_add_action_or_reset(test, sg_free_table_wrapper, sgt);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+--
+2.39.5
+
--- /dev/null
+From d0c488aba8e375736ba591c202249049fc188817 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 12:52:12 -0700
+Subject: drm/xe/guc: Fix capture of steering registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: John Harrison <John.C.Harrison@Intel.com>
+
+[ Upstream commit 5e639707ddb8f080fbde805a1bfa6668a1b45298 ]
+
+The list of registers to capture on a GPU hang includes some that
+require steering. Unfortunately, the flag to say this was being wiped
+to due a missing OR on the assignment of the next flag field.
+
+Fix that.
+
+Fixes: b170d696c1e2 ("drm/xe/guc: Add XE_LP steered register lists")
+Cc: Zhanjun Dong <zhanjun.dong@intel.com>
+Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Cc: Lucas De Marchi <lucas.demarchi@intel.com>
+Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: intel-xe@lists.freedesktop.org
+Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Zhanjun Dong <zhanjun.dong@intel.com>
+Link: https://lore.kernel.org/r/20250417195215.3002210-2-John.C.Harrison@Intel.com
+(cherry picked from commit 532da44b54a10d50ebad14a8a02bd0b78ec23e8b)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_capture.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
+index f6d523e4c5feb..9095618648bcb 100644
+--- a/drivers/gpu/drm/xe/xe_guc_capture.c
++++ b/drivers/gpu/drm/xe/xe_guc_capture.c
+@@ -359,7 +359,7 @@ static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
+
+ ext->reg = XE_REG(extlist->reg.__reg.addr);
+ ext->flags = FIELD_PREP(GUC_REGSET_STEERING_NEEDED, 1);
+- ext->flags = FIELD_PREP(GUC_REGSET_STEERING_GROUP, slice_id);
++ ext->flags |= FIELD_PREP(GUC_REGSET_STEERING_GROUP, slice_id);
+ ext->flags |= FIELD_PREP(GUC_REGSET_STEERING_INSTANCE, subslice_id);
+ ext->regname = extlist->name;
+ }
+--
+2.39.5
+
--- /dev/null
+From 369ad5feeb693686f451aa34f22fbe4014ddcfad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 13:36:08 +0100
+Subject: firmware: cs_dsp: tests: Depend on FW_CS_DSP rather then enabling it
+
+From: Nico Pache <npache@redhat.com>
+
+[ Upstream commit a0b887f6eb9a0d1be3c57d00b0f3ba8408d3018a ]
+
+FW_CS_DSP gets enabled if KUNIT is enabled. The test should rather
+depend on if the feature is enabled. Fix this by moving FW_CS_DSP to the
+depends on clause.
+
+Fixes: dd0b6b1f29b9 ("firmware: cs_dsp: Add KUnit testing of bin file download")
+Signed-off-by: Nico Pache <npache@redhat.com>
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250411123608.1676462-4-rf@opensource.cirrus.com
+Reviewed-by: David Gow <davidgow@google.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/cirrus/Kconfig | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/cirrus/Kconfig b/drivers/firmware/cirrus/Kconfig
+index 0a883091259a2..e3c2e38b746df 100644
+--- a/drivers/firmware/cirrus/Kconfig
++++ b/drivers/firmware/cirrus/Kconfig
+@@ -6,14 +6,11 @@ config FW_CS_DSP
+
+ config FW_CS_DSP_KUNIT_TEST_UTILS
+ tristate
+- depends on KUNIT && REGMAP
+- select FW_CS_DSP
+
+ config FW_CS_DSP_KUNIT_TEST
+ tristate "KUnit tests for Cirrus Logic cs_dsp" if !KUNIT_ALL_TESTS
+- depends on KUNIT && REGMAP
++ depends on KUNIT && REGMAP && FW_CS_DSP
+ default KUNIT_ALL_TESTS
+- select FW_CS_DSP
+ select FW_CS_DSP_KUNIT_TEST_UTILS
+ help
+ This builds KUnit tests for cs_dsp.
+--
+2.39.5
+
--- /dev/null
+From f5722191ff78246dfefd8f336fc9a2f776d30c2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:26:32 -0700
+Subject: ice: Check VF VSI Pointer Value in ice_vc_add_fdir_fltr()
+
+From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
+
+[ Upstream commit 425c5f266b2edeee0ce16fedd8466410cdcfcfe3 ]
+
+As mentioned in the commit baeb705fd6a7 ("ice: always check VF VSI
+pointer values"), we need to perform a null pointer check on the return
+value of ice_get_vf_vsi() before using it.
+
+Fixes: 6ebbe97a4881 ("ice: Add a per-VF limit on number of FDIR filters")
+Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20250425222636.3188441-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+index 9be4bd717512d..f90f545b3144d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+@@ -2097,6 +2097,11 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
+ pf = vf->pf;
+ dev = ice_pf_to_dev(pf);
+ vf_vsi = ice_get_vf_vsi(vf);
++ if (!vf_vsi) {
++ dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id);
++ v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++ goto err_exit;
++ }
+
+ #define ICE_VF_MAX_FDIR_FILTERS 128
+ if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) ||
+--
+2.39.5
+
--- /dev/null
+From 7d3dc15b9d58825c4541a8c163c885059a9d2a73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 14:12:38 +0200
+Subject: ice: Don't check device type when checking GNSS presence
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit e2c6737e6e82e9991646cd5389391bb6d3572a68 ]
+
+Don't check if the device type is E810T as non-E810T devices can support
+GNSS too and PCA9575 check is enough to determine if GNSS is present or
+not.
+
+Rename ice_gnss_is_gps_present() to ice_gnss_is_module_present()
+because GNSS module supports multiple GNSS providers, not only GPS.
+
+Move functions related to PCA9575 from ice_ptp_hw.c to ice_common.c
+to be able to access them when PTP is disabled in the kernel, but GNSS
+is enabled.
+
+Remove logical AND with ICE_AQC_LINK_TOPO_NODE_TYPE_M in
+ice_get_pca9575_handle(), which has no effect, and reorder device type
+checks to check the device_id first, then set other variables.
+
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 3ffcd7b657c9 ("ice: fix Get Tx Topology AQ command error on E830")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_common.c | 90 ++++++++++++++++++++
+ drivers/net/ethernet/intel/ice/ice_common.h | 2 +
+ drivers/net/ethernet/intel/ice/ice_gnss.c | 29 +++----
+ drivers/net/ethernet/intel/ice/ice_gnss.h | 4 +-
+ drivers/net/ethernet/intel/ice/ice_lib.c | 2 +-
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 93 ---------------------
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 -
+ 7 files changed, 105 insertions(+), 116 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
+index 1e801300310e9..f48cb93e10183 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.c
++++ b/drivers/net/ethernet/intel/ice/ice_common.c
+@@ -5765,6 +5765,96 @@ ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
+ }
+
++/**
++ * ice_get_pca9575_handle - find and return the PCA9575 controller
++ * @hw: pointer to the hw struct
++ * @pca9575_handle: GPIO controller's handle
++ *
++ * Find and return the GPIO controller's handle in the netlist.
++ * When found - the value will be cached in the hw structure and following calls
++ * will return cached value.
++ *
++ * Return: 0 on success, -ENXIO when there's no PCA9575 present.
++ */
++int ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle)
++{
++ struct ice_aqc_get_link_topo *cmd;
++ struct ice_aq_desc desc;
++ int err;
++ u8 idx;
++
++ /* If handle was read previously return cached value */
++ if (hw->io_expander_handle) {
++ *pca9575_handle = hw->io_expander_handle;
++ return 0;
++ }
++
++#define SW_PCA9575_SFP_TOPO_IDX 2
++#define SW_PCA9575_QSFP_TOPO_IDX 1
++
++ /* Check if the SW IO expander controlling SMA exists in the netlist. */
++ if (hw->device_id == ICE_DEV_ID_E810C_SFP)
++ idx = SW_PCA9575_SFP_TOPO_IDX;
++ else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
++ idx = SW_PCA9575_QSFP_TOPO_IDX;
++ else
++ return -ENXIO;
++
++ /* If handle was not detected read it from the netlist */
++ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
++ cmd = &desc.params.get_link_topo;
++ cmd->addr.topo_params.node_type_ctx =
++ ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL;
++ cmd->addr.topo_params.index = idx;
++
++ err = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
++ if (err)
++ return -ENXIO;
++
++ /* Verify if we found the right IO expander type */
++ if (desc.params.get_link_topo.node_part_num !=
++ ICE_AQC_GET_LINK_TOPO_NODE_NR_PCA9575)
++ return -ENXIO;
++
++ /* If present save the handle and return it */
++ hw->io_expander_handle =
++ le16_to_cpu(desc.params.get_link_topo.addr.handle);
++ *pca9575_handle = hw->io_expander_handle;
++
++ return 0;
++}
++
++/**
++ * ice_read_pca9575_reg - read the register from the PCA9575 controller
++ * @hw: pointer to the hw struct
++ * @offset: GPIO controller register offset
++ * @data: pointer to data to be read from the GPIO controller
++ *
++ * Return: 0 on success, negative error code otherwise.
++ */
++int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
++{
++ struct ice_aqc_link_topo_addr link_topo;
++ __le16 addr;
++ u16 handle;
++ int err;
++
++ memset(&link_topo, 0, sizeof(link_topo));
++
++ err = ice_get_pca9575_handle(hw, &handle);
++ if (err)
++ return err;
++
++ link_topo.handle = cpu_to_le16(handle);
++ link_topo.topo_params.node_type_ctx =
++ FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M,
++ ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED);
++
++ addr = cpu_to_le16((u16)offset);
++
++ return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
++}
++
+ /**
+ * ice_aq_set_gpio
+ * @hw: pointer to the hw struct
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
+index 15ba385437389..54a8692839dd0 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.h
++++ b/drivers/net/ethernet/intel/ice/ice_common.h
+@@ -306,5 +306,7 @@ int
+ ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
+ u16 bus_addr, __le16 addr, u8 params, const u8 *data,
+ struct ice_sq_cd *cd);
++int ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle);
++int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data);
+ bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw);
+ #endif /* _ICE_COMMON_H_ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c
+index b2148dbe49b28..6b26290452d48 100644
+--- a/drivers/net/ethernet/intel/ice/ice_gnss.c
++++ b/drivers/net/ethernet/intel/ice/ice_gnss.c
+@@ -381,32 +381,23 @@ void ice_gnss_exit(struct ice_pf *pf)
+ }
+
+ /**
+- * ice_gnss_is_gps_present - Check if GPS HW is present
++ * ice_gnss_is_module_present - Check if GNSS HW is present
+ * @hw: pointer to HW struct
++ *
++ * Return: true when GNSS is present, false otherwise.
+ */
+-bool ice_gnss_is_gps_present(struct ice_hw *hw)
++bool ice_gnss_is_module_present(struct ice_hw *hw)
+ {
+- if (!hw->func_caps.ts_func_info.src_tmr_owned)
+- return false;
++ int err;
++ u8 data;
+
+- if (!ice_is_gps_in_netlist(hw))
++ if (!hw->func_caps.ts_func_info.src_tmr_owned ||
++ !ice_is_gps_in_netlist(hw))
+ return false;
+
+-#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
+- if (ice_is_e810t(hw)) {
+- int err;
+- u8 data;
+-
+- err = ice_read_pca9575_reg(hw, ICE_PCA9575_P0_IN, &data);
+- if (err || !!(data & ICE_P0_GNSS_PRSNT_N))
+- return false;
+- } else {
+- return false;
+- }
+-#else
+- if (!ice_is_e810t(hw))
++ err = ice_read_pca9575_reg(hw, ICE_PCA9575_P0_IN, &data);
++ if (err || !!(data & ICE_P0_GNSS_PRSNT_N))
+ return false;
+-#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
+
+ return true;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.h b/drivers/net/ethernet/intel/ice/ice_gnss.h
+index 75e567ad70594..15daf603ed7bf 100644
+--- a/drivers/net/ethernet/intel/ice/ice_gnss.h
++++ b/drivers/net/ethernet/intel/ice/ice_gnss.h
+@@ -37,11 +37,11 @@ struct gnss_serial {
+ #if IS_ENABLED(CONFIG_GNSS)
+ void ice_gnss_init(struct ice_pf *pf);
+ void ice_gnss_exit(struct ice_pf *pf);
+-bool ice_gnss_is_gps_present(struct ice_hw *hw);
++bool ice_gnss_is_module_present(struct ice_hw *hw);
+ #else
+ static inline void ice_gnss_init(struct ice_pf *pf) { }
+ static inline void ice_gnss_exit(struct ice_pf *pf) { }
+-static inline bool ice_gnss_is_gps_present(struct ice_hw *hw)
++static inline bool ice_gnss_is_module_present(struct ice_hw *hw)
+ {
+ return false;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index d0faa087793da..e0785e820d601 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -3882,7 +3882,7 @@ void ice_init_feature_support(struct ice_pf *pf)
+ ice_set_feature_support(pf, ICE_F_CGU);
+ if (ice_is_clock_mux_in_netlist(&pf->hw))
+ ice_set_feature_support(pf, ICE_F_SMA_CTRL);
+- if (ice_gnss_is_gps_present(&pf->hw))
++ if (ice_gnss_is_module_present(&pf->hw))
+ ice_set_feature_support(pf, ICE_F_GNSS);
+ break;
+ default:
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index ec91822e92806..53ce40fa2fe6b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -5315,68 +5315,6 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready)
+ * to access the extended GPIOs available.
+ */
+
+-/**
+- * ice_get_pca9575_handle
+- * @hw: pointer to the hw struct
+- * @pca9575_handle: GPIO controller's handle
+- *
+- * Find and return the GPIO controller's handle in the netlist.
+- * When found - the value will be cached in the hw structure and following calls
+- * will return cached value
+- */
+-static int
+-ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle)
+-{
+- struct ice_aqc_get_link_topo *cmd;
+- struct ice_aq_desc desc;
+- int status;
+- u8 idx;
+-
+- /* If handle was read previously return cached value */
+- if (hw->io_expander_handle) {
+- *pca9575_handle = hw->io_expander_handle;
+- return 0;
+- }
+-
+- /* If handle was not detected read it from the netlist */
+- cmd = &desc.params.get_link_topo;
+- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+-
+- /* Set node type to GPIO controller */
+- cmd->addr.topo_params.node_type_ctx =
+- (ICE_AQC_LINK_TOPO_NODE_TYPE_M &
+- ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
+-
+-#define SW_PCA9575_SFP_TOPO_IDX 2
+-#define SW_PCA9575_QSFP_TOPO_IDX 1
+-
+- /* Check if the SW IO expander controlling SMA exists in the netlist. */
+- if (hw->device_id == ICE_DEV_ID_E810C_SFP)
+- idx = SW_PCA9575_SFP_TOPO_IDX;
+- else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
+- idx = SW_PCA9575_QSFP_TOPO_IDX;
+- else
+- return -EOPNOTSUPP;
+-
+- cmd->addr.topo_params.index = idx;
+-
+- status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+- if (status)
+- return -EOPNOTSUPP;
+-
+- /* Verify if we found the right IO expander type */
+- if (desc.params.get_link_topo.node_part_num !=
+- ICE_AQC_GET_LINK_TOPO_NODE_NR_PCA9575)
+- return -EOPNOTSUPP;
+-
+- /* If present save the handle and return it */
+- hw->io_expander_handle =
+- le16_to_cpu(desc.params.get_link_topo.addr.handle);
+- *pca9575_handle = hw->io_expander_handle;
+-
+- return 0;
+-}
+-
+ /**
+ * ice_read_sma_ctrl
+ * @hw: pointer to the hw struct
+@@ -5441,37 +5379,6 @@ int ice_write_sma_ctrl(struct ice_hw *hw, u8 data)
+ return status;
+ }
+
+-/**
+- * ice_read_pca9575_reg
+- * @hw: pointer to the hw struct
+- * @offset: GPIO controller register offset
+- * @data: pointer to data to be read from the GPIO controller
+- *
+- * Read the register from the GPIO controller
+- */
+-int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
+-{
+- struct ice_aqc_link_topo_addr link_topo;
+- __le16 addr;
+- u16 handle;
+- int err;
+-
+- memset(&link_topo, 0, sizeof(link_topo));
+-
+- err = ice_get_pca9575_handle(hw, &handle);
+- if (err)
+- return err;
+-
+- link_topo.handle = cpu_to_le16(handle);
+- link_topo.topo_params.node_type_ctx =
+- FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M,
+- ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED);
+-
+- addr = cpu_to_le16((u16)offset);
+-
+- return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
+-}
+-
+ /**
+ * ice_ptp_read_sdp_ac - read SDP available connections section from NVM
+ * @hw: pointer to the HW struct
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+index 6779ce120515a..15f048d9b5823 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+@@ -395,7 +395,6 @@ int ice_phy_cfg_intr_e82x(struct ice_hw *hw, u8 quad, bool ena, u8 threshold);
+ /* E810 family functions */
+ int ice_read_sma_ctrl(struct ice_hw *hw, u8 *data);
+ int ice_write_sma_ctrl(struct ice_hw *hw, u8 data);
+-int ice_read_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data);
+ int ice_ptp_read_sdp_ac(struct ice_hw *hw, __le16 *entries, uint *num_entries);
+ int ice_cgu_get_num_pins(struct ice_hw *hw, bool input);
+ enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
+--
+2.39.5
+
--- /dev/null
+From 5d5ba6363a892c010e03f1798922fce2e8e95092 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:26:31 -0700
+Subject: ice: fix Get Tx Topology AQ command error on E830
+
+From: Paul Greenwalt <paul.greenwalt@intel.com>
+
+[ Upstream commit 3ffcd7b657c9d96eb3ffe174449b4248dd7fc6a9 ]
+
+The Get Tx Topology AQ command (opcode 0x0418) has different read flag
+requirements depending on the hardware/firmware. For E810, E822, and E823
+firmware the read flag must be set, and for newer hardware (E825 and E830)
+it must not be set.
+
+This results in failure to configure Tx topology and the following warning
+message during probe:
+
+ DDP package does not support Tx scheduling layers switching feature -
+ please update to the latest DDP package and try again
+
+The current implementation only handles E825-C but not E830. It is
+confusing as we first check ice_is_e825c() and then set the flag in the set
+case. Finally, we check ice_is_e825c() again and set the flag for all other
+hardware in both the set and get case.
+
+Instead, notice that we always need the read flag for set, but only need
+the read flag for get on E810, E822, and E823 firmware. Fix the logic to
+check the MAC type and set the read flag in get only on the older devices
+which require it.
+
+Fixes: ba1124f58afd ("ice: Add E830 device IDs, MAC type and registers")
+Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20250425222636.3188441-2-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ddp.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index 69d5b1a28491d..59323c019544f 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2345,15 +2345,15 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+ cmd->set_flags |= ICE_AQC_TX_TOPO_FLAGS_SRC_RAM |
+ ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW;
+
+- if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
+- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
++ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+ } else {
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_tx_topo);
+ cmd->get_flags = ICE_AQC_TX_TOPO_GET_RAM;
+- }
+
+- if (hw->mac_type != ICE_MAC_GENERIC_3K_E825)
+- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
++ if (hw->mac_type == ICE_MAC_E810 ||
++ hw->mac_type == ICE_MAC_GENERIC)
++ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
++ }
+
+ status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+ if (status)
+--
+2.39.5
+
--- /dev/null
+From 2e916bcc8e8690ea64bb59fc2c61e39416d4f85d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 14:12:39 +0200
+Subject: ice: Remove unnecessary ice_is_e8xx() functions
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit 9973ac9f23a79285d70365c72e98bffdb94a429d ]
+
+Remove unnecessary ice_is_e8xx() functions and PHY model. Instead, use
+MAC type where applicable.
+
+Don't check device type in ice_ptp_maybe_trigger_tx_interrupt(), because
+in reality it depends on the ready bitmap, which only E810 does not
+have.
+
+Call ice_ptp_cfg_phy_interrupt() unconditionally, because all further
+function calls check the MAC type anyway and this allows simpler code
+in the future with addition of the new MAC types.
+
+Reorder ICE_MAC_* cases in switches in ice_ptp* as in enum ice_mac_type.
+
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 3ffcd7b657c9 ("ice: fix Get Tx Topology AQ command error on E830")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 5 -
+ drivers/net/ethernet/intel/ice/ice_common.c | 118 +---------------
+ drivers/net/ethernet/intel/ice/ice_common.h | 5 -
+ drivers/net/ethernet/intel/ice/ice_ddp.c | 4 +-
+ drivers/net/ethernet/intel/ice/ice_ptp.c | 133 +++++++++---------
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 142 ++++++++++----------
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 10 +-
+ drivers/net/ethernet/intel/ice/ice_type.h | 9 --
+ 8 files changed, 147 insertions(+), 279 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
+index 71e05d30f0fda..d7b90a77bb49a 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -1047,10 +1047,5 @@ static inline void ice_clear_rdma_cap(struct ice_pf *pf)
+ clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
+ }
+
+-static inline enum ice_phy_model ice_get_phy_model(const struct ice_hw *hw)
+-{
+- return hw->ptp.phy_model;
+-}
+-
+ extern const struct xdp_metadata_ops ice_xdp_md_ops;
+ #endif /* _ICE_H_ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
+index f48cb93e10183..59df31c2c83f7 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.c
++++ b/drivers/net/ethernet/intel/ice/ice_common.c
+@@ -186,7 +186,7 @@ static int ice_set_mac_type(struct ice_hw *hw)
+ * ice_is_generic_mac - check if device's mac_type is generic
+ * @hw: pointer to the hardware structure
+ *
+- * Return: true if mac_type is generic (with SBQ support), false if not
++ * Return: true if mac_type is ICE_MAC_GENERIC*, false otherwise.
+ */
+ bool ice_is_generic_mac(struct ice_hw *hw)
+ {
+@@ -194,120 +194,6 @@ bool ice_is_generic_mac(struct ice_hw *hw)
+ hw->mac_type == ICE_MAC_GENERIC_3K_E825);
+ }
+
+-/**
+- * ice_is_e810
+- * @hw: pointer to the hardware structure
+- *
+- * returns true if the device is E810 based, false if not.
+- */
+-bool ice_is_e810(struct ice_hw *hw)
+-{
+- return hw->mac_type == ICE_MAC_E810;
+-}
+-
+-/**
+- * ice_is_e810t
+- * @hw: pointer to the hardware structure
+- *
+- * returns true if the device is E810T based, false if not.
+- */
+-bool ice_is_e810t(struct ice_hw *hw)
+-{
+- switch (hw->device_id) {
+- case ICE_DEV_ID_E810C_SFP:
+- switch (hw->subsystem_device_id) {
+- case ICE_SUBDEV_ID_E810T:
+- case ICE_SUBDEV_ID_E810T2:
+- case ICE_SUBDEV_ID_E810T3:
+- case ICE_SUBDEV_ID_E810T4:
+- case ICE_SUBDEV_ID_E810T6:
+- case ICE_SUBDEV_ID_E810T7:
+- return true;
+- }
+- break;
+- case ICE_DEV_ID_E810C_QSFP:
+- switch (hw->subsystem_device_id) {
+- case ICE_SUBDEV_ID_E810T2:
+- case ICE_SUBDEV_ID_E810T3:
+- case ICE_SUBDEV_ID_E810T5:
+- return true;
+- }
+- break;
+- default:
+- break;
+- }
+-
+- return false;
+-}
+-
+-/**
+- * ice_is_e822 - Check if a device is E822 family device
+- * @hw: pointer to the hardware structure
+- *
+- * Return: true if the device is E822 based, false if not.
+- */
+-bool ice_is_e822(struct ice_hw *hw)
+-{
+- switch (hw->device_id) {
+- case ICE_DEV_ID_E822C_BACKPLANE:
+- case ICE_DEV_ID_E822C_QSFP:
+- case ICE_DEV_ID_E822C_SFP:
+- case ICE_DEV_ID_E822C_10G_BASE_T:
+- case ICE_DEV_ID_E822C_SGMII:
+- case ICE_DEV_ID_E822L_BACKPLANE:
+- case ICE_DEV_ID_E822L_SFP:
+- case ICE_DEV_ID_E822L_10G_BASE_T:
+- case ICE_DEV_ID_E822L_SGMII:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+-/**
+- * ice_is_e823
+- * @hw: pointer to the hardware structure
+- *
+- * returns true if the device is E823-L or E823-C based, false if not.
+- */
+-bool ice_is_e823(struct ice_hw *hw)
+-{
+- switch (hw->device_id) {
+- case ICE_DEV_ID_E823L_BACKPLANE:
+- case ICE_DEV_ID_E823L_SFP:
+- case ICE_DEV_ID_E823L_10G_BASE_T:
+- case ICE_DEV_ID_E823L_1GBE:
+- case ICE_DEV_ID_E823L_QSFP:
+- case ICE_DEV_ID_E823C_BACKPLANE:
+- case ICE_DEV_ID_E823C_QSFP:
+- case ICE_DEV_ID_E823C_SFP:
+- case ICE_DEV_ID_E823C_10G_BASE_T:
+- case ICE_DEV_ID_E823C_SGMII:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+-/**
+- * ice_is_e825c - Check if a device is E825C family device
+- * @hw: pointer to the hardware structure
+- *
+- * Return: true if the device is E825-C based, false if not.
+- */
+-bool ice_is_e825c(struct ice_hw *hw)
+-{
+- switch (hw->device_id) {
+- case ICE_DEV_ID_E825C_BACKPLANE:
+- case ICE_DEV_ID_E825C_QSFP:
+- case ICE_DEV_ID_E825C_SFP:
+- case ICE_DEV_ID_E825C_SGMII:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+ /**
+ * ice_is_pf_c827 - check if pf contains c827 phy
+ * @hw: pointer to the hw struct
+@@ -2409,7 +2295,7 @@ ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
+ info->tmr_index_owned = ((number & ICE_TS_TMR_IDX_OWND_M) != 0);
+ info->tmr_index_assoc = ((number & ICE_TS_TMR_IDX_ASSOC_M) != 0);
+
+- if (!ice_is_e825c(hw)) {
++ if (hw->mac_type != ICE_MAC_GENERIC_3K_E825) {
+ info->clk_freq = FIELD_GET(ICE_TS_CLK_FREQ_M, number);
+ info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
+ } else {
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
+index 54a8692839dd0..9b00aa0ddf10e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.h
++++ b/drivers/net/ethernet/intel/ice/ice_common.h
+@@ -131,7 +131,6 @@ int
+ ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
+ struct ice_sq_cd *cd);
+ bool ice_is_generic_mac(struct ice_hw *hw);
+-bool ice_is_e810(struct ice_hw *hw);
+ int ice_clear_pf_cfg(struct ice_hw *hw);
+ int
+ ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
+@@ -276,10 +275,6 @@ ice_stat_update40(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
+ void
+ ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
+ u64 *prev_stat, u64 *cur_stat);
+-bool ice_is_e810t(struct ice_hw *hw);
+-bool ice_is_e822(struct ice_hw *hw);
+-bool ice_is_e823(struct ice_hw *hw);
+-bool ice_is_e825c(struct ice_hw *hw);
+ int
+ ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
+ struct ice_aqc_txsched_elem_data *buf);
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index 03988be03729b..69d5b1a28491d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2345,14 +2345,14 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+ cmd->set_flags |= ICE_AQC_TX_TOPO_FLAGS_SRC_RAM |
+ ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW;
+
+- if (ice_is_e825c(hw))
++ if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
+ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+ } else {
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_tx_topo);
+ cmd->get_flags = ICE_AQC_TX_TOPO_GET_RAM;
+ }
+
+- if (!ice_is_e825c(hw))
++ if (hw->mac_type != ICE_MAC_GENERIC_3K_E825)
+ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+
+ status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index a99e0fbd0b8b5..92ce419ff0bcb 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -1318,20 +1318,20 @@ ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port)
+ struct ice_hw *hw = &pf->hw;
+ int err;
+
+- if (ice_is_e810(hw))
+- return 0;
+-
+ mutex_lock(&ptp_port->ps_lock);
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- err = ice_stop_phy_timer_eth56g(hw, port, true);
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
++ err = 0;
+ break;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ kthread_cancel_delayed_work_sync(&ptp_port->ov_work);
+
+ err = ice_stop_phy_timer_e82x(hw, port, true);
+ break;
++ case ICE_MAC_GENERIC_3K_E825:
++ err = ice_stop_phy_timer_eth56g(hw, port, true);
++ break;
+ default:
+ err = -ENODEV;
+ }
+@@ -1361,19 +1361,16 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
+ unsigned long flags;
+ int err;
+
+- if (ice_is_e810(hw))
+- return 0;
+-
+ if (!ptp_port->link_up)
+ return ice_ptp_port_phy_stop(ptp_port);
+
+ mutex_lock(&ptp_port->ps_lock);
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- err = ice_start_phy_timer_eth56g(hw, port);
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
++ err = 0;
+ break;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ /* Start the PHY timer in Vernier mode */
+ kthread_cancel_delayed_work_sync(&ptp_port->ov_work);
+
+@@ -1398,6 +1395,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
+ kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work,
+ 0);
+ break;
++ case ICE_MAC_GENERIC_3K_E825:
++ err = ice_start_phy_timer_eth56g(hw, port);
++ break;
+ default:
+ err = -ENODEV;
+ }
+@@ -1432,12 +1432,13 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
+ /* Skip HW writes if reset is in progress */
+ if (pf->hw.reset_ongoing)
+ return;
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_E810:
++
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ /* Do not reconfigure E810 PHY */
+ return;
+- case ICE_PHY_ETH56G:
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
++ case ICE_MAC_GENERIC_3K_E825:
+ ice_ptp_port_phy_restart(ptp_port);
+ return;
+ default:
+@@ -1465,46 +1466,44 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
+
+ ice_ptp_reset_ts_memory(hw);
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G: {
+- int port;
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
++ return 0;
++ case ICE_MAC_GENERIC: {
++ int quad;
+
+- for (port = 0; port < hw->ptp.num_lports; port++) {
++ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports);
++ quad++) {
+ int err;
+
+- err = ice_phy_cfg_intr_eth56g(hw, port, ena, threshold);
++ err = ice_phy_cfg_intr_e82x(hw, quad, ena, threshold);
+ if (err) {
+- dev_err(dev, "Failed to configure PHY interrupt for port %d, err %d\n",
+- port, err);
++ dev_err(dev, "Failed to configure PHY interrupt for quad %d, err %d\n",
++ quad, err);
+ return err;
+ }
+ }
+
+ return 0;
+ }
+- case ICE_PHY_E82X: {
+- int quad;
++ case ICE_MAC_GENERIC_3K_E825: {
++ int port;
+
+- for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports);
+- quad++) {
++ for (port = 0; port < hw->ptp.num_lports; port++) {
+ int err;
+
+- err = ice_phy_cfg_intr_e82x(hw, quad, ena, threshold);
++ err = ice_phy_cfg_intr_eth56g(hw, port, ena, threshold);
+ if (err) {
+- dev_err(dev, "Failed to configure PHY interrupt for quad %d, err %d\n",
+- quad, err);
++ dev_err(dev, "Failed to configure PHY interrupt for port %d, err %d\n",
++ port, err);
+ return err;
+ }
+ }
+
+ return 0;
+ }
+- case ICE_PHY_E810:
+- return 0;
+- case ICE_PHY_UNSUP:
++ case ICE_MAC_UNKNOWN:
+ default:
+- dev_warn(dev, "%s: Unexpected PHY model %d\n", __func__,
+- ice_get_phy_model(hw));
+ return -EOPNOTSUPP;
+ }
+ }
+@@ -1740,7 +1739,7 @@ static int ice_ptp_write_perout(struct ice_hw *hw, unsigned int chan,
+ /* 0. Reset mode & out_en in AUX_OUT */
+ wr32(hw, GLTSYN_AUX_OUT(chan, tmr_idx), 0);
+
+- if (ice_is_e825c(hw)) {
++ if (hw->mac_type == ICE_MAC_GENERIC_3K_E825) {
+ int err;
+
+ /* Enable/disable CGU 1PPS output for E825C */
+@@ -1825,7 +1824,7 @@ static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq,
+ return ice_ptp_write_perout(hw, rq->index, gpio_pin, 0, 0);
+
+ if (strncmp(pf->ptp.pin_desc[pin_desc_idx].name, "1PPS", 64) == 0 &&
+- period != NSEC_PER_SEC && hw->ptp.phy_model == ICE_PHY_E82X) {
++ period != NSEC_PER_SEC && hw->mac_type == ICE_MAC_GENERIC) {
+ dev_err(ice_pf_to_dev(pf), "1PPS pin supports only 1 s period\n");
+ return -EOPNOTSUPP;
+ }
+@@ -2080,7 +2079,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
+ /* For Vernier mode on E82X, we need to recalibrate after new settime.
+ * Start with marking timestamps as invalid.
+ */
+- if (ice_get_phy_model(hw) == ICE_PHY_E82X) {
++ if (hw->mac_type == ICE_MAC_GENERIC) {
+ err = ice_ptp_clear_phy_offset_ready_e82x(hw);
+ if (err)
+ dev_warn(ice_pf_to_dev(pf), "Failed to mark timestamps as invalid before settime\n");
+@@ -2104,7 +2103,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
+ ice_ptp_enable_all_perout(pf);
+
+ /* Recalibrate and re-enable timestamp blocks for E822/E823 */
+- if (ice_get_phy_model(hw) == ICE_PHY_E82X)
++ if (hw->mac_type == ICE_MAC_GENERIC)
+ ice_ptp_restart_all_phy(pf);
+ exit:
+ if (err) {
+@@ -2558,7 +2557,7 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf)
+ pf->ptp.info.getcrosststamp = ice_ptp_getcrosststamp_e82x;
+
+ #endif /* CONFIG_ICE_HWTS */
+- if (ice_is_e825c(&pf->hw)) {
++ if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
+ pf->ptp.ice_pin_desc = ice_pin_desc_e825c;
+ pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e825c);
+ } else {
+@@ -2646,10 +2645,17 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
+ info->enable = ice_ptp_gpio_enable;
+ info->verify = ice_verify_pin;
+
+- if (ice_is_e810(&pf->hw))
++ switch (pf->hw.mac_type) {
++ case ICE_MAC_E810:
+ ice_ptp_set_funcs_e810(pf);
+- else
++ return;
++ case ICE_MAC_GENERIC:
++ case ICE_MAC_GENERIC_3K_E825:
+ ice_ptp_set_funcs_e82x(pf);
++ return;
++ default:
++ return;
++ }
+ }
+
+ /**
+@@ -2779,7 +2785,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
+ bool trigger_oicr = false;
+ unsigned int i;
+
+- if (ice_is_e810(hw))
++ if (!pf->ptp.port.tx.has_ready_bitmap)
+ return;
+
+ if (!ice_pf_src_tmr_owned(pf))
+@@ -2914,14 +2920,12 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
+ */
+ ice_ptp_flush_all_tx_tracker(pf);
+
+- if (!ice_is_e810(hw)) {
+- /* Enable quad interrupts */
+- err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
+- if (err)
+- return err;
++ /* Enable quad interrupts */
++ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
++ if (err)
++ return err;
+
+- ice_ptp_restart_all_phy(pf);
+- }
++ ice_ptp_restart_all_phy(pf);
+
+ /* Re-enable all periodic outputs and external timestamp events */
+ ice_ptp_enable_all_perout(pf);
+@@ -2973,8 +2977,9 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
+
+ static bool ice_is_primary(struct ice_hw *hw)
+ {
+- return ice_is_e825c(hw) && ice_is_dual(hw) ?
+- !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) : true;
++ return hw->mac_type == ICE_MAC_GENERIC_3K_E825 && ice_is_dual(hw) ?
++ !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) :
++ true;
+ }
+
+ static int ice_ptp_setup_adapter(struct ice_pf *pf)
+@@ -2992,7 +2997,7 @@ static int ice_ptp_setup_pf(struct ice_pf *pf)
+ struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf);
+ struct ice_ptp *ptp = &pf->ptp;
+
+- if (WARN_ON(!ctrl_ptp) || ice_get_phy_model(&pf->hw) == ICE_PHY_UNSUP)
++ if (WARN_ON(!ctrl_ptp) || pf->hw.mac_type == ICE_MAC_UNKNOWN)
+ return -ENODEV;
+
+ INIT_LIST_HEAD(&ptp->port.list_node);
+@@ -3009,7 +3014,7 @@ static void ice_ptp_cleanup_pf(struct ice_pf *pf)
+ {
+ struct ice_ptp *ptp = &pf->ptp;
+
+- if (ice_get_phy_model(&pf->hw) != ICE_PHY_UNSUP) {
++ if (pf->hw.mac_type != ICE_MAC_UNKNOWN) {
+ mutex_lock(&pf->adapter->ports.lock);
+ list_del(&ptp->port.list_node);
+ mutex_unlock(&pf->adapter->ports.lock);
+@@ -3136,18 +3141,18 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
+
+ mutex_init(&ptp_port->ps_lock);
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx,
+- ptp_port->port_num);
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ kthread_init_delayed_work(&ptp_port->ov_work,
+ ice_ptp_wait_for_offsets);
+
+ return ice_ptp_init_tx_e82x(pf, &ptp_port->tx,
+ ptp_port->port_num);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx,
++ ptp_port->port_num);
+ default:
+ return -ENODEV;
+ }
+@@ -3164,8 +3169,8 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
+ */
+ static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
+ {
+- switch (ice_get_phy_model(&pf->hw)) {
+- case ICE_PHY_E82X:
++ switch (pf->hw.mac_type) {
++ case ICE_MAC_GENERIC:
+ /* E822 based PHY has the clock owner process the interrupt
+ * for all ports.
+ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index 53ce40fa2fe6b..8475d422f1ec4 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -746,7 +746,7 @@ static int ice_init_cgu_e82x(struct ice_hw *hw)
+ int err;
+
+ /* Disable sticky lock detection so lock err reported is accurate */
+- if (ice_is_e825c(hw))
++ if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
+ err = ice_cfg_cgu_pll_dis_sticky_bits_e825c(hw);
+ else
+ err = ice_cfg_cgu_pll_dis_sticky_bits_e82x(hw);
+@@ -756,7 +756,7 @@ static int ice_init_cgu_e82x(struct ice_hw *hw)
+ /* Configure the CGU PLL using the parameters from the function
+ * capabilities.
+ */
+- if (ice_is_e825c(hw))
++ if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
+ err = ice_cfg_cgu_pll_e825c(hw, ts_info->time_ref,
+ (enum ice_clk_src)ts_info->clk_src);
+ else
+@@ -827,8 +827,8 @@ static u32 ice_ptp_tmr_cmd_to_port_reg(struct ice_hw *hw,
+ /* Certain hardware families share the same register values for the
+ * port register and source timer register.
+ */
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_ptp_tmr_cmd_to_src_reg(hw, cmd) & TS_CMD_MASK_E810;
+ default:
+ break;
+@@ -2729,10 +2729,7 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw)
+ {
+ struct ice_ptp_hw *ptp = &hw->ptp;
+ struct ice_eth56g_params *params;
+- u32 phy_rev;
+- int err;
+
+- ptp->phy_model = ICE_PHY_ETH56G;
+ params = &ptp->phy.eth56g;
+ params->onestep_ena = false;
+ params->peer_delay = 0;
+@@ -2742,9 +2739,6 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw)
+ ptp->num_lports = params->num_phys * ptp->ports_per_phy;
+
+ ice_sb_access_ena_eth56g(hw, true);
+- err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev);
+- if (err || phy_rev != PHY_REVISION_ETH56G)
+- ptp->phy_model = ICE_PHY_UNSUP;
+ }
+
+ /* E822 family functions
+@@ -4792,7 +4786,6 @@ int ice_phy_cfg_intr_e82x(struct ice_hw *hw, u8 quad, bool ena, u8 threshold)
+ */
+ static void ice_ptp_init_phy_e82x(struct ice_ptp_hw *ptp)
+ {
+- ptp->phy_model = ICE_PHY_E82X;
+ ptp->num_lports = 8;
+ ptp->ports_per_phy = 8;
+ }
+@@ -5445,7 +5438,6 @@ int ice_ptp_read_sdp_ac(struct ice_hw *hw, __le16 *entries, uint *num_entries)
+ */
+ static void ice_ptp_init_phy_e810(struct ice_ptp_hw *ptp)
+ {
+- ptp->phy_model = ICE_PHY_E810;
+ ptp->num_lports = 8;
+ ptp->ports_per_phy = 4;
+
+@@ -5454,9 +5446,8 @@ static void ice_ptp_init_phy_e810(struct ice_ptp_hw *ptp)
+
+ /* Device agnostic functions
+ *
+- * The following functions implement shared behavior common to both E822 and
+- * E810 devices, possibly calling a device specific implementation where
+- * necessary.
++ * The following functions implement shared behavior common to all devices,
++ * possibly calling a device specific implementation where necessary.
+ */
+
+ /**
+@@ -5519,14 +5510,19 @@ void ice_ptp_init_hw(struct ice_hw *hw)
+ {
+ struct ice_ptp_hw *ptp = &hw->ptp;
+
+- if (ice_is_e822(hw) || ice_is_e823(hw))
+- ice_ptp_init_phy_e82x(ptp);
+- else if (ice_is_e810(hw))
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ ice_ptp_init_phy_e810(ptp);
+- else if (ice_is_e825c(hw))
++ break;
++ case ICE_MAC_GENERIC:
++ ice_ptp_init_phy_e82x(ptp);
++ break;
++ case ICE_MAC_GENERIC_3K_E825:
+ ice_ptp_init_phy_e825(hw);
+- else
+- ptp->phy_model = ICE_PHY_UNSUP;
++ break;
++ default:
++ return;
++ }
+ }
+
+ /**
+@@ -5547,11 +5543,11 @@ void ice_ptp_init_hw(struct ice_hw *hw)
+ static int ice_ptp_write_port_cmd(struct ice_hw *hw, u8 port,
+ enum ice_ptp_tmr_cmd cmd)
+ {
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_ptp_write_port_cmd_eth56g(hw, port, cmd);
+- case ICE_PHY_E82X:
++ switch (hw->mac_type) {
++ case ICE_MAC_GENERIC:
+ return ice_ptp_write_port_cmd_e82x(hw, port, cmd);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_ptp_write_port_cmd_eth56g(hw, port, cmd);
+ default:
+ return -EOPNOTSUPP;
+ }
+@@ -5612,8 +5608,8 @@ static int ice_ptp_port_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
+ u32 port;
+
+ /* PHY models which can program all ports simultaneously */
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_ptp_port_cmd_e810(hw, cmd);
+ default:
+ break;
+@@ -5691,17 +5687,17 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
+
+ /* PHY timers */
+ /* Fill Rx and Tx ports and send msg to PHY */
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- err = ice_ptp_prep_phy_time_eth56g(hw,
+- (u32)(time & 0xFFFFFFFF));
+- break;
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
+ break;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ err = ice_ptp_prep_phy_time_e82x(hw, time & 0xFFFFFFFF);
+ break;
++ case ICE_MAC_GENERIC_3K_E825:
++ err = ice_ptp_prep_phy_time_eth56g(hw,
++ (u32)(time & 0xFFFFFFFF));
++ break;
+ default:
+ err = -EOPNOTSUPP;
+ }
+@@ -5737,16 +5733,16 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
+ wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
+ wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- err = ice_ptp_prep_phy_incval_eth56g(hw, incval);
+- break;
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ err = ice_ptp_prep_phy_incval_e810(hw, incval);
+ break;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ err = ice_ptp_prep_phy_incval_e82x(hw, incval);
+ break;
++ case ICE_MAC_GENERIC_3K_E825:
++ err = ice_ptp_prep_phy_incval_eth56g(hw, incval);
++ break;
+ default:
+ err = -EOPNOTSUPP;
+ }
+@@ -5806,16 +5802,16 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
+ wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
+ wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- err = ice_ptp_prep_phy_adj_eth56g(hw, adj);
+- break;
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ err = ice_ptp_prep_phy_adj_e810(hw, adj);
+ break;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ err = ice_ptp_prep_phy_adj_e82x(hw, adj);
+ break;
++ case ICE_MAC_GENERIC_3K_E825:
++ err = ice_ptp_prep_phy_adj_eth56g(hw, adj);
++ break;
+ default:
+ err = -EOPNOTSUPP;
+ }
+@@ -5839,13 +5835,13 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
+ */
+ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
+ {
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_read_ptp_tstamp_eth56g(hw, block, idx, tstamp);
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ return ice_read_phy_tstamp_e82x(hw, block, idx, tstamp);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_read_ptp_tstamp_eth56g(hw, block, idx, tstamp);
+ default:
+ return -EOPNOTSUPP;
+ }
+@@ -5869,13 +5865,13 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
+ */
+ int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
+ {
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_clear_ptp_tstamp_eth56g(hw, block, idx);
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_clear_phy_tstamp_e810(hw, block, idx);
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ return ice_clear_phy_tstamp_e82x(hw, block, idx);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_clear_ptp_tstamp_eth56g(hw, block, idx);
+ default:
+ return -EOPNOTSUPP;
+ }
+@@ -5932,14 +5928,14 @@ static int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
+ */
+ void ice_ptp_reset_ts_memory(struct ice_hw *hw)
+ {
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- ice_ptp_reset_ts_memory_eth56g(hw);
+- break;
+- case ICE_PHY_E82X:
++ switch (hw->mac_type) {
++ case ICE_MAC_GENERIC:
+ ice_ptp_reset_ts_memory_e82x(hw);
+ break;
+- case ICE_PHY_E810:
++ case ICE_MAC_GENERIC_3K_E825:
++ ice_ptp_reset_ts_memory_eth56g(hw);
++ break;
++ case ICE_MAC_E810:
+ default:
+ return;
+ }
+@@ -5961,13 +5957,13 @@ int ice_ptp_init_phc(struct ice_hw *hw)
+ /* Clear event err indications for auxiliary pins */
+ (void)rd32(hw, GLTSYN_STAT(src_idx));
+
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_ptp_init_phc_eth56g(hw);
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_ptp_init_phc_e810(hw);
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ return ice_ptp_init_phc_e82x(hw);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_ptp_init_phc_eth56g(hw);
+ default:
+ return -EOPNOTSUPP;
+ }
+@@ -5986,16 +5982,16 @@ int ice_ptp_init_phc(struct ice_hw *hw)
+ */
+ int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
+ {
+- switch (ice_get_phy_model(hw)) {
+- case ICE_PHY_ETH56G:
+- return ice_get_phy_tx_tstamp_ready_eth56g(hw, block,
+- tstamp_ready);
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ice_get_phy_tx_tstamp_ready_e810(hw, block,
+ tstamp_ready);
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ return ice_get_phy_tx_tstamp_ready_e82x(hw, block,
+ tstamp_ready);
++ case ICE_MAC_GENERIC_3K_E825:
++ return ice_get_phy_tx_tstamp_ready_eth56g(hw, block,
++ tstamp_ready);
+ break;
+ default:
+ return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+index 15f048d9b5823..6b46794075584 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+@@ -430,13 +430,13 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port);
+ */
+ static inline u64 ice_get_base_incval(struct ice_hw *hw)
+ {
+- switch (hw->ptp.phy_model) {
+- case ICE_PHY_ETH56G:
+- return ICE_ETH56G_NOMINAL_INCVAL;
+- case ICE_PHY_E810:
++ switch (hw->mac_type) {
++ case ICE_MAC_E810:
+ return ICE_PTP_NOMINAL_INCVAL_E810;
+- case ICE_PHY_E82X:
++ case ICE_MAC_GENERIC:
+ return ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
++ case ICE_MAC_GENERIC_3K_E825:
++ return ICE_ETH56G_NOMINAL_INCVAL;
+ default:
+ return 0;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
+index 33a1a5934c0d5..0aab21113cc43 100644
+--- a/drivers/net/ethernet/intel/ice/ice_type.h
++++ b/drivers/net/ethernet/intel/ice/ice_type.h
+@@ -871,14 +871,6 @@ union ice_phy_params {
+ struct ice_eth56g_params eth56g;
+ };
+
+-/* PHY model */
+-enum ice_phy_model {
+- ICE_PHY_UNSUP = -1,
+- ICE_PHY_E810 = 1,
+- ICE_PHY_E82X,
+- ICE_PHY_ETH56G,
+-};
+-
+ /* Global Link Topology */
+ enum ice_global_link_topo {
+ ICE_LINK_TOPO_UP_TO_2_LINKS,
+@@ -888,7 +880,6 @@ enum ice_global_link_topo {
+ };
+
+ struct ice_ptp_hw {
+- enum ice_phy_model phy_model;
+ union ice_phy_params phy;
+ u8 num_lports;
+ u8 ports_per_phy;
+--
+2.39.5
+
--- /dev/null
+From 72b8ef5b0b8d95bf3b05c36fd9d3f1b7cc8e856a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:26:33 -0700
+Subject: idpf: fix offloads support for encapsulated packets
+
+From: Madhu Chittim <madhu.chittim@intel.com>
+
+[ Upstream commit 713dd6c2deca88cba0596b1e2576f7b7a8e5c59e ]
+
+Split offloads into csum, tso and other offloads so that tunneled
+packets do not by default have all the offloads enabled.
+
+Stateless offloads for encapsulated packets are not yet supported in
+firmware/software but in the driver we were setting the features same as
+non encapsulated features.
+
+Fixed naming to clarify CSUM bits are being checked for Tx.
+
+Inherit netdev features to VLAN interfaces as well.
+
+Fixes: 0fe45467a104 ("idpf: add create vport and netdev configuration")
+Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
+Signed-off-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Zachary Goldstein <zachmgoldstein@google.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250425222636.3188441-4-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf.h | 18 +++----
+ drivers/net/ethernet/intel/idpf/idpf_lib.c | 57 ++++++++--------------
+ 2 files changed, 27 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h
+index 66544faab710a..aef0e9775a330 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf.h
++++ b/drivers/net/ethernet/intel/idpf/idpf.h
+@@ -629,13 +629,13 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all,
+ VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 |\
+ VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6)
+
+-#define IDPF_CAP_RX_CSUM_L4V4 (\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP)
++#define IDPF_CAP_TX_CSUM_L4V4 (\
++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |\
++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP)
+
+-#define IDPF_CAP_RX_CSUM_L4V6 (\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP)
++#define IDPF_CAP_TX_CSUM_L4V6 (\
++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |\
++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP)
+
+ #define IDPF_CAP_RX_CSUM (\
+ VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |\
+@@ -644,11 +644,9 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all,
+ VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\
+ VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP)
+
+-#define IDPF_CAP_SCTP_CSUM (\
++#define IDPF_CAP_TX_SCTP_CSUM (\
+ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |\
+- VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |\
+- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP)
++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP)
+
+ #define IDPF_CAP_TUNNEL_TX_CSUM (\
+ VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL |\
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+index a055a47449f12..78951d62f6171 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+@@ -703,8 +703,10 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
+ {
+ struct idpf_adapter *adapter = vport->adapter;
+ struct idpf_vport_config *vport_config;
++ netdev_features_t other_offloads = 0;
++ netdev_features_t csum_offloads = 0;
++ netdev_features_t tso_offloads = 0;
+ netdev_features_t dflt_features;
+- netdev_features_t offloads = 0;
+ struct idpf_netdev_priv *np;
+ struct net_device *netdev;
+ u16 idx = vport->idx;
+@@ -766,53 +768,32 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
+
+ if (idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS))
+ dflt_features |= NETIF_F_RXHASH;
+- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V4))
+- dflt_features |= NETIF_F_IP_CSUM;
+- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V6))
+- dflt_features |= NETIF_F_IPV6_CSUM;
++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V4))
++ csum_offloads |= NETIF_F_IP_CSUM;
++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V6))
++ csum_offloads |= NETIF_F_IPV6_CSUM;
+ if (idpf_is_cap_ena(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM))
+- dflt_features |= NETIF_F_RXCSUM;
+- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_SCTP_CSUM))
+- dflt_features |= NETIF_F_SCTP_CRC;
++ csum_offloads |= NETIF_F_RXCSUM;
++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_SCTP_CSUM))
++ csum_offloads |= NETIF_F_SCTP_CRC;
+
+ if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV4_TCP))
+- dflt_features |= NETIF_F_TSO;
++ tso_offloads |= NETIF_F_TSO;
+ if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV6_TCP))
+- dflt_features |= NETIF_F_TSO6;
++ tso_offloads |= NETIF_F_TSO6;
+ if (idpf_is_cap_ena_all(adapter, IDPF_SEG_CAPS,
+ VIRTCHNL2_CAP_SEG_IPV4_UDP |
+ VIRTCHNL2_CAP_SEG_IPV6_UDP))
+- dflt_features |= NETIF_F_GSO_UDP_L4;
++ tso_offloads |= NETIF_F_GSO_UDP_L4;
+ if (idpf_is_cap_ena_all(adapter, IDPF_RSC_CAPS, IDPF_CAP_RSC))
+- offloads |= NETIF_F_GRO_HW;
+- /* advertise to stack only if offloads for encapsulated packets is
+- * supported
+- */
+- if (idpf_is_cap_ena(vport->adapter, IDPF_SEG_CAPS,
+- VIRTCHNL2_CAP_SEG_TX_SINGLE_TUNNEL)) {
+- offloads |= NETIF_F_GSO_UDP_TUNNEL |
+- NETIF_F_GSO_GRE |
+- NETIF_F_GSO_GRE_CSUM |
+- NETIF_F_GSO_PARTIAL |
+- NETIF_F_GSO_UDP_TUNNEL_CSUM |
+- NETIF_F_GSO_IPXIP4 |
+- NETIF_F_GSO_IPXIP6 |
+- 0;
+-
+- if (!idpf_is_cap_ena_all(vport->adapter, IDPF_CSUM_CAPS,
+- IDPF_CAP_TUNNEL_TX_CSUM))
+- netdev->gso_partial_features |=
+- NETIF_F_GSO_UDP_TUNNEL_CSUM;
+-
+- netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+- offloads |= NETIF_F_TSO_MANGLEID;
+- }
++ other_offloads |= NETIF_F_GRO_HW;
+ if (idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_LOOPBACK))
+- offloads |= NETIF_F_LOOPBACK;
++ other_offloads |= NETIF_F_LOOPBACK;
+
+- netdev->features |= dflt_features;
+- netdev->hw_features |= dflt_features | offloads;
+- netdev->hw_enc_features |= dflt_features | offloads;
++ netdev->features |= dflt_features | csum_offloads | tso_offloads;
++ netdev->hw_features |= netdev->features | other_offloads;
++ netdev->vlan_features |= netdev->features | other_offloads;
++ netdev->hw_enc_features |= dflt_features | other_offloads;
+ idpf_set_ethtool_ops(netdev);
+ SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
+
+--
+2.39.5
+
--- /dev/null
+From 34143c28f6adb9d2877335733fbf70bb8b7f694e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:54:21 +0200
+Subject: idpf: fix potential memory leak on kcalloc() failure
+
+From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+
+[ Upstream commit 8a558cbda51bef09773c72bf74a32047479110c7 ]
+
+In case of failing on rss_data->rss_key allocation the function is
+freeing vport without freeing earlier allocated q_vector_idxs. Fix it.
+
+Move from freeing in error branch to goto scheme.
+
+Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport")
+Reviewed-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Suggested-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com>
+Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_lib.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+index 78951d62f6171..6e8a82dae1628 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+@@ -1112,11 +1112,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
+
+ num_max_q = max(max_q->max_txq, max_q->max_rxq);
+ vport->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL);
+- if (!vport->q_vector_idxs) {
+- kfree(vport);
++ if (!vport->q_vector_idxs)
++ goto free_vport;
+
+- return NULL;
+- }
+ idpf_vport_init(vport, max_q);
+
+ /* This alloc is done separate from the LUT because it's not strictly
+@@ -1126,11 +1124,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
+ */
+ rss_data = &adapter->vport_config[idx]->user_config.rss_data;
+ rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL);
+- if (!rss_data->rss_key) {
+- kfree(vport);
++ if (!rss_data->rss_key)
++ goto free_vector_idxs;
+
+- return NULL;
+- }
+ /* Initialize default rss key */
+ netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size);
+
+@@ -1143,6 +1139,13 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
+ adapter->next_vport = idpf_get_free_slot(adapter);
+
+ return vport;
++
++free_vector_idxs:
++ kfree(vport->q_vector_idxs);
++free_vport:
++ kfree(vport);
++
++ return NULL;
+ }
+
+ /**
+--
+2.39.5
+
--- /dev/null
+From 25072abc2a265c4c159c43e5db4dadded9fe73b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 13:52:23 +0200
+Subject: idpf: protect shutdown from reset
+
+From: Larysa Zaremba <larysa.zaremba@intel.com>
+
+[ Upstream commit ed375b182140eeb9c73609b17939c8a29b27489e ]
+
+Before the referenced commit, the shutdown just called idpf_remove(),
+this way IDPF_REMOVE_IN_PROG was protecting us from the serv_task
+rescheduling reset. Without this flag set the shutdown process is
+vulnerable to HW reset or any other triggering conditions (such as
+default mailbox being destroyed).
+
+When one of conditions checked in idpf_service_task becomes true,
+vc_event_task can be rescheduled during shutdown, this leads to accessing
+freed memory e.g. idpf_req_rel_vector_indexes() trying to read
+vport->q_vector_idxs. This in turn causes the system to become defunct
+during e.g. systemctl kexec.
+
+Considering using IDPF_REMOVE_IN_PROG would lead to more heavy shutdown
+process, instead just cancel the serv_task before cancelling
+adapter->serv_task before cancelling adapter->vc_event_task to ensure that
+reset will not be scheduled while we are doing a shutdown.
+
+Fixes: 4c9106f4906a ("idpf: fix adapter NULL pointer dereference on reboot")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
+index bec4a02c53733..b35713036a54a 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
+@@ -89,6 +89,7 @@ static void idpf_shutdown(struct pci_dev *pdev)
+ {
+ struct idpf_adapter *adapter = pci_get_drvdata(pdev);
+
++ cancel_delayed_work_sync(&adapter->serv_task);
+ cancel_delayed_work_sync(&adapter->vc_event_task);
+ idpf_vc_core_deinit(adapter);
+ idpf_deinit_dflt_mbx(adapter);
+--
+2.39.5
+
--- /dev/null
+From bbb039939389d8527686eb5fd4e5b4e054219826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 14:03:09 -0700
+Subject: igc: fix lock order in igc_ptp_reset
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit c7d6cb96d5c33b5148f3dc76fcd30a9b8cd9e973 ]
+
+Commit 1a931c4f5e68 ("igc: add lock preventing multiple simultaneous PTM
+transactions") added a new mutex to protect concurrent PTM transactions.
+This lock is acquired in igc_ptp_reset() in order to ensure the PTM
+registers are properly disabled after a device reset.
+
+The flow where the lock is acquired already holds a spinlock, so acquiring
+a mutex leads to a sleep-while-locking bug, reported both by smatch,
+and the kernel test robot.
+
+The critical section in igc_ptp_reset() does correctly use the
+readx_poll_timeout_atomic variants, but the standard PTM flow uses regular
+sleeping variants. This makes converting the mutex to a spinlock a bit
+tricky.
+
+Instead, re-order the locking in igc_ptp_reset. Acquire the mutex first,
+and then the tmreg_lock spinlock. This is safe because there is no other
+ordering dependency on these locks, as this is the only place where both
+locks were acquired simultaneously. Indeed, any other flow acquiring locks
+in that order would be wrong regardless.
+
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Fixes: 1a931c4f5e68 ("igc: add lock preventing multiple simultaneous PTM transactions")
+Link: https://lore.kernel.org/intel-wired-lan/Z_-P-Hc1yxcw0lTB@stanley.mountain/
+Link: https://lore.kernel.org/intel-wired-lan/202504211511.f7738f5d-lkp@intel.com/T/#u
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Vitaly Lifshits <vitaly.lifshits@intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index 612ed26a29c5d..efc7b30e42113 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -1290,6 +1290,8 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ /* reset the tstamp_config */
+ igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
+
++ mutex_lock(&adapter->ptm_lock);
++
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+
+ switch (adapter->hw.mac.type) {
+@@ -1308,7 +1310,6 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ if (!igc_is_crosststamp_supported(adapter))
+ break;
+
+- mutex_lock(&adapter->ptm_lock);
+ wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
+ wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
+
+@@ -1332,7 +1333,6 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
+
+ igc_ptm_reset(hw);
+- mutex_unlock(&adapter->ptm_lock);
+ break;
+ default:
+ /* No work to do. */
+@@ -1349,5 +1349,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ out:
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
++ mutex_unlock(&adapter->ptm_lock);
++
+ wrfl();
+ }
+--
+2.39.5
+
--- /dev/null
+From 66d2a4ec484e4aaefb1824a7f0353ee0e3521ddc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:03:51 +0530
+Subject: iommu/arm-smmu-v3: Add missing S2FWB feature detection
+
+From: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
+
+[ Upstream commit 45e00e36718902d81bdaebb37b3a8244e685bc48 ]
+
+Commit 67e4fe398513 ("iommu/arm-smmu-v3: Use S2FWB for NESTED domains")
+introduced S2FWB usage but omitted the corresponding feature detection.
+As a result, vIOMMU allocation fails on FVP in arm_vsmmu_alloc(), due to
+the following check:
+
+ if (!arm_smmu_master_canwbs(master) &&
+ !(smmu->features & ARM_SMMU_FEAT_S2FWB))
+ return ERR_PTR(-EOPNOTSUPP);
+
+This patch adds the missing detection logic to prevent allocation
+failure when S2FWB is supported.
+
+Fixes: 67e4fe398513 ("iommu/arm-smmu-v3: Use S2FWB for NESTED domains")
+Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Pranjal Shrivastava <praan@google.com>
+Link: https://lore.kernel.org/r/20250408033351.1012411-1-aneesh.kumar@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index ae803c64ae1ee..e495334d1c43a 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -4416,6 +4416,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
+ reg = readl_relaxed(smmu->base + ARM_SMMU_IDR3);
+ if (FIELD_GET(IDR3_RIL, reg))
+ smmu->features |= ARM_SMMU_FEAT_RANGE_INV;
++ if (FIELD_GET(IDR3_FWB, reg))
++ smmu->features |= ARM_SMMU_FEAT_S2FWB;
+
+ /* IDR5 */
+ reg = readl_relaxed(smmu->base + ARM_SMMU_IDR5);
+--
+2.39.5
+
--- /dev/null
+From 69678f5136fd772fc5541520aea289f8caf9fb83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 16:50:47 +0100
+Subject: net: dlink: Correct endianness handling of led_mode
+
+From: Simon Horman <horms@kernel.org>
+
+[ Upstream commit e7e5ae71831c44d58627a991e603845a2fed2cab ]
+
+As it's name suggests, parse_eeprom() parses EEPROM data.
+
+This is done by reading data, 16 bits at a time as follows:
+
+ for (i = 0; i < 128; i++)
+ ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom(np, i));
+
+sromdata is at the same memory location as psrom.
+And the type of psrom is a pointer to struct t_SROM.
+
+As can be seen in the loop above, data is stored in sromdata, and thus psrom,
+as 16-bit little-endian values.
+
+However, the integer fields of t_SROM are host byte order integers.
+And in the case of led_mode this leads to a little endian value
+being incorrectly treated as host byte order.
+
+Looking at rio_set_led_mode, this does appear to be a bug as that code
+masks led_mode with 0x1, 0x2 and 0x8. Logic that would be effected by a
+reversed byte order.
+
+This problem would only manifest on big endian hosts.
+
+Found by inspection while investigating a sparse warning
+regarding the crc field of t_SROM.
+
+I believe that warning is a false positive. And although I plan
+to send a follow-up to use little-endian types for other the integer
+fields of PSROM_t I do not believe that will involve any bug fixes.
+
+Compile tested only.
+
+Fixes: c3f45d322cbd ("dl2k: Add support for IP1000A-based cards")
+Signed-off-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250425-dlink-led-mode-v1-1-6bae3c36e736@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ drivers/net/ethernet/dlink/dl2k.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index d0ea926078706..6bf8a7aeef908 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -352,7 +352,7 @@ parse_eeprom (struct net_device *dev)
+ eth_hw_addr_set(dev, psrom->mac_addr);
+
+ if (np->chip_id == CHIP_IP1000A) {
+- np->led_mode = psrom->led_mode;
++ np->led_mode = le16_to_cpu(psrom->led_mode);
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h
+index 195dc6cfd8955..0e33e2eaae960 100644
+--- a/drivers/net/ethernet/dlink/dl2k.h
++++ b/drivers/net/ethernet/dlink/dl2k.h
+@@ -335,7 +335,7 @@ typedef struct t_SROM {
+ u16 sub_system_id; /* 0x06 */
+ u16 pci_base_1; /* 0x08 (IP1000A only) */
+ u16 pci_base_2; /* 0x0a (IP1000A only) */
+- u16 led_mode; /* 0x0c (IP1000A only) */
++ __le16 led_mode; /* 0x0c (IP1000A only) */
+ u16 reserved1[9]; /* 0x0e-0x1f */
+ u8 mac_addr[6]; /* 0x20-0x25 */
+ u8 reserved2[10]; /* 0x26-0x2f */
+--
+2.39.5
+
--- /dev/null
+From 248ad2ccb90f183043538b65ef1dd1c2a20712e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Apr 2025 17:48:55 +0300
+Subject: net: dsa: felix: fix broken taprio gate states after clock jump
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 426d487bca38b34f39c483edfc6313a036446b33 ]
+
+Simplest setup to reproduce the issue: connect 2 ports of the
+LS1028A-RDB together (eno0 with swp0) and run:
+
+$ ip link set eno0 up && ip link set swp0 up
+$ tc qdisc replace dev swp0 parent root handle 100 taprio num_tc 8 \
+ queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 map 0 1 2 3 4 5 6 7 \
+ base-time 0 sched-entry S 20 300000 sched-entry S 10 200000 \
+ sched-entry S 20 300000 sched-entry S 48 200000 \
+ sched-entry S 20 300000 sched-entry S 83 200000 \
+ sched-entry S 40 300000 sched-entry S 00 200000 flags 2
+$ ptp4l -i eno0 -f /etc/linuxptp/configs/gPTP.cfg -m &
+$ ptp4l -i swp0 -f /etc/linuxptp/configs/gPTP.cfg -m
+
+One will observe that the PTP state machine on swp0 starts
+synchronizing, then it attempts to do a clock step, and after that, it
+never fails to recover from the condition below.
+
+ptp4l[82.427]: selected best master clock 00049f.fffe.05f627
+ptp4l[82.428]: port 1 (swp0): MASTER to UNCALIBRATED on RS_SLAVE
+ptp4l[83.252]: port 1 (swp0): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
+ptp4l[83.886]: rms 4537731277 max 9075462553 freq -18518 +/- 11467 delay 818 +/- 0
+ptp4l[84.170]: timed out while polling for tx timestamp
+ptp4l[84.171]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it
+ptp4l[84.172]: port 1 (swp0): send peer delay request failed
+ptp4l[84.173]: port 1 (swp0): clearing fault immediately
+ptp4l[84.269]: port 1 (swp0): SLAVE to LISTENING on INIT_COMPLETE
+ptp4l[85.303]: timed out while polling for tx timestamp
+ptp4l[84.171]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it
+ptp4l[84.172]: port 1 (swp0): send peer delay request failed
+ptp4l[84.173]: port 1 (swp0): clearing fault immediately
+ptp4l[84.269]: port 1 (swp0): SLAVE to LISTENING on INIT_COMPLETE
+ptp4l[85.303]: timed out while polling for tx timestamp
+ptp4l[85.304]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it
+ptp4l[85.305]: port 1 (swp0): send peer delay response failed
+ptp4l[85.306]: port 1 (swp0): clearing fault immediately
+ptp4l[86.304]: timed out while polling for tx timestamp
+
+A hint is given by the non-zero statistics for dropped packets which
+were expecting hardware TX timestamps:
+
+$ ethtool --include-statistics -T swp0
+(...)
+Statistics:
+ tx_pkts: 30
+ tx_lost: 11
+ tx_err: 0
+
+We know that when PTP clock stepping takes place (from ocelot_ptp_settime64()
+or from ocelot_ptp_adjtime()), vsc9959_tas_clock_adjust() is called.
+
+Another interesting hint is that placing an early return in
+vsc9959_tas_clock_adjust(), so as to neutralize this function, fixes the
+issue and TX timestamps are no longer dropped.
+
+The debugging function written by me and included below is intended to
+read the GCL RAM, after the admin schedule became operational, through
+the two status registers available for this purpose:
+QSYS_GCL_STATUS_REG_1 and QSYS_GCL_STATUS_REG_2.
+
+static void vsc9959_print_tas_gcl(struct ocelot *ocelot)
+{
+ u32 val, list_length, interval, gate_state;
+ int i, err;
+
+ err = read_poll_timeout(ocelot_read, val,
+ !(val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING),
+ 10, 100000, false, ocelot, QSYS_PARAM_STATUS_REG_8);
+ if (err) {
+ dev_err(ocelot->dev,
+ "Failed to wait for TAS config pending bit to clear: %pe\n",
+ ERR_PTR(err));
+ return;
+ }
+
+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_3);
+ list_length = QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(val);
+
+ dev_info(ocelot->dev, "GCL length: %u\n", list_length);
+
+ for (i = 0; i < list_length; i++) {
+ ocelot_rmw(ocelot,
+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(i),
+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M,
+ QSYS_GCL_STATUS_REG_1);
+ interval = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_2);
+ val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_1);
+ gate_state = QSYS_GCL_STATUS_REG_1_GATE_STATE_X(val);
+
+ dev_info(ocelot->dev, "GCL entry %d: states 0x%x interval %u\n",
+ i, gate_state, interval);
+ }
+}
+
+Calling it from two places: after the initial QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE
+performed by vsc9959_qos_port_tas_set(), and after the one done by
+vsc9959_tas_clock_adjust(), I notice the following difference.
+
+From the tc-taprio process context, where the schedule was initially
+configured, the GCL looks like this:
+
+mscc_felix 0000:00:00.5: GCL length: 8
+mscc_felix 0000:00:00.5: GCL entry 0: states 0x20 interval 300000
+mscc_felix 0000:00:00.5: GCL entry 1: states 0x10 interval 200000
+mscc_felix 0000:00:00.5: GCL entry 2: states 0x20 interval 300000
+mscc_felix 0000:00:00.5: GCL entry 3: states 0x48 interval 200000
+mscc_felix 0000:00:00.5: GCL entry 4: states 0x20 interval 300000
+mscc_felix 0000:00:00.5: GCL entry 5: states 0x83 interval 200000
+mscc_felix 0000:00:00.5: GCL entry 6: states 0x40 interval 300000
+mscc_felix 0000:00:00.5: GCL entry 7: states 0x0 interval 200000
+
+But from the ptp4l clock stepping process context, when the
+vsc9959_tas_clock_adjust() hook is called, the GCL RAM of the
+operational schedule now looks like this:
+
+mscc_felix 0000:00:00.5: GCL length: 8
+mscc_felix 0000:00:00.5: GCL entry 0: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 1: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 2: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 3: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 4: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 5: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 6: states 0x0 interval 0
+mscc_felix 0000:00:00.5: GCL entry 7: states 0x0 interval 0
+
+I do not have a formal explanation, just experimental conclusions.
+It appears that after triggering QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE
+for a port's TAS, the GCL entry RAM is updated anyway, despite what the
+documentation claims: "Specify the time interval in
+QSYS::GCL_CFG_REG_2.TIME_INTERVAL. This triggers the actual RAM
+write with the gate state and the time interval for the entry number
+specified". We don't touch that register (through vsc9959_tas_gcl_set())
+from vsc9959_tas_clock_adjust(), yet the GCL RAM is updated anyway.
+
+It seems to be updated with effectively stale memory, which in my
+testing can hold a variety of things, including even pieces of the
+previously applied schedule, for particular schedule lengths.
+
+As such, in most circumstances it is very difficult to pinpoint this
+issue, because the newly updated schedule would "behave strangely",
+but ultimately might still pass traffic to some extent, due to some
+gate entries still being present in the stale GCL entry RAM. It is easy
+to miss.
+
+With the particular schedule given at the beginning, the GCL RAM
+"happens" to be reproducibly rewritten with all zeroes, and this is
+consistent with what we see: when the time-aware shaper has gate entries
+with all gates closed, traffic is dropped on TX, no wonder we can't
+retrieve TX timestamps.
+
+Rewriting the GCL entry RAM when reapplying the new base time fixes the
+observed issue.
+
+Fixes: 8670dc33f48b ("net: dsa: felix: update base time of time-aware shaper when adjusting PTP time")
+Reported-by: Richie Pearn <richard.pearn@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250426144859.3128352-2-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 940f1b71226d6..7b35d24c38d76 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1543,7 +1543,7 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
+ struct tc_taprio_qopt_offload *taprio;
+ struct ocelot_port *ocelot_port;
+ struct timespec64 base_ts;
+- int port;
++ int i, port;
+ u32 val;
+
+ mutex_lock(&ocelot->fwd_domain_lock);
+@@ -1575,6 +1575,9 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
+ QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M,
+ QSYS_PARAM_CFG_REG_3);
+
++ for (i = 0; i < taprio->num_entries; i++)
++ vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]);
++
+ ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
+ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
+ QSYS_TAS_PARAM_CFG_CTRL);
+--
+2.39.5
+
--- /dev/null
+From 7f58f134b6596083f09c2a8f8eeb1db0dc4ce722 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 10:38:48 +0200
+Subject: net: ethernet: mtk-star-emac: fix spinlock recursion issues on rx/tx
+ poll
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit 6fe0866014486736cc3ba1c6fd4606d3dbe55c9c ]
+
+Use spin_lock_irqsave and spin_unlock_irqrestore instead of spin_lock
+and spin_unlock in mtk_star_emac driver to avoid spinlock recursion
+occurrence that can happen when enabling the DMA interrupts again in
+rx/tx poll.
+
+```
+BUG: spinlock recursion on CPU#0, swapper/0/0
+ lock: 0xffff00000db9cf20, .magic: dead4ead, .owner: swapper/0/0,
+ .owner_cpu: 0
+CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted
+ 6.15.0-rc2-next-20250417-00001-gf6a27738686c-dirty #28 PREEMPT
+Hardware name: MediaTek MT8365 Open Platform EVK (DT)
+Call trace:
+ show_stack+0x18/0x24 (C)
+ dump_stack_lvl+0x60/0x80
+ dump_stack+0x18/0x24
+ spin_dump+0x78/0x88
+ do_raw_spin_lock+0x11c/0x120
+ _raw_spin_lock+0x20/0x2c
+ mtk_star_handle_irq+0xc0/0x22c [mtk_star_emac]
+ __handle_irq_event_percpu+0x48/0x140
+ handle_irq_event+0x4c/0xb0
+ handle_fasteoi_irq+0xa0/0x1bc
+ handle_irq_desc+0x34/0x58
+ generic_handle_domain_irq+0x1c/0x28
+ gic_handle_irq+0x4c/0x120
+ do_interrupt_handler+0x50/0x84
+ el1_interrupt+0x34/0x68
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x6c/0x70
+ regmap_mmio_read32le+0xc/0x20 (P)
+ _regmap_bus_reg_read+0x6c/0xac
+ _regmap_read+0x60/0xdc
+ regmap_read+0x4c/0x80
+ mtk_star_rx_poll+0x2f4/0x39c [mtk_star_emac]
+ __napi_poll+0x38/0x188
+ net_rx_action+0x164/0x2c0
+ handle_softirqs+0x100/0x244
+ __do_softirq+0x14/0x20
+ ____do_softirq+0x10/0x20
+ call_on_irq_stack+0x24/0x64
+ do_softirq_own_stack+0x1c/0x40
+ __irq_exit_rcu+0xd4/0x10c
+ irq_exit_rcu+0x10/0x1c
+ el1_interrupt+0x38/0x68
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x6c/0x70
+ cpuidle_enter_state+0xac/0x320 (P)
+ cpuidle_enter+0x38/0x50
+ do_idle+0x1e4/0x260
+ cpu_startup_entry+0x34/0x3c
+ rest_init+0xdc/0xe0
+ console_on_rootfs+0x0/0x6c
+ __primary_switched+0x88/0x90
+```
+
+Fixes: 0a8bd81fd6aa ("net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-1-f3fde2e529d8@collabora.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_star_emac.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+index 25989c79c92e6..47a00e02365a2 100644
+--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+@@ -1163,6 +1163,7 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
+ struct net_device *ndev = priv->ndev;
+ unsigned int head = ring->head;
+ unsigned int entry = ring->tail;
++ unsigned long flags;
+
+ while (entry != head && count < (MTK_STAR_RING_NUM_DESCS - 1)) {
+ ret = mtk_star_tx_complete_one(priv);
+@@ -1182,9 +1183,9 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
+ netif_wake_queue(ndev);
+
+ if (napi_complete(napi)) {
+- spin_lock(&priv->lock);
++ spin_lock_irqsave(&priv->lock, flags);
+ mtk_star_enable_dma_irq(priv, false, true);
+- spin_unlock(&priv->lock);
++ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ return 0;
+@@ -1341,6 +1342,7 @@ static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
+ static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
+ {
+ struct mtk_star_priv *priv;
++ unsigned long flags;
+ int work_done = 0;
+
+ priv = container_of(napi, struct mtk_star_priv, rx_napi);
+@@ -1348,9 +1350,9 @@ static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
+ work_done = mtk_star_rx(priv, budget);
+ if (work_done < budget) {
+ napi_complete_done(napi, work_done);
+- spin_lock(&priv->lock);
++ spin_lock_irqsave(&priv->lock, flags);
+ mtk_star_enable_dma_irq(priv, true, false);
+- spin_unlock(&priv->lock);
++ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ return work_done;
+--
+2.39.5
+
--- /dev/null
+From 5430987a07af832d90d0457c330ffd87c8461bdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 10:38:49 +0200
+Subject: net: ethernet: mtk-star-emac: rearm interrupts in rx_poll only when
+ advised
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit e54b4db35e201a9173da9cb7abc8377e12abaf87 ]
+
+In mtk_star_rx_poll function, on event processing completion, the
+mtk_star_emac driver calls napi_complete_done but ignores its return
+code and enable RX DMA interrupts inconditionally. This return code
+gives the info if a device should avoid rearming its interrupts or not,
+so fix this behaviour by taking it into account.
+
+Fixes: 8c7bd5a454ff ("net: ethernet: mtk-star-emac: new driver")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-2-f3fde2e529d8@collabora.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_star_emac.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+index 47a00e02365a2..c2ab87828d858 100644
+--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+@@ -1348,8 +1348,7 @@ static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
+ priv = container_of(napi, struct mtk_star_priv, rx_napi);
+
+ work_done = mtk_star_rx(priv, budget);
+- if (work_done < budget) {
+- napi_complete_done(napi, work_done);
++ if (work_done < budget && napi_complete_done(napi, work_done)) {
+ spin_lock_irqsave(&priv->lock, flags);
+ mtk_star_enable_dma_irq(priv, true, false);
+ spin_unlock_irqrestore(&priv->lock, flags);
+--
+2.39.5
+
--- /dev/null
+From 99560dea4a00660bdccb58ce7743d6bd865971ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Apr 2025 02:05:44 +0100
+Subject: net: ethernet: mtk_eth_soc: fix SER panic with 4GB+ RAM
+
+From: Chad Monroe <chad@monroe.io>
+
+[ Upstream commit 6e0490fc36cdac696f96e57b61d93b9ae32e0f4c ]
+
+If the mtk_poll_rx() function detects the MTK_RESETTING flag, it will
+jump to release_desc and refill the high word of the SDP on the 4GB RFB.
+Subsequently, mtk_rx_clean will process an incorrect SDP, leading to a
+panic.
+
+Add patch from MediaTek's SDK to resolve this.
+
+Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988")
+Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/71f47ea785699c6aa3b922d66c2bdc1a43da25b1
+Signed-off-by: Chad Monroe <chad@monroe.io>
+Link: https://patch.msgid.link/4adc2aaeb0fb1b9cdc56bf21cf8e7fa328daa345.1745715843.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 1365888a4be11..c6d60f1d4f77a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2202,14 +2202,18 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+ ring->data[idx] = new_data;
+ rxd->rxd1 = (unsigned int)dma_addr;
+ release_desc:
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
++ if (unlikely(dma_addr == DMA_MAPPING_ERROR))
++ addr64 = FIELD_GET(RX_DMA_ADDR64_MASK,
++ rxd->rxd2);
++ else
++ addr64 = RX_DMA_PREP_ADDR64(dma_addr);
++ }
++
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+ rxd->rxd2 = RX_DMA_LSO;
+ else
+- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
+-
+- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) &&
+- likely(dma_addr != DMA_MAPPING_ERROR))
+- rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
++ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size) | addr64;
+
+ ring->calc_idx = idx;
+ done++;
+--
+2.39.5
+
--- /dev/null
+From 9448ddbf4402fda9482c1eddc887eb3bdc01a5b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 05:29:53 +0100
+Subject: net: ethernet: mtk_eth_soc: sync mtk_clks_source_name array
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 8c47d5753a119f1c986bc3ed92e9178d2624e1e8 ]
+
+When removing the clock bits for clocks which aren't used by the
+Ethernet driver their names should also have been removed from the
+mtk_clks_source_name array.
+
+Remove them now as enum mtk_clks_map needs to match the
+mtk_clks_source_name array so the driver can make sure that all required
+clocks are present and correctly name missing clocks.
+
+Fixes: 887b1d1adb2e ("net: ethernet: mtk_eth_soc: drop clocks unused by Ethernet driver")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/d075e706ff1cebc07f9ec666736d0b32782fd487.1745555321.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 477b8732b8609..1365888a4be11 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -269,12 +269,8 @@ static const char * const mtk_clks_source_name[] = {
+ "ethwarp_wocpu2",
+ "ethwarp_wocpu1",
+ "ethwarp_wocpu0",
+- "top_usxgmii0_sel",
+- "top_usxgmii1_sel",
+ "top_sgm0_sel",
+ "top_sgm1_sel",
+- "top_xfi_phy0_xtal_sel",
+- "top_xfi_phy1_xtal_sel",
+ "top_eth_gmii_sel",
+ "top_eth_refck_50m_sel",
+ "top_eth_sys_200m_sel",
+--
+2.39.5
+
--- /dev/null
+From 70223680bd99cf287fc161b25c456c53ef6848e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 11:08:26 +0200
+Subject: net: fec: ERR007885 Workaround for conventional TX
+
+From: Mattias Barthel <mattias.barthel@atlascopco.com>
+
+[ Upstream commit a179aad12badc43201cbf45d1e8ed2c1383c76b9 ]
+
+Activate TX hang workaround also in
+fec_enet_txq_submit_skb() when TSO is not enabled.
+
+Errata: ERR007885
+
+Symptoms: NETDEV WATCHDOG: eth0 (fec): transmit queue 0 timed out
+
+commit 37d6017b84f7 ("net: fec: Workaround for imx6sx enet tx hang when enable three queues")
+There is a TDAR race condition for mutliQ when the software sets TDAR
+and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
+This will cause the udma_tx and udma_tx_arbiter state machines to hang.
+
+So, the Workaround is checking TDAR status four time, if TDAR cleared by
+ hardware and then write TDAR, otherwise don't set TDAR.
+
+Fixes: 53bb20d1faba ("net: fec: add variable reg_desc_active to speed things up")
+Signed-off-by: Mattias Barthel <mattias.barthel@atlascopco.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250429090826.3101258-1-mattiasbarthel@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index f7c4ce8e9a265..c5d5fa8d7dfdd 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -714,7 +714,12 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+ txq->bd.cur = bdp;
+
+ /* Trigger transmission start */
+- writel(0, txq->bd.reg_desc_active);
++ if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
++ !readl(txq->bd.reg_desc_active) ||
++ !readl(txq->bd.reg_desc_active) ||
++ !readl(txq->bd.reg_desc_active) ||
++ !readl(txq->bd.reg_desc_active))
++ writel(0, txq->bd.reg_desc_active);
+
+ return 0;
+ }
+--
+2.39.5
+
--- /dev/null
+From 86671667bce25753224e8efcadad7206f4c020aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 17:30:52 +0800
+Subject: net: hns3: defer calling ptp_clock_register()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 4971394d9d624f91689d766f31ce668d169d9959 ]
+
+Currently the ptp_clock_register() is called before relative
+ptp resource ready. It may cause unexpected result when upper
+layer called the ptp API during the timewindow. Fix it by
+moving the ptp_clock_register() to the function end.
+
+Fixes: 0bf5eb788512 ("net: hns3: add support for PTP")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20250430093052.2400464-5-shaojijie@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+index 181af419b878d..0ffda5146bae5 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+@@ -439,6 +439,13 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
+ ptp->info.settime64 = hclge_ptp_settime;
+
+ ptp->info.n_alarm = 0;
++
++ spin_lock_init(&ptp->lock);
++ ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
++ ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
++ ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
++ hdev->ptp = ptp;
++
+ ptp->clock = ptp_clock_register(&ptp->info, &hdev->pdev->dev);
+ if (IS_ERR(ptp->clock)) {
+ dev_err(&hdev->pdev->dev,
+@@ -450,12 +457,6 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
+ return -ENODEV;
+ }
+
+- spin_lock_init(&ptp->lock);
+- ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
+- ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+- ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
+- hdev->ptp = ptp;
+-
+ return 0;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 48b1c58cd6c0baa3d901ca2d2f43899b2026bae4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 17:30:50 +0800
+Subject: net: hns3: fix an interrupt residual problem
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit 8e6b9c6ea5a55045eed6526d8ee49e93192d1a58 ]
+
+When a VF is passthrough to a VM, and the VM is killed, the reported
+interrupt may not been handled, it will remain, and won't be clear by
+the nic engine even with a flr or tqp reset. When the VM restart, the
+interrupt of the first vector may be dropped by the second enable_irq
+in vfio, see the issue below:
+https://gitlab.com/qemu-project/qemu/-/issues/2884#note_2423361621
+
+We notice that the vfio has always behaved this way, and the interrupt
+is a residue of the nic engine, so we fix the problem by moving the
+vector enable process out of the enable_irq loop.
+
+Fixes: 08a100689d4b ("net: hns3: re-organize vector handle")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Link: https://patch.msgid.link/20250430093052.2400464-3-shaojijie@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3_enet.c | 82 +++++++++----------
+ 1 file changed, 39 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 9ff797fb36c45..b03b8758c7774 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -473,20 +473,14 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector,
+ writel(mask_en, tqp_vector->mask_addr);
+ }
+
+-static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector)
++static void hns3_irq_enable(struct hns3_enet_tqp_vector *tqp_vector)
+ {
+ napi_enable(&tqp_vector->napi);
+ enable_irq(tqp_vector->vector_irq);
+-
+- /* enable vector */
+- hns3_mask_vector_irq(tqp_vector, 1);
+ }
+
+-static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector)
++static void hns3_irq_disable(struct hns3_enet_tqp_vector *tqp_vector)
+ {
+- /* disable vector */
+- hns3_mask_vector_irq(tqp_vector, 0);
+-
+ disable_irq(tqp_vector->vector_irq);
+ napi_disable(&tqp_vector->napi);
+ cancel_work_sync(&tqp_vector->rx_group.dim.work);
+@@ -707,11 +701,42 @@ static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
+ return 0;
+ }
+
++static void hns3_enable_irqs_and_tqps(struct net_device *netdev)
++{
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
++ struct hnae3_handle *h = priv->ae_handle;
++ u16 i;
++
++ for (i = 0; i < priv->vector_num; i++)
++ hns3_irq_enable(&priv->tqp_vector[i]);
++
++ for (i = 0; i < priv->vector_num; i++)
++ hns3_mask_vector_irq(&priv->tqp_vector[i], 1);
++
++ for (i = 0; i < h->kinfo.num_tqps; i++)
++ hns3_tqp_enable(h->kinfo.tqp[i]);
++}
++
++static void hns3_disable_irqs_and_tqps(struct net_device *netdev)
++{
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
++ struct hnae3_handle *h = priv->ae_handle;
++ u16 i;
++
++ for (i = 0; i < h->kinfo.num_tqps; i++)
++ hns3_tqp_disable(h->kinfo.tqp[i]);
++
++ for (i = 0; i < priv->vector_num; i++)
++ hns3_mask_vector_irq(&priv->tqp_vector[i], 0);
++
++ for (i = 0; i < priv->vector_num; i++)
++ hns3_irq_disable(&priv->tqp_vector[i]);
++}
++
+ static int hns3_nic_net_up(struct net_device *netdev)
+ {
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
+ struct hnae3_handle *h = priv->ae_handle;
+- int i, j;
+ int ret;
+
+ ret = hns3_nic_reset_all_ring(h);
+@@ -720,23 +745,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
+
+ clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
+
+- /* enable the vectors */
+- for (i = 0; i < priv->vector_num; i++)
+- hns3_vector_enable(&priv->tqp_vector[i]);
+-
+- /* enable rcb */
+- for (j = 0; j < h->kinfo.num_tqps; j++)
+- hns3_tqp_enable(h->kinfo.tqp[j]);
++ hns3_enable_irqs_and_tqps(netdev);
+
+ /* start the ae_dev */
+ ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0;
+ if (ret) {
+ set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
+- while (j--)
+- hns3_tqp_disable(h->kinfo.tqp[j]);
+-
+- for (j = i - 1; j >= 0; j--)
+- hns3_vector_disable(&priv->tqp_vector[j]);
++ hns3_disable_irqs_and_tqps(netdev);
+ }
+
+ return ret;
+@@ -823,17 +838,9 @@ static void hns3_reset_tx_queue(struct hnae3_handle *h)
+ static void hns3_nic_net_down(struct net_device *netdev)
+ {
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
+- struct hnae3_handle *h = hns3_get_handle(netdev);
+ const struct hnae3_ae_ops *ops;
+- int i;
+
+- /* disable vectors */
+- for (i = 0; i < priv->vector_num; i++)
+- hns3_vector_disable(&priv->tqp_vector[i]);
+-
+- /* disable rcb */
+- for (i = 0; i < h->kinfo.num_tqps; i++)
+- hns3_tqp_disable(h->kinfo.tqp[i]);
++ hns3_disable_irqs_and_tqps(netdev);
+
+ /* stop ae_dev */
+ ops = priv->ae_handle->ae_algo->ops;
+@@ -5864,8 +5871,6 @@ int hns3_set_channels(struct net_device *netdev,
+ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
+ {
+ struct hns3_nic_priv *priv = netdev_priv(ndev);
+- struct hnae3_handle *h = priv->ae_handle;
+- int i;
+
+ if (!if_running)
+ return;
+@@ -5876,11 +5881,7 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
+ netif_carrier_off(ndev);
+ netif_tx_disable(ndev);
+
+- for (i = 0; i < priv->vector_num; i++)
+- hns3_vector_disable(&priv->tqp_vector[i]);
+-
+- for (i = 0; i < h->kinfo.num_tqps; i++)
+- hns3_tqp_disable(h->kinfo.tqp[i]);
++ hns3_disable_irqs_and_tqps(ndev);
+
+ /* delay ring buffer clearing to hns3_reset_notify_uninit_enet
+ * during reset process, because driver may not be able
+@@ -5896,7 +5897,6 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
+ {
+ struct hns3_nic_priv *priv = netdev_priv(ndev);
+ struct hnae3_handle *h = priv->ae_handle;
+- int i;
+
+ if (!if_running)
+ return;
+@@ -5912,11 +5912,7 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
+
+ clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
+
+- for (i = 0; i < priv->vector_num; i++)
+- hns3_vector_enable(&priv->tqp_vector[i]);
+-
+- for (i = 0; i < h->kinfo.num_tqps; i++)
+- hns3_tqp_enable(h->kinfo.tqp[i]);
++ hns3_enable_irqs_and_tqps(ndev);
+
+ netif_tx_wake_all_queues(ndev);
+
+--
+2.39.5
+
--- /dev/null
+From e65e62d85225cc0a71c3cd053ddfa9a45e3dedf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 17:30:51 +0800
+Subject: net: hns3: fixed debugfs tm_qset size
+
+From: Hao Lan <lanhao@huawei.com>
+
+[ Upstream commit e317aebeefcb3b0c71f2305af3c22871ca6b3833 ]
+
+The size of the tm_qset file of debugfs is limited to 64 KB,
+which is too small in the scenario with 1280 qsets.
+The size needs to be expanded to 1 MB.
+
+Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process")
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Peiyang Wang <wangpeiyang1@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Link: https://patch.msgid.link/20250430093052.2400464-4-shaojijie@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+index 9bbece25552b1..3d70c97a0bedf 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+@@ -60,7 +60,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
+ .name = "tm_qset",
+ .cmd = HNAE3_DBG_CMD_TM_QSET,
+ .dentry = HNS3_DBG_DENTRY_TM,
+- .buf_len = HNS3_DBG_READ_LEN,
++ .buf_len = HNS3_DBG_READ_LEN_1MB,
+ .init = hns3_dbg_common_file_init,
+ },
+ {
+--
+2.39.5
+
--- /dev/null
+From d8b03508d25b62a9c802cf7b9bad2e3aa61b222e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 17:30:49 +0800
+Subject: net: hns3: store rx VLAN tag offload state for VF
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit ef2383d078edcbe3055032436b16cdf206f26de2 ]
+
+The VF driver missed to store the rx VLAN tag strip state when
+user change the rx VLAN tag offload state. And it will default
+to enable the rx vlan tag strip when re-init VF device after
+reset. So if user disable rx VLAN tag offload, and trig reset,
+then the HW will still strip the VLAN tag from packet nad fill
+into RX BD, but the VF driver will ignore it for rx VLAN tag
+offload disabled. It may cause the rx VLAN tag dropped.
+
+Fixes: b2641e2ad456 ("net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250430093052.2400464-2-shaojijie@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++++-----
+ .../hisilicon/hns3/hns3vf/hclgevf_main.h | 1 +
+ 2 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 9ba767740a043..dada42e7e0ec9 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -1292,9 +1292,8 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev)
+ rtnl_unlock();
+ }
+
+-static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
++static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable)
+ {
+- struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+ struct hclge_vf_to_pf_msg send_msg;
+
+ hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
+@@ -1303,6 +1302,19 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
+ return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
+ }
+
++static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
++{
++ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
++ int ret;
++
++ ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable);
++ if (ret)
++ return ret;
++
++ hdev->rxvtag_strip_en = enable;
++ return 0;
++}
++
+ static int hclgevf_reset_tqp(struct hnae3_handle *handle)
+ {
+ #define HCLGEVF_RESET_ALL_QUEUE_DONE 1U
+@@ -2204,12 +2216,13 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev)
+ tc_valid, tc_size);
+ }
+
+-static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev)
++static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev,
++ bool rxvtag_strip_en)
+ {
+ struct hnae3_handle *nic = &hdev->nic;
+ int ret;
+
+- ret = hclgevf_en_hw_strip_rxvtag(nic, true);
++ ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "failed to enable rx vlan offload, ret = %d\n", ret);
+@@ -2879,7 +2892,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
+ if (ret)
+ return ret;
+
+- ret = hclgevf_init_vlan_config(hdev);
++ ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "failed(%d) to initialize VLAN config\n", ret);
+@@ -2994,7 +3007,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
+ goto err_config;
+ }
+
+- ret = hclgevf_init_vlan_config(hdev);
++ ret = hclgevf_init_vlan_config(hdev, true);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "failed(%d) to initialize VLAN config\n", ret);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+index cccef32284616..0208425ab594f 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+@@ -253,6 +253,7 @@ struct hclgevf_dev {
+ int *vector_irq;
+
+ bool gro_en;
++ bool rxvtag_strip_en;
+
+ unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
+
+--
+2.39.5
+
--- /dev/null
+From ac5a870d2ed2fc7e4c20eebfd3ad63f580d92f70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Apr 2025 17:32:09 +0200
+Subject: net: ipv6: fix UDPv6 GSO segmentation with NAT
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit b936a9b8d4a585ccb6d454921c36286bfe63e01d ]
+
+If any address or port is changed, update it in all packets and recalculate
+checksum.
+
+Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250426153210.14044-1-nbd@nbd.name
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp_offload.c | 61 +++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 60 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index ecfca59f31f13..da5d4aea1b591 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -247,6 +247,62 @@ static struct sk_buff *__udpv4_gso_segment_list_csum(struct sk_buff *segs)
+ return segs;
+ }
+
++static void __udpv6_gso_segment_csum(struct sk_buff *seg,
++ struct in6_addr *oldip,
++ const struct in6_addr *newip,
++ __be16 *oldport, __be16 newport)
++{
++ struct udphdr *uh = udp_hdr(seg);
++
++ if (ipv6_addr_equal(oldip, newip) && *oldport == newport)
++ return;
++
++ if (uh->check) {
++ inet_proto_csum_replace16(&uh->check, seg, oldip->s6_addr32,
++ newip->s6_addr32, true);
++
++ inet_proto_csum_replace2(&uh->check, seg, *oldport, newport,
++ false);
++ if (!uh->check)
++ uh->check = CSUM_MANGLED_0;
++ }
++
++ *oldip = *newip;
++ *oldport = newport;
++}
++
++static struct sk_buff *__udpv6_gso_segment_list_csum(struct sk_buff *segs)
++{
++ const struct ipv6hdr *iph;
++ const struct udphdr *uh;
++ struct ipv6hdr *iph2;
++ struct sk_buff *seg;
++ struct udphdr *uh2;
++
++ seg = segs;
++ uh = udp_hdr(seg);
++ iph = ipv6_hdr(seg);
++ uh2 = udp_hdr(seg->next);
++ iph2 = ipv6_hdr(seg->next);
++
++ if (!(*(const u32 *)&uh->source ^ *(const u32 *)&uh2->source) &&
++ ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
++ ipv6_addr_equal(&iph->daddr, &iph2->daddr))
++ return segs;
++
++ while ((seg = seg->next)) {
++ uh2 = udp_hdr(seg);
++ iph2 = ipv6_hdr(seg);
++
++ __udpv6_gso_segment_csum(seg, &iph2->saddr, &iph->saddr,
++ &uh2->source, uh->source);
++ __udpv6_gso_segment_csum(seg, &iph2->daddr, &iph->daddr,
++ &uh2->dest, uh->dest);
++ }
++
++ return segs;
++}
++
+ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb,
+ netdev_features_t features,
+ bool is_ipv6)
+@@ -259,7 +315,10 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb,
+
+ udp_hdr(skb)->len = htons(sizeof(struct udphdr) + mss);
+
+- return is_ipv6 ? skb : __udpv4_gso_segment_list_csum(skb);
++ if (is_ipv6)
++ return __udpv6_gso_segment_list_csum(skb);
++ else
++ return __udpv4_gso_segment_list_csum(skb);
+ }
+
+ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
+--
+2.39.5
+
--- /dev/null
+From 29716197a57ceba541f52fa39f72f36e7320a9fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 10:55:27 +0530
+Subject: net: lan743x: Fix memleak issue when GSO enabled
+
+From: Thangaraj Samynathan <thangaraj.s@microchip.com>
+
+[ Upstream commit 2d52e2e38b85c8b7bc00dca55c2499f46f8c8198 ]
+
+Always map the `skb` to the LS descriptor. Previously skb was
+mapped to EXT descriptor when the number of fragments is zero with
+GSO enabled. Mapping the skb to EXT descriptor prevents it from
+being freed, leading to a memory leak
+
+Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
+Signed-off-by: Thangaraj Samynathan <thangaraj.s@microchip.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250429052527.10031-1-thangaraj.s@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_main.c | 8 ++++++--
+ drivers/net/ethernet/microchip/lan743x_main.h | 1 +
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
+index 23760b613d3ec..e2d6bfb5d6933 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -1815,6 +1815,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
+ if (nr_frags <= 0) {
+ tx->frame_data0 |= TX_DESC_DATA0_LS_;
+ tx->frame_data0 |= TX_DESC_DATA0_IOC_;
++ tx->frame_last = tx->frame_first;
+ }
+ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
+ tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
+@@ -1884,6 +1885,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
+ tx->frame_first = 0;
+ tx->frame_data0 = 0;
+ tx->frame_tail = 0;
++ tx->frame_last = 0;
+ return -ENOMEM;
+ }
+
+@@ -1924,16 +1926,18 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx,
+ TX_DESC_DATA0_DTYPE_DATA_) {
+ tx->frame_data0 |= TX_DESC_DATA0_LS_;
+ tx->frame_data0 |= TX_DESC_DATA0_IOC_;
++ tx->frame_last = tx->frame_tail;
+ }
+
+- tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
+- buffer_info = &tx->buffer_info[tx->frame_tail];
++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_last];
++ buffer_info = &tx->buffer_info[tx->frame_last];
+ buffer_info->skb = skb;
+ if (time_stamp)
+ buffer_info->flags |= TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED;
+ if (ignore_sync)
+ buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
+
++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
+ tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
+ tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
+ tx->last_tail = tx->frame_tail;
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
+index 7f73d66854bee..db5fc73e41cca 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.h
++++ b/drivers/net/ethernet/microchip/lan743x_main.h
+@@ -980,6 +980,7 @@ struct lan743x_tx {
+ u32 frame_first;
+ u32 frame_data0;
+ u32 frame_tail;
++ u32 frame_last;
+
+ struct lan743x_tx_buffer_info *buffer_info;
+
+--
+2.39.5
+
--- /dev/null
+From c1f2948a6e1d60ccf4b5f55d958cb9c735ec0666 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:20:09 -0400
+Subject: net: mdio: mux-meson-gxl: set reversed bit when using internal phy
+
+From: Da Xue <da@libre.computer>
+
+[ Upstream commit b23285e93bef729e67519a5209d5b7fde3b4af50 ]
+
+This bit is necessary to receive packets from the internal PHY.
+Without this bit set, no activity occurs on the interface.
+
+Normally u-boot sets this bit, but if u-boot is compiled without
+net support, the interface will be up but without any activity.
+If bit is set once, it will work until the IP is powered down or reset.
+
+The vendor SDK sets this bit along with the PHY_ID bits.
+
+Signed-off-by: Da Xue <da@libre.computer>
+Fixes: 9a24e1ff4326 ("net: mdio: add amlogic gxl mdio mux support")
+Link: https://patch.msgid.link/20250425192009.1439508-1-da@libre.computer
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mdio/mdio-mux-meson-gxl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c
+index 00c66240136b1..3dd12a8c8b03e 100644
+--- a/drivers/net/mdio/mdio-mux-meson-gxl.c
++++ b/drivers/net/mdio/mdio-mux-meson-gxl.c
+@@ -17,6 +17,7 @@
+ #define REG2_LEDACT GENMASK(23, 22)
+ #define REG2_LEDLINK GENMASK(25, 24)
+ #define REG2_DIV4SEL BIT(27)
++#define REG2_REVERSED BIT(28)
+ #define REG2_ADCBYPASS BIT(30)
+ #define REG2_CLKINSEL BIT(31)
+ #define ETH_REG3 0x4
+@@ -65,7 +66,7 @@ static void gxl_enable_internal_mdio(struct gxl_mdio_mux *priv)
+ * The only constraint is that it must match the one in
+ * drivers/net/phy/meson-gxl.c to properly match the PHY.
+ */
+- writel(FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
++ writel(REG2_REVERSED | FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
+ priv->regs + ETH_REG2);
+
+ /* Enable the internal phy */
+--
+2.39.5
+
--- /dev/null
+From d2b596ed8eb492afa7ebbf05c189e0eb40571bfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:36:11 +0300
+Subject: net/mlx5: E-switch, Fix error handling for enabling roce
+
+From: Chris Mi <cmi@nvidia.com>
+
+[ Upstream commit 90538d23278a981e344d364e923162fce752afeb ]
+
+The cited commit assumes enabling roce always succeeds. But it is
+not true. Add error handling for it.
+
+Fixes: 80f09dfc237f ("net/mlx5: Eswitch, enable RoCE loopback traffic")
+Signed-off-by: Chris Mi <cmi@nvidia.com>
+Reviewed-by: Roi Dayan <roid@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250423083611.324567-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 5 ++++-
+ drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 9 +++++----
+ drivers/net/ethernet/mellanox/mlx5/core/rdma.h | 4 ++--
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 20cc01ceee8a9..2e0920199d471 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -3532,7 +3532,9 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
+ int err;
+
+ mutex_init(&esw->offloads.termtbl_mutex);
+- mlx5_rdma_enable_roce(esw->dev);
++ err = mlx5_rdma_enable_roce(esw->dev);
++ if (err)
++ goto err_roce;
+
+ err = mlx5_esw_host_number_init(esw);
+ if (err)
+@@ -3593,6 +3595,7 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
+ esw_offloads_metadata_uninit(esw);
+ err_metadata:
+ mlx5_rdma_disable_roce(esw->dev);
++err_roce:
+ mutex_destroy(&esw->offloads.termtbl_mutex);
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
+index f585ef5a34243..5c552b71e371c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
+@@ -140,17 +140,17 @@ void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
+ mlx5_nic_vport_disable_roce(dev);
+ }
+
+-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
+ {
+ int err;
+
+ if (!MLX5_CAP_GEN(dev, roce))
+- return;
++ return 0;
+
+ err = mlx5_nic_vport_enable_roce(dev);
+ if (err) {
+ mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
+- return;
++ return err;
+ }
+
+ err = mlx5_rdma_add_roce_addr(dev);
+@@ -165,10 +165,11 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
+ goto del_roce_addr;
+ }
+
+- return;
++ return err;
+
+ del_roce_addr:
+ mlx5_rdma_del_roce_addr(dev);
+ disable_roce:
+ mlx5_nic_vport_disable_roce(dev);
++ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h
+index 750cff2a71a4b..3d9e76c3d42fb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h
+@@ -8,12 +8,12 @@
+
+ #ifdef CONFIG_MLX5_ESWITCH
+
+-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev);
++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev);
+ void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev);
+
+ #else /* CONFIG_MLX5_ESWITCH */
+
+-static inline void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) {}
++static inline int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) { return 0; }
+ static inline void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) {}
+
+ #endif /* CONFIG_MLX5_ESWITCH */
+--
+2.39.5
+
--- /dev/null
+From 864fa70dcb01092119876cc1a36ba0f6915b64ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:36:08 +0300
+Subject: net/mlx5: E-Switch, Initialize MAC Address for Default GID
+
+From: Maor Gottlieb <maorg@nvidia.com>
+
+[ Upstream commit 5d1a04f347e6cbf5ffe74da409a5d71fbe8c5f19 ]
+
+Initialize the source MAC address when creating the default GID entry.
+Since this entry is used only for loopback traffic, it only needs to
+be a unicast address. A zeroed-out MAC address is sufficient for this
+purpose.
+Without this fix, random bits would be assigned as the source address.
+If these bits formed a multicast address, the firmware would return an
+error, preventing the user from switching to switchdev mode:
+
+Error: mlx5_core: Failed setting eswitch to offloads.
+kernel answers: Invalid argument
+
+Fixes: 80f09dfc237f ("net/mlx5: Eswitch, enable RoCE loopback traffic")
+Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250423083611.324567-3-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
+index a42f6cd99b744..f585ef5a34243 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c
+@@ -118,8 +118,8 @@ static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *
+
+ static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
+ {
++ u8 mac[ETH_ALEN] = {};
+ union ib_gid gid;
+- u8 mac[ETH_ALEN];
+
+ mlx5_rdma_make_default_gid(dev, &gid);
+ return mlx5_core_roce_gid_set(dev, 0,
+--
+2.39.5
+
--- /dev/null
+From f4377a31e98417736643e4c77da3dcc6c046c2d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:36:10 +0300
+Subject: net/mlx5e: Fix lock order in
+ mlx5e_tx_reporter_ptpsq_unhealthy_recover
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 1c2940ec0ddf51c689ee9ab85ead85c11b77809d ]
+
+RTNL needs to be acquired before state_lock.
+
+Fixes: fdce06bda7e5 ("net/mlx5e: Acquire RTNL lock before RQs/SQs activation/deactivation")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250423083611.324567-5-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+index 09433b91be176..c8adf309ecad0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+@@ -177,6 +177,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+
+ priv = ptpsq->txqsq.priv;
+
++ rtnl_lock();
+ mutex_lock(&priv->state_lock);
+ chs = &priv->channels;
+ netdev = priv->netdev;
+@@ -184,22 +185,19 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+ carrier_ok = netif_carrier_ok(netdev);
+ netif_carrier_off(netdev);
+
+- rtnl_lock();
+ mlx5e_deactivate_priv_channels(priv);
+- rtnl_unlock();
+
+ mlx5e_ptp_close(chs->ptp);
+ err = mlx5e_ptp_open(priv, &chs->params, chs->c[0]->lag_port, &chs->ptp);
+
+- rtnl_lock();
+ mlx5e_activate_priv_channels(priv);
+- rtnl_unlock();
+
+ /* return carrier back if needed */
+ if (carrier_ok)
+ netif_carrier_on(netdev);
+
+ mutex_unlock(&priv->state_lock);
++ rtnl_unlock();
+
+ return err;
+ }
+--
+2.39.5
+
--- /dev/null
+From 114765a3b060fa24a16d955d4b04ad921edb29dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:36:09 +0300
+Subject: net/mlx5e: TC, Continue the attr process even if encap entry is
+ invalid
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+[ Upstream commit 172c034264c894518c012387f2de2f9d6443505d ]
+
+Previously the offload of the rule with header rewrite and mirror to
+both internal and external destinations is skipped if the encap entry
+is not valid. But it shouldn't because driver will try to offload it
+again if neighbor is updated and encap entry is valid, to replace the
+old FTE added for slow path. But the extra split attr doesn't exist at
+that time as the process is skipped, driver then fails to offload it.
+To fix this issue, remove the checking and continue the attr process
+if encap entry is invalid.
+
+Fixes: b11bde56246e ("net/mlx5e: TC, Offload rewrite and mirror to both internal and external dests")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250423083611.324567-4-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 9ba99609999f4..f1d908f611349 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1750,9 +1750,6 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr
+ !list_is_first(&attr->list, &flow->attrs))
+ return 0;
+
+- if (flow_flag_test(flow, SLOW))
+- return 0;
+-
+ esw_attr = attr->esw_attr;
+ if (!esw_attr->split_count ||
+ esw_attr->split_count == esw_attr->out_count - 1)
+@@ -1766,7 +1763,7 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr
+ for (i = esw_attr->split_count; i < esw_attr->out_count; i++) {
+ /* external dest with encap is considered as internal by firmware */
+ if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK &&
+- !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP_VALID))
++ !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP))
+ ext_dest = true;
+ else
+ int_dest = true;
+--
+2.39.5
+
--- /dev/null
+From 1e52218d965704e43d8cb42343db92b10eb12894 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:36:07 +0300
+Subject: net/mlx5e: Use custom tunnel header for vxlan gbp
+
+From: Vlad Dogaru <vdogaru@nvidia.com>
+
+[ Upstream commit eacc77a73275895eca0e3655dc6c671853500e2e ]
+
+Symbolic (e.g. "vxlan") and custom (e.g. "tunnel_header_0") tunnels
+cannot be combined, but the match params interface does not have fields
+for matching on vxlan gbp. To match vxlan bgp, the tc_tun layer uses
+tunnel_header_0.
+
+Allow matching on both VNI and GBP by matching the VNI with a custom
+tunnel header instead of the symbolic field name.
+
+Matching solely on the VNI continues to use the symbolic field name.
+
+Fixes: 74a778b4a63f ("net/mlx5: HWS, added definers handling")
+Signed-off-by: Vlad Dogaru <vdogaru@nvidia.com>
+Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250423083611.324567-2-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/tc_tun_vxlan.c | 32 +++++++++++++++++--
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
+index e4e487c8431b8..b9cf79e271244 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
+@@ -165,9 +165,6 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
+ struct flow_match_enc_keyid enc_keyid;
+ void *misc_c, *misc_v;
+
+- misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters);
+- misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters);
+-
+ if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
+ return 0;
+
+@@ -182,6 +179,30 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
+ err = mlx5e_tc_tun_parse_vxlan_gbp_option(priv, spec, f);
+ if (err)
+ return err;
++
++ /* We can't mix custom tunnel headers with symbolic ones and we
++ * don't have a symbolic field name for GBP, so we use custom
++ * tunnel headers in this case. We need hardware support to
++ * match on custom tunnel headers, but we already know it's
++ * supported because the previous call successfully checked for
++ * that.
++ */
++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
++ misc_parameters_5);
++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
++ misc_parameters_5);
++
++ /* Shift by 8 to account for the reserved bits in the vxlan
++ * header after the VNI.
++ */
++ MLX5_SET(fte_match_set_misc5, misc_c, tunnel_header_1,
++ be32_to_cpu(enc_keyid.mask->keyid) << 8);
++ MLX5_SET(fte_match_set_misc5, misc_v, tunnel_header_1,
++ be32_to_cpu(enc_keyid.key->keyid) << 8);
++
++ spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5;
++
++ return 0;
+ }
+
+ /* match on VNI is required */
+@@ -195,6 +216,11 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
+ return -EOPNOTSUPP;
+ }
+
++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
++ misc_parameters);
++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
++ misc_parameters);
++
+ MLX5_SET(fte_match_set_misc, misc_c, vxlan_vni,
+ be32_to_cpu(enc_keyid.mask->keyid));
+ MLX5_SET(fte_match_set_misc, misc_v, vxlan_vni,
+--
+2.39.5
+
--- /dev/null
+From 4fbf2cdb04069a413c368f0bd89e079f8277260e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 01:37:33 +0300
+Subject: net: mscc: ocelot: delete PVID VLAN when readding it as non-PVID
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 5ec6d7d737a491256cd37e33910f7ac1978db591 ]
+
+The following set of commands:
+
+ip link add br0 type bridge vlan_filtering 1 # vlan_default_pvid 1 is implicit
+ip link set swp0 master br0
+bridge vlan add dev swp0 vid 1
+
+should result in the dropping of untagged and 802.1p-tagged traffic, but
+we see that it continues to be accepted. Whereas, had we deleted VID 1
+instead, the aforementioned dropping would have worked
+
+This is because the ANA_PORT_DROP_CFG update logic doesn't run, because
+ocelot_vlan_add() only calls ocelot_port_set_pvid() if the new VLAN has
+the BRIDGE_VLAN_INFO_PVID flag.
+
+Similar to other drivers like mt7530_port_vlan_add() which handle this
+case correctly, we need to test whether the VLAN we're changing used to
+have the BRIDGE_VLAN_INFO_PVID flag, but lost it now. That amounts to a
+PVID deletion and should be treated as such.
+
+Regarding blame attribution: this never worked properly since the
+introduction of bridge VLAN filtering in commit 7142529f1688 ("net:
+mscc: ocelot: add VLAN filtering"). However, there was a significant
+paradigm shift which aligned the ANA_PORT_DROP_CFG register with the
+PVID concept rather than with the native VLAN concept, and that change
+wasn't targeted for 'stable'. Realistically, that is as far as this fix
+needs to be propagated to.
+
+Fixes: be0576fed6d3 ("net: mscc: ocelot: move the logic to drop 802.1p traffic to the pvid deletion")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250424223734.3096202-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
+index ef93df5208871..08bee56aea35f 100644
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -830,6 +830,7 @@ EXPORT_SYMBOL(ocelot_vlan_prepare);
+ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
+ bool untagged)
+ {
++ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ int err;
+
+ /* Ignore VID 0 added to our RX filter by the 8021q module, since
+@@ -849,6 +850,11 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
+ ocelot_bridge_vlan_find(ocelot, vid));
+ if (err)
+ return err;
++ } else if (ocelot_port->pvid_vlan &&
++ ocelot_bridge_vlan_find(ocelot, vid) == ocelot_port->pvid_vlan) {
++ err = ocelot_port_set_pvid(ocelot, port, NULL);
++ if (err)
++ return err;
+ }
+
+ /* Untagged egress vlan clasification */
+--
+2.39.5
+
--- /dev/null
+From 44650b2602c4fa1ab5846ec72bd28a7dac6645d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 09:59:48 +0800
+Subject: net: use sock_gen_put() when sk_state is TCP_TIME_WAIT
+
+From: Jibin Zhang <jibin.zhang@mediatek.com>
+
+[ Upstream commit f920436a44295ca791ebb6dae3f4190142eec703 ]
+
+It is possible for a pointer of type struct inet_timewait_sock to be
+returned from the functions __inet_lookup_established() and
+__inet6_lookup_established(). This can cause a crash when the
+returned pointer is of type struct inet_timewait_sock and
+sock_put() is called on it. The following is a crash call stack that
+shows sk->sk_wmem_alloc being accessed in sk_free() during the call to
+sock_put() on a struct inet_timewait_sock pointer. To avoid this issue,
+use sock_gen_put() instead of sock_put() when sk->sk_state
+is TCP_TIME_WAIT.
+
+mrdump.ko ipanic() + 120
+vmlinux notifier_call_chain(nr_to_call=-1, nr_calls=0) + 132
+vmlinux atomic_notifier_call_chain(val=0) + 56
+vmlinux panic() + 344
+vmlinux add_taint() + 164
+vmlinux end_report() + 136
+vmlinux kasan_report(size=0) + 236
+vmlinux report_tag_fault() + 16
+vmlinux do_tag_recovery() + 16
+vmlinux __do_kernel_fault() + 88
+vmlinux do_bad_area() + 28
+vmlinux do_tag_check_fault() + 60
+vmlinux do_mem_abort() + 80
+vmlinux el1_abort() + 56
+vmlinux el1h_64_sync_handler() + 124
+vmlinux > 0xFFFFFFC080011294()
+vmlinux __lse_atomic_fetch_add_release(v=0xF2FFFF82A896087C)
+vmlinux __lse_atomic_fetch_sub_release(v=0xF2FFFF82A896087C)
+vmlinux arch_atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C)
++ 8
+vmlinux raw_atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C)
++ 8
+vmlinux atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C) + 8
+vmlinux __refcount_sub_and_test(i=1, r=0xF2FFFF82A896087C,
+oldp=0) + 8
+vmlinux __refcount_dec_and_test(r=0xF2FFFF82A896087C, oldp=0) + 8
+vmlinux refcount_dec_and_test(r=0xF2FFFF82A896087C) + 8
+vmlinux sk_free(sk=0xF2FFFF82A8960700) + 28
+vmlinux sock_put() + 48
+vmlinux tcp6_check_fraglist_gro() + 236
+vmlinux tcp6_gro_receive() + 624
+vmlinux ipv6_gro_receive() + 912
+vmlinux dev_gro_receive() + 1116
+vmlinux napi_gro_receive() + 196
+ccmni.ko ccmni_rx_callback() + 208
+ccmni.ko ccmni_queue_recv_skb() + 388
+ccci_dpmaif.ko dpmaif_rxq_push_thread() + 1088
+vmlinux kthread() + 268
+vmlinux 0xFFFFFFC08001F30C()
+
+Fixes: c9d1d23e5239 ("net: add heuristic for enabling TCP fraglist GRO")
+Signed-off-by: Jibin Zhang <jibin.zhang@mediatek.com>
+Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250429020412.14163-1-shiming.cheng@mediatek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_offload.c | 2 +-
+ net/ipv6/tcpv6_offload.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
+index 2dfac79dc78b8..e04ebe651c334 100644
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -435,7 +435,7 @@ static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
+ iif, sdif);
+ NAPI_GRO_CB(skb)->is_flist = !sk;
+ if (sk)
+- sock_put(sk);
++ sock_gen_put(sk);
+ }
+
+ INDIRECT_CALLABLE_SCOPE
+diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
+index ae2da28f9dfb1..5ab509a5fbdfc 100644
+--- a/net/ipv6/tcpv6_offload.c
++++ b/net/ipv6/tcpv6_offload.c
+@@ -42,7 +42,7 @@ static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
+ iif, sdif);
+ NAPI_GRO_CB(skb)->is_flist = !sk;
+ if (sk)
+- sock_put(sk);
++ sock_gen_put(sk);
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 6e302f9663db5d33008655aca1e9021ba161c92f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 15:30:42 +0200
+Subject: net: vertexcom: mse102x: Add range check for CMD_RTS
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit d4dda902dac194e3231a1ed0f76c6c3b6340ba8a ]
+
+Since there is no protection in the SPI protocol against electrical
+interferences, the driver shouldn't blindly trust the length payload
+of CMD_RTS. So introduce a bounds check for incoming frames.
+
+Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250430133043.7722-4-wahrenst@gmx.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/vertexcom/mse102x.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
+index 3edf2c3753f0e..2c06d1d05164f 100644
+--- a/drivers/net/ethernet/vertexcom/mse102x.c
++++ b/drivers/net/ethernet/vertexcom/mse102x.c
+@@ -6,6 +6,7 @@
+
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
++#include <linux/if_vlan.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -337,8 +338,9 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
+ }
+
+ rxlen = cmd_resp & LEN_MASK;
+- if (!rxlen) {
+- net_dbg_ratelimited("%s: No frame length defined\n", __func__);
++ if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) {
++ net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
++ rxlen);
+ mse->stats.invalid_len++;
+ return;
+ }
+--
+2.39.5
+
--- /dev/null
+From 29ed1ca8fb38088528a5e4a6c747b4071143d48b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 15:30:41 +0200
+Subject: net: vertexcom: mse102x: Fix LEN_MASK
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 74987089ec678b4018dba0a609e9f4bf6ef7f4ad ]
+
+The LEN_MASK for CMD_RTS doesn't cover the whole parameter mask.
+The Bit 11 is reserved, so adjust LEN_MASK accordingly.
+
+Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250430133043.7722-3-wahrenst@gmx.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/vertexcom/mse102x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
+index 92ebf16331598..3edf2c3753f0e 100644
+--- a/drivers/net/ethernet/vertexcom/mse102x.c
++++ b/drivers/net/ethernet/vertexcom/mse102x.c
+@@ -33,7 +33,7 @@
+ #define CMD_CTR (0x2 << CMD_SHIFT)
+
+ #define CMD_MASK GENMASK(15, CMD_SHIFT)
+-#define LEN_MASK GENMASK(CMD_SHIFT - 1, 0)
++#define LEN_MASK GENMASK(CMD_SHIFT - 2, 0)
+
+ #define DET_CMD_LEN 4
+ #define DET_SOF_LEN 2
+--
+2.39.5
+
--- /dev/null
+From d00908df3c1a759cbe266bdbbbf34c5fd3847e42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 15:30:40 +0200
+Subject: net: vertexcom: mse102x: Fix possible stuck of SPI interrupt
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 55f362885951b2d00fd7fbb02ef0227deea572c2 ]
+
+The MSE102x doesn't provide any SPI commands for interrupt handling.
+So in case the interrupt fired before the driver requests the IRQ,
+the interrupt will never fire again. In order to fix this always poll
+for pending packets after opening the interface.
+
+Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250430133043.7722-2-wahrenst@gmx.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/vertexcom/mse102x.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
+index 89dc4c401a8de..92ebf16331598 100644
+--- a/drivers/net/ethernet/vertexcom/mse102x.c
++++ b/drivers/net/ethernet/vertexcom/mse102x.c
+@@ -509,6 +509,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse)
+ static int mse102x_net_open(struct net_device *ndev)
+ {
+ struct mse102x_net *mse = netdev_priv(ndev);
++ struct mse102x_net_spi *mses = to_mse102x_spi(mse);
+ int ret;
+
+ ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,
+@@ -524,6 +525,13 @@ static int mse102x_net_open(struct net_device *ndev)
+
+ netif_carrier_on(ndev);
+
++ /* The SPI interrupt can stuck in case of pending packet(s).
++ * So poll for possible packet(s) to re-arm the interrupt.
++ */
++ mutex_lock(&mses->lock);
++ mse102x_rx_pkt_spi(mse);
++ mutex_unlock(&mses->lock);
++
+ netif_dbg(mse, ifup, ndev, "network device up\n");
+
+ return 0;
+--
+2.39.5
+
--- /dev/null
+From 1149a3664e911d031e51a1b0ef332b54322272d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 15:30:43 +0200
+Subject: net: vertexcom: mse102x: Fix RX error handling
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit ee512922ddd7d64afe2b28830a88f19063217649 ]
+
+In case the CMD_RTS got corrupted by interferences, the MSE102x
+doesn't allow a retransmission of the command. Instead the Ethernet
+frame must be shifted out of the SPI FIFO. Since the actual length is
+unknown, assume the maximum possible value.
+
+Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250430133043.7722-5-wahrenst@gmx.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/vertexcom/mse102x.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
+index 2c06d1d05164f..e4d993f313740 100644
+--- a/drivers/net/ethernet/vertexcom/mse102x.c
++++ b/drivers/net/ethernet/vertexcom/mse102x.c
+@@ -263,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp,
+ }
+
+ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
+- unsigned int frame_len)
++ unsigned int frame_len, bool drop)
+ {
+ struct mse102x_net_spi *mses = to_mse102x_spi(mse);
+ struct spi_transfer *xfer = &mses->spi_xfer;
+@@ -281,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
+ netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",
+ __func__, ret);
+ mse->stats.xfer_err++;
++ } else if (drop) {
++ netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__);
++ ret = -EINVAL;
+ } else if (*sof != cpu_to_be16(DET_SOF)) {
+ netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",
+ __func__, *sof);
+@@ -308,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
+ struct sk_buff *skb;
+ unsigned int rxalign;
+ unsigned int rxlen;
++ bool drop = false;
+ __be16 rx = 0;
+ u16 cmd_resp;
+ u8 *rxpkt;
+@@ -330,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
+ net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",
+ __func__, cmd_resp);
+ mse->stats.invalid_rts++;
+- return;
++ drop = true;
++ goto drop;
+ }
+
+ net_dbg_ratelimited("%s: Unexpected response to first CMD\n",
+@@ -342,9 +347,16 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
+ net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
+ rxlen);
+ mse->stats.invalid_len++;
+- return;
++ drop = true;
+ }
+
++ /* In case of a invalid CMD_RTS, the frame must be consumed anyway.
++ * So assume the maximum possible frame length.
++ */
++drop:
++ if (drop)
++ rxlen = VLAN_ETH_FRAME_LEN;
++
+ rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
+ skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
+ if (!skb)
+@@ -355,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
+ * They are copied, but ignored.
+ */
+ rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;
+- if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) {
++ if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) {
+ mse->ndev->stats.rx_errors++;
+ dev_kfree_skb(skb);
+ return;
+--
+2.39.5
+
--- /dev/null
+From 0c7ea91ccd9dcb77606473b331055949f824f02f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 19:07:05 -0300
+Subject: net_sched: drr: Fix double list add in class with netem as child
+ qdisc
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit f99a3fbf023e20b626be4b0f042463d598050c9a ]
+
+As described in Gerrard's report [1], there are use cases where a netem
+child qdisc will make the parent qdisc's enqueue callback reentrant.
+In the case of drr, there won't be a UAF, but the code will add the same
+classifier to the list twice, which will cause memory corruption.
+
+In addition to checking for qlen being zero, this patch checks whether the
+class was already added to the active_list (cl_is_active) before adding
+to the list to cover for the reentrant case.
+
+[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/
+
+Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20250425220710.3964791-2-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_drr.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
+index c69b999fae171..25b77ed0c1f28 100644
+--- a/net/sched/sch_drr.c
++++ b/net/sched/sch_drr.c
+@@ -35,6 +35,11 @@ struct drr_sched {
+ struct Qdisc_class_hash clhash;
+ };
+
++static bool cl_is_active(struct drr_class *cl)
++{
++ return !list_empty(&cl->alist);
++}
++
+ static struct drr_class *drr_find_class(struct Qdisc *sch, u32 classid)
+ {
+ struct drr_sched *q = qdisc_priv(sch);
+@@ -336,7 +341,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ struct drr_sched *q = qdisc_priv(sch);
+ struct drr_class *cl;
+ int err = 0;
+- bool first;
+
+ cl = drr_classify(skb, sch, &err);
+ if (cl == NULL) {
+@@ -346,7 +350,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ return err;
+ }
+
+- first = !cl->qdisc->q.qlen;
+ err = qdisc_enqueue(skb, cl->qdisc, to_free);
+ if (unlikely(err != NET_XMIT_SUCCESS)) {
+ if (net_xmit_drop_count(err)) {
+@@ -356,7 +359,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ return err;
+ }
+
+- if (first) {
++ if (!cl_is_active(cl)) {
+ list_add_tail(&cl->alist, &q->active);
+ cl->deficit = cl->quantum;
+ }
+--
+2.39.5
+
--- /dev/null
+From c7db8e7e5f8d29a4992cb4390f8c785cea8fd232 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 19:07:07 -0300
+Subject: net_sched: ets: Fix double list add in class with netem as child
+ qdisc
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit 1a6d0c00fa07972384b0c308c72db091d49988b6 ]
+
+As described in Gerrard's report [1], there are use cases where a netem
+child qdisc will make the parent qdisc's enqueue callback reentrant.
+In the case of ets, there won't be a UAF, but the code will add the same
+classifier to the list twice, which will cause memory corruption.
+
+In addition to checking for qlen being zero, this patch checks whether
+the class was already added to the active_list (cl_is_active) before
+doing the addition to cater for the reentrant case.
+
+[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/
+
+Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20250425220710.3964791-4-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index 516038a441638..9e4cd2cefa8c6 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -74,6 +74,11 @@ static const struct nla_policy ets_class_policy[TCA_ETS_MAX + 1] = {
+ [TCA_ETS_QUANTA_BAND] = { .type = NLA_U32 },
+ };
+
++static bool cl_is_active(struct ets_class *cl)
++{
++ return !list_empty(&cl->alist);
++}
++
+ static int ets_quantum_parse(struct Qdisc *sch, const struct nlattr *attr,
+ unsigned int *quantum,
+ struct netlink_ext_ack *extack)
+@@ -416,7 +421,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ struct ets_sched *q = qdisc_priv(sch);
+ struct ets_class *cl;
+ int err = 0;
+- bool first;
+
+ cl = ets_classify(skb, sch, &err);
+ if (!cl) {
+@@ -426,7 +430,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ return err;
+ }
+
+- first = !cl->qdisc->q.qlen;
+ err = qdisc_enqueue(skb, cl->qdisc, to_free);
+ if (unlikely(err != NET_XMIT_SUCCESS)) {
+ if (net_xmit_drop_count(err)) {
+@@ -436,7 +439,7 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ return err;
+ }
+
+- if (first && !ets_class_is_strict(q, cl)) {
++ if (!cl_is_active(cl) && !ets_class_is_strict(q, cl)) {
+ list_add_tail(&cl->alist, &q->active);
+ cl->deficit = cl->quantum;
+ }
+--
+2.39.5
+
--- /dev/null
+From 61afe07bdbdfdf365c1ec5030d9ef95538666182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 19:07:06 -0300
+Subject: net_sched: hfsc: Fix a UAF vulnerability in class with netem as child
+ qdisc
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit 141d34391abbb315d68556b7c67ad97885407547 ]
+
+As described in Gerrard's report [1], we have a UAF case when an hfsc class
+has a netem child qdisc. The crux of the issue is that hfsc is assuming
+that checking for cl->qdisc->q.qlen == 0 guarantees that it hasn't inserted
+the class in the vttree or eltree (which is not true for the netem
+duplicate case).
+
+This patch checks the n_active class variable to make sure that the code
+won't insert the class in the vttree or eltree twice, catering for the
+reentrant case.
+
+[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/
+
+Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs")
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20250425220710.3964791-3-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_hfsc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
+index 5bb4ab9941d6e..1c857dc95e4f3 100644
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -1565,7 +1565,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
+ return err;
+ }
+
+- if (first) {
++ if (first && !cl->cl_nactive) {
+ if (cl->cl_flags & HFSC_RSC)
+ init_ed(cl, len);
+ if (cl->cl_flags & HFSC_FSC)
+--
+2.39.5
+
--- /dev/null
+From e45299fc8f0df4abc9dcdcf05da735dae0e377b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 19:07:08 -0300
+Subject: net_sched: qfq: Fix double list add in class with netem as child
+ qdisc
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit f139f37dcdf34b67f5bf92bc8e0f7f6b3ac63aa4 ]
+
+As described in Gerrard's report [1], there are use cases where a netem
+child qdisc will make the parent qdisc's enqueue callback reentrant.
+In the case of qfq, there won't be a UAF, but the code will add the same
+classifier to the list twice, which will cause memory corruption.
+
+This patch checks whether the class was already added to the agg->active
+list (cl_is_active) before doing the addition to cater for the reentrant
+case.
+
+[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/
+
+Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20250425220710.3964791-5-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_qfq.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
+index 6a07cdbdb9e12..faba1501ac2fa 100644
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -202,6 +202,11 @@ struct qfq_sched {
+ */
+ enum update_reason {enqueue, requeue};
+
++static bool cl_is_active(struct qfq_class *cl)
++{
++ return !list_empty(&cl->alist);
++}
++
+ static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid)
+ {
+ struct qfq_sched *q = qdisc_priv(sch);
+@@ -1214,7 +1219,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ struct qfq_class *cl;
+ struct qfq_aggregate *agg;
+ int err = 0;
+- bool first;
+
+ cl = qfq_classify(skb, sch, &err);
+ if (cl == NULL) {
+@@ -1236,7 +1240,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ }
+
+ gso_segs = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+- first = !cl->qdisc->q.qlen;
+ err = qdisc_enqueue(skb, cl->qdisc, to_free);
+ if (unlikely(err != NET_XMIT_SUCCESS)) {
+ pr_debug("qfq_enqueue: enqueue failed %d\n", err);
+@@ -1252,8 +1255,8 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ ++sch->q.qlen;
+
+ agg = cl->agg;
+- /* if the queue was not empty, then done here */
+- if (!first) {
++ /* if the class is active, then done here */
++ if (cl_is_active(cl)) {
+ if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) &&
+ list_first_entry(&agg->active, struct qfq_class, alist)
+ == cl && cl->deficit < len)
+--
+2.39.5
+
--- /dev/null
+From 5fc3c8ca28ef459330d496e1f0fc75510d935e31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 10:18:01 -0700
+Subject: nvme-pci: fix queue unquiesce check on slot_reset
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit a75401227eeb827b1a162df1aa9d5b33da921c43 ]
+
+A zero return means the reset was successfully scheduled. We don't want
+to unquiesce the queues while the reset_work is pending, as that will
+just flush out requeued requests to a failed completion.
+
+Fixes: 71a5bb153be104 ("nvme: ensure disabling pairs with unquiesce")
+Reported-by: Dhankaran Singh Ajravat <dhankaran@meta.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 1dc12784efafc..d49b69565d04c 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3578,7 +3578,7 @@ static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev)
+
+ dev_info(dev->ctrl.device, "restart after slot reset\n");
+ pci_restore_state(pdev);
+- if (!nvme_try_sched_reset(&dev->ctrl))
++ if (nvme_try_sched_reset(&dev->ctrl))
+ nvme_unquiesce_io_queues(&dev->ctrl);
+ return PCI_ERS_RESULT_RECOVERED;
+ }
+--
+2.39.5
+
--- /dev/null
+From a3cde99f22ae4872781db24d5282b4206d413ca7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 10:42:01 -0600
+Subject: nvme-tcp: fix premature queue removal and I/O failover
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Liang <mliang@purestorage.com>
+
+[ Upstream commit 77e40bbce93059658aee02786a32c5c98a240a8a ]
+
+This patch addresses a data corruption issue observed in nvme-tcp during
+testing.
+
+In an NVMe native multipath setup, when an I/O timeout occurs, all
+inflight I/Os are canceled almost immediately after the kernel socket is
+shut down. These canceled I/Os are reported as host path errors,
+triggering a failover that succeeds on a different path.
+
+However, at this point, the original I/O may still be outstanding in the
+host's network transmission path (e.g., the NIC’s TX queue). From the
+user-space app's perspective, the buffer associated with the I/O is
+considered completed since they're acked on the different path and may
+be reused for new I/O requests.
+
+Because nvme-tcp enables zero-copy by default in the transmission path,
+this can lead to corrupted data being sent to the original target,
+ultimately causing data corruption.
+
+We can reproduce this data corruption by injecting delay on one path and
+triggering i/o timeout.
+
+To prevent this issue, this change ensures that all inflight
+transmissions are fully completed from host's perspective before
+returning from queue stop. To handle concurrent I/O timeout from multiple
+namespaces under the same controller, always wait in queue stop
+regardless of queue's state.
+
+This aligns with the behavior of queue stopping in other NVMe fabric
+transports.
+
+Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
+Signed-off-by: Michael Liang <mliang@purestorage.com>
+Reviewed-by: Mohamed Khalfella <mkhalfella@purestorage.com>
+Reviewed-by: Randy Jennings <randyj@purestorage.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 327f3f2f5399c..d991baa82a1c2 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1944,7 +1944,7 @@ static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue)
+ cancel_work_sync(&queue->io_work);
+ }
+
+-static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
++static void nvme_tcp_stop_queue_nowait(struct nvme_ctrl *nctrl, int qid)
+ {
+ struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
+ struct nvme_tcp_queue *queue = &ctrl->queues[qid];
+@@ -1963,6 +1963,31 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
+ mutex_unlock(&queue->queue_lock);
+ }
+
++static void nvme_tcp_wait_queue(struct nvme_ctrl *nctrl, int qid)
++{
++ struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
++ struct nvme_tcp_queue *queue = &ctrl->queues[qid];
++ int timeout = 100;
++
++ while (timeout > 0) {
++ if (!test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags) ||
++ !sk_wmem_alloc_get(queue->sock->sk))
++ return;
++ msleep(2);
++ timeout -= 2;
++ }
++ dev_warn(nctrl->device,
++ "qid %d: timeout draining sock wmem allocation expired\n",
++ qid);
++}
++
++static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
++{
++ nvme_tcp_stop_queue_nowait(nctrl, qid);
++ nvme_tcp_wait_queue(nctrl, qid);
++}
++
++
+ static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue)
+ {
+ write_lock_bh(&queue->sock->sk->sk_callback_lock);
+@@ -2030,7 +2055,9 @@ static void nvme_tcp_stop_io_queues(struct nvme_ctrl *ctrl)
+ int i;
+
+ for (i = 1; i < ctrl->queue_count; i++)
+- nvme_tcp_stop_queue(ctrl, i);
++ nvme_tcp_stop_queue_nowait(ctrl, i);
++ for (i = 1; i < ctrl->queue_count; i++)
++ nvme_tcp_wait_queue(ctrl, i);
+ }
+
+ static int nvme_tcp_start_io_queues(struct nvme_ctrl *ctrl,
+--
+2.39.5
+
--- /dev/null
+From 39acfe1a11e6af4ca20f03a180452b8996d24017 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 08:40:25 +1000
+Subject: nvme-tcp: select CONFIG_TLS from CONFIG_NVME_TCP_TLS
+
+From: Alistair Francis <alistair23@gmail.com>
+
+[ Upstream commit 521987940ad4fd37fe3d0340ec6f39c4e8e91e36 ]
+
+Ensure that TLS support is enabled in the kernel when
+CONFIG_NVME_TCP_TLS is enabled. Without this the code compiles, but does
+not actually work unless something else enables CONFIG_TLS.
+
+Fixes: be8e82caa68 ("nvme-tcp: enable TLS handshake upcall")
+Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
+index 486afe5981845..09ed1f61c9a85 100644
+--- a/drivers/nvme/host/Kconfig
++++ b/drivers/nvme/host/Kconfig
+@@ -97,6 +97,7 @@ config NVME_TCP_TLS
+ depends on NVME_TCP
+ select NET_HANDSHAKE
+ select KEYS
++ select TLS
+ help
+ Enables TLS encryption for NVMe TCP using the netlink handshake API.
+
+--
+2.39.5
+
--- /dev/null
+From 0f2878b3d02f6df0156e49540d2c0b30fc62ee45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 08:23:47 +1000
+Subject: nvmet-tcp: select CONFIG_TLS from CONFIG_NVME_TARGET_TCP_TLS
+
+From: Alistair Francis <alistair.francis@wdc.com>
+
+[ Upstream commit ac38b7ef704c0659568fd4b2c7e6c1255fc51798 ]
+
+Ensure that TLS support is enabled in the kernel when
+CONFIG_NVME_TARGET_TCP_TLS is enabled. Without this the code compiles,
+but does not actually work unless something else enables CONFIG_TLS.
+
+Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
+Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig
+index fb7446d6d6829..4c253b433bf78 100644
+--- a/drivers/nvme/target/Kconfig
++++ b/drivers/nvme/target/Kconfig
+@@ -98,6 +98,7 @@ config NVME_TARGET_TCP_TLS
+ bool "NVMe over Fabrics TCP target TLS encryption support"
+ depends on NVME_TARGET_TCP
+ select NET_HANDSHAKE
++ select TLS
+ help
+ Enables TLS encryption for the NVMe TCP target using the netlink handshake API.
+
+--
+2.39.5
+
--- /dev/null
+From 75dd43d368b27eb8c69a62a8c4e9ae607a471e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 04:46:24 -0700
+Subject: octeon_ep: Fix host hang issue during device reboot
+
+From: Sathesh B Edara <sedara@marvell.com>
+
+[ Upstream commit 34f42736b325287a7b2ce37e415838f539767bda ]
+
+When the host loses heartbeat messages from the device,
+the driver calls the device-specific ndo_stop function,
+which frees the resources. If the driver is unloaded in
+this scenario, it calls ndo_stop again, attempting to free
+resources that have already been freed, leading to a host
+hang issue. To resolve this, dev_close should be called
+instead of the device-specific stop function.dev_close
+internally calls ndo_stop to stop the network interface
+and performs additional cleanup tasks. During the driver
+unload process, if the device is already down, ndo_stop
+is not called.
+
+Fixes: 5cb96c29aa0e ("octeon_ep: add heartbeat monitor")
+Signed-off-by: Sathesh B Edara <sedara@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250429114624.19104-1-sedara@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeon_ep/octep_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+index 0a679e95196fe..24499bb36c005 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+@@ -1223,7 +1223,7 @@ static void octep_hb_timeout_task(struct work_struct *work)
+ miss_cnt);
+ rtnl_lock();
+ if (netif_running(oct->netdev))
+- octep_stop(oct->netdev);
++ dev_close(oct->netdev);
+ rtnl_unlock();
+ }
+
+--
+2.39.5
+
--- /dev/null
+From e716cd99a0ffcb2c88a94d400afea1116cf0594f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 06:39:44 -0700
+Subject: octeon_ep_vf: Resolve netdevice usage count issue
+
+From: Sathesh B Edara <sedara@marvell.com>
+
+[ Upstream commit 8548c84c004be3da4ffbe35ed0589041a4050c03 ]
+
+The netdevice usage count increases during transmit queue timeouts
+because netdev_hold is called in ndo_tx_timeout, scheduling a task
+to reinitialize the card. Although netdev_put is called at the end
+of the scheduled work, rtnl_unlock checks the reference count during
+cleanup. This could cause issues if transmit timeout is called on
+multiple queues.
+
+Fixes: cb7dd712189f ("octeon_ep_vf: Add driver framework and device initialization")
+Signed-off-by: Sathesh B Edara <sedara@marvell.com>
+Link: https://patch.msgid.link/20250424133944.28128-1-sedara@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
+index 18c922dd5fc64..ccb69bc5c9529 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
++++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
+@@ -835,7 +835,9 @@ static void octep_vf_tx_timeout(struct net_device *netdev, unsigned int txqueue)
+ struct octep_vf_device *oct = netdev_priv(netdev);
+
+ netdev_hold(netdev, NULL, GFP_ATOMIC);
+- schedule_work(&oct->tx_timeout_task);
++ if (!schedule_work(&oct->tx_timeout_task))
++ netdev_put(netdev, NULL);
++
+ }
+
+ static int octep_vf_set_mac(struct net_device *netdev, void *p)
+--
+2.39.5
+
--- /dev/null
+From 7da2dc150c7f21eae03da77c01aa7723a4ab1dda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 12:44:07 -0700
+Subject: pds_core: make pdsc_auxbus_dev_del() void
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit e8562da829432d04a0de1830146984c89844f35e ]
+
+Since there really is no useful return, advertising a return value
+is rather misleading. Make pdsc_auxbus_dev_del() a void function.
+
+Link: https://patch.msgid.link/r/20250320194412.67983-2-shannon.nelson@amd.com
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/auxbus.c | 7 +------
+ drivers/net/ethernet/amd/pds_core/core.h | 2 +-
+ drivers/net/ethernet/amd/pds_core/devlink.c | 6 ++++--
+ 3 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c
+index b76a9b7e0aed6..d53b2124b1498 100644
+--- a/drivers/net/ethernet/amd/pds_core/auxbus.c
++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c
+@@ -172,13 +172,9 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf,
+ return padev;
+ }
+
+-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
+ {
+ struct pds_auxiliary_dev *padev;
+- int err = 0;
+-
+- if (!cf)
+- return -ENODEV;
+
+ mutex_lock(&pf->config_lock);
+
+@@ -192,7 +188,6 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
+ pf->vfs[cf->vf_id].padev = NULL;
+
+ mutex_unlock(&pf->config_lock);
+- return err;
+ }
+
+ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
+diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h
+index ec637dc4327a5..08b8280437dcf 100644
+--- a/drivers/net/ethernet/amd/pds_core/core.h
++++ b/drivers/net/ethernet/amd/pds_core/core.h
+@@ -304,7 +304,7 @@ int pdsc_register_notify(struct notifier_block *nb);
+ void pdsc_unregister_notify(struct notifier_block *nb);
+ void pdsc_notify(unsigned long event, void *data);
+ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf);
+-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf);
++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf);
+
+ void pdsc_process_adminq(struct pdsc_qcq *qcq);
+ void pdsc_work_thread(struct work_struct *work);
+diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
+index ca23cde385e67..48a7c22fe3320 100644
+--- a/drivers/net/ethernet/amd/pds_core/devlink.c
++++ b/drivers/net/ethernet/amd/pds_core/devlink.c
+@@ -56,8 +56,10 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id,
+ for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) {
+ struct pdsc *vf = pdsc->vfs[vf_id].vf;
+
+- err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) :
+- pdsc_auxbus_dev_del(vf, pdsc);
++ if (ctx->val.vbool)
++ err = pdsc_auxbus_dev_add(vf, pdsc);
++ else
++ pdsc_auxbus_dev_del(vf, pdsc);
+ }
+
+ return err;
+--
+2.39.5
+
--- /dev/null
+From 7edfdcae5d4348e6eddd41beecaee6fbf6230c43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 13:38:57 -0700
+Subject: pds_core: remove write-after-free of client_id
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit dfd76010f8e821b66116dec3c7d90dd2403d1396 ]
+
+A use-after-free error popped up in stress testing:
+
+[Mon Apr 21 21:21:33 2025] BUG: KFENCE: use-after-free write in pdsc_auxbus_dev_del+0xef/0x160 [pds_core]
+[Mon Apr 21 21:21:33 2025] Use-after-free write at 0x000000007013ecd1 (in kfence-#47):
+[Mon Apr 21 21:21:33 2025] pdsc_auxbus_dev_del+0xef/0x160 [pds_core]
+[Mon Apr 21 21:21:33 2025] pdsc_remove+0xc0/0x1b0 [pds_core]
+[Mon Apr 21 21:21:33 2025] pci_device_remove+0x24/0x70
+[Mon Apr 21 21:21:33 2025] device_release_driver_internal+0x11f/0x180
+[Mon Apr 21 21:21:33 2025] driver_detach+0x45/0x80
+[Mon Apr 21 21:21:33 2025] bus_remove_driver+0x83/0xe0
+[Mon Apr 21 21:21:33 2025] pci_unregister_driver+0x1a/0x80
+
+The actual device uninit usually happens on a separate thread
+scheduled after this code runs, but there is no guarantee of order
+of thread execution, so this could be a problem. There's no
+actual need to clear the client_id at this point, so simply
+remove the offending code.
+
+Fixes: 10659034c622 ("pds_core: add the aux client API")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250425203857.71547-1-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/auxbus.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c
+index 4d3387bebe6a4..889a18962270a 100644
+--- a/drivers/net/ethernet/amd/pds_core/auxbus.c
++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c
+@@ -186,7 +186,6 @@ void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf,
+ pds_client_unregister(pf, padev->client_id);
+ auxiliary_device_delete(&padev->aux_dev);
+ auxiliary_device_uninit(&padev->aux_dev);
+- padev->client_id = 0;
+ *pd_ptr = NULL;
+
+ mutex_unlock(&pf->config_lock);
+--
+2.39.5
+
--- /dev/null
+From 3dd3215a3e8119d2927448dfe70c0f8db1cd806c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 12:44:08 -0700
+Subject: pds_core: specify auxiliary_device to be created
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit b699bdc720c0255d1bb76cecba7382c1f2107af5 ]
+
+In preparation for adding a new auxiliary_device for the PF,
+make the vif type an argument to pdsc_auxbus_dev_add(). Pass in
+the address of the padev pointer so that the caller can specify
+where to save it and keep the mutex usage within the function.
+
+Link: https://patch.msgid.link/r/20250320194412.67983-3-shannon.nelson@amd.com
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/auxbus.c | 37 ++++++++++-----------
+ drivers/net/ethernet/amd/pds_core/core.h | 7 ++--
+ drivers/net/ethernet/amd/pds_core/devlink.c | 5 +--
+ drivers/net/ethernet/amd/pds_core/main.c | 11 +++---
+ 4 files changed, 33 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c
+index d53b2124b1498..4d3387bebe6a4 100644
+--- a/drivers/net/ethernet/amd/pds_core/auxbus.c
++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c
+@@ -172,29 +172,32 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf,
+ return padev;
+ }
+
+-void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf,
++ struct pds_auxiliary_dev **pd_ptr)
+ {
+ struct pds_auxiliary_dev *padev;
+
++ if (!*pd_ptr)
++ return;
++
+ mutex_lock(&pf->config_lock);
+
+- padev = pf->vfs[cf->vf_id].padev;
+- if (padev) {
+- pds_client_unregister(pf, padev->client_id);
+- auxiliary_device_delete(&padev->aux_dev);
+- auxiliary_device_uninit(&padev->aux_dev);
+- padev->client_id = 0;
+- }
+- pf->vfs[cf->vf_id].padev = NULL;
++ padev = *pd_ptr;
++ pds_client_unregister(pf, padev->client_id);
++ auxiliary_device_delete(&padev->aux_dev);
++ auxiliary_device_uninit(&padev->aux_dev);
++ padev->client_id = 0;
++ *pd_ptr = NULL;
+
+ mutex_unlock(&pf->config_lock);
+ }
+
+-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf,
++ enum pds_core_vif_types vt,
++ struct pds_auxiliary_dev **pd_ptr)
+ {
+ struct pds_auxiliary_dev *padev;
+ char devname[PDS_DEVNAME_LEN];
+- enum pds_core_vif_types vt;
+ unsigned long mask;
+ u16 vt_support;
+ int client_id;
+@@ -203,6 +206,9 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
+ if (!cf)
+ return -ENODEV;
+
++ if (vt >= PDS_DEV_TYPE_MAX)
++ return -EINVAL;
++
+ mutex_lock(&pf->config_lock);
+
+ mask = BIT_ULL(PDSC_S_FW_DEAD) |
+@@ -214,17 +220,10 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
+ goto out_unlock;
+ }
+
+- /* We only support vDPA so far, so it is the only one to
+- * be verified that it is available in the Core device and
+- * enabled in the devlink param. In the future this might
+- * become a loop for several VIF types.
+- */
+-
+ /* Verify that the type is supported and enabled. It is not
+ * an error if there is no auxbus device support for this
+ * VF, it just means something else needs to happen with it.
+ */
+- vt = PDS_DEV_TYPE_VDPA;
+ vt_support = !!le16_to_cpu(pf->dev_ident.vif_types[vt]);
+ if (!(vt_support &&
+ pf->viftype_status[vt].supported &&
+@@ -250,7 +249,7 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
+ err = PTR_ERR(padev);
+ goto out_unlock;
+ }
+- pf->vfs[cf->vf_id].padev = padev;
++ *pd_ptr = padev;
+
+ out_unlock:
+ mutex_unlock(&pf->config_lock);
+diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h
+index 08b8280437dcf..becd3104473c2 100644
+--- a/drivers/net/ethernet/amd/pds_core/core.h
++++ b/drivers/net/ethernet/amd/pds_core/core.h
+@@ -303,8 +303,11 @@ void pdsc_health_thread(struct work_struct *work);
+ int pdsc_register_notify(struct notifier_block *nb);
+ void pdsc_unregister_notify(struct notifier_block *nb);
+ void pdsc_notify(unsigned long event, void *data);
+-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf);
+-void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf);
++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf,
++ enum pds_core_vif_types vt,
++ struct pds_auxiliary_dev **pd_ptr);
++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf,
++ struct pds_auxiliary_dev **pd_ptr);
+
+ void pdsc_process_adminq(struct pdsc_qcq *qcq);
+ void pdsc_work_thread(struct work_struct *work);
+diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
+index 48a7c22fe3320..d8dc39da4161f 100644
+--- a/drivers/net/ethernet/amd/pds_core/devlink.c
++++ b/drivers/net/ethernet/amd/pds_core/devlink.c
+@@ -57,9 +57,10 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id,
+ struct pdsc *vf = pdsc->vfs[vf_id].vf;
+
+ if (ctx->val.vbool)
+- err = pdsc_auxbus_dev_add(vf, pdsc);
++ err = pdsc_auxbus_dev_add(vf, pdsc, vt_entry->vif_id,
++ &pdsc->vfs[vf_id].padev);
+ else
+- pdsc_auxbus_dev_del(vf, pdsc);
++ pdsc_auxbus_dev_del(vf, pdsc, &pdsc->vfs[vf_id].padev);
+ }
+
+ return err;
+diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c
+index 660268ff95623..a3a68889137b6 100644
+--- a/drivers/net/ethernet/amd/pds_core/main.c
++++ b/drivers/net/ethernet/amd/pds_core/main.c
+@@ -190,7 +190,8 @@ static int pdsc_init_vf(struct pdsc *vf)
+ devl_unlock(dl);
+
+ pf->vfs[vf->vf_id].vf = vf;
+- err = pdsc_auxbus_dev_add(vf, pf);
++ err = pdsc_auxbus_dev_add(vf, pf, PDS_DEV_TYPE_VDPA,
++ &pf->vfs[vf->vf_id].padev);
+ if (err) {
+ devl_lock(dl);
+ devl_unregister(dl);
+@@ -417,7 +418,7 @@ static void pdsc_remove(struct pci_dev *pdev)
+
+ pf = pdsc_get_pf_struct(pdsc->pdev);
+ if (!IS_ERR(pf)) {
+- pdsc_auxbus_dev_del(pdsc, pf);
++ pdsc_auxbus_dev_del(pdsc, pf, &pf->vfs[pdsc->vf_id].padev);
+ pf->vfs[pdsc->vf_id].vf = NULL;
+ }
+ } else {
+@@ -482,7 +483,8 @@ static void pdsc_reset_prepare(struct pci_dev *pdev)
+
+ pf = pdsc_get_pf_struct(pdsc->pdev);
+ if (!IS_ERR(pf))
+- pdsc_auxbus_dev_del(pdsc, pf);
++ pdsc_auxbus_dev_del(pdsc, pf,
++ &pf->vfs[pdsc->vf_id].padev);
+ }
+
+ pdsc_unmap_bars(pdsc);
+@@ -527,7 +529,8 @@ static void pdsc_reset_done(struct pci_dev *pdev)
+
+ pf = pdsc_get_pf_struct(pdsc->pdev);
+ if (!IS_ERR(pf))
+- pdsc_auxbus_dev_add(pdsc, pf);
++ pdsc_auxbus_dev_add(pdsc, pf, PDS_DEV_TYPE_VDPA,
++ &pf->vfs[pdsc->vf_id].padev);
+ }
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 7e0cc38739c2f563a1181cc2d00b64a595280f7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 11:16:00 +0800
+Subject: pinctrl: imx: Return NULL if no group is matched and found
+
+From: Hui Wang <hui.wang@canonical.com>
+
+[ Upstream commit e64c0ff0d5d85791fbcd126ee558100a06a24a97 ]
+
+Currently if no group is matched and found, this function will return
+the last grp to the caller, this is not expected, it is supposed to
+return NULL in this case.
+
+Fixes: e566fc11ea76 ("pinctrl: imx: use generic pinctrl helpers for managing groups")
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/20250327031600.99723-1-hui.wang@canonical.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/freescale/pinctrl-imx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
+index 842a1e6cbfc41..18de313285404 100644
+--- a/drivers/pinctrl/freescale/pinctrl-imx.c
++++ b/drivers/pinctrl/freescale/pinctrl-imx.c
+@@ -37,16 +37,16 @@ static inline const struct group_desc *imx_pinctrl_find_group_by_name(
+ struct pinctrl_dev *pctldev,
+ const char *name)
+ {
+- const struct group_desc *grp = NULL;
++ const struct group_desc *grp;
+ int i;
+
+ for (i = 0; i < pctldev->num_groups; i++) {
+ grp = pinctrl_generic_get_group(pctldev, i);
+ if (grp && !strcmp(grp->grp.name, name))
+- break;
++ return grp;
+ }
+
+- return grp;
++ return NULL;
+ }
+
+ static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+--
+2.39.5
+
--- /dev/null
+From 0b971008034b0d2e4ab667b139d5690051c0c00a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 09:32:29 +0530
+Subject: pinctrl: qcom: Fix PINGROUP definition for sm8750
+
+From: Maulik Shah <maulik.shah@oss.qualcomm.com>
+
+[ Upstream commit 12b8a672d2aa053064151659f49e7310674d42d3 ]
+
+On newer SoCs intr_target_bit position is at 8 instead of 5. Fix it.
+
+Also add missing intr_wakeup_present_bit and intr_wakeup_enable_bit which
+enables forwarding of GPIO interrupts to parent PDC interrupt controller.
+
+Fixes: afe9803e3b82 ("pinctrl: qcom: Add sm8750 pinctrl driver")
+Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Melody Olvera <melody.olvera@oss.qualcomm.com>
+Link: https://lore.kernel.org/20250429-pinctrl_sm8750-v2-1-87d45dd3bd82@oss.qualcomm.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-sm8750.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-sm8750.c b/drivers/pinctrl/qcom/pinctrl-sm8750.c
+index 1af11cd95fb0e..b94fb4ee0ec38 100644
+--- a/drivers/pinctrl/qcom/pinctrl-sm8750.c
++++ b/drivers/pinctrl/qcom/pinctrl-sm8750.c
+@@ -46,7 +46,9 @@
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+- .intr_target_bit = 5, \
++ .intr_wakeup_present_bit = 6, \
++ .intr_wakeup_enable_bit = 7, \
++ .intr_target_bit = 8, \
+ .intr_target_kpss_val = 3, \
+ .intr_raw_status_bit = 4, \
+ .intr_polarity_bit = 1, \
+--
+2.39.5
+
--- /dev/null
+From 7758f2e262fff9882acd9d2aaacc537dc4ec7255 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 06:12:18 +0530
+Subject: powerpc/boot: Check for ld-option support
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit b2accfe7ca5bc9f9af28e603b79bdd5ad8df5c0b ]
+
+Commit 579aee9fc594 ("powerpc: suppress some linker warnings in recent linker versions")
+enabled support to add linker option "--no-warn-rwx-segments",
+if the version is greater than 2.39. Similar build warning were
+reported recently from linker version 2.35.2.
+
+ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions
+ld: warning: arch/powerpc/boot/zImage.pseries has a LOAD segment with RWX permissions
+
+Fix the warning by checking for "--no-warn-rwx-segments"
+option support in linker to enable it, instead of checking
+for the version range.
+
+Fixes: 579aee9fc594 ("powerpc: suppress some linker warnings in recent linker versions")
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Closes: https://lore.kernel.org/linuxppc-dev/61cf556c-4947-4bd6-af63-892fc0966dad@linux.ibm.com/
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250401004218.24869-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/boot/wrapper | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
+index 1db60fe13802d..267ca6d4d9b38 100755
+--- a/arch/powerpc/boot/wrapper
++++ b/arch/powerpc/boot/wrapper
+@@ -234,10 +234,8 @@ fi
+
+ # suppress some warnings in recent ld versions
+ nowarn="-z noexecstack"
+-if ! ld_is_lld; then
+- if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then
+- nowarn="$nowarn --no-warn-rwx-segments"
+- fi
++if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then
++ nowarn="$nowarn --no-warn-rwx-segments"
+ fi
+
+ platformo=$object/"$platform".o
+--
+2.39.5
+
--- /dev/null
+From b2f1318c79918d9d306040f2c1e27b92a3480747 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 13:51:54 +0530
+Subject: powerpc/boot: Fix dash warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit e3f506b78d921e48a00d005bea5c45ec36a99240 ]
+
+'commit b2accfe7ca5b ("powerpc/boot: Check for ld-option support")' suppressed
+linker warnings, but the expressed used did not go well with POSIX shell (dash)
+resulting with this warning
+
+arch/powerpc/boot/wrapper: 237: [: 0: unexpected operator
+ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions
+
+Fix the check to handle the reported warning. Patch also fixes
+couple of shellcheck reported errors for the same line.
+
+In arch/powerpc/boot/wrapper line 237:
+if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then
+ ^-- SC2046 (warning): Quote this to prevent word splitting.
+ ^------^ SC2086 (info): Double quote to prevent globbing and word splitting.
+ ^---------^ SC3020 (warning): In POSIX sh, &> is undefined.
+
+Fixes: b2accfe7ca5b ("powerpc/boot: Check for ld-option support")
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Suggested-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Reviewed-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250423082154.30625-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/boot/wrapper | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
+index 267ca6d4d9b38..3d8dc822282ac 100755
+--- a/arch/powerpc/boot/wrapper
++++ b/arch/powerpc/boot/wrapper
+@@ -234,7 +234,7 @@ fi
+
+ # suppress some warnings in recent ld versions
+ nowarn="-z noexecstack"
+-if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then
++if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then
+ nowarn="$nowarn --no-warn-rwx-segments"
+ fi
+
+--
+2.39.5
+
--- /dev/null
+From 37475c6a5911d17360d1fc80beff97e58e441df9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 00:18:21 +0100
+Subject: powerpc64/ftrace: fix module loading without patchable function
+ entries
+
+From: Anthony Iliopoulos <ailiop@suse.com>
+
+[ Upstream commit 534f5a8ba27863141e29766467a3e1f61bcb47ac ]
+
+get_stubs_size assumes that there must always be at least one patchable
+function entry, which is not always the case (modules that export data
+but no code), otherwise it returns -ENOEXEC and thus the section header
+sh_size is set to that value. During module_memory_alloc() the size is
+passed to execmem_alloc() after being page-aligned and thus set to zero
+which will cause it to fail the allocation (and thus module loading) as
+__vmalloc_node_range() checks for zero-sized allocs and returns null:
+
+[ 115.466896] module_64: cast_common: doesn't contain __patchable_function_entries.
+[ 115.469189] ------------[ cut here ]------------
+[ 115.469496] WARNING: CPU: 0 PID: 274 at mm/vmalloc.c:3778 __vmalloc_node_range_noprof+0x8b4/0x8f0
+...
+[ 115.478574] ---[ end trace 0000000000000000 ]---
+[ 115.479545] execmem: unable to allocate memory
+
+Fix this by removing the check completely, since it is anyway not
+helpful to propagate this as an error upwards.
+
+Fixes: eec37961a56a ("powerpc64/ftrace: Move ftrace sequence out of line")
+Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
+Acked-by: Naveen N Rao (AMD) <naveen@kernel.org>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250204231821.39140-1-ailiop@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/module_64.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
+index 34a5aec4908fb..126bf3b06ab7e 100644
+--- a/arch/powerpc/kernel/module_64.c
++++ b/arch/powerpc/kernel/module_64.c
+@@ -258,10 +258,6 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
+ break;
+ }
+ }
+- if (i == hdr->e_shnum) {
+- pr_err("%s: doesn't contain __patchable_function_entries.\n", me->name);
+- return -ENOEXEC;
+- }
+ #endif
+
+ pr_debug("Looks like a total of %lu stubs, max\n", relocs);
+--
+2.39.5
+
--- /dev/null
+From 90802819f6f4d4270ec9db07ebf1f5a7ac9ed4a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 10:33:20 +0300
+Subject: ptp: ocp: Fix NULL dereference in Adva board SMA sysfs operations
+
+From: Sagi Maimon <sagi.maimon@adtran.com>
+
+[ Upstream commit e98386d79a23c57cf179fe4138322e277aa3aa74 ]
+
+On Adva boards, SMA sysfs store/get operations can call
+__handle_signal_outputs() or __handle_signal_inputs() while the `irig`
+and `dcf` pointers are uninitialized, leading to a NULL pointer
+dereference in __handle_signal() and causing a kernel crash. Adva boards
+don't use `irig` or `dcf` functionality, so add Adva-specific callbacks
+`ptp_ocp_sma_adva_set_outputs()` and `ptp_ocp_sma_adva_set_inputs()` that
+avoid invoking `irig` or `dcf` input/output routines.
+
+Fixes: ef61f5528fca ("ptp: ocp: add Adva timecard support")
+Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20250429073320.33277-1-maimon.sagi@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 52 +++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index 4b7344e1816e4..605cce32a3d37 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -2578,12 +2578,60 @@ static const struct ocp_sma_op ocp_fb_sma_op = {
+ .set_output = ptp_ocp_sma_fb_set_output,
+ };
+
++static int
++ptp_ocp_sma_adva_set_output(struct ptp_ocp *bp, int sma_nr, u32 val)
++{
++ u32 reg, mask, shift;
++ unsigned long flags;
++ u32 __iomem *gpio;
++
++ gpio = sma_nr > 2 ? &bp->sma_map1->gpio2 : &bp->sma_map2->gpio2;
++ shift = sma_nr & 1 ? 0 : 16;
++
++ mask = 0xffff << (16 - shift);
++
++ spin_lock_irqsave(&bp->lock, flags);
++
++ reg = ioread32(gpio);
++ reg = (reg & mask) | (val << shift);
++
++ iowrite32(reg, gpio);
++
++ spin_unlock_irqrestore(&bp->lock, flags);
++
++ return 0;
++}
++
++static int
++ptp_ocp_sma_adva_set_inputs(struct ptp_ocp *bp, int sma_nr, u32 val)
++{
++ u32 reg, mask, shift;
++ unsigned long flags;
++ u32 __iomem *gpio;
++
++ gpio = sma_nr > 2 ? &bp->sma_map2->gpio1 : &bp->sma_map1->gpio1;
++ shift = sma_nr & 1 ? 0 : 16;
++
++ mask = 0xffff << (16 - shift);
++
++ spin_lock_irqsave(&bp->lock, flags);
++
++ reg = ioread32(gpio);
++ reg = (reg & mask) | (val << shift);
++
++ iowrite32(reg, gpio);
++
++ spin_unlock_irqrestore(&bp->lock, flags);
++
++ return 0;
++}
++
+ static const struct ocp_sma_op ocp_adva_sma_op = {
+ .tbl = { ptp_ocp_adva_sma_in, ptp_ocp_adva_sma_out },
+ .init = ptp_ocp_sma_fb_init,
+ .get = ptp_ocp_sma_fb_get,
+- .set_inputs = ptp_ocp_sma_fb_set_inputs,
+- .set_output = ptp_ocp_sma_fb_set_output,
++ .set_inputs = ptp_ocp_sma_adva_set_inputs,
++ .set_output = ptp_ocp_sma_adva_set_output,
+ };
+
+ static int
+--
+2.39.5
+
--- /dev/null
+From 760eecde7ed414aa1ddd4ad6942d32a06996f013 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 12:04:44 +0800
+Subject: rtase: Modify the condition used to detect overflow in
+ rtase_calc_time_mitigation
+
+From: Justin Lai <justinlai0215@realtek.com>
+
+[ Upstream commit 68f9d8974b545668e1be2422240b25a92e304b14 ]
+
+Fix the following compile error reported by the kernel test
+robot by modifying the condition used to detect overflow in
+rtase_calc_time_mitigation.
+
+In file included from include/linux/mdio.h:10:0,
+ from drivers/net/ethernet/realtek/rtase/rtase_main.c:58:
+ In function 'u16_encode_bits',
+ inlined from 'rtase_calc_time_mitigation.constprop' at drivers/net/
+ ethernet/realtek/rtase/rtase_main.c:1915:13,
+ inlined from 'rtase_init_software_variable.isra.41' at drivers/net/
+ ethernet/realtek/rtase/rtase_main.c:1961:13,
+ inlined from 'rtase_init_one' at drivers/net/ethernet/realtek/
+ rtase/rtase_main.c:2111:2:
+>> include/linux/bitfield.h:178:3: error: call to '__field_overflow'
+ declared with attribute error: value doesn't fit into mask
+ __field_overflow(); \
+ ^~~~~~~~~~~~~~~~~~
+ include/linux/bitfield.h:198:2: note: in expansion of macro
+ '____MAKE_OP'
+ ____MAKE_OP(u##size,u##size,,)
+ ^~~~~~~~~~~
+ include/linux/bitfield.h:200:1: note: in expansion of macro
+ '__MAKE_OP'
+ __MAKE_OP(16)
+ ^~~~~~~~~
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503182158.nkAlbJWX-lkp@intel.com/
+Fixes: a36e9f5cfe9e ("rtase: Add support for a pci table in this module")
+Signed-off-by: Justin Lai <justinlai0215@realtek.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250424040444.5530-1-justinlai0215@realtek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/rtase/rtase_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c b/drivers/net/ethernet/realtek/rtase/rtase_main.c
+index 2aacc1996796d..55b8d36661530 100644
+--- a/drivers/net/ethernet/realtek/rtase/rtase_main.c
++++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c
+@@ -1925,8 +1925,8 @@ static u16 rtase_calc_time_mitigation(u32 time_us)
+
+ time_us = min_t(int, time_us, RTASE_MITI_MAX_TIME);
+
+- msb = fls(time_us);
+- if (msb >= RTASE_MITI_COUNT_BIT_NUM) {
++ if (time_us > RTASE_MITI_TIME_COUNT_MASK) {
++ msb = fls(time_us);
+ time_unit = msb - RTASE_MITI_COUNT_BIT_NUM;
+ time_count = time_us >> (msb - RTASE_MITI_COUNT_BIT_NUM);
+ } else {
+--
+2.39.5
+
--- /dev/null
+From 70dfd909759c01e0c717168fba096002b3812d92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 10:06:05 +0900
+Subject: scsi: ufs: core: Remove redundant query_complete trace
+
+From: Keoseong Park <keosung.park@samsung.com>
+
+[ Upstream commit 0e9693b97a0eee1df7bae33aec207c975fbcbdb8 ]
+
+The query_complete trace was not removed after ufshcd_issue_dev_cmd() was
+called from the bsg path, resulting in duplicate output.
+
+Below is an example of the trace:
+
+ ufs-utils-773 [000] ..... 218.176933: ufshcd_upiu: query_send: 0000:00:04.0: HDR:16 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ufs-utils-773 [000] ..... 218.177145: ufshcd_upiu: query_complete: 0000:00:04.0: HDR:36 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+ ufs-utils-773 [000] ..... 218.177146: ufshcd_upiu: query_complete: 0000:00:04.0: HDR:36 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+
+Remove the redundant trace call in the bsg path, preventing duplication.
+
+Signed-off-by: Keoseong Park <keosung.park@samsung.com>
+Link: https://lore.kernel.org/r/20250425010605epcms2p67e89b351398832fe0fd547404d3afc65@epcms2p6
+Fixes: 71aabb747d5f ("scsi: ufs: core: Reuse exec_dev_cmd")
+Reviewed-by: Avri Altman <avri.altman@sandisk.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 128e35a848b7b..99e7e4a570f0e 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -7201,8 +7201,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
+ err = -EINVAL;
+ }
+ }
+- ufshcd_add_query_upiu_trace(hba, err ? UFS_QUERY_ERR : UFS_QUERY_COMP,
+- (struct utp_upiu_req *)lrbp->ucd_rsp_ptr);
+
+ return err;
+ }
+--
+2.39.5
+
bcachefs-remove-incorrect-__counted_by-annotation.patch
drm-amd-display-default-ips-to-rcg_in_active_ips2_in_off.patch
asoc-soc-core-stop-using-of_property_read_bool-for-non-boolean-properties.patch
+asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch
+firmware-cs_dsp-tests-depend-on-fw_cs_dsp-rather-the.patch
+asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch
+book3s64-radix-align-section-vmemmap-start-address-t.patch
+powerpc64-ftrace-fix-module-loading-without-patchabl.patch
+pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch
+powerpc-boot-check-for-ld-option-support.patch
+asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch
+iommu-arm-smmu-v3-add-missing-s2fwb-feature-detectio.patch
+alsa-hda-realtek-enable-speaker-for-hp-platform.patch
+drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch
+wifi-iwlwifi-back-off-on-continuous-errors.patch
+wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch
+wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch
+wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch
+powerpc-boot-fix-dash-warning.patch
+vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch
+xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch
+xsk-fix-offset-calculation-in-unaligned-mode.patch
+net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch
+net-mlx5-e-switch-initialize-mac-address-for-default.patch
+net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch
+net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch
+net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch
+accel-ivpu-correct-dct-interrupt-handling.patch
+spi-spi-mem-add-fix-to-avoid-divide-error.patch
+asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch
+cpufreq-introduce-policy-boost_supported-flag.patch
+cpufreq-acpi-set-policy-boost_supported.patch
+cpufreq-acpi-re-sync-cpu-boost-state-on-system-resum.patch
+bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch
+bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch
+bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch
+bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch
+bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch
+bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch
+net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch
+octeon_ep_vf-resolve-netdevice-usage-count-issue.patch
+bnxt_en-improve-tx-timestamping-fifo-configuration.patch
+rtase-modify-the-condition-used-to-detect-overflow-i.patch
+net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch
+net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch
+net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch
+pds_core-make-pdsc_auxbus_dev_del-void.patch
+pds_core-specify-auxiliary_device-to-be-created.patch
+pds_core-remove-write-after-free-of-client_id.patch
+net_sched-drr-fix-double-list-add-in-class-with-nete.patch
+net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch
+net_sched-ets-fix-double-list-add-in-class-with-nete.patch
+net_sched-qfq-fix-double-list-add-in-class-with-nete.patch
+ice-don-t-check-device-type-when-checking-gnss-prese.patch
+ice-remove-unnecessary-ice_is_e8xx-functions.patch
+ice-fix-get-tx-topology-aq-command-error-on-e830.patch
+ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch
+idpf-fix-offloads-support-for-encapsulated-packets.patch
+scsi-ufs-core-remove-redundant-query_complete-trace.patch
+drm-xe-guc-fix-capture-of-steering-registers.patch
+pinctrl-qcom-fix-pingroup-definition-for-sm8750.patch
+alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch
+nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch
+drm-tests-shmem-fix-memleak.patch
+drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch
+net-dlink-correct-endianness-handling-of-led_mode.patch
+net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch
+idpf-fix-potential-memory-leak-on-kcalloc-failure.patch
+idpf-protect-shutdown-from-reset.patch
+igc-fix-lock-order-in-igc_ptp_reset.patch
+net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch
+net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch
+net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch
+alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch
+bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch
+bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch
+bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch
+bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch
+bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch
+bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch
+bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch
+nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch
+nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch
+nvmet-tcp-select-config_tls-from-config_nvme_target_.patch
+asoc-stm32-sai-skip-useless-iterations-on-kernel-rat.patch
+asoc-stm32-sai-add-a-check-on-minimal-kernel-frequen.patch
+asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch
+bnxt_en-fix-module-unload-sequence.patch
+net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch
+ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch
+net-lan743x-fix-memleak-issue-when-gso-enabled.patch
+net-fec-err007885-workaround-for-conventional-tx.patch
+octeon_ep-fix-host-hang-issue-during-device-reboot.patch
+net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch
+net-hns3-fix-an-interrupt-residual-problem.patch
+net-hns3-fixed-debugfs-tm_qset-size.patch
+net-hns3-defer-calling-ptp_clock_register.patch
+net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch
+net-vertexcom-mse102x-fix-len_mask.patch
+net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch
+net-vertexcom-mse102x-fix-rx-error-handling.patch
--- /dev/null
+From 91677475fdada43ad01da8ef743966b196e31c4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 17:43:33 +0530
+Subject: spi: spi-mem: Add fix to avoid divide error
+
+From: Raju Rangoju <Raju.Rangoju@amd.com>
+
+[ Upstream commit 8e4d3d8a5e51e07bd0d6cdd81b5e4af79f796927 ]
+
+For some SPI flash memory operations, dummy bytes are not mandatory. For
+example, in Winbond SPINAND flash memory devices, the `write_cache` and
+`update_cache` operation variants have zero dummy bytes. Calculating the
+duration for SPI memory operations with zero dummy bytes causes
+a divide error when `ncycles` is calculated in the
+spi_mem_calc_op_duration().
+
+Add changes to skip the 'ncylcles' calculation for zero dummy bytes.
+
+Following divide error is fixed by this change:
+
+ Oops: divide error: 0000 [#1] PREEMPT SMP NOPTI
+...
+
+ ? do_trap+0xdb/0x100
+ ? do_error_trap+0x75/0xb0
+ ? spi_mem_calc_op_duration+0x56/0xb0
+ ? exc_divide_error+0x3b/0x70
+ ? spi_mem_calc_op_duration+0x56/0xb0
+ ? asm_exc_divide_error+0x1b/0x20
+ ? spi_mem_calc_op_duration+0x56/0xb0
+ ? spinand_select_op_variant+0xee/0x190 [spinand]
+ spinand_match_and_init+0x13e/0x1a0 [spinand]
+ spinand_manufacturer_match+0x6e/0xa0 [spinand]
+ spinand_probe+0x357/0x7f0 [spinand]
+ ? kernfs_activate+0x87/0xd0
+ spi_mem_probe+0x7a/0xb0
+ spi_probe+0x7d/0x130
+
+Fixes: 226d6cb3cb79 ("spi: spi-mem: Estimate the time taken by operations")
+Suggested-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
+Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
+Link: https://patch.msgid.link/20250424121333.417372-1-Raju.Rangoju@amd.com
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mem.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index a9f0f47f4759b..74b013c41601d 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -585,7 +585,11 @@ u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
+ ns_per_cycles = 1000000000 / op->max_freq;
+ ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
+ ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);
+- ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
++
++ /* Dummy bytes are optional for some SPI flash memory operations */
++ if (op->dummy.nbytes)
++ ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
++
+ ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1);
+
+ return ncycles * ns_per_cycles;
+--
+2.39.5
+
--- /dev/null
+From 67314f081e8fbe7e70b79ca93c6ba296f8ccb613 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 17:51:31 +0300
+Subject: vxlan: vnifilter: Fix unlocked deletion of default FDB entry
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 087a9eb9e5978e3ba362e1163691e41097e8ca20 ]
+
+When a VNI is deleted from a VXLAN device in 'vnifilter' mode, the FDB
+entry associated with the default remote (assuming one was configured)
+is deleted without holding the hash lock. This is wrong and will result
+in a warning [1] being generated by the lockdep annotation that was
+added by commit ebe642067455 ("vxlan: Create wrappers for FDB lookup").
+
+Reproducer:
+
+ # ip link add vx0 up type vxlan dstport 4789 external vnifilter local 192.0.2.1
+ # bridge vni add vni 10010 remote 198.51.100.1 dev vx0
+ # bridge vni del vni 10010 dev vx0
+
+Fix by acquiring the hash lock before the deletion and releasing it
+afterwards. Blame the original commit that introduced the issue rather
+than the one that exposed it.
+
+[1]
+WARNING: CPU: 3 PID: 392 at drivers/net/vxlan/vxlan_core.c:417 vxlan_find_mac+0x17f/0x1a0
+[...]
+RIP: 0010:vxlan_find_mac+0x17f/0x1a0
+[...]
+Call Trace:
+ <TASK>
+ __vxlan_fdb_delete+0xbe/0x560
+ vxlan_vni_delete_group+0x2ba/0x940
+ vxlan_vni_del.isra.0+0x15f/0x580
+ vxlan_process_vni_filter+0x38b/0x7b0
+ vxlan_vnifilter_process+0x3bb/0x510
+ rtnetlink_rcv_msg+0x2f7/0xb70
+ netlink_rcv_skb+0x131/0x360
+ netlink_unicast+0x426/0x710
+ netlink_sendmsg+0x75a/0xc20
+ __sock_sendmsg+0xc1/0x150
+ ____sys_sendmsg+0x5aa/0x7b0
+ ___sys_sendmsg+0xfc/0x180
+ __sys_sendmsg+0x121/0x1b0
+ do_syscall_64+0xbb/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+Fixes: f9c4bb0b245c ("vxlan: vni filtering support on collect metadata device")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://patch.msgid.link/20250423145131.513029-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_vnifilter.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c
+index 6e6e9f05509ab..06d19e90eadb5 100644
+--- a/drivers/net/vxlan/vxlan_vnifilter.c
++++ b/drivers/net/vxlan/vxlan_vnifilter.c
+@@ -627,7 +627,11 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan,
+ * default dst remote_ip previously added for this vni
+ */
+ if (!vxlan_addr_any(&vninode->remote_ip) ||
+- !vxlan_addr_any(&dst->remote_ip))
++ !vxlan_addr_any(&dst->remote_ip)) {
++ u32 hash_index = fdb_head_index(vxlan, all_zeros_mac,
++ vninode->vni);
++
++ spin_lock_bh(&vxlan->hash_lock[hash_index]);
+ __vxlan_fdb_delete(vxlan, all_zeros_mac,
+ (vxlan_addr_any(&vninode->remote_ip) ?
+ dst->remote_ip : vninode->remote_ip),
+@@ -635,6 +639,8 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan,
+ vninode->vni, vninode->vni,
+ dst->remote_ifindex,
+ true);
++ spin_unlock_bh(&vxlan->hash_lock[hash_index]);
++ }
+
+ if (vxlan->dev->flags & IFF_UP) {
+ if (vxlan_addr_multicast(&vninode->remote_ip) &&
+--
+2.39.5
+
--- /dev/null
+From f85d3e6b1fe1e9b285d14febaa541af358b40c75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Apr 2025 09:59:58 +0300
+Subject: wifi: iwlwifi: back off on continuous errors
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit d49437a6afc707951e5767ef70c9726b6c05da08 ]
+
+When errors occur repeatedly, the driver shouldn't go into a
+tight loop trying to reset the device. Implement the backoff
+I had already defined IWL_TRANS_RESET_DELAY for, but clearly
+forgotten the implementation of.
+
+Fixes: 9a2f13c40c63 ("wifi: iwlwifi: implement reset escalation")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250420095642.8816e299efa2.I82cde34e2345a2b33b1f03dbb040f5ad3439a5aa@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/intel/iwlwifi/iwl-trans.c | 27 ++++++++++++++-----
+ .../net/wireless/intel/iwlwifi/iwl-trans.h | 7 +++--
+ .../net/wireless/intel/iwlwifi/pcie/trans.c | 3 ++-
+ 3 files changed, 28 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+index 47854a36413e1..8ad2bd64dbd3d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+@@ -21,6 +21,7 @@ struct iwl_trans_dev_restart_data {
+ struct list_head list;
+ unsigned int restart_count;
+ time64_t last_error;
++ bool backoff;
+ char name[];
+ };
+
+@@ -125,13 +126,20 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans)
+ if (!data)
+ return at_least;
+
+- if (ktime_get_boottime_seconds() - data->last_error >=
++ if (!data->backoff &&
++ ktime_get_boottime_seconds() - data->last_error >=
+ IWL_TRANS_RESET_OK_TIME)
+ data->restart_count = 0;
+
+ index = data->restart_count;
+- if (index >= ARRAY_SIZE(escalation_list))
++ if (index >= ARRAY_SIZE(escalation_list)) {
+ index = ARRAY_SIZE(escalation_list) - 1;
++ if (!data->backoff) {
++ data->backoff = true;
++ return IWL_RESET_MODE_BACKOFF;
++ }
++ data->backoff = false;
++ }
+
+ return max(at_least, escalation_list[index]);
+ }
+@@ -140,7 +148,8 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans)
+
+ static void iwl_trans_restart_wk(struct work_struct *wk)
+ {
+- struct iwl_trans *trans = container_of(wk, typeof(*trans), restart.wk);
++ struct iwl_trans *trans = container_of(wk, typeof(*trans),
++ restart.wk.work);
+ struct iwl_trans_reprobe *reprobe;
+ enum iwl_reset_mode mode;
+
+@@ -168,6 +177,12 @@ static void iwl_trans_restart_wk(struct work_struct *wk)
+ return;
+
+ mode = iwl_trans_determine_restart_mode(trans);
++ if (mode == IWL_RESET_MODE_BACKOFF) {
++ IWL_ERR(trans, "Too many device errors - delay next reset\n");
++ queue_delayed_work(system_unbound_wq, &trans->restart.wk,
++ IWL_TRANS_RESET_DELAY);
++ return;
++ }
+
+ iwl_trans_inc_restart_count(trans->dev);
+
+@@ -227,7 +242,7 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
+ trans->dev = dev;
+ trans->num_rx_queues = 1;
+
+- INIT_WORK(&trans->restart.wk, iwl_trans_restart_wk);
++ INIT_DELAYED_WORK(&trans->restart.wk, iwl_trans_restart_wk);
+
+ return trans;
+ }
+@@ -271,7 +286,7 @@ int iwl_trans_init(struct iwl_trans *trans)
+
+ void iwl_trans_free(struct iwl_trans *trans)
+ {
+- cancel_work_sync(&trans->restart.wk);
++ cancel_delayed_work_sync(&trans->restart.wk);
+ kmem_cache_destroy(trans->dev_cmd_pool);
+ }
+
+@@ -403,7 +418,7 @@ void iwl_trans_op_mode_leave(struct iwl_trans *trans)
+
+ iwl_trans_pcie_op_mode_leave(trans);
+
+- cancel_work_sync(&trans->restart.wk);
++ cancel_delayed_work_sync(&trans->restart.wk);
+
+ trans->op_mode = NULL;
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+index f6234065dbdde..9c64e1fd4c096 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+@@ -958,7 +958,7 @@ struct iwl_trans {
+ struct iwl_dma_ptr invalid_tx_cmd;
+
+ struct {
+- struct work_struct wk;
++ struct delayed_work wk;
+ struct iwl_fw_error_dump_mode mode;
+ bool during_reset;
+ } restart;
+@@ -1159,7 +1159,7 @@ static inline void iwl_trans_schedule_reset(struct iwl_trans *trans,
+ */
+ trans->restart.during_reset = test_bit(STATUS_IN_SW_RESET,
+ &trans->status);
+- queue_work(system_unbound_wq, &trans->restart.wk);
++ queue_delayed_work(system_unbound_wq, &trans->restart.wk, 0);
+ }
+
+ static inline void iwl_trans_fw_error(struct iwl_trans *trans,
+@@ -1258,6 +1258,9 @@ enum iwl_reset_mode {
+ IWL_RESET_MODE_RESCAN,
+ IWL_RESET_MODE_FUNC_RESET,
+ IWL_RESET_MODE_PROD_RESET,
++
++ /* keep last - special backoff value */
++ IWL_RESET_MODE_BACKOFF,
+ };
+
+ void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index c917ed4c19bcc..b1ccace7377fb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -2351,7 +2351,8 @@ void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode)
+ struct iwl_trans_pcie_removal *removal;
+ char _msg = 0, *msg = &_msg;
+
+- if (WARN_ON(mode < IWL_RESET_MODE_REMOVE_ONLY))
++ if (WARN_ON(mode < IWL_RESET_MODE_REMOVE_ONLY ||
++ mode == IWL_RESET_MODE_BACKOFF))
+ return;
+
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
+--
+2.39.5
+
--- /dev/null
+From 4f7a9a624557ab9e0f73a0b0823efeaead65efc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Apr 2025 10:00:00 +0300
+Subject: wifi: iwlwifi: don't warn if the NIC is gone in resume
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit 15220a257319ffe3bf95796326dfe0aacdbeb1c4 ]
+
+Some BIOSes decide to power gate the WLAN device during S3. Since
+iwlwifi doesn't expect this, it gets very noisy reporting that the
+device is no longer available. Wifi is still available because iwlwifi
+recovers, but it spews scary prints in the log.
+
+Fix that by failing gracefully.
+
+Fixes: e8bb19c1d590 ("wifi: iwlwifi: support fast resume")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250420095642.d8d58146c829.I569ca15eaaa774d633038a749cc6ec7448419714@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/intel/iwlwifi/iwl-trans.c | 1 -
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 20 ++++++++++++++++---
+ .../wireless/intel/iwlwifi/pcie/internal.h | 9 +++++----
+ .../net/wireless/intel/iwlwifi/pcie/trans.c | 13 +++++++++---
+ drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +-
+ 5 files changed, 33 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+index 8ad2bd64dbd3d..ced8261c725f8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+@@ -555,7 +555,6 @@ void __releases(nic_access)
+ iwl_trans_release_nic_access(struct iwl_trans *trans)
+ {
+ iwl_trans_pcie_release_nic_access(trans);
+- __release(nic_access);
+ }
+ IWL_EXPORT_SYMBOL(iwl_trans_release_nic_access);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index e0b657b2f74b0..89a28e42975cb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -1703,10 +1703,24 @@ static int _iwl_pci_resume(struct device *device, bool restore)
+ * need to reset it completely.
+ * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan,
+ * so assume that any bits there mean that the device is usable.
++ * For older devices, just try silently to grab the NIC.
+ */
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ &&
+- !iwl_read32(trans, CSR_FUNC_SCRATCH))
+- device_was_powered_off = true;
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
++ if (!iwl_read32(trans, CSR_FUNC_SCRATCH))
++ device_was_powered_off = true;
++ } else {
++ /*
++ * bh are re-enabled by iwl_trans_pcie_release_nic_access,
++ * so re-enable them if _iwl_trans_pcie_grab_nic_access fails.
++ */
++ local_bh_disable();
++ if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
++ iwl_trans_pcie_release_nic_access(trans);
++ } else {
++ device_was_powered_off = true;
++ local_bh_enable();
++ }
++ }
+
+ if (restore || device_was_powered_off) {
+ trans->state = IWL_TRANS_NO_FW;
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+index 45460f93d24ad..114a9195ad7f7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+@@ -558,10 +558,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
+ void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions,
+ struct device *dev);
+
+-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
+-#define _iwl_trans_pcie_grab_nic_access(trans) \
++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent);
++#define _iwl_trans_pcie_grab_nic_access(trans, silent) \
+ __cond_lock(nic_access_nobh, \
+- likely(__iwl_trans_pcie_grab_nic_access(trans)))
++ likely(__iwl_trans_pcie_grab_nic_access(trans, silent)))
+
+ void iwl_trans_pcie_check_product_reset_status(struct pci_dev *pdev);
+ void iwl_trans_pcie_check_product_reset_mode(struct pci_dev *pdev);
+@@ -1105,7 +1105,8 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
+ int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
+ u32 *val);
+ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
+-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
++void __releases(nic_access_nobh)
++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
+
+ /* transport gen 1 exported functions */
+ void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index b1ccace7377fb..102a6123bba0e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -2406,7 +2406,7 @@ EXPORT_SYMBOL(iwl_trans_pcie_reset);
+ * This version doesn't disable BHs but rather assumes they're
+ * already disabled.
+ */
+-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
+ {
+ int ret;
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+@@ -2458,6 +2458,11 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
+ if (unlikely(ret < 0)) {
+ u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
+
++ if (silent) {
++ spin_unlock(&trans_pcie->reg_lock);
++ return false;
++ }
++
+ WARN_ONCE(1,
+ "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
+ cntrl);
+@@ -2489,7 +2494,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
+ bool ret;
+
+ local_bh_disable();
+- ret = __iwl_trans_pcie_grab_nic_access(trans);
++ ret = __iwl_trans_pcie_grab_nic_access(trans, false);
+ if (ret) {
+ /* keep BHs disabled until iwl_trans_pcie_release_nic_access */
+ return ret;
+@@ -2498,7 +2503,8 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
+ return false;
+ }
+
+-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
++void __releases(nic_access_nobh)
++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
+ {
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+@@ -2525,6 +2531,7 @@ void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
+ * scheduled on different CPUs (after we drop reg_lock).
+ */
+ out:
++ __release(nic_access_nobh);
+ spin_unlock_bh(&trans_pcie->reg_lock);
+ }
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+index 7c1dd5cc084ac..83c6fcafcf1a4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+@@ -1021,7 +1021,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
+ * returned. This needs to be done only on NICs that have
+ * apmg_wake_up_wa set (see above.)
+ */
+- if (!_iwl_trans_pcie_grab_nic_access(trans))
++ if (!_iwl_trans_pcie_grab_nic_access(trans, false))
+ return -EIO;
+
+ /*
+--
+2.39.5
+
--- /dev/null
+From 55d6400174de1e57667449b3c84cb4560a667df1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Apr 2025 10:00:01 +0300
+Subject: wifi: iwlwifi: fix the check for the SCRATCH register upon resume
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit a17821321a9b42f26e77335cd525fee72dc1cd63 ]
+
+We can't rely on the SCRATCH register being 0 on platform that power
+gate the NIC in S3. Even in those platforms, the SCRATCH register is
+still returning 0x1010000.
+
+Make sure that we understand that those platforms have powered off the
+device.
+
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597
+Fixes: cb347bd29d0d ("wifi: iwlwifi: mvm: fix hibernation")
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250420095642.a7e082ee785c.I9418d76f860f54261cfa89e1f7ac10300904ba40@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 +
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 ++++--
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+index be9e464c9b7b0..3ff493e920d28 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+@@ -148,6 +148,7 @@
+ * during a error FW error.
+ */
+ #define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)
++#define CSR_FUNC_SCRATCH_POWER_OFF_MASK 0xFFFF
+
+ /* Bits for CSR_HW_IF_CONFIG_REG */
+ #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F)
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 89a28e42975cb..d4c1bc20971fb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -1702,11 +1702,13 @@ static int _iwl_pci_resume(struct device *device, bool restore)
+ * Scratch value was altered, this means the device was powered off, we
+ * need to reset it completely.
+ * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan,
+- * so assume that any bits there mean that the device is usable.
++ * but not bits [15:8]. So if we have bits set in lower word, assume
++ * the device is alive.
+ * For older devices, just try silently to grab the NIC.
+ */
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+- if (!iwl_read32(trans, CSR_FUNC_SCRATCH))
++ if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) &
++ CSR_FUNC_SCRATCH_POWER_OFF_MASK))
+ device_was_powered_off = true;
+ } else {
+ /*
+--
+2.39.5
+
--- /dev/null
+From 66ba6ffe38495237b2c1459736c0fa8bad0e4207 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 21:52:25 +0300
+Subject: wifi: plfxlc: Remove erroneous assert in plfxlc_mac_release
+
+From: Murad Masimov <m.masimov@mt-integration.ru>
+
+[ Upstream commit 0fb15ae3b0a9221be01715dac0335647c79f3362 ]
+
+plfxlc_mac_release() asserts that mac->lock is held. This assertion is
+incorrect, because even if it was possible, it would not be the valid
+behaviour. The function is used when probe fails or after the device is
+disconnected. In both cases mac->lock can not be held as the driver is
+not working with the device at the moment. All functions that use mac->lock
+unlock it just after it was held. There is also no need to hold mac->lock
+for plfxlc_mac_release() itself, as mac data is not affected, except for
+mac->flags, which is modified atomically.
+
+This bug leads to the following warning:
+================================================================
+WARNING: CPU: 0 PID: 127 at drivers/net/wireless/purelifi/plfxlc/mac.c:106 plfxlc_mac_release+0x7d/0xa0
+Modules linked in:
+CPU: 0 PID: 127 Comm: kworker/0:2 Not tainted 6.1.124-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+Workqueue: usb_hub_wq hub_event
+RIP: 0010:plfxlc_mac_release+0x7d/0xa0 drivers/net/wireless/purelifi/plfxlc/mac.c:106
+Call Trace:
+ <TASK>
+ probe+0x941/0xbd0 drivers/net/wireless/purelifi/plfxlc/usb.c:694
+ usb_probe_interface+0x5c0/0xaf0 drivers/usb/core/driver.c:396
+ really_probe+0x2ab/0xcb0 drivers/base/dd.c:639
+ __driver_probe_device+0x1a2/0x3d0 drivers/base/dd.c:785
+ driver_probe_device+0x50/0x420 drivers/base/dd.c:815
+ __device_attach_driver+0x2cf/0x510 drivers/base/dd.c:943
+ bus_for_each_drv+0x183/0x200 drivers/base/bus.c:429
+ __device_attach+0x359/0x570 drivers/base/dd.c:1015
+ bus_probe_device+0xba/0x1e0 drivers/base/bus.c:489
+ device_add+0xb48/0xfd0 drivers/base/core.c:3696
+ usb_set_configuration+0x19dd/0x2020 drivers/usb/core/message.c:2165
+ usb_generic_driver_probe+0x84/0x140 drivers/usb/core/generic.c:238
+ usb_probe_device+0x130/0x260 drivers/usb/core/driver.c:293
+ really_probe+0x2ab/0xcb0 drivers/base/dd.c:639
+ __driver_probe_device+0x1a2/0x3d0 drivers/base/dd.c:785
+ driver_probe_device+0x50/0x420 drivers/base/dd.c:815
+ __device_attach_driver+0x2cf/0x510 drivers/base/dd.c:943
+ bus_for_each_drv+0x183/0x200 drivers/base/bus.c:429
+ __device_attach+0x359/0x570 drivers/base/dd.c:1015
+ bus_probe_device+0xba/0x1e0 drivers/base/bus.c:489
+ device_add+0xb48/0xfd0 drivers/base/core.c:3696
+ usb_new_device+0xbdd/0x18f0 drivers/usb/core/hub.c:2620
+ hub_port_connect drivers/usb/core/hub.c:5477 [inline]
+ hub_port_connect_change drivers/usb/core/hub.c:5617 [inline]
+ port_event drivers/usb/core/hub.c:5773 [inline]
+ hub_event+0x2efe/0x5730 drivers/usb/core/hub.c:5855
+ process_one_work+0x8a9/0x11d0 kernel/workqueue.c:2292
+ worker_thread+0xa47/0x1200 kernel/workqueue.c:2439
+ kthread+0x28d/0x320 kernel/kthread.c:376
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
+ </TASK>
+================================================================
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 68d57a07bfe5 ("wireless: add plfxlc driver for pureLiFi X, XL, XC devices")
+Reported-by: syzbot+7d4f142f6c288de8abfe@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=7d4f142f6c288de8abfe
+Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
+Link: https://patch.msgid.link/20250321185226.71-2-m.masimov@mt-integration.ru
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/purelifi/plfxlc/mac.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c
+index eae93efa61504..82d1bf7edba20 100644
+--- a/drivers/net/wireless/purelifi/plfxlc/mac.c
++++ b/drivers/net/wireless/purelifi/plfxlc/mac.c
+@@ -102,7 +102,6 @@ int plfxlc_mac_init_hw(struct ieee80211_hw *hw)
+ void plfxlc_mac_release(struct plfxlc_mac *mac)
+ {
+ plfxlc_chip_release(&mac->chip);
+- lockdep_assert_held(&mac->lock);
+ }
+
+ int plfxlc_op_start(struct ieee80211_hw *hw)
+--
+2.39.5
+
--- /dev/null
+From 5fc4adc64e21b01fb94dfd6c178e33c6829cb60a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 13:29:25 +0200
+Subject: xsk: Fix offset calculation in unaligned mode
+
+From: e.kubanski <e.kubanski@partner.samsung.com>
+
+[ Upstream commit bf20af07909925ec0ae6cd4f3b7be0279dfa8768 ]
+
+Bring back previous offset calculation behaviour
+in AF_XDP unaligned umem mode.
+
+In unaligned mode, upper 16 bits should contain
+data offset, lower 48 bits should contain
+only specific chunk location without offset.
+
+Remove pool->headroom duplication into 48bit address.
+
+Signed-off-by: Eryk Kubanski <e.kubanski@partner.samsung.com>
+Fixes: bea14124bacb ("xsk: Get rid of xdp_buff_xsk::orig_addr")
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://patch.msgid.link/20250416112925.7501-1-e.kubanski@partner.samsung.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xsk_buff_pool.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index 7f0a75d6563d8..b3699a8488444 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -232,8 +232,8 @@ static inline u64 xp_get_handle(struct xdp_buff_xsk *xskb,
+ return orig_addr;
+
+ offset = xskb->xdp.data - xskb->xdp.data_hard_start;
+- orig_addr -= offset;
+ offset += pool->headroom;
++ orig_addr -= offset;
+ return orig_addr + (offset << XSK_UNALIGNED_BUF_OFFSET_SHIFT);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 030e720e93704aca610770e3abde7c14b08da2d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 12:19:08 +0200
+Subject: xsk: Fix race condition in AF_XDP generic RX path
+
+From: e.kubanski <e.kubanski@partner.samsung.com>
+
+[ Upstream commit a1356ac7749cafc4e27aa62c0c4604b5dca4983e ]
+
+Move rx_lock from xsk_socket to xsk_buff_pool.
+Fix synchronization for shared umem mode in
+generic RX path where multiple sockets share
+single xsk_buff_pool.
+
+RX queue is exclusive to xsk_socket, while FILL
+queue can be shared between multiple sockets.
+This could result in race condition where two
+CPU cores access RX path of two different sockets
+sharing the same umem.
+
+Protect both queues by acquiring spinlock in shared
+xsk_buff_pool.
+
+Lock contention may be minimized in the future by some
+per-thread FQ buffering.
+
+It's safe and necessary to move spin_lock_bh(rx_lock)
+after xsk_rcv_check():
+* xs->pool and spinlock_init is synchronized by
+ xsk_bind() -> xsk_is_bound() memory barriers.
+* xsk_rcv_check() may return true at the moment
+ of xsk_release() or xsk_unbind_dev(),
+ however this will not cause any data races or
+ race conditions. xsk_unbind_dev() removes xdp
+ socket from all maps and waits for completion
+ of all outstanding rx operations. Packets in
+ RX path will either complete safely or drop.
+
+Signed-off-by: Eryk Kubanski <e.kubanski@partner.samsung.com>
+Fixes: bf0bdd1343efb ("xdp: fix race on generic receive path")
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://patch.msgid.link/20250416101908.10919-1-e.kubanski@partner.samsung.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xdp_sock.h | 3 ---
+ include/net/xsk_buff_pool.h | 2 ++
+ net/xdp/xsk.c | 6 +++---
+ net/xdp/xsk_buff_pool.c | 1 +
+ 4 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
+index a58ae7589d121..e8bd6ddb7b127 100644
+--- a/include/net/xdp_sock.h
++++ b/include/net/xdp_sock.h
+@@ -71,9 +71,6 @@ struct xdp_sock {
+ */
+ u32 tx_budget_spent;
+
+- /* Protects generic receive. */
+- spinlock_t rx_lock;
+-
+ /* Statistics */
+ u64 rx_dropped;
+ u64 rx_queue_full;
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index 50779406bc2d9..7f0a75d6563d8 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -53,6 +53,8 @@ struct xsk_buff_pool {
+ refcount_t users;
+ struct xdp_umem *umem;
+ struct work_struct work;
++ /* Protects generic receive in shared and non-shared umem mode. */
++ spinlock_t rx_lock;
+ struct list_head free_list;
+ struct list_head xskb_list;
+ u32 heads_cnt;
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index a373a7130d757..c13e13fa79fc0 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -337,13 +337,14 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
+ u32 len = xdp_get_buff_len(xdp);
+ int err;
+
+- spin_lock_bh(&xs->rx_lock);
+ err = xsk_rcv_check(xs, xdp, len);
+ if (!err) {
++ spin_lock_bh(&xs->pool->rx_lock);
+ err = __xsk_rcv(xs, xdp, len);
+ xsk_flush(xs);
++ spin_unlock_bh(&xs->pool->rx_lock);
+ }
+- spin_unlock_bh(&xs->rx_lock);
++
+ return err;
+ }
+
+@@ -1730,7 +1731,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol,
+ xs = xdp_sk(sk);
+ xs->state = XSK_READY;
+ mutex_init(&xs->mutex);
+- spin_lock_init(&xs->rx_lock);
+
+ INIT_LIST_HEAD(&xs->map_list);
+ spin_lock_init(&xs->map_list_lock);
+diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
+index d158cb6dd3919..63ae121d29e6c 100644
+--- a/net/xdp/xsk_buff_pool.c
++++ b/net/xdp/xsk_buff_pool.c
+@@ -87,6 +87,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
+ pool->addrs = umem->addrs;
+ pool->tx_metadata_len = umem->tx_metadata_len;
+ pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM;
++ spin_lock_init(&pool->rx_lock);
+ INIT_LIST_HEAD(&pool->free_list);
+ INIT_LIST_HEAD(&pool->xskb_list);
+ INIT_LIST_HEAD(&pool->xsk_tx_list);
+--
+2.39.5
+