From: Greg Kroah-Hartman Date: Thu, 21 Aug 2025 13:20:16 +0000 (+0200) Subject: 6.16-stable patches X-Git-Tag: v6.16.3~86 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9908729f18aa03e39d758df3b4a88d8ed64a9a3f;p=thirdparty%2Fkernel%2Fstable-queue.git 6.16-stable patches added patches: hwmon-gsc-hwmon-fix-fan-pwm-setpoint-show-functions.patch iio-adc-ad7173-fix-calibration-channel.patch iio-adc-ad7173-fix-channels-index-for-syscalib_mode.patch iio-adc-ad7173-fix-setting-odr-in-probe.patch iio-adc-ad_sigma_delta-change-to-buffer-predisable.patch iio-imu-bno055-fix-oob-access-of-hw_xlate-array.patch pwm-imx-tpm-reset-counter-if-cmod-is-0.patch pwm-mediatek-fix-duty-and-period-setting.patch pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch soc-qcom-mdt_loader-ensure-we-don-t-read-past-the-elf-header.patch wifi-ath11k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch wifi-ath11k-fix-dest-ring-buffer-corruption.patch wifi-ath11k-fix-source-ring-buffer-corruption.patch wifi-ath12k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch wifi-ath12k-fix-dest-ring-buffer-corruption.patch wifi-ath12k-fix-source-ring-buffer-corruption.patch wifi-brcmsmac-remove-const-from-tbl_ptr-parameter-in-wlc_lcnphy_common_read_table.patch zynq_fpga-use-sgtable-based-scatterlist-wrappers.patch --- diff --git a/queue-6.16/hwmon-gsc-hwmon-fix-fan-pwm-setpoint-show-functions.patch b/queue-6.16/hwmon-gsc-hwmon-fix-fan-pwm-setpoint-show-functions.patch new file mode 100644 index 0000000000..28ef42ec93 --- /dev/null +++ b/queue-6.16/hwmon-gsc-hwmon-fix-fan-pwm-setpoint-show-functions.patch @@ -0,0 +1,59 @@ +From 9c62e2282900332c8b711d9f9e37af369a8ef71b Mon Sep 17 00:00:00 2001 +From: Tim Harvey +Date: Fri, 18 Jul 2025 13:02:59 -0700 +Subject: hwmon: (gsc-hwmon) fix fan pwm setpoint show functions + +From: Tim Harvey + +commit 9c62e2282900332c8b711d9f9e37af369a8ef71b upstream. + +The Linux hwmon sysfs API values for pwmX_auto_pointY_pwm represent an +integer value between 0 (0%) to 255 (100%) and the pwmX_auto_pointY_temp +represent millidegrees Celcius. + +Commit a6d80df47ee2 ("hwmon: (gsc-hwmon) fix fan pwm temperature +scaling") properly addressed the incorrect scaling in the +pwm_auto_point_temp_store implementation but erroneously scaled +the pwm_auto_point_pwm_show (pwm value) instead of the +pwm_auto_point_temp_show (temp value) resulting in: + # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm + 25500 + # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp + 4500 + +Fix the scaling of these attributes: + # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm + 255 + # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp + 45000 + +Fixes: a6d80df47ee2 ("hwmon: (gsc-hwmon) fix fan pwm temperature scaling") +Cc: stable@vger.kernel.org +Signed-off-by: Tim Harvey +Link: https://lore.kernel.org/r/20250718200259.1840792-1-tharvey@gateworks.com +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/gsc-hwmon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/gsc-hwmon.c ++++ b/drivers/hwmon/gsc-hwmon.c +@@ -64,7 +64,7 @@ static ssize_t pwm_auto_point_temp_show( + return ret; + + ret = regs[0] | regs[1] << 8; +- return sprintf(buf, "%d\n", ret * 10); ++ return sprintf(buf, "%d\n", ret * 100); + } + + static ssize_t pwm_auto_point_temp_store(struct device *dev, +@@ -99,7 +99,7 @@ static ssize_t pwm_auto_point_pwm_show(s + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + +- return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10))); ++ return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100); + } + + static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0); diff --git a/queue-6.16/iio-adc-ad7173-fix-calibration-channel.patch b/queue-6.16/iio-adc-ad7173-fix-calibration-channel.patch new file mode 100644 index 0000000000..55d2a7077e --- /dev/null +++ b/queue-6.16/iio-adc-ad7173-fix-calibration-channel.patch @@ -0,0 +1,53 @@ +From 1d9a21ffb43b6fd326ead98f0d0afd6d104b739a Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Tue, 8 Jul 2025 20:38:33 -0500 +Subject: iio: adc: ad7173: fix calibration channel +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Lechner + +commit 1d9a21ffb43b6fd326ead98f0d0afd6d104b739a upstream. + +Fix the channel index values passed to ad_sd_calibrate() in +ad7173_calibrate_all(). + +ad7173_calibrate_all() expects these values to be that of the CHANNELx +register assigned to the channel, not the datasheet INPUTx number of the +channel. The incorrect values were causing register writes to fail for +some channels because they set the WEN bit that must always be 0 for +register access and set the R/W bit to read instead of write. For other +channels, the channel number was just wrong because the CHANNELx +registers are generally assigned in reverse order and so almost never +match the INPUTx numbers. + +Fixes: 031bdc8aee01 ("iio: adc: ad7173: add calibration support") +Signed-off-by: David Lechner +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250708-iio-adc-ad7313-fix-calibration-channel-v1-1-e6174e2c7cbf@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad7173.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/iio/adc/ad7173.c ++++ b/drivers/iio/adc/ad7173.c +@@ -392,13 +392,12 @@ static int ad7173_calibrate_all(struct a + if (indio_dev->channels[i].type != IIO_VOLTAGE) + continue; + +- ret = ad_sd_calibrate(&st->sd, AD7173_MODE_CAL_INT_ZERO, st->channels[i].ain); ++ ret = ad_sd_calibrate(&st->sd, AD7173_MODE_CAL_INT_ZERO, i); + if (ret < 0) + return ret; + + if (st->info->has_internal_fs_calibration) { +- ret = ad_sd_calibrate(&st->sd, AD7173_MODE_CAL_INT_FULL, +- st->channels[i].ain); ++ ret = ad_sd_calibrate(&st->sd, AD7173_MODE_CAL_INT_FULL, i); + if (ret < 0) + return ret; + } diff --git a/queue-6.16/iio-adc-ad7173-fix-channels-index-for-syscalib_mode.patch b/queue-6.16/iio-adc-ad7173-fix-channels-index-for-syscalib_mode.patch new file mode 100644 index 0000000000..fd4deee8ed --- /dev/null +++ b/queue-6.16/iio-adc-ad7173-fix-channels-index-for-syscalib_mode.patch @@ -0,0 +1,56 @@ +From 0eb8d7b25397330beab8ee62c681975b79f37223 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Thu, 3 Jul 2025 14:51:17 -0500 +Subject: iio: adc: ad7173: fix channels index for syscalib_mode + +From: David Lechner + +commit 0eb8d7b25397330beab8ee62c681975b79f37223 upstream. + +Fix the index used to look up the channel when accessing the +syscalib_mode attribute. The address field is a 0-based index (same +as scan_index) that it used to access the channel in the +ad7173_channels array throughout the driver. The channels field, on +the other hand, may not match the address field depending on the +channel configuration specified in the device tree and could result +in an out-of-bounds access. + +Fixes: 031bdc8aee01 ("iio: adc: ad7173: add calibration support") +Signed-off-by: David Lechner +Link: https://patch.msgid.link/20250703-iio-adc-ad7173-fix-channels-index-for-syscalib_mode-v1-1-7fdaedb9cac0@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad7173.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/iio/adc/ad7173.c ++++ b/drivers/iio/adc/ad7173.c +@@ -319,7 +319,7 @@ static int ad7173_set_syscalib_mode(stru + { + struct ad7173_state *st = iio_priv(indio_dev); + +- st->channels[chan->channel].syscalib_mode = mode; ++ st->channels[chan->address].syscalib_mode = mode; + + return 0; + } +@@ -329,7 +329,7 @@ static int ad7173_get_syscalib_mode(stru + { + struct ad7173_state *st = iio_priv(indio_dev); + +- return st->channels[chan->channel].syscalib_mode; ++ return st->channels[chan->address].syscalib_mode; + } + + static ssize_t ad7173_write_syscalib(struct iio_dev *indio_dev, +@@ -348,7 +348,7 @@ static ssize_t ad7173_write_syscalib(str + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + +- mode = st->channels[chan->channel].syscalib_mode; ++ mode = st->channels[chan->address].syscalib_mode; + if (sys_calib) { + if (mode == AD7173_SYSCALIB_ZERO_SCALE) + ret = ad_sd_calibrate(&st->sd, AD7173_MODE_CAL_SYS_ZERO, diff --git a/queue-6.16/iio-adc-ad7173-fix-setting-odr-in-probe.patch b/queue-6.16/iio-adc-ad7173-fix-setting-odr-in-probe.patch new file mode 100644 index 0000000000..723f684076 --- /dev/null +++ b/queue-6.16/iio-adc-ad7173-fix-setting-odr-in-probe.patch @@ -0,0 +1,47 @@ +From 6fa908abd19cc35c205f343b79c67ff38dbc9b76 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Thu, 10 Jul 2025 15:43:40 -0500 +Subject: iio: adc: ad7173: fix setting ODR in probe + +From: David Lechner + +commit 6fa908abd19cc35c205f343b79c67ff38dbc9b76 upstream. + +Fix the setting of the ODR register value in the probe function for +AD7177. The AD7177 chip has a different ODR value after reset than the +other chips (0x7 vs. 0x0) and 0 is a reserved value on that chip. + +The driver already has this information available in odr_start_value +and uses it when checking valid values when writing to the +sampling_frequency attribute, but failed to set the correct initial +value in the probe function. + +Fixes: 37ae8381ccda ("iio: adc: ad7173: add support for additional models") +Signed-off-by: David Lechner +Link: https://patch.msgid.link/20250710-iio-adc-ad7173-fix-setting-odr-in-probe-v1-1-78a100fec998@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad7173.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/iio/adc/ad7173.c ++++ b/drivers/iio/adc/ad7173.c +@@ -1595,6 +1595,7 @@ static int ad7173_fw_parse_channel_confi + chan_st_priv->cfg.bipolar = false; + chan_st_priv->cfg.input_buf = st->info->has_input_buf; + chan_st_priv->cfg.ref_sel = AD7173_SETUP_REF_SEL_INT_REF; ++ chan_st_priv->cfg.odr = st->info->odr_start_value; + chan_st_priv->cfg.openwire_comp_chan = -1; + st->adc_mode |= AD7173_ADC_MODE_REF_EN; + if (st->info->data_reg_only_16bit) +@@ -1661,7 +1662,7 @@ static int ad7173_fw_parse_channel_confi + chan->scan_index = chan_index; + chan->channel = ain[0]; + chan_st_priv->cfg.input_buf = st->info->has_input_buf; +- chan_st_priv->cfg.odr = 0; ++ chan_st_priv->cfg.odr = st->info->odr_start_value; + chan_st_priv->cfg.openwire_comp_chan = -1; + + chan_st_priv->cfg.bipolar = fwnode_property_read_bool(child, "bipolar"); diff --git a/queue-6.16/iio-adc-ad_sigma_delta-change-to-buffer-predisable.patch b/queue-6.16/iio-adc-ad_sigma_delta-change-to-buffer-predisable.patch new file mode 100644 index 0000000000..31a3fc22d0 --- /dev/null +++ b/queue-6.16/iio-adc-ad_sigma_delta-change-to-buffer-predisable.patch @@ -0,0 +1,50 @@ +From 66d4374d97f85516b5a22418c5e798aed2606dec Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Thu, 3 Jul 2025 16:07:44 -0500 +Subject: iio: adc: ad_sigma_delta: change to buffer predisable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Lechner + +commit 66d4374d97f85516b5a22418c5e798aed2606dec upstream. + +Change the buffer disable callback from postdisable to predisable. +This balances the existing posteanble callback. Using postdisable +with posteanble can be problematic, for example, if update_scan_mode +fails, it would call postdisable without ever having called posteanble, +so the drivers using this would be in an unexpected state when +postdisable was called. + +Fixes: af3008485ea0 ("iio:adc: Add common code for ADI Sigma Delta devices") +Signed-off-by: David Lechner +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250703-iio-adc-ad_sigma_delta-buffer-predisable-v1-1-f2ab85138f1f@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad_sigma_delta.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/ad_sigma_delta.c ++++ b/drivers/iio/adc/ad_sigma_delta.c +@@ -520,7 +520,7 @@ err_unlock: + return ret; + } + +-static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev) ++static int ad_sd_buffer_predisable(struct iio_dev *indio_dev) + { + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + +@@ -644,7 +644,7 @@ static bool ad_sd_validate_scan_mask(str + + static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = { + .postenable = &ad_sd_buffer_postenable, +- .postdisable = &ad_sd_buffer_postdisable, ++ .predisable = &ad_sd_buffer_predisable, + .validate_scan_mask = &ad_sd_validate_scan_mask, + }; + diff --git a/queue-6.16/iio-imu-bno055-fix-oob-access-of-hw_xlate-array.patch b/queue-6.16/iio-imu-bno055-fix-oob-access-of-hw_xlate-array.patch new file mode 100644 index 0000000000..be172b49a7 --- /dev/null +++ b/queue-6.16/iio-imu-bno055-fix-oob-access-of-hw_xlate-array.patch @@ -0,0 +1,81 @@ +From 399b883ec828e436f1a721bf8551b4da8727e65b Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Wed, 9 Jul 2025 21:20:00 -0500 +Subject: iio: imu: bno055: fix OOB access of hw_xlate array + +From: David Lechner + +commit 399b883ec828e436f1a721bf8551b4da8727e65b upstream. + +Fix a potential out-of-bounds array access of the hw_xlate array in +bno055.c. + +In bno055_get_regmask(), hw_xlate was iterated over the length of the +vals array instead of the length of the hw_xlate array. In the case of +bno055_gyr_scale, the vals array is larger than the hw_xlate array, +so this could result in an out-of-bounds access. In practice, this +shouldn't happen though because a match should always be found which +breaks out of the for loop before it iterates beyond the end of the +hw_xlate array. + +By adding a new hw_xlate_len field to the bno055_sysfs_attr, we can be +sure we are iterating over the correct length. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202507100510.rGt1YOOx-lkp@intel.com/ +Fixes: 4aefe1c2bd0c ("iio: imu: add Bosch Sensortec BNO055 core driver") +Signed-off-by: David Lechner +Link: https://patch.msgid.link/20250709-iio-const-data-19-v2-1-fb3fc9191251@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/imu/bno055/bno055.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/iio/imu/bno055/bno055.c ++++ b/drivers/iio/imu/bno055/bno055.c +@@ -118,6 +118,7 @@ struct bno055_sysfs_attr { + int len; + int *fusion_vals; + int *hw_xlate; ++ int hw_xlate_len; + int type; + }; + +@@ -170,20 +171,24 @@ static int bno055_gyr_scale_vals[] = { + 1000, 1877467, 2000, 1877467, + }; + ++static int bno055_gyr_scale_hw_xlate[] = {0, 1, 2, 3, 4}; + static struct bno055_sysfs_attr bno055_gyr_scale = { + .vals = bno055_gyr_scale_vals, + .len = ARRAY_SIZE(bno055_gyr_scale_vals), + .fusion_vals = (int[]){1, 900}, +- .hw_xlate = (int[]){4, 3, 2, 1, 0}, ++ .hw_xlate = bno055_gyr_scale_hw_xlate, ++ .hw_xlate_len = ARRAY_SIZE(bno055_gyr_scale_hw_xlate), + .type = IIO_VAL_FRACTIONAL, + }; + + static int bno055_gyr_lpf_vals[] = {12, 23, 32, 47, 64, 116, 230, 523}; ++static int bno055_gyr_lpf_hw_xlate[] = {5, 4, 7, 3, 6, 2, 1, 0}; + static struct bno055_sysfs_attr bno055_gyr_lpf = { + .vals = bno055_gyr_lpf_vals, + .len = ARRAY_SIZE(bno055_gyr_lpf_vals), + .fusion_vals = (int[]){32}, +- .hw_xlate = (int[]){5, 4, 7, 3, 6, 2, 1, 0}, ++ .hw_xlate = bno055_gyr_lpf_hw_xlate, ++ .hw_xlate_len = ARRAY_SIZE(bno055_gyr_lpf_hw_xlate), + .type = IIO_VAL_INT, + }; + +@@ -561,7 +566,7 @@ static int bno055_get_regmask(struct bno + + idx = (hwval & mask) >> shift; + if (attr->hw_xlate) +- for (i = 0; i < attr->len; i++) ++ for (i = 0; i < attr->hw_xlate_len; i++) + if (attr->hw_xlate[i] == idx) { + idx = i; + break; diff --git a/queue-6.16/pwm-imx-tpm-reset-counter-if-cmod-is-0.patch b/queue-6.16/pwm-imx-tpm-reset-counter-if-cmod-is-0.patch new file mode 100644 index 0000000000..56dc0586c7 --- /dev/null +++ b/queue-6.16/pwm-imx-tpm-reset-counter-if-cmod-is-0.patch @@ -0,0 +1,58 @@ +From 65c6f742ab14ab1a2679fba72b82dcc0289d96f1 Mon Sep 17 00:00:00 2001 +From: Laurentiu Mihalcea +Date: Mon, 28 Jul 2025 15:41:44 -0400 +Subject: pwm: imx-tpm: Reset counter if CMOD is 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Laurentiu Mihalcea + +commit 65c6f742ab14ab1a2679fba72b82dcc0289d96f1 upstream. + +As per the i.MX93 TRM, section 67.3.2.1 "MOD register update", the value +of the TPM counter does NOT get updated when writing MOD.MOD unless +SC.CMOD != 0. Therefore, with the current code, assuming the following +sequence: + + 1) pwm_disable() + 2) pwm_apply_might_sleep() /* period is changed here */ + 3) pwm_enable() + +and assuming only one channel is active, if CNT.COUNT is higher than the +MOD.MOD value written during the pwm_apply_might_sleep() call then, when +re-enabling the PWM during pwm_enable(), the counter will end up resetting +after UINT32_MAX - CNT.COUNT + MOD.MOD cycles instead of MOD.MOD cycles as +normally expected. + +Fix this problem by forcing a reset of the TPM counter before MOD.MOD is +written. + +Fixes: 738a1cfec2ed ("pwm: Add i.MX TPM PWM driver support") +Cc: stable@vger.kernel.org +Signed-off-by: Laurentiu Mihalcea +Link: https://lore.kernel.org/r/20250728194144.22884-1-laurentiumihalcea111@gmail.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-imx-tpm.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/pwm/pwm-imx-tpm.c ++++ b/drivers/pwm/pwm-imx-tpm.c +@@ -205,6 +205,15 @@ static int pwm_imx_tpm_apply_hw(struct p + writel(val, tpm->base + PWM_IMX_TPM_SC); + + /* ++ * if the counter is disabled (CMOD == 0), programming the new ++ * period length (MOD) will not reset the counter (CNT). If ++ * CNT.COUNT happens to be bigger than the new MOD value then ++ * the counter will end up being reset way too late. Therefore, ++ * manually reset it to 0. ++ */ ++ if (!cmod) ++ writel(0x0, tpm->base + PWM_IMX_TPM_CNT); ++ /* + * set period count: + * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register + * is updated when MOD register is written. diff --git a/queue-6.16/pwm-mediatek-fix-duty-and-period-setting.patch b/queue-6.16/pwm-mediatek-fix-duty-and-period-setting.patch new file mode 100644 index 0000000000..4a946f5504 --- /dev/null +++ b/queue-6.16/pwm-mediatek-fix-duty-and-period-setting.patch @@ -0,0 +1,81 @@ +From f21d136caf8171f94159d975ea4620c164431bd9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 28 Jul 2025 18:00:18 +0200 +Subject: pwm: mediatek: Fix duty and period setting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit f21d136caf8171f94159d975ea4620c164431bd9 upstream. + +The period generated by the hardware is + + (PWMDWIDTH + 1) << CLKDIV) / freq + +according to my tests with a signal analyser and also the documentation. + +The current algorithm doesn't consider the `+ 1` part and so configures +slightly too high periods. The same issue exists for the duty cycle +setting. So subtract 1 from both the register values for period and +duty cycle. If period is 0, bail out, if duty_cycle is 0, just disable +the PWM which results in a constant low output. + +Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support") +Signed-off-by: Uwe Kleine-König +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/6d1fa87a76f8020bfe3171529b8e19baffceab10.1753717973.git.u.kleine-koenig@baylibre.com +Cc: stable@vger.kernel.org +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-mediatek.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/drivers/pwm/pwm-mediatek.c ++++ b/drivers/pwm/pwm-mediatek.c +@@ -164,7 +164,10 @@ static int pwm_mediatek_config(struct pw + do_div(resolution, clk_rate); + + cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); +- while (cnt_period > 8191) { ++ if (!cnt_period) ++ return -EINVAL; ++ ++ while (cnt_period > 8192) { + resolution *= 2; + clkdiv++; + cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, +@@ -187,9 +190,16 @@ static int pwm_mediatek_config(struct pw + } + + cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution); ++ + pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); +- pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period); +- pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty); ++ pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period - 1); ++ ++ if (cnt_duty) { ++ pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty - 1); ++ pwm_mediatek_enable(chip, pwm); ++ } else { ++ pwm_mediatek_disable(chip, pwm); ++ } + + out: + pwm_mediatek_clk_disable(chip, pwm); +@@ -218,11 +228,8 @@ static int pwm_mediatek_apply(struct pwm + if (err) + return err; + +- if (!pwm->state.enabled) { ++ if (!pwm->state.enabled) + err = pwm_mediatek_clk_enable(chip, pwm); +- if (!err) +- pwm_mediatek_enable(chip, pwm); +- } + + return err; + } diff --git a/queue-6.16/pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch b/queue-6.16/pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch new file mode 100644 index 0000000000..e89011e2cd --- /dev/null +++ b/queue-6.16/pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch @@ -0,0 +1,121 @@ +From 704d918341c378c5f9505dfdf32d315e256d3846 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 28 Jul 2025 18:00:17 +0200 +Subject: pwm: mediatek: Handle hardware enable and clock enable separately +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit 704d918341c378c5f9505dfdf32d315e256d3846 upstream. + +Stop handling the clocks in pwm_mediatek_enable() and +pwm_mediatek_disable(). This is a preparing change for the next commit +that requires that clocks and the enable bit are handled separately. + +Also move these two functions a bit further up in the source file to +make them usable in pwm_mediatek_config(), which is needed in the next +commit, too. + +Signed-off-by: Uwe Kleine-König +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/55c94fe2917ece152ee1e998f4675642a7716f13.1753717973.git.u.kleine-koenig@baylibre.com +Cc: stable@vger.kernel.org +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-mediatek.c | 60 +++++++++++++++++++++------------------------ + 1 file changed, 28 insertions(+), 32 deletions(-) + +--- a/drivers/pwm/pwm-mediatek.c ++++ b/drivers/pwm/pwm-mediatek.c +@@ -115,6 +115,26 @@ static inline void pwm_mediatek_writel(s + writel(value, chip->regs + chip->soc->reg_offset[num] + offset); + } + ++static void pwm_mediatek_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); ++ u32 value; ++ ++ value = readl(pc->regs); ++ value |= BIT(pwm->hwpwm); ++ writel(value, pc->regs); ++} ++ ++static void pwm_mediatek_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); ++ u32 value; ++ ++ value = readl(pc->regs); ++ value &= ~BIT(pwm->hwpwm); ++ writel(value, pc->regs); ++} ++ + static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, + int duty_ns, int period_ns) + { +@@ -177,35 +197,6 @@ out: + return ret; + } + +-static int pwm_mediatek_enable(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); +- u32 value; +- int ret; +- +- ret = pwm_mediatek_clk_enable(chip, pwm); +- if (ret < 0) +- return ret; +- +- value = readl(pc->regs); +- value |= BIT(pwm->hwpwm); +- writel(value, pc->regs); +- +- return 0; +-} +- +-static void pwm_mediatek_disable(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); +- u32 value; +- +- value = readl(pc->regs); +- value &= ~BIT(pwm->hwpwm); +- writel(value, pc->regs); +- +- pwm_mediatek_clk_disable(chip, pwm); +-} +- + static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -215,8 +206,10 @@ static int pwm_mediatek_apply(struct pwm + return -EINVAL; + + if (!state->enabled) { +- if (pwm->state.enabled) ++ if (pwm->state.enabled) { + pwm_mediatek_disable(chip, pwm); ++ pwm_mediatek_clk_disable(chip, pwm); ++ } + + return 0; + } +@@ -225,8 +218,11 @@ static int pwm_mediatek_apply(struct pwm + if (err) + return err; + +- if (!pwm->state.enabled) +- err = pwm_mediatek_enable(chip, pwm); ++ if (!pwm->state.enabled) { ++ err = pwm_mediatek_clk_enable(chip, pwm); ++ if (!err) ++ pwm_mediatek_enable(chip, pwm); ++ } + + return err; + } diff --git a/queue-6.16/series b/queue-6.16/series index 2ac0af3803..1264508696 100644 --- a/queue-6.16/series +++ b/queue-6.16/series @@ -70,3 +70,21 @@ ata-libata-scsi-return-aborted-command-when-missing-sense-and-result-tf.patch scsi-ufs-ufs-pci-fix-hibernate-state-transition-for-intel-mtl-like-host-controllers.patch scsi-ufs-ufs-pci-fix-default-runtime-and-system-pm-levels.patch ata-libata-scsi-fix-cdl-control.patch +soc-qcom-mdt_loader-ensure-we-don-t-read-past-the-elf-header.patch +zynq_fpga-use-sgtable-based-scatterlist-wrappers.patch +iio-imu-bno055-fix-oob-access-of-hw_xlate-array.patch +iio-adc-ad_sigma_delta-change-to-buffer-predisable.patch +iio-adc-ad7173-fix-channels-index-for-syscalib_mode.patch +iio-adc-ad7173-fix-calibration-channel.patch +iio-adc-ad7173-fix-setting-odr-in-probe.patch +wifi-brcmsmac-remove-const-from-tbl_ptr-parameter-in-wlc_lcnphy_common_read_table.patch +wifi-ath12k-fix-dest-ring-buffer-corruption.patch +wifi-ath12k-fix-source-ring-buffer-corruption.patch +wifi-ath12k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch +wifi-ath11k-fix-dest-ring-buffer-corruption.patch +wifi-ath11k-fix-source-ring-buffer-corruption.patch +wifi-ath11k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch +pwm-imx-tpm-reset-counter-if-cmod-is-0.patch +pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch +pwm-mediatek-fix-duty-and-period-setting.patch +hwmon-gsc-hwmon-fix-fan-pwm-setpoint-show-functions.patch diff --git a/queue-6.16/soc-qcom-mdt_loader-ensure-we-don-t-read-past-the-elf-header.patch b/queue-6.16/soc-qcom-mdt_loader-ensure-we-don-t-read-past-the-elf-header.patch new file mode 100644 index 0000000000..b42becf7d8 --- /dev/null +++ b/queue-6.16/soc-qcom-mdt_loader-ensure-we-don-t-read-past-the-elf-header.patch @@ -0,0 +1,109 @@ +From 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Tue, 10 Jun 2025 21:58:28 -0500 +Subject: soc: qcom: mdt_loader: Ensure we don't read past the ELF header + +From: Bjorn Andersson + +commit 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef upstream. + +When the MDT loader is used in remoteproc, the ELF header is sanitized +beforehand, but that's not necessary the case for other clients. + +Validate the size of the firmware buffer to ensure that we don't read +past the end as we iterate over the header. e_phentsize and e_shentsize +are validated as well, to ensure that the assumptions about step size in +the traversal are valid. + +Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom") +Cc: stable@vger.kernel.org +Reported-by: Doug Anderson +Signed-off-by: Bjorn Andersson +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250610-mdt-loader-validation-and-fixes-v2-1-f7073e9ab899@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/soc/qcom/mdt_loader.c | 43 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- a/drivers/soc/qcom/mdt_loader.c ++++ b/drivers/soc/qcom/mdt_loader.c +@@ -18,6 +18,37 @@ + #include + #include + ++static bool mdt_header_valid(const struct firmware *fw) ++{ ++ const struct elf32_hdr *ehdr; ++ size_t phend; ++ size_t shend; ++ ++ if (fw->size < sizeof(*ehdr)) ++ return false; ++ ++ ehdr = (struct elf32_hdr *)fw->data; ++ ++ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) ++ return false; ++ ++ if (ehdr->e_phentsize != sizeof(struct elf32_phdr)) ++ return -EINVAL; ++ ++ phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff); ++ if (phend > fw->size) ++ return false; ++ ++ if (ehdr->e_shentsize != sizeof(struct elf32_shdr)) ++ return -EINVAL; ++ ++ shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff); ++ if (shend > fw->size) ++ return false; ++ ++ return true; ++} ++ + static bool mdt_phdr_valid(const struct elf32_phdr *phdr) + { + if (phdr->p_type != PT_LOAD) +@@ -82,6 +113,9 @@ ssize_t qcom_mdt_get_size(const struct f + phys_addr_t max_addr = 0; + int i; + ++ if (!mdt_header_valid(fw)) ++ return -EINVAL; ++ + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); + +@@ -134,6 +168,9 @@ void *qcom_mdt_read_metadata(const struc + ssize_t ret; + void *data; + ++ if (!mdt_header_valid(fw)) ++ return ERR_PTR(-EINVAL); ++ + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); + +@@ -214,6 +251,9 @@ int qcom_mdt_pas_init(struct device *dev + int ret; + int i; + ++ if (!mdt_header_valid(fw)) ++ return -EINVAL; ++ + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); + +@@ -310,6 +350,9 @@ static int __qcom_mdt_load(struct device + if (!fw || !mem_region || !mem_phys || !mem_size) + return -EINVAL; + ++ if (!mdt_header_valid(fw)) ++ return -EINVAL; ++ + is_split = qcom_mdt_bins_are_split(fw, fw_name); + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); diff --git a/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch b/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch new file mode 100644 index 0000000000..7ef8981fd0 --- /dev/null +++ b/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch @@ -0,0 +1,61 @@ +From aa6956150f820e6a6deba44be325ddfcb5b10f88 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 4 Jun 2025 16:34:57 +0200 +Subject: wifi: ath11k: fix dest ring-buffer corruption when ring is full + +From: Johan Hovold + +commit aa6956150f820e6a6deba44be325ddfcb5b10f88 upstream. + +Add the missing memory barriers to make sure that destination ring +descriptors are read before updating the tail pointer (and passing +ownership to the device) to avoid memory corruption on weakly ordered +architectures like aarch64 when the ring is full. + +Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Cc: stable@vger.kernel.org # 5.6 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250604143457.26032-6-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/hal.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -854,7 +854,6 @@ void ath11k_hal_srng_access_end(struct a + { + lockdep_assert_held(&srng->lock); + +- /* TODO: See if we need a write memory barrier here */ + if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) { + /* For LMAC rings, ring pointer updates are done through FW and + * hence written to a shared memory location that is read by FW +@@ -869,7 +868,11 @@ void ath11k_hal_srng_access_end(struct a + WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; +- *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; ++ /* Make sure descriptor is read before updating the ++ * tail pointer. ++ */ ++ dma_mb(); ++ WRITE_ONCE(*srng->u.dst_ring.tp_addr, srng->u.dst_ring.tp); + } + } else { + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { +@@ -885,6 +888,10 @@ void ath11k_hal_srng_access_end(struct a + srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; ++ /* Make sure descriptor is read before updating the ++ * tail pointer. ++ */ ++ mb(); + ath11k_hif_write32(ab, + (unsigned long)srng->u.dst_ring.tp_addr - + (unsigned long)ab->mem, diff --git a/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption.patch b/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption.patch new file mode 100644 index 0000000000..55d320979c --- /dev/null +++ b/queue-6.16/wifi-ath11k-fix-dest-ring-buffer-corruption.patch @@ -0,0 +1,83 @@ +From 8c1ba5091fa9a2d1478da63173b16a701bdf86bb Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 4 Jun 2025 16:34:53 +0200 +Subject: wifi: ath11k: fix dest ring-buffer corruption + +From: Johan Hovold + +commit 8c1ba5091fa9a2d1478da63173b16a701bdf86bb upstream. + +Add the missing memory barrier to make sure that destination ring +descriptors are read after the head pointers to avoid using stale data +on weakly ordered architectures like aarch64. + +The barrier is added to the ath11k_hal_srng_access_begin() helper for +symmetry with follow-on fixes for source ring buffer corruption which +will add barriers to ath11k_hal_srng_access_end(). + +Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Cc: stable@vger.kernel.org # 5.6 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250604143457.26032-2-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/ce.c | 3 --- + drivers/net/wireless/ath/ath11k/dp_rx.c | 3 --- + drivers/net/wireless/ath/ath11k/hal.c | 12 +++++++++++- + 3 files changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -393,9 +393,6 @@ static int ath11k_ce_completed_recv_next + goto err; + } + +- /* Make sure descriptor is read after the head pointer. */ +- dma_rmb(); +- + *nbytes = ath11k_hal_ce_dst_status_get_length(desc); + + *skb = pipe->dest_ring->skb[sw_index]; +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2650,9 +2650,6 @@ int ath11k_dp_process_rx(struct ath11k_b + try_again: + ath11k_hal_srng_access_begin(ab, srng); + +- /* Make sure descriptor is read after the head pointer. */ +- dma_rmb(); +- + while (likely(desc = + (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, + srng))) { +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -823,13 +823,23 @@ u32 *ath11k_hal_srng_src_peek(struct ath + + void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng) + { ++ u32 hp; ++ + lockdep_assert_held(&srng->lock); + + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.cached_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; + } else { +- srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr); ++ hp = READ_ONCE(*srng->u.dst_ring.hp_addr); ++ ++ if (hp != srng->u.dst_ring.cached_hp) { ++ srng->u.dst_ring.cached_hp = hp; ++ /* Make sure descriptor is read after the head ++ * pointer. ++ */ ++ dma_rmb(); ++ } + + /* Try to prefetch the next descriptor in the ring */ + if (srng->flags & HAL_SRNG_FLAGS_CACHED) diff --git a/queue-6.16/wifi-ath11k-fix-source-ring-buffer-corruption.patch b/queue-6.16/wifi-ath11k-fix-source-ring-buffer-corruption.patch new file mode 100644 index 0000000000..18ff9ffc24 --- /dev/null +++ b/queue-6.16/wifi-ath11k-fix-source-ring-buffer-corruption.patch @@ -0,0 +1,56 @@ +From 6efa0df54022c6c9fd4d294b87622c7fcdc418c8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 4 Jun 2025 16:34:56 +0200 +Subject: wifi: ath11k: fix source ring-buffer corruption + +From: Johan Hovold + +commit 6efa0df54022c6c9fd4d294b87622c7fcdc418c8 upstream. + +Add the missing memory barrier to make sure that LMAC source ring +descriptors are written before updating the head pointer to avoid +passing stale data to the firmware on weakly ordered architectures like +aarch64. + +Note that non-LMAC rings use MMIO write accessors which have the +required write memory barrier. + +Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Cc: stable@vger.kernel.org # 5.6 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250604143457.26032-5-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/hal.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -862,7 +862,11 @@ void ath11k_hal_srng_access_end(struct a + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; +- *srng->u.src_ring.hp_addr = srng->u.src_ring.hp; ++ /* Make sure descriptor is written before updating the ++ * head pointer. ++ */ ++ dma_wmb(); ++ WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; + *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; +@@ -871,6 +875,10 @@ void ath11k_hal_srng_access_end(struct a + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; ++ /* Assume implementation use an MMIO write accessor ++ * which has the required wmb() so that the descriptor ++ * is written before the updating the head pointer. ++ */ + ath11k_hif_write32(ab, + (unsigned long)srng->u.src_ring.hp_addr - + (unsigned long)ab->mem, diff --git a/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch b/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch new file mode 100644 index 0000000000..cafe0f2592 --- /dev/null +++ b/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption-when-ring-is-full.patch @@ -0,0 +1,61 @@ +From ed32169be1ccb9b1a295275ba7746dc6bf103e80 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 17 Jun 2025 10:44:02 +0200 +Subject: wifi: ath12k: fix dest ring-buffer corruption when ring is full + +From: Johan Hovold + +commit ed32169be1ccb9b1a295275ba7746dc6bf103e80 upstream. + +Add the missing memory barriers to make sure that destination ring +descriptors are read before updating the tail pointer (and passing +ownership to the device) to avoid memory corruption on weakly ordered +architectures like aarch64 when the ring is full. + +Tested-on: WCN7850 hw2.0 WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Cc: stable@vger.kernel.org # 6.3 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250617084402.14475-5-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath12k/hal.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath12k/hal.c ++++ b/drivers/net/wireless/ath/ath12k/hal.c +@@ -2170,7 +2170,6 @@ void ath12k_hal_srng_access_end(struct a + { + lockdep_assert_held(&srng->lock); + +- /* TODO: See if we need a write memory barrier here */ + if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) { + /* For LMAC rings, ring pointer updates are done through FW and + * hence written to a shared memory location that is read by FW +@@ -2185,7 +2184,11 @@ void ath12k_hal_srng_access_end(struct a + WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; +- *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; ++ /* Make sure descriptor is read before updating the ++ * tail pointer. ++ */ ++ dma_mb(); ++ WRITE_ONCE(*srng->u.dst_ring.tp_addr, srng->u.dst_ring.tp); + } + } else { + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { +@@ -2201,6 +2204,10 @@ void ath12k_hal_srng_access_end(struct a + srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; ++ /* Make sure descriptor is read before updating the ++ * tail pointer. ++ */ ++ mb(); + ath12k_hif_write32(ab, + (unsigned long)srng->u.dst_ring.tp_addr - + (unsigned long)ab->mem, diff --git a/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption.patch b/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption.patch new file mode 100644 index 0000000000..34f6ac1183 --- /dev/null +++ b/queue-6.16/wifi-ath12k-fix-dest-ring-buffer-corruption.patch @@ -0,0 +1,73 @@ +From 8157ce533a60521f21d466eb4de45d9735b19484 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 17 Jun 2025 10:43:59 +0200 +Subject: wifi: ath12k: fix dest ring-buffer corruption + +From: Johan Hovold + +commit 8157ce533a60521f21d466eb4de45d9735b19484 upstream. + +Add the missing memory barrier to make sure that destination ring +descriptors are read after the head pointers to avoid using stale data +on weakly ordered architectures like aarch64. + +The barrier is added to the ath12k_hal_srng_access_begin() helper for +symmetry with follow-on fixes for source ring buffer corruption which +will add barriers to ath12k_hal_srng_access_end(). + +Tested-on: WCN7850 hw2.0 WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Cc: stable@vger.kernel.org # 6.3 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250617084402.14475-2-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath12k/ce.c | 3 --- + drivers/net/wireless/ath/ath12k/hal.c | 17 ++++++++++++++--- + 2 files changed, 14 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath12k/ce.c ++++ b/drivers/net/wireless/ath/ath12k/ce.c +@@ -433,9 +433,6 @@ static int ath12k_ce_completed_recv_next + goto err; + } + +- /* Make sure descriptor is read after the head pointer. */ +- dma_rmb(); +- + *nbytes = ath12k_hal_ce_dst_status_get_length(desc); + + *skb = pipe->dest_ring->skb[sw_index]; +--- a/drivers/net/wireless/ath/ath12k/hal.c ++++ b/drivers/net/wireless/ath/ath12k/hal.c +@@ -2143,13 +2143,24 @@ void *ath12k_hal_srng_src_get_next_reape + + void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) + { ++ u32 hp; ++ + lockdep_assert_held(&srng->lock); + +- if (srng->ring_dir == HAL_SRNG_DIR_SRC) ++ if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.cached_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; +- else +- srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr); ++ } else { ++ hp = READ_ONCE(*srng->u.dst_ring.hp_addr); ++ ++ if (hp != srng->u.dst_ring.cached_hp) { ++ srng->u.dst_ring.cached_hp = hp; ++ /* Make sure descriptor is read after the head ++ * pointer. ++ */ ++ dma_rmb(); ++ } ++ } + } + + /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin() diff --git a/queue-6.16/wifi-ath12k-fix-source-ring-buffer-corruption.patch b/queue-6.16/wifi-ath12k-fix-source-ring-buffer-corruption.patch new file mode 100644 index 0000000000..765cdeffe7 --- /dev/null +++ b/queue-6.16/wifi-ath12k-fix-source-ring-buffer-corruption.patch @@ -0,0 +1,56 @@ +From e834da4cbd6fe1d24f89368bf0c80adcad212726 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 17 Jun 2025 10:44:01 +0200 +Subject: wifi: ath12k: fix source ring-buffer corruption + +From: Johan Hovold + +commit e834da4cbd6fe1d24f89368bf0c80adcad212726 upstream. + +Add the missing memory barrier to make sure that LMAC source ring +descriptors are written before updating the head pointer to avoid +passing stale data to the firmware on weakly ordered architectures like +aarch64. + +Note that non-LMAC rings use MMIO write accessors which have the +required write memory barrier. + +Tested-on: WCN7850 hw2.0 WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Cc: stable@vger.kernel.org # 6.3 +Signed-off-by: Johan Hovold +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20250617084402.14475-4-johan+linaro@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath12k/hal.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath12k/hal.c ++++ b/drivers/net/wireless/ath/ath12k/hal.c +@@ -2178,7 +2178,11 @@ void ath12k_hal_srng_access_end(struct a + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; +- *srng->u.src_ring.hp_addr = srng->u.src_ring.hp; ++ /* Make sure descriptor is written before updating the ++ * head pointer. ++ */ ++ dma_wmb(); ++ WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp); + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; + *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; +@@ -2187,6 +2191,10 @@ void ath12k_hal_srng_access_end(struct a + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; ++ /* Assume implementation use an MMIO write accessor ++ * which has the required wmb() so that the descriptor ++ * is written before the updating the head pointer. ++ */ + ath12k_hif_write32(ab, + (unsigned long)srng->u.src_ring.hp_addr - + (unsigned long)ab->mem, diff --git a/queue-6.16/wifi-brcmsmac-remove-const-from-tbl_ptr-parameter-in-wlc_lcnphy_common_read_table.patch b/queue-6.16/wifi-brcmsmac-remove-const-from-tbl_ptr-parameter-in-wlc_lcnphy_common_read_table.patch new file mode 100644 index 0000000000..a22e24ea6b --- /dev/null +++ b/queue-6.16/wifi-brcmsmac-remove-const-from-tbl_ptr-parameter-in-wlc_lcnphy_common_read_table.patch @@ -0,0 +1,46 @@ +From 81284e86bf8849f8e98e8ead3ff5811926b2107f Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 15 Jul 2025 19:45:23 -0700 +Subject: wifi: brcmsmac: Remove const from tbl_ptr parameter in wlc_lcnphy_common_read_table() + +From: Nathan Chancellor + +commit 81284e86bf8849f8e98e8ead3ff5811926b2107f upstream. + +A new warning in clang [1] complains that diq_start in +wlc_lcnphy_tx_iqlo_cal() is passed uninitialized as a const pointer to +wlc_lcnphy_common_read_table(): + + drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c:2728:13: error: variable 'diq_start' is uninitialized when passed as a const pointer argument here [-Werror,-Wuninitialized-const-pointer] + 2728 | &diq_start, 1, 16, 69); + | ^~~~~~~~~ + +The table pointer passed to wlc_lcnphy_common_read_table() should not be +considered constant, as wlc_phy_read_table() is ultimately going to +update it. Remove the const qualifier from the tbl_ptr to clear up the +warning. + +Cc: stable@vger.kernel.org +Closes: https://github.com/ClangBuiltLinux/linux/issues/2108 +Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers") +Link: https://github.com/llvm/llvm-project/commit/00dacf8c22f065cb52efb14cd091d441f19b319e [1] +Signed-off-by: Nathan Chancellor +Acked-by: Arend van Spriel > +Link: https://patch.msgid.link/20250715-brcmsmac-fix-uninit-const-pointer-v1-1-16e6a51a8ef4@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +@@ -919,7 +919,7 @@ void wlc_lcnphy_read_table(struct brcms_ + + static void + wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id, +- const u16 *tbl_ptr, u32 tbl_len, ++ u16 *tbl_ptr, u32 tbl_len, + u32 tbl_width, u32 tbl_offset) + { + struct phytbl_info tab; diff --git a/queue-6.16/zynq_fpga-use-sgtable-based-scatterlist-wrappers.patch b/queue-6.16/zynq_fpga-use-sgtable-based-scatterlist-wrappers.patch new file mode 100644 index 0000000000..288b4ed10b --- /dev/null +++ b/queue-6.16/zynq_fpga-use-sgtable-based-scatterlist-wrappers.patch @@ -0,0 +1,46 @@ +From 37e00703228ab44d0aacc32a97809a4f6f58df1b Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski +Date: Mon, 16 Jun 2025 14:09:32 +0200 +Subject: zynq_fpga: use sgtable-based scatterlist wrappers + +From: Marek Szyprowski + +commit 37e00703228ab44d0aacc32a97809a4f6f58df1b upstream. + +Use common wrappers operating directly on the struct sg_table objects to +fix incorrect use of statterlists related calls. dma_unmap_sg() function +has to be called with the number of elements originally passed to the +dma_map_sg() function, not the one returned in sgtable's nents. + +CC: stable@vger.kernel.org +Fixes: 425902f5c8e3 ("fpga zynq: Use the scatterlist interface") +Signed-off-by: Marek Szyprowski +Reviewed-by: Jason Gunthorpe +Reviewed-by: Xu Yilun +Link: https://lore.kernel.org/r/20250616120932.1090614-1-m.szyprowski@samsung.com +Signed-off-by: Xu Yilun +Signed-off-by: Greg Kroah-Hartman +--- + drivers/fpga/zynq-fpga.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/fpga/zynq-fpga.c ++++ b/drivers/fpga/zynq-fpga.c +@@ -406,7 +406,7 @@ static int zynq_fpga_ops_write(struct fp + } + + priv->dma_nelms = +- dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); ++ dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); + if (priv->dma_nelms == 0) { + dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); + return -ENOMEM; +@@ -478,7 +478,7 @@ out_clk: + clk_disable(priv->clk); + + out_free: +- dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); ++ dma_unmap_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); + return err; + } +