From: Sasha Levin Date: Tue, 6 May 2025 11:50:05 +0000 (-0400) Subject: Fixes for 6.14 X-Git-Tag: v5.15.182~57 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ce11679d6b9f1f83f5d80361a85985780f825435;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.14 Signed-off-by: Sasha Levin --- diff --git a/queue-6.14/accel-ivpu-correct-dct-interrupt-handling.patch b/queue-6.14/accel-ivpu-correct-dct-interrupt-handling.patch new file mode 100644 index 0000000000..7b6b8953e4 --- /dev/null +++ b/queue-6.14/accel-ivpu-correct-dct-interrupt-handling.patch @@ -0,0 +1,97 @@ +From 7cc981f9ddefe79879847bdb5635a8030fc4d43f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 12:26:16 +0200 +Subject: accel/ivpu: Correct DCT interrupt handling + +From: Karol Wachowski + +[ 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 +Signed-off-by: Maciej Falkowski +Reviewed-by: Jeff Hugo +Signed-off-by: Jacek Lawrynowicz +Link: https://lore.kernel.org/r/20250416102616.384577-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/alsa-hda-realtek-enable-speaker-for-hp-platform.patch b/queue-6.14/alsa-hda-realtek-enable-speaker-for-hp-platform.patch new file mode 100644 index 0000000000..ec5b7264d7 --- /dev/null +++ b/queue-6.14/alsa-hda-realtek-enable-speaker-for-hp-platform.patch @@ -0,0 +1,66 @@ +From c925e39096a8c7ffbf65b9640cd2ba1f21e42b18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 15:04:02 +0800 +Subject: ALSA: hda/realtek - Enable speaker for HP platform + +From: Kailang Yang + +[ 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 +Link: https://lore.kernel.org/eb4c14a4d85740069c909e756bbacb0e@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch b/queue-6.14/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch new file mode 100644 index 0000000000..b43847bda3 --- /dev/null +++ b/queue-6.14/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch @@ -0,0 +1,62 @@ +From bdf2aa2ec88dd5aabba224dfcf229cc3e7b971c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 07:31:41 +0200 +Subject: ALSA: hda/realtek: Fix built-mic regression on other ASUS models + +From: Takashi Iwai + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch b/queue-6.14/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch new file mode 100644 index 0000000000..0afd5053d9 --- /dev/null +++ b/queue-6.14/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch @@ -0,0 +1,45 @@ +From 4a3395f9f5ab4fcc97c08250b8dae27702ecefab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 14:48:41 +0200 +Subject: ALSA: ump: Fix buffer overflow at UMP SysEx message conversion + +From: Takashi Iwai + +[ 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 +Link: https://patch.msgid.link/20250429124845.25128-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch b/queue-6.14/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch new file mode 100644 index 0000000000..dd3246aa2b --- /dev/null +++ b/queue-6.14/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch @@ -0,0 +1,38 @@ +From 78c9d2b7bd43d99cb5631044954676e775b4e60d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20250425060144.1773265-2-venkataprasad.potturu@amd.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch b/queue-6.14/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch new file mode 100644 index 0000000000..b83899a85e --- /dev/null +++ b/queue-6.14/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch @@ -0,0 +1,45 @@ +From bc036ee644e6050fad94dc4a09d2471b47137381 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20250411123608.1676462-3-rf@opensource.cirrus.com +Reviewed-by: David Gow +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch b/queue-6.14/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch new file mode 100644 index 0000000000..b6da7a684a --- /dev/null +++ b/queue-6.14/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch @@ -0,0 +1,37 @@ +From ab76ea450ebb73b2622cdbfe01837c25c9e252f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit 68715cb5c0e00284d93f976c6368809f64131b0b ] + +mic_name returned by devm_kasprintf() could be NULL. +Add a check for it. + +Signed-off-by: Chenyuan Yang +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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch b/queue-6.14/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch new file mode 100644 index 0000000000..efa836883f --- /dev/null +++ b/queue-6.14/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch @@ -0,0 +1,46 @@ +From 02ba48d82dfd7db60c299fcc8003a168b43be4df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20250429094910.1150970-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch b/queue-6.14/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch new file mode 100644 index 0000000000..4a6147c5fd --- /dev/null +++ b/queue-6.14/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch @@ -0,0 +1,69 @@ +From 56fbbe46f174ddb85833bedfc564044df85a488f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 10:59:53 +0000 +Subject: ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence + +From: Sheetal + +[ 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 +Link: https://patch.msgid.link/20250404105953.2784819-1-sheetal@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-stm32-sai-add-a-check-on-minimal-kernel-frequen.patch b/queue-6.14/asoc-stm32-sai-add-a-check-on-minimal-kernel-frequen.patch new file mode 100644 index 0000000000..bf5e36e8b9 --- /dev/null +++ b/queue-6.14/asoc-stm32-sai-add-a-check-on-minimal-kernel-frequen.patch @@ -0,0 +1,46 @@ +From af76111bd263d358a494b1e692c6101e0c2c606a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 18:52:09 +0200 +Subject: ASoC: stm32: sai: add a check on minimal kernel frequency + +From: Olivier Moysan + +[ 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 +Link: https://patch.msgid.link/20250430165210.321273-3-olivier.moysan@foss.st.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/asoc-stm32-sai-skip-useless-iterations-on-kernel-rat.patch b/queue-6.14/asoc-stm32-sai-skip-useless-iterations-on-kernel-rat.patch new file mode 100644 index 0000000000..d7fcf8514a --- /dev/null +++ b/queue-6.14/asoc-stm32-sai-skip-useless-iterations-on-kernel-rat.patch @@ -0,0 +1,72 @@ +From bf50f3b32fc51500b4ca518977203fc9ef06fd12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 18:52:08 +0200 +Subject: ASoC: stm32: sai: skip useless iterations on kernel rate loop + +From: Olivier Moysan + +[ 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 +Link: https://patch.msgid.link/20250430165210.321273-2-olivier.moysan@foss.st.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch b/queue-6.14/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch new file mode 100644 index 0000000000..4d4a2023b0 --- /dev/null +++ b/queue-6.14/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch @@ -0,0 +1,82 @@ +From 9bd1c3ce36bca85e0f3deeb2a16a99ccba6e17e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Kiran K +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch b/queue-6.14/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch new file mode 100644 index 0000000000..8e9a7905d6 --- /dev/null +++ b/queue-6.14/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch @@ -0,0 +1,99 @@ +From 3244a325c3c8fdea8b5764d0970e82600ac3de36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 09:18:42 +0530 +Subject: Bluetooth: btintel_pcie: Avoid redundant buffer allocation + +From: Kiran K + +[ 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 +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch b/queue-6.14/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch new file mode 100644 index 0000000000..c11ee0c23a --- /dev/null +++ b/queue-6.14/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch @@ -0,0 +1,197 @@ +From 839c4be34b6b56f54a2ccff47a2afcc7c8955b5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 21:00:37 +0800 +Subject: Bluetooth: btusb: avoid NULL pointer dereference in skb_dequeue() + +From: En-Wei Wu + +[ 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 +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch b/queue-6.14/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch new file mode 100644 index 0000000000..8b2c74da6d --- /dev/null +++ b/queue-6.14/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch @@ -0,0 +1,338 @@ +From 685678ddbdd926bf72b9254fbfd86de838335e51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch b/queue-6.14/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch new file mode 100644 index 0000000000..490b453e57 --- /dev/null +++ b/queue-6.14/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch @@ -0,0 +1,346 @@ +From fa3f19bd6e421e93044b0a6f3f72c4673e3a1dd1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch b/queue-6.14/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch new file mode 100644 index 0000000000..7dd0de7a16 --- /dev/null +++ b/queue-6.14/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch @@ -0,0 +1,37 @@ +From f809edfa758f765b3c246794548c126ad97d97a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 22:51:03 +0300 +Subject: Bluetooth: L2CAP: copy RX timestamp to new fragments + +From: Pauli Virtanen + +[ 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 +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch b/queue-6.14/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch new file mode 100644 index 0000000000..4ea6f01e83 --- /dev/null +++ b/queue-6.14/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch @@ -0,0 +1,43 @@ +From 4f26fb2c6ad52c7e7b344929c225cc443116f2b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Pavan Chebbi +Signed-off-by: Somnath Kotur +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch b/queue-6.14/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch new file mode 100644 index 0000000000..39c95862d2 --- /dev/null +++ b/queue-6.14/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch @@ -0,0 +1,51 @@ +From bfc50fedc292b0c5b33641888cc3064f8de5d132 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:59 -0700 +Subject: bnxt_en: call pci_alloc_irq_vectors() after bnxt_reserve_rings() + +From: Kashyap Desai + +[ 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 +Signed-off-by: Kashyap Desai +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch b/queue-6.14/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch new file mode 100644 index 0000000000..5440d1adc5 --- /dev/null +++ b/queue-6.14/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch @@ -0,0 +1,48 @@ +From b783c5564756319b70504305b0e6a66d47554d9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:01 -0700 +Subject: bnxt_en: Fix coredump logic to free allocated buffer + +From: Shruti Parab + +[ 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 +Reviewed-by: Kalesh AP +Signed-off-by: Shruti Parab +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch b/queue-6.14/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch new file mode 100644 index 0000000000..414c629750 --- /dev/null +++ b/queue-6.14/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch @@ -0,0 +1,50 @@ +From 0aba37a3aca37e1a3624146425467777dba7cd7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:56 -0700 +Subject: bnxt_en: Fix error handling path in bnxt_init_chip() + +From: Shravya KN + +[ 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 +Reviewed-by: Somnath Kotur +Signed-off-by: Shravya KN +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch b/queue-6.14/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch new file mode 100644 index 0000000000..7a6f17c61c --- /dev/null +++ b/queue-6.14/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch @@ -0,0 +1,85 @@ +From b024233bd747180fae933091dc9bbc72e135b7a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:03 -0700 +Subject: bnxt_en: Fix ethtool -d byte order for 32-bit values + +From: Michael Chan + +[ 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 +Reviewed-by: Kalesh AP +Reviewed-by: Andy Gospodarek +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch b/queue-6.14/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch new file mode 100644 index 0000000000..cf8db6a00d --- /dev/null +++ b/queue-6.14/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch @@ -0,0 +1,49 @@ +From 81f7fe6813ff816817b4dc953fc5fe715bfbc1b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Kalesh AP +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-fix-module-unload-sequence.patch b/queue-6.14/bnxt_en-fix-module-unload-sequence.patch new file mode 100644 index 0000000000..5013e31f3e --- /dev/null +++ b/queue-6.14/bnxt_en-fix-module-unload-sequence.patch @@ -0,0 +1,48 @@ +From 1cd098738a2dccd3eb870f5460ee66e245af2af7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 10:03:43 -0700 +Subject: bnxt_en: fix module unload sequence + +From: Vadim Fedorenko + +[ 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 +Closes: https://lore.kernel.org/netdev/CAMArcTWDe2cd41=ub=zzvYifaYcYv-N-csxfqxUvejy_L0D6UQ@mail.gmail.com/ +Signed-off-by: Vadim Fedorenko +Reviewed-by: Jacob Keller +Reviewed-by: Michael Chan +Tested-by: Taehee Yoo +Link: https://patch.msgid.link/20250430170343.759126-1-vadfed@meta.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch b/queue-6.14/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch new file mode 100644 index 0000000000..bc43992ee1 --- /dev/null +++ b/queue-6.14/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch @@ -0,0 +1,95 @@ +From 91a2f4312dfcfb505b6a0eaaa97961e2dab3c047 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:02 -0700 +Subject: bnxt_en: Fix out-of-bound memcpy() during ethtool -w + +From: Shruti Parab + +[ 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 +Signed-off-by: Shruti Parab +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/bnxt_en-improve-tx-timestamping-fifo-configuration.patch b/queue-6.14/bnxt_en-improve-tx-timestamping-fifo-configuration.patch new file mode 100644 index 0000000000..2895a40139 --- /dev/null +++ b/queue-6.14/bnxt_en-improve-tx-timestamping-fifo-configuration.patch @@ -0,0 +1,121 @@ +From 818038a92a298c17ecef472a48489d575c86d961 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 05:55:47 -0700 +Subject: bnxt_en: improve TX timestamping FIFO configuration + +From: Vadim Fedorenko + +[ 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 +Reviewed-by: Pavan Chebbi +Signed-off-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250424125547.460632-1-vadfed@meta.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/book3s64-radix-align-section-vmemmap-start-address-t.patch b/queue-6.14/book3s64-radix-align-section-vmemmap-start-address-t.patch new file mode 100644 index 0000000000..e191b28064 --- /dev/null +++ b/queue-6.14/book3s64-radix-align-section-vmemmap-start-address-t.patch @@ -0,0 +1,160 @@ +From f7ded002ce8260b3b5a5a76fa787acc0b231b12a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 07:44:10 -0500 +Subject: book3s64/radix : Align section vmemmap start address to PAGE_SIZE + +From: Donet Tom + +[ 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 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) +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Donet Tom +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/8f98ec2b442977c618f7256cec88eb17dde3f2b9.1741609795.git.donettom@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/cpufreq-acpi-re-sync-cpu-boost-state-on-system-resum.patch b/queue-6.14/cpufreq-acpi-re-sync-cpu-boost-state-on-system-resum.patch new file mode 100644 index 0000000000..51edf078fb --- /dev/null +++ b/queue-6.14/cpufreq-acpi-re-sync-cpu-boost-state-on-system-resum.patch @@ -0,0 +1,72 @@ +From 8a7088de1b8bb994f154c559f3c03610ca71f973 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220013 +Tested-by: Nicholas Chin +Reviewed-by: Lifeng Zheng +Signed-off-by: Viresh Kumar +Link: https://patch.msgid.link/9c7de55fb06015c1b77e7dafd564b659838864e0.1745511526.git.viresh.kumar@linaro.org +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/cpufreq-acpi-set-policy-boost_supported.patch b/queue-6.14/cpufreq-acpi-set-policy-boost_supported.patch new file mode 100644 index 0000000000..45d7aa730a --- /dev/null +++ b/queue-6.14/cpufreq-acpi-set-policy-boost_supported.patch @@ -0,0 +1,40 @@ +From dbf0e3ebb5beefa9026191b6793afa6f4d1c90a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jan 2025 15:30:42 +0530 +Subject: cpufreq: acpi: Set policy->boost_supported + +From: Viresh Kumar + +[ 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 +Stable-dep-of: 3d59224947b0 ("cpufreq: ACPI: Re-sync CPU boost state on system resume") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/cpufreq-introduce-policy-boost_supported-flag.patch b/queue-6.14/cpufreq-introduce-policy-boost_supported-flag.patch new file mode 100644 index 0000000000..e51ee62129 --- /dev/null +++ b/queue-6.14/cpufreq-introduce-policy-boost_supported-flag.patch @@ -0,0 +1,62 @@ +From 26e5213be2816e03e00a4656e5643eb3cc2be899 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jan 2025 11:04:25 +0530 +Subject: cpufreq: Introduce policy->boost_supported flag + +From: Viresh Kumar + +[ 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 +Stable-dep-of: 3d59224947b0 ("cpufreq: ACPI: Re-sync CPU boost state on system resume") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch b/queue-6.14/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch new file mode 100644 index 0000000000..00800bd10c --- /dev/null +++ b/queue-6.14/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch @@ -0,0 +1,67 @@ +From 067f4e8967e222afcaa566861d93614e426ebaf7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Fixes: 99afb7cc8c44 ("drm/i915/pxp: Add ARB session creation and cleanup") +Reviewed-by: Jani Nikula +Link: https://lore.kernel.org/r/20250415090616.2649889-1-jani.nikula@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit b484c1e225a6a582fc78c4d7af7b286408bb7d41) +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch b/queue-6.14/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch new file mode 100644 index 0000000000..f51160f7f0 --- /dev/null +++ b/queue-6.14/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch @@ -0,0 +1,53 @@ +From 1cace7ab8e5ed03f49ebd3a7cb69ef94a62d845b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Apr 2025 22:32:59 -0700 +Subject: drm/mipi-dbi: Fix blanking for non-16 bit formats + +From: Russell Cloran + +[ 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 +Link: https://lore.kernel.org/r/20250415053259.79572-1-rcloran@gmail.com +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/drm-tests-shmem-fix-memleak.patch b/queue-6.14/drm-tests-shmem-fix-memleak.patch new file mode 100644 index 0000000000..76090b3cd1 --- /dev/null +++ b/queue-6.14/drm-tests-shmem-fix-memleak.patch @@ -0,0 +1,45 @@ +From 80b548d6446cdfbaa436071d40aee8abc5262990 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Apr 2025 16:07:58 +0200 +Subject: drm/tests: shmem: Fix memleak + +From: Maxime Ripard + +[ 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 +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 +Link: https://lore.kernel.org/r/20250408140758.1831333-1-mripard@kernel.org +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/drm-xe-guc-fix-capture-of-steering-registers.patch b/queue-6.14/drm-xe-guc-fix-capture-of-steering-registers.patch new file mode 100644 index 0000000000..1c0d096fe8 --- /dev/null +++ b/queue-6.14/drm-xe-guc-fix-capture-of-steering-registers.patch @@ -0,0 +1,53 @@ +From d0c488aba8e375736ba591c202249049fc188817 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Alan Previn +Cc: Matt Roper +Cc: Lucas De Marchi +Cc: "Thomas Hellström" +Cc: Rodrigo Vivi +Cc: intel-xe@lists.freedesktop.org +Signed-off-by: John Harrison +Reviewed-by: Matt Roper +Reviewed-by: Zhanjun Dong +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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/firmware-cs_dsp-tests-depend-on-fw_cs_dsp-rather-the.patch b/queue-6.14/firmware-cs_dsp-tests-depend-on-fw_cs_dsp-rather-the.patch new file mode 100644 index 0000000000..239a535812 --- /dev/null +++ b/queue-6.14/firmware-cs_dsp-tests-depend-on-fw_cs_dsp-rather-the.patch @@ -0,0 +1,47 @@ +From 369ad5feeb693686f451aa34f22fbe4014ddcfad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Richard Fitzgerald +Link: https://patch.msgid.link/20250411123608.1676462-4-rf@opensource.cirrus.com +Reviewed-by: David Gow +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch b/queue-6.14/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch new file mode 100644 index 0000000000..35f6902a6b --- /dev/null +++ b/queue-6.14/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch @@ -0,0 +1,44 @@ +From f5722191ff78246dfefd8f336fc9a2f776d30c2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Przemek Kitszel +Reviewed-by: Simon Horman +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20250425222636.3188441-3-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/ice-don-t-check-device-type-when-checking-gnss-prese.patch b/queue-6.14/ice-don-t-check-device-type-when-checking-gnss-prese.patch new file mode 100644 index 0000000000..e1b902b403 --- /dev/null +++ b/queue-6.14/ice-don-t-check-device-type-when-checking-gnss-prese.patch @@ -0,0 +1,356 @@ +From 7d3dc15b9d58825c4541a8c163c885059a9d2a73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 14:12:38 +0200 +Subject: ice: Don't check device type when checking GNSS presence + +From: Karol Kolacinski + +[ 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 +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 3ffcd7b657c9 ("ice: fix Get Tx Topology AQ command error on E830") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/ice-fix-get-tx-topology-aq-command-error-on-e830.patch b/queue-6.14/ice-fix-get-tx-topology-aq-command-error-on-e830.patch new file mode 100644 index 0000000000..2830e7b1f3 --- /dev/null +++ b/queue-6.14/ice-fix-get-tx-topology-aq-command-error-on-e830.patch @@ -0,0 +1,71 @@ +From 5d5ba6363a892c010e03f1798922fce2e8e95092 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:26:31 -0700 +Subject: ice: fix Get Tx Topology AQ command error on E830 + +From: Paul Greenwalt + +[ 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 +Signed-off-by: Jacob Keller +Reviewed-by: Michal Swiatkowski +Tested-by: Krishneil Singh +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20250425222636.3188441-2-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/ice-remove-unnecessary-ice_is_e8xx-functions.patch b/queue-6.14/ice-remove-unnecessary-ice_is_e8xx-functions.patch new file mode 100644 index 0000000000..f327f1efe0 --- /dev/null +++ b/queue-6.14/ice-remove-unnecessary-ice_is_e8xx-functions.patch @@ -0,0 +1,908 @@ +From 2e916bcc8e8690ea64bb59fc2c61e39416d4f85d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 14:12:39 +0200 +Subject: ice: Remove unnecessary ice_is_e8xx() functions + +From: Karol Kolacinski + +[ 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 +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 3ffcd7b657c9 ("ice: fix Get Tx Topology AQ command error on E830") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/idpf-fix-offloads-support-for-encapsulated-packets.patch b/queue-6.14/idpf-fix-offloads-support-for-encapsulated-packets.patch new file mode 100644 index 0000000000..e0c55d7899 --- /dev/null +++ b/queue-6.14/idpf-fix-offloads-support-for-encapsulated-packets.patch @@ -0,0 +1,162 @@ +From 72b8ef5b0b8d95bf3b05c36fd9d3f1b7cc8e856a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:26:33 -0700 +Subject: idpf: fix offloads support for encapsulated packets + +From: Madhu Chittim + +[ 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 +Signed-off-by: Madhu Chittim +Tested-by: Zachary Goldstein +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250425222636.3188441-4-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch b/queue-6.14/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch new file mode 100644 index 0000000000..c035e4861f --- /dev/null +++ b/queue-6.14/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch @@ -0,0 +1,76 @@ +From 34143c28f6adb9d2877335733fbf70bb8b7f694e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 12:54:21 +0200 +Subject: idpf: fix potential memory leak on kcalloc() failure + +From: Michal Swiatkowski + +[ 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 +Reviewed-by: Aleksandr Loktionov +Suggested-by: Pavan Kumar Linga +Signed-off-by: Michal Swiatkowski +Reviewed-by: Simon Horman +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/idpf-protect-shutdown-from-reset.patch b/queue-6.14/idpf-protect-shutdown-from-reset.patch new file mode 100644 index 0000000000..0269569223 --- /dev/null +++ b/queue-6.14/idpf-protect-shutdown-from-reset.patch @@ -0,0 +1,53 @@ +From 25072abc2a265c4c159c43e5db4dadded9fe73b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Apr 2025 13:52:23 +0200 +Subject: idpf: protect shutdown from reset + +From: Larysa Zaremba + +[ 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 +Signed-off-by: Larysa Zaremba +Reviewed-by: Simon Horman +Reviewed-by: Emil Tantilov +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/igc-fix-lock-order-in-igc_ptp_reset.patch b/queue-6.14/igc-fix-lock-order-in-igc_ptp_reset.patch new file mode 100644 index 0000000000..9558b3a690 --- /dev/null +++ b/queue-6.14/igc-fix-lock-order-in-igc_ptp_reset.patch @@ -0,0 +1,82 @@ +From bbb039939389d8527686eb5fd4e5b4e054219826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Apr 2025 14:03:09 -0700 +Subject: igc: fix lock order in igc_ptp_reset + +From: Jacob Keller + +[ 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 +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 +Reviewed-by: Vitaly Lifshits +Tested-by: Mor Bar-Gabay +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/iommu-arm-smmu-v3-add-missing-s2fwb-feature-detectio.patch b/queue-6.14/iommu-arm-smmu-v3-add-missing-s2fwb-feature-detectio.patch new file mode 100644 index 0000000000..5ca1da0fbd --- /dev/null +++ b/queue-6.14/iommu-arm-smmu-v3-add-missing-s2fwb-feature-detectio.patch @@ -0,0 +1,49 @@ +From 66d2a4ec484e4aaefb1824a7f0353ee0e3521ddc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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) + +[ 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) +Reviewed-by: Jason Gunthorpe +Reviewed-by: Nicolin Chen +Reviewed-by: Pranjal Shrivastava +Link: https://lore.kernel.org/r/20250408033351.1012411-1-aneesh.kumar@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-dlink-correct-endianness-handling-of-led_mode.patch b/queue-6.14/net-dlink-correct-endianness-handling-of-led_mode.patch new file mode 100644 index 0000000000..5557bbbf75 --- /dev/null +++ b/queue-6.14/net-dlink-correct-endianness-handling-of-led_mode.patch @@ -0,0 +1,80 @@ +From 69678f5136fd772fc5541520aea289f8caf9fb83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 16:50:47 +0100 +Subject: net: dlink: Correct endianness handling of led_mode + +From: Simon Horman + +[ 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 +Link: https://patch.msgid.link/20250425-dlink-led-mode-v1-1-6bae3c36e736@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch b/queue-6.14/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch new file mode 100644 index 0000000000..51b6ad37fc --- /dev/null +++ b/queue-6.14/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch @@ -0,0 +1,197 @@ +From 248ad2ccb90f183043538b65ef1dd1c2a20712e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Apr 2025 17:48:55 +0300 +Subject: net: dsa: felix: fix broken taprio gate states after clock jump + +From: Vladimir Oltean + +[ 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 +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20250426144859.3128352-2-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch b/queue-6.14/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch new file mode 100644 index 0000000000..ff390b71d8 --- /dev/null +++ b/queue-6.14/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch @@ -0,0 +1,124 @@ +From 7f58f134b6596083f09c2a8f8eeb1db0dc4ce722 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Maxime Chevallier +Acked-by: Bartosz Golaszewski +Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-1-f3fde2e529d8@collabora.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch b/queue-6.14/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch new file mode 100644 index 0000000000..516310bda4 --- /dev/null +++ b/queue-6.14/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch @@ -0,0 +1,43 @@ +From 5430987a07af832d90d0457c330ffd87c8461bdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Bartosz Golaszewski +Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-2-f3fde2e529d8@collabora.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch b/queue-6.14/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch new file mode 100644 index 0000000000..648041726a --- /dev/null +++ b/queue-6.14/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch @@ -0,0 +1,57 @@ +From 99560dea4a00660bdccb58ce7743d6bd865971ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Apr 2025 02:05:44 +0100 +Subject: net: ethernet: mtk_eth_soc: fix SER panic with 4GB+ RAM + +From: Chad Monroe + +[ 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 +Link: https://patch.msgid.link/4adc2aaeb0fb1b9cdc56bf21cf8e7fa328daa345.1745715843.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch b/queue-6.14/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch new file mode 100644 index 0000000000..00083d1aa4 --- /dev/null +++ b/queue-6.14/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch @@ -0,0 +1,47 @@ +From 9448ddbf4402fda9482c1eddc887eb3bdc01a5b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 05:29:53 +0100 +Subject: net: ethernet: mtk_eth_soc: sync mtk_clks_source_name array + +From: Daniel Golle + +[ 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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/d075e706ff1cebc07f9ec666736d0b32782fd487.1745555321.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-fec-err007885-workaround-for-conventional-tx.patch b/queue-6.14/net-fec-err007885-workaround-for-conventional-tx.patch new file mode 100644 index 0000000000..400de669ad --- /dev/null +++ b/queue-6.14/net-fec-err007885-workaround-for-conventional-tx.patch @@ -0,0 +1,55 @@ +From 70223680bd99cf287fc161b25c456c53ef6848e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 11:08:26 +0200 +Subject: net: fec: ERR007885 Workaround for conventional TX + +From: Mattias Barthel + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250429090826.3101258-1-mattiasbarthel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-hns3-defer-calling-ptp_clock_register.patch b/queue-6.14/net-hns3-defer-calling-ptp_clock_register.patch new file mode 100644 index 0000000000..d0a4579019 --- /dev/null +++ b/queue-6.14/net-hns3-defer-calling-ptp_clock_register.patch @@ -0,0 +1,59 @@ +From 86671667bce25753224e8efcadad7206f4c020aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:52 +0800 +Subject: net: hns3: defer calling ptp_clock_register() + +From: Jian Shen + +[ 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 +Signed-off-by: Jijie Shao +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250430093052.2400464-5-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/net-hns3-fix-an-interrupt-residual-problem.patch b/queue-6.14/net-hns3-fix-an-interrupt-residual-problem.patch new file mode 100644 index 0000000000..635fe43889 --- /dev/null +++ b/queue-6.14/net-hns3-fix-an-interrupt-residual-problem.patch @@ -0,0 +1,192 @@ +From 48b1c58cd6c0baa3d901ca2d2f43899b2026bae4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:50 +0800 +Subject: net: hns3: fix an interrupt residual problem + +From: Yonglong Liu + +[ 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 +Signed-off-by: Jijie Shao +Link: https://patch.msgid.link/20250430093052.2400464-3-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/net-hns3-fixed-debugfs-tm_qset-size.patch b/queue-6.14/net-hns3-fixed-debugfs-tm_qset-size.patch new file mode 100644 index 0000000000..c57d0268ad --- /dev/null +++ b/queue-6.14/net-hns3-fixed-debugfs-tm_qset-size.patch @@ -0,0 +1,40 @@ +From e65e62d85225cc0a71c3cd053ddfa9a45e3dedf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:51 +0800 +Subject: net: hns3: fixed debugfs tm_qset size + +From: Hao Lan + +[ 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 +Signed-off-by: Peiyang Wang +Signed-off-by: Jijie Shao +Link: https://patch.msgid.link/20250430093052.2400464-4-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch b/queue-6.14/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch new file mode 100644 index 0000000000..1d3f73e4a1 --- /dev/null +++ b/queue-6.14/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch @@ -0,0 +1,113 @@ +From d8b03508d25b62a9c802cf7b9bad2e3aa61b222e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:49 +0800 +Subject: net: hns3: store rx VLAN tag offload state for VF + +From: Jian Shen + +[ 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 +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250430093052.2400464-2-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch b/queue-6.14/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch new file mode 100644 index 0000000000..4991e17e48 --- /dev/null +++ b/queue-6.14/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch @@ -0,0 +1,104 @@ +From ac5a870d2ed2fc7e4c20eebfd3ad63f580d92f70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Apr 2025 17:32:09 +0200 +Subject: net: ipv6: fix UDPv6 GSO segmentation with NAT + +From: Felix Fietkau + +[ 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 +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250426153210.14044-1-nbd@nbd.name +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-lan743x-fix-memleak-issue-when-gso-enabled.patch b/queue-6.14/net-lan743x-fix-memleak-issue-when-gso-enabled.patch new file mode 100644 index 0000000000..435b34da60 --- /dev/null +++ b/queue-6.14/net-lan743x-fix-memleak-issue-when-gso-enabled.patch @@ -0,0 +1,81 @@ +From 29716197a57ceba541f52fa39f72f36e7320a9fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 10:55:27 +0530 +Subject: net: lan743x: Fix memleak issue when GSO enabled + +From: Thangaraj Samynathan + +[ 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 +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250429052527.10031-1-thangaraj.s@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch b/queue-6.14/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch new file mode 100644 index 0000000000..9633bd763f --- /dev/null +++ b/queue-6.14/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch @@ -0,0 +1,51 @@ +From c1f2948a6e1d60ccf4b5f55d958cb9c735ec0666 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch b/queue-6.14/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch new file mode 100644 index 0000000000..303b70b847 --- /dev/null +++ b/queue-6.14/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch @@ -0,0 +1,110 @@ +From d2b596ed8eb492afa7ebbf05c189e0eb40571bfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:11 +0300 +Subject: net/mlx5: E-switch, Fix error handling for enabling roce + +From: Chris Mi + +[ 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 +Reviewed-by: Roi Dayan +Reviewed-by: Maor Gottlieb +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-6-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/net-mlx5-e-switch-initialize-mac-address-for-default.patch b/queue-6.14/net-mlx5-e-switch-initialize-mac-address-for-default.patch new file mode 100644 index 0000000000..f9942c449e --- /dev/null +++ b/queue-6.14/net-mlx5-e-switch-initialize-mac-address-for-default.patch @@ -0,0 +1,48 @@ +From 864fa70dcb01092119876cc1a36ba0f6915b64ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:08 +0300 +Subject: net/mlx5: E-Switch, Initialize MAC Address for Default GID + +From: Maor Gottlieb + +[ 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 +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-3-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch b/queue-6.14/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch new file mode 100644 index 0000000000..7794ec8137 --- /dev/null +++ b/queue-6.14/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch @@ -0,0 +1,62 @@ +From f4377a31e98417736643e4c77da3dcc6c046c2d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Dragos Tatulea +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250423083611.324567-5-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch b/queue-6.14/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch new file mode 100644 index 0000000000..629b2f8e8a --- /dev/null +++ b/queue-6.14/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch @@ -0,0 +1,56 @@ +From 114765a3b060fa24a16d955d4b04ad921edb29dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Cosmin Ratiu +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250423083611.324567-4-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch b/queue-6.14/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch new file mode 100644 index 0000000000..46484130d7 --- /dev/null +++ b/queue-6.14/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch @@ -0,0 +1,91 @@ +From 1e52218d965704e43d8cb42343db92b10eb12894 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:07 +0300 +Subject: net/mlx5e: Use custom tunnel header for vxlan gbp + +From: Vlad Dogaru + +[ 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 +Reviewed-by: Yevgeny Kliteynik +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-2-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch b/queue-6.14/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch new file mode 100644 index 0000000000..210627f734 --- /dev/null +++ b/queue-6.14/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch @@ -0,0 +1,72 @@ +From 4fbf2cdb04069a413c368f0bd89e079f8277260e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20250424223734.3096202-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch b/queue-6.14/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch new file mode 100644 index 0000000000..37b2e4b0ff --- /dev/null +++ b/queue-6.14/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch @@ -0,0 +1,100 @@ +From 44650b2602c4fa1ab5846ec72bd28a7dac6645d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Shiming Cheng +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250429020412.14163-1-shiming.cheng@mediatek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch b/queue-6.14/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch new file mode 100644 index 0000000000..462ac5fdc2 --- /dev/null +++ b/queue-6.14/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch @@ -0,0 +1,50 @@ +From 6e302f9663db5d33008655aca1e9021ba161c92f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:42 +0200 +Subject: net: vertexcom: mse102x: Add range check for CMD_RTS + +From: Stefan Wahren + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-4-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 + diff --git a/queue-6.14/net-vertexcom-mse102x-fix-len_mask.patch b/queue-6.14/net-vertexcom-mse102x-fix-len_mask.patch new file mode 100644 index 0000000000..d58ce5bd6a --- /dev/null +++ b/queue-6.14/net-vertexcom-mse102x-fix-len_mask.patch @@ -0,0 +1,38 @@ +From 29ed1ca8fb38088528a5e4a6c747b4071143d48b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:41 +0200 +Subject: net: vertexcom: mse102x: Fix LEN_MASK + +From: Stefan Wahren + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-3-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch b/queue-6.14/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch new file mode 100644 index 0000000000..5aecc87bfd --- /dev/null +++ b/queue-6.14/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch @@ -0,0 +1,53 @@ +From d00908df3c1a759cbe266bdbbbf34c5fd3847e42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:40 +0200 +Subject: net: vertexcom: mse102x: Fix possible stuck of SPI interrupt + +From: Stefan Wahren + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-2-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net-vertexcom-mse102x-fix-rx-error-handling.patch b/queue-6.14/net-vertexcom-mse102x-fix-rx-error-handling.patch new file mode 100644 index 0000000000..8d2a2ca4bb --- /dev/null +++ b/queue-6.14/net-vertexcom-mse102x-fix-rx-error-handling.patch @@ -0,0 +1,95 @@ +From 1149a3664e911d031e51a1b0ef332b54322272d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:43 +0200 +Subject: net: vertexcom: mse102x: Fix RX error handling + +From: Stefan Wahren + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-5-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net_sched-drr-fix-double-list-add-in-class-with-nete.patch b/queue-6.14/net_sched-drr-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..a30d882948 --- /dev/null +++ b/queue-6.14/net_sched-drr-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,75 @@ +From 0c7ea91ccd9dcb77606473b331055949f824f02f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-2-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net_sched-ets-fix-double-list-add-in-class-with-nete.patch b/queue-6.14/net_sched-ets-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..f3cc54dd57 --- /dev/null +++ b/queue-6.14/net_sched-ets-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,75 @@ +From c7db8e7e5f8d29a4992cb4390f8c785cea8fd232 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-4-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch b/queue-6.14/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch new file mode 100644 index 0000000000..34bfda006f --- /dev/null +++ b/queue-6.14/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch @@ -0,0 +1,49 @@ +From 61afe07bdbdfdf365c1ec5030d9ef95538666182 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Jamal Hadi Salim +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-3-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch b/queue-6.14/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..ab0db0407b --- /dev/null +++ b/queue-6.14/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,77 @@ +From e45299fc8f0df4abc9dcdcf05da735dae0e377b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-5-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch b/queue-6.14/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch new file mode 100644 index 0000000000..b764e3eec9 --- /dev/null +++ b/queue-6.14/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch @@ -0,0 +1,38 @@ +From 5fc3c8ca28ef459330d496e1f0fc75510d935e31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 10:18:01 -0700 +Subject: nvme-pci: fix queue unquiesce check on slot_reset + +From: Keith Busch + +[ 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 +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch b/queue-6.14/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch new file mode 100644 index 0000000000..b79b656de1 --- /dev/null +++ b/queue-6.14/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch @@ -0,0 +1,112 @@ +From a3cde99f22ae4872781db24d5282b4206d413ca7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Mohamed Khalfella +Reviewed-by: Randy Jennings +Reviewed-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch b/queue-6.14/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch new file mode 100644 index 0000000000..8c1cd2d46e --- /dev/null +++ b/queue-6.14/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch @@ -0,0 +1,38 @@ +From 39acfe1a11e6af4ca20f03a180452b8996d24017 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 08:40:25 +1000 +Subject: nvme-tcp: select CONFIG_TLS from CONFIG_NVME_TCP_TLS + +From: Alistair Francis + +[ 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 +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch b/queue-6.14/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch new file mode 100644 index 0000000000..730a9cae2e --- /dev/null +++ b/queue-6.14/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch @@ -0,0 +1,38 @@ +From 0f2878b3d02f6df0156e49540d2c0b30fc62ee45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 08:23:47 +1000 +Subject: nvmet-tcp: select CONFIG_TLS from CONFIG_NVME_TARGET_TCP_TLS + +From: Alistair Francis + +[ 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 +Reviewed-by: Hannes Reinecke +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/octeon_ep-fix-host-hang-issue-during-device-reboot.patch b/queue-6.14/octeon_ep-fix-host-hang-issue-during-device-reboot.patch new file mode 100644 index 0000000000..5d05c09a97 --- /dev/null +++ b/queue-6.14/octeon_ep-fix-host-hang-issue-during-device-reboot.patch @@ -0,0 +1,47 @@ +From 75dd43d368b27eb8c69a62a8c4e9ae607a471e38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 04:46:24 -0700 +Subject: octeon_ep: Fix host hang issue during device reboot + +From: Sathesh B Edara + +[ 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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250429114624.19104-1-sedara@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch b/queue-6.14/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch new file mode 100644 index 0000000000..0a5b1f716d --- /dev/null +++ b/queue-6.14/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch @@ -0,0 +1,43 @@ +From e716cd99a0ffcb2c88a94d400afea1116cf0594f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 06:39:44 -0700 +Subject: octeon_ep_vf: Resolve netdevice usage count issue + +From: Sathesh B Edara + +[ 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 +Link: https://patch.msgid.link/20250424133944.28128-1-sedara@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/pds_core-make-pdsc_auxbus_dev_del-void.patch b/queue-6.14/pds_core-make-pdsc_auxbus_dev_del-void.patch new file mode 100644 index 0000000000..e318b4121d --- /dev/null +++ b/queue-6.14/pds_core-make-pdsc_auxbus_dev_del-void.patch @@ -0,0 +1,87 @@ +From 7da2dc150c7f21eae03da77c01aa7723a4ab1dda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:44:07 -0700 +Subject: pds_core: make pdsc_auxbus_dev_del() void + +From: Shannon Nelson + +[ 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 +Reviewed-by: Jonathan Cameron +Reviewed-by: Kalesh AP +Reviewed-by: Dave Jiang +Signed-off-by: Shannon Nelson +Signed-off-by: Jason Gunthorpe +Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/pds_core-remove-write-after-free-of-client_id.patch b/queue-6.14/pds_core-remove-write-after-free-of-client_id.patch new file mode 100644 index 0000000000..9c6ccc4ae6 --- /dev/null +++ b/queue-6.14/pds_core-remove-write-after-free-of-client_id.patch @@ -0,0 +1,52 @@ +From 7edfdcae5d4348e6eddd41beecaee6fbf6230c43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 13:38:57 -0700 +Subject: pds_core: remove write-after-free of client_id + +From: Shannon Nelson + +[ 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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250425203857.71547-1-shannon.nelson@amd.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/pds_core-specify-auxiliary_device-to-be-created.patch b/queue-6.14/pds_core-specify-auxiliary_device-to-be-created.patch new file mode 100644 index 0000000000..7d3967cbde --- /dev/null +++ b/queue-6.14/pds_core-specify-auxiliary_device-to-be-created.patch @@ -0,0 +1,195 @@ +From 3dd3215a3e8119d2927448dfe70c0f8db1cd806c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:44:08 -0700 +Subject: pds_core: specify auxiliary_device to be created + +From: Shannon Nelson + +[ 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 +Reviewed-by: Jonathan Cameron +Reviewed-by: Dave Jiang +Signed-off-by: Shannon Nelson +Signed-off-by: Jason Gunthorpe +Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch b/queue-6.14/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch new file mode 100644 index 0000000000..353aa422ef --- /dev/null +++ b/queue-6.14/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch @@ -0,0 +1,50 @@ +From 7e0cc38739c2f563a1181cc2d00b64a595280f7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 11:16:00 +0800 +Subject: pinctrl: imx: Return NULL if no group is matched and found + +From: Hui Wang + +[ 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 +Reviewed-by: Frank Li +Link: https://lore.kernel.org/20250327031600.99723-1-hui.wang@canonical.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/pinctrl-qcom-fix-pingroup-definition-for-sm8750.patch b/queue-6.14/pinctrl-qcom-fix-pingroup-definition-for-sm8750.patch new file mode 100644 index 0000000000..2dce0204b8 --- /dev/null +++ b/queue-6.14/pinctrl-qcom-fix-pingroup-definition-for-sm8750.patch @@ -0,0 +1,44 @@ +From 0b971008034b0d2e4ab667b139d5690051c0c00a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 09:32:29 +0530 +Subject: pinctrl: qcom: Fix PINGROUP definition for sm8750 + +From: Maulik Shah + +[ 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 +Reviewed-by: Abel Vesa +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Melody Olvera +Link: https://lore.kernel.org/20250429-pinctrl_sm8750-v2-1-87d45dd3bd82@oss.qualcomm.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/powerpc-boot-check-for-ld-option-support.patch b/queue-6.14/powerpc-boot-check-for-ld-option-support.patch new file mode 100644 index 0000000000..6808e7dd17 --- /dev/null +++ b/queue-6.14/powerpc-boot-check-for-ld-option-support.patch @@ -0,0 +1,53 @@ +From 7758f2e262fff9882acd9d2aaacc537dc4ec7255 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 06:12:18 +0530 +Subject: powerpc/boot: Check for ld-option support + +From: Madhavan Srinivasan + +[ 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 +Suggested-by: Christophe Leroy +Tested-by: Venkat Rao Bagalkote +Closes: https://lore.kernel.org/linuxppc-dev/61cf556c-4947-4bd6-af63-892fc0966dad@linux.ibm.com/ +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250401004218.24869-1-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/powerpc-boot-fix-dash-warning.patch b/queue-6.14/powerpc-boot-fix-dash-warning.patch new file mode 100644 index 0000000000..6bc428f8b6 --- /dev/null +++ b/queue-6.14/powerpc-boot-fix-dash-warning.patch @@ -0,0 +1,53 @@ +From b2f1318c79918d9d306040f2c1e27b92a3480747 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 13:51:54 +0530 +Subject: powerpc/boot: Fix dash warning + +From: Madhavan Srinivasan + +[ 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 +Suggested-by: Stephen Rothwell +Tested-by: Venkat Rao Bagalkote +Reviewed-by: Stephen Rothwell +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250423082154.30625-1-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/powerpc64-ftrace-fix-module-loading-without-patchabl.patch b/queue-6.14/powerpc64-ftrace-fix-module-loading-without-patchabl.patch new file mode 100644 index 0000000000..dcc5fac977 --- /dev/null +++ b/queue-6.14/powerpc64-ftrace-fix-module-loading-without-patchabl.patch @@ -0,0 +1,56 @@ +From 37475c6a5911d17360d1fc80beff97e58e441df9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 00:18:21 +0100 +Subject: powerpc64/ftrace: fix module loading without patchable function + entries + +From: Anthony Iliopoulos + +[ 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 +Acked-by: Naveen N Rao (AMD) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250204231821.39140-1-ailiop@suse.com +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch b/queue-6.14/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch new file mode 100644 index 0000000000..aa9d9fb7b7 --- /dev/null +++ b/queue-6.14/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch @@ -0,0 +1,97 @@ +From 90802819f6f4d4270ec9db07ebf1f5a7ac9ed4a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 10:33:20 +0300 +Subject: ptp: ocp: Fix NULL dereference in Adva board SMA sysfs operations + +From: Sagi Maimon + +[ 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 +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250429073320.33277-1-maimon.sagi@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/rtase-modify-the-condition-used-to-detect-overflow-i.patch b/queue-6.14/rtase-modify-the-condition-used-to-detect-overflow-i.patch new file mode 100644 index 0000000000..4cf9d3dd14 --- /dev/null +++ b/queue-6.14/rtase-modify-the-condition-used-to-detect-overflow-i.patch @@ -0,0 +1,66 @@ +From 760eecde7ed414aa1ddd4ad6942d32a06996f013 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250424040444.5530-1-justinlai0215@realtek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/scsi-ufs-core-remove-redundant-query_complete-trace.patch b/queue-6.14/scsi-ufs-core-remove-redundant-query_complete-trace.patch new file mode 100644 index 0000000000..a6fb51ddc3 --- /dev/null +++ b/queue-6.14/scsi-ufs-core-remove-redundant-query_complete-trace.patch @@ -0,0 +1,46 @@ +From 70dfd909759c01e0c717168fba096002b3812d92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 10:06:05 +0900 +Subject: scsi: ufs: core: Remove redundant query_complete trace + +From: Keoseong Park + +[ 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 +Link: https://lore.kernel.org/r/20250425010605epcms2p67e89b351398832fe0fd547404d3afc65@epcms2p6 +Fixes: 71aabb747d5f ("scsi: ufs: core: Reuse exec_dev_cmd") +Reviewed-by: Avri Altman +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/series b/queue-6.14/series index cb72db838b..ca2a65c0cb 100644 --- a/queue-6.14/series +++ b/queue-6.14/series @@ -47,3 +47,101 @@ tracing-fix-oob-write-in-trace_seq_to_buffer.patch 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 diff --git a/queue-6.14/spi-spi-mem-add-fix-to-avoid-divide-error.patch b/queue-6.14/spi-spi-mem-add-fix-to-avoid-divide-error.patch new file mode 100644 index 0000000000..a6f027a1e7 --- /dev/null +++ b/queue-6.14/spi-spi-mem-add-fix-to-avoid-divide-error.patch @@ -0,0 +1,71 @@ +From 91677475fdada43ad01da8ef743966b196e31c4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 17:43:33 +0530 +Subject: spi: spi-mem: Add fix to avoid divide error + +From: Raju Rangoju + +[ 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 +Co-developed-by: Akshata MukundShetty +Signed-off-by: Akshata MukundShetty +Signed-off-by: Raju Rangoju +Link: https://patch.msgid.link/20250424121333.417372-1-Raju.Rangoju@amd.com +Reviewed-by: Miquel Raynal +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch b/queue-6.14/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch new file mode 100644 index 0000000000..0af5dfb301 --- /dev/null +++ b/queue-6.14/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch @@ -0,0 +1,87 @@ +From 67314f081e8fbe7e70b79ca93c6ba296f8ccb613 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 17:51:31 +0300 +Subject: vxlan: vnifilter: Fix unlocked deletion of default FDB entry + +From: Ido Schimmel + +[ 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: + + __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 +Reviewed-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20250423145131.513029-1-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/wifi-iwlwifi-back-off-on-continuous-errors.patch b/queue-6.14/wifi-iwlwifi-back-off-on-continuous-errors.patch new file mode 100644 index 0000000000..6c8478f6e6 --- /dev/null +++ b/queue-6.14/wifi-iwlwifi-back-off-on-continuous-errors.patch @@ -0,0 +1,160 @@ +From f85d3e6b1fe1e9b285d14febaa541af358b40c75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 09:59:58 +0300 +Subject: wifi: iwlwifi: back off on continuous errors + +From: Johannes Berg + +[ 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 +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250420095642.8816e299efa2.I82cde34e2345a2b33b1f03dbb040f5ad3439a5aa@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch b/queue-6.14/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch new file mode 100644 index 0000000000..5d5c046153 --- /dev/null +++ b/queue-6.14/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch @@ -0,0 +1,171 @@ +From 4f7a9a624557ab9e0f73a0b0823efeaead65efc4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250420095642.d8d58146c829.I569ca15eaaa774d633038a749cc6ec7448419714@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.14/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch b/queue-6.14/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch new file mode 100644 index 0000000000..9349224b57 --- /dev/null +++ b/queue-6.14/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch @@ -0,0 +1,63 @@ +From 55d6400174de1e57667449b3c84cb4560a667df1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 10:00:01 +0300 +Subject: wifi: iwlwifi: fix the check for the SCRATCH register upon resume + +From: Emmanuel Grumbach + +[ 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 +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250420095642.a7e082ee785c.I9418d76f860f54261cfa89e1f7ac10300904ba40@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch b/queue-6.14/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch new file mode 100644 index 0000000000..5741e5a924 --- /dev/null +++ b/queue-6.14/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch @@ -0,0 +1,89 @@ +From 66ba6ffe38495237b2c1459736c0fa8bad0e4207 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Mar 2025 21:52:25 +0300 +Subject: wifi: plfxlc: Remove erroneous assert in plfxlc_mac_release + +From: Murad Masimov + +[ 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: + + 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 + +================================================================ + +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 +Link: https://patch.msgid.link/20250321185226.71-2-m.masimov@mt-integration.ru +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/xsk-fix-offset-calculation-in-unaligned-mode.patch b/queue-6.14/xsk-fix-offset-calculation-in-unaligned-mode.patch new file mode 100644 index 0000000000..7aa7a68c12 --- /dev/null +++ b/queue-6.14/xsk-fix-offset-calculation-in-unaligned-mode.patch @@ -0,0 +1,45 @@ +From 5fc4adc64e21b01fb94dfd6c178e33c6829cb60a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 13:29:25 +0200 +Subject: xsk: Fix offset calculation in unaligned mode + +From: e.kubanski + +[ 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 +Fixes: bea14124bacb ("xsk: Get rid of xdp_buff_xsk::orig_addr") +Acked-by: Magnus Karlsson +Link: https://patch.msgid.link/20250416112925.7501-1-e.kubanski@partner.samsung.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.14/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch b/queue-6.14/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch new file mode 100644 index 0000000000..15c83ae90e --- /dev/null +++ b/queue-6.14/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch @@ -0,0 +1,122 @@ +From 030e720e93704aca610770e3abde7c14b08da2d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 12:19:08 +0200 +Subject: xsk: Fix race condition in AF_XDP generic RX path + +From: e.kubanski + +[ 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 +Fixes: bf0bdd1343efb ("xdp: fix race on generic receive path") +Acked-by: Magnus Karlsson +Link: https://patch.msgid.link/20250416101908.10919-1-e.kubanski@partner.samsung.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 +