diff --git a/Makefile b/Makefile
index fa2cd06f09e2..5b757b260bb8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 4
-SUBLEVEL = 289
+SUBLEVEL = 290
EXTRAVERSION =
NAME = Kleptomaniac Octopus
diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml
index def41776bbaf..0e48c4e84df9 100644
--- a/android/abi_gki_aarch64.xml
+++ b/android/abi_gki_aarch64.xml
@@ -426,6 +426,7 @@
+
@@ -37447,6 +37448,10 @@
+
+
+
+
@@ -149383,6 +149388,14 @@
+
+
+
+
+
+
+
+
diff --git a/android/abi_gki_aarch64_cuttlefish b/android/abi_gki_aarch64_cuttlefish
index c2732aa7dba0..6d6db2054797 100644
--- a/android/abi_gki_aarch64_cuttlefish
+++ b/android/abi_gki_aarch64_cuttlefish
@@ -230,7 +230,6 @@
vring_del_virtqueue
vring_interrupt
vring_transport_features
- wait_for_completion
wait_woken
__wake_up
__warn_printk
@@ -739,11 +738,13 @@
blk_mq_complete_request
blk_mq_end_request
blk_mq_free_tag_set
+ blk_mq_freeze_queue
blk_mq_init_queue
- blk_mq_quiesce_queue
+ blk_mq_quiesce_queue_nowait
blk_mq_start_request
blk_mq_start_stopped_hw_queues
blk_mq_stop_hw_queue
+ blk_mq_unfreeze_queue
blk_mq_unquiesce_queue
blk_mq_virtio_map_queues
blk_put_request
@@ -800,6 +801,7 @@
__splice_from_pipe
system_freezing_cnt
__unregister_chrdev
+ wait_for_completion
# required by virtio_input.ko
input_alloc_absinfo
@@ -813,14 +815,10 @@
# required by virtio_mmio.ko
device_for_each_child
- devm_ioremap
- devm_kfree
- __devm_request_region
- iomem_resource
+ devm_platform_ioremap_resource
memparse
platform_device_register_full
platform_get_irq
- platform_get_resource
sscanf
# required by virtio_net.ko
@@ -956,6 +954,12 @@
sock_i_ino
# preserved by --additions-only
+ blk_mq_quiesce_queue
+ devm_ioremap
+ devm_kfree
+ __devm_request_region
generic_shutdown_super
+ iomem_resource
+ platform_get_resource
refcount_dec_and_test_checked
refcount_inc_checked
diff --git a/arch/arm/configs/vendor/sdxlemur.config b/arch/arm/configs/vendor/sdxlemur.config
index f51895fb5d48..2646540a9f28 100644
--- a/arch/arm/configs/vendor/sdxlemur.config
+++ b/arch/arm/configs/vendor/sdxlemur.config
@@ -250,6 +250,7 @@ CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_CCID=y
CONFIG_USB_G_QTI=y
CONFIG_USB_BAM=y
+CONFIG_USB_RTL8152=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_ARM_PSCI=y
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index f297601c9f71..652998c83640 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -219,12 +219,14 @@
<&cru HCLK_OTG>,
<&cru SCLK_OTG_ADP>;
pm_qos = <&qos_usb_host>, <&qos_usb_otg>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_SDCARD {
reg = ;
clocks = <&cru HCLK_SDMMC>,
<&cru SCLK_SDMMC>;
pm_qos = <&qos_sdmmc>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_GMAC {
reg = ;
@@ -233,6 +235,7 @@
<&cru SCLK_MAC_REF>,
<&cru SCLK_GMAC_RX_TX>;
pm_qos = <&qos_gmac>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_MMC_NAND {
reg = ;
@@ -246,6 +249,7 @@
<&cru SCLK_SFC>;
pm_qos = <&qos_emmc>, <&qos_nand>,
<&qos_sdio>, <&qos_sfc>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_VPU {
reg = ;
@@ -253,6 +257,7 @@
<&cru HCLK_VPU>,
<&cru SCLK_CORE_VPU>;
pm_qos = <&qos_vpu>, <&qos_vpu_r128>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_VO {
reg = ;
@@ -269,6 +274,7 @@
<&cru SCLK_VOPB_PWM>;
pm_qos = <&qos_rga_rd>, <&qos_rga_wr>,
<&qos_vop_m0>, <&qos_vop_m1>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_VI {
reg = ;
@@ -280,11 +286,13 @@
pm_qos = <&qos_isp_128>, <&qos_isp_rd>,
<&qos_isp_wr>, <&qos_isp_m1>,
<&qos_vip>;
+ #power-domain-cells = <0>;
};
power-domain@PX30_PD_GPU {
reg = ;
clocks = <&cru SCLK_GPU>;
pm_qos = <&qos_gpu>;
+ #power-domain-cells = <0>;
};
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 5bb84ec31c6f..f6f5a64fef09 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -272,13 +272,17 @@
power-domain@RK3328_PD_HEVC {
reg = ;
+ clocks = <&cru SCLK_VENC_CORE>;
+ #power-domain-cells = <0>;
};
power-domain@RK3328_PD_VIDEO {
reg = ;
+ #power-domain-cells = <0>;
};
power-domain@RK3328_PD_VPU {
reg = ;
clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ #power-domain-cells = <0>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index e5a25bc7d799..e52c2dc1710a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1001,6 +1001,7 @@
clocks = <&cru ACLK_IEP>,
<&cru HCLK_IEP>;
pm_qos = <&qos_iep>;
+ #power-domain-cells = <0>;
};
pd_rga@RK3399_PD_RGA {
reg = ;
@@ -1008,12 +1009,14 @@
<&cru HCLK_RGA>;
pm_qos = <&qos_rga_r>,
<&qos_rga_w>;
+ #power-domain-cells = <0>;
};
pd_vcodec@RK3399_PD_VCODEC {
reg = ;
clocks = <&cru ACLK_VCODEC>,
<&cru HCLK_VCODEC>;
pm_qos = <&qos_video_m0>;
+ #power-domain-cells = <0>;
};
pd_vdu@RK3399_PD_VDU {
reg = ;
@@ -1021,6 +1024,7 @@
<&cru HCLK_VDU>;
pm_qos = <&qos_video_m1_r>,
<&qos_video_m1_w>;
+ #power-domain-cells = <0>;
};
/* These power domains are grouped by VD_GPU */
@@ -1028,43 +1032,63 @@
reg = ;
clocks = <&cru ACLK_GPU>;
pm_qos = <&qos_gpu>;
+ #power-domain-cells = <0>;
};
/* These power domains are grouped by VD_LOGIC */
pd_edp@RK3399_PD_EDP {
reg = ;
clocks = <&cru PCLK_EDP_CTRL>;
+ #power-domain-cells = <0>;
};
pd_emmc@RK3399_PD_EMMC {
reg = ;
clocks = <&cru ACLK_EMMC>;
pm_qos = <&qos_emmc>;
+ #power-domain-cells = <0>;
};
pd_gmac@RK3399_PD_GMAC {
reg = ;
clocks = <&cru ACLK_GMAC>,
<&cru PCLK_GMAC>;
pm_qos = <&qos_gmac>;
+ #power-domain-cells = <0>;
};
pd_sd@RK3399_PD_SD {
reg = ;
clocks = <&cru HCLK_SDMMC>,
<&cru SCLK_SDMMC>;
pm_qos = <&qos_sd>;
+ #power-domain-cells = <0>;
};
pd_sdioaudio@RK3399_PD_SDIOAUDIO {
reg = ;
clocks = <&cru HCLK_SDIO>;
pm_qos = <&qos_sdioaudio>;
+ #power-domain-cells = <0>;
+ };
+ pd_tcpc0@RK3399_PD_TCPD0 {
+ reg = ;
+ clocks = <&cru SCLK_UPHY0_TCPDCORE>,
+ <&cru SCLK_UPHY0_TCPDPHY_REF>;
+ #power-domain-cells = <0>;
+ };
+ pd_tcpc1@RK3399_PD_TCPD1 {
+ reg = ;
+ clocks = <&cru SCLK_UPHY1_TCPDCORE>,
+ <&cru SCLK_UPHY1_TCPDPHY_REF>;
+ #power-domain-cells = <0>;
};
pd_usb3@RK3399_PD_USB3 {
reg = ;
clocks = <&cru ACLK_USB3>;
pm_qos = <&qos_usb_otg0>,
<&qos_usb_otg1>;
+ #power-domain-cells = <0>;
};
pd_vio@RK3399_PD_VIO {
reg = ;
+ #power-domain-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -1074,6 +1098,7 @@
<&cru HCLK_HDCP>,
<&cru PCLK_HDCP>;
pm_qos = <&qos_hdcp>;
+ #power-domain-cells = <0>;
};
pd_isp0@RK3399_PD_ISP0 {
reg = ;
@@ -1081,6 +1106,7 @@
<&cru HCLK_ISP0>;
pm_qos = <&qos_isp0_m0>,
<&qos_isp0_m1>;
+ #power-domain-cells = <0>;
};
pd_isp1@RK3399_PD_ISP1 {
reg = ;
@@ -1088,19 +1114,11 @@
<&cru HCLK_ISP1>;
pm_qos = <&qos_isp1_m0>,
<&qos_isp1_m1>;
- };
- pd_tcpc0@RK3399_PD_TCPC0 {
- reg = ;
- clocks = <&cru SCLK_UPHY0_TCPDCORE>,
- <&cru SCLK_UPHY0_TCPDPHY_REF>;
- };
- pd_tcpc1@RK3399_PD_TCPC1 {
- reg = ;
- clocks = <&cru SCLK_UPHY1_TCPDCORE>,
- <&cru SCLK_UPHY1_TCPDPHY_REF>;
+ #power-domain-cells = <0>;
};
pd_vo@RK3399_PD_VO {
reg = ;
+ #power-domain-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -1110,12 +1128,14 @@
<&cru HCLK_VOP0>;
pm_qos = <&qos_vop_big_r>,
<&qos_vop_big_w>;
+ #power-domain-cells = <0>;
};
pd_vopl@RK3399_PD_VOPL {
reg = ;
clocks = <&cru ACLK_VOP1>,
<&cru HCLK_VOP1>;
pm_qos = <&qos_vop_little>;
+ #power-domain-cells = <0>;
};
};
};
diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
index 31a9c634c81e..081922c72daa 100644
--- a/arch/m68k/fpsp040/skeleton.S
+++ b/arch/m68k/fpsp040/skeleton.S
@@ -502,7 +502,8 @@ in_ea:
.section .fixup,"ax"
.even
1:
- jbra fpsp040_die
+ jbsr fpsp040_die
+ jbra .Lnotkern
.section __ex_table,"a"
.align 4
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 417d8f0e8962..0d03b4f2077b 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -182,6 +182,8 @@ ENTRY(ret_from_signal)
movel %curptr@(TASK_STACK),%a1
tstb %a1@(TINFO_FLAGS+2)
jge 1f
+ lea %sp@(SWITCH_STACK_SIZE),%a1
+ movel %a1,%curptr@(TASK_THREAD+THREAD_ESP0)
jbsr syscall_trace
1: RESTORE_SWITCH_STACK
addql #4,%sp
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 6363ec83a290..38dcc1a2097d 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -388,6 +388,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
ret = -EPERM;
if (!capable(CAP_SYS_ADMIN))
goto out;
+
+ down_read(¤t->mm->mmap_sem);
} else {
struct vm_area_struct *vma;
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index 5bf314871e9f..38311a403b08 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -1155,7 +1155,7 @@ asmlinkage void set_esp0(unsigned long ssp)
*/
asmlinkage void fpsp040_die(void)
{
- do_exit(SIGSEGV);
+ force_sigsegv(SIGSEGV);
}
#ifdef CONFIG_M68KFPU_EMU
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 65567f26d7bd..2750518a5d5e 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -442,6 +442,13 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
},
},
+ {
+ /* Asus Vivobook X1504VAP */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "X1504VAP"),
+ },
+ },
{
/* Asus Vivobook X1704VAP */
.matches = {
@@ -514,6 +521,17 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "16T90SP"),
},
},
+ {
+ /*
+ * TongFang GM5HG0A in case of the SKIKK Vanaheim relabel the
+ * board-name is changed, so check OEM strings instead. Note
+ * OEM string matches are always exact matches.
+ * https://bugzilla.kernel.org/show_bug.cgi?id=219614
+ */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_OEM_STRING, "GM5HG0A"),
+ },
+ },
{ }
};
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index a82352a87808..1c14c8295b45 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -41,7 +41,7 @@
#define DC_VER "3.2.48"
-#define MAX_SURFACES 3
+#define MAX_SURFACES 4
#define MAX_PLANES 6
#define MAX_STREAMS 6
#define MAX_SINKS_PER_LINK 4
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
index ded71ea82413..8968aa2bf156 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
@@ -67,11 +67,15 @@ static inline double dml_max5(double a, double b, double c, double d, double e)
static inline double dml_ceil(double a, double granularity)
{
+ if (granularity == 0)
+ return 0;
return (double) dcn_bw_ceil2(a, granularity);
}
static inline double dml_floor(double a, double granularity)
{
+ if (granularity == 0)
+ return 0;
return (double) dcn_bw_floor2(a, granularity);
}
@@ -97,11 +101,15 @@ static inline double dml_ceil_2(double f)
static inline double dml_ceil_ex(double x, double granularity)
{
+ if (granularity == 0)
+ return 0;
return (double) dcn_bw_ceil2(x, granularity);
}
static inline double dml_floor_ex(double x, double granularity)
{
+ if (granularity == 0)
+ return 0;
return (double) dcn_bw_floor2(x, granularity);
}
diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
index 662e67279a7b..41705436a748 100644
--- a/drivers/gpu/drm/v3d/v3d_irq.c
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
@@ -102,7 +102,10 @@ v3d_irq(int irq, void *arg)
to_v3d_fence(v3d->bin_job->base.irq_fence);
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
+
+ v3d->bin_job = NULL;
dma_fence_signal(&fence->base);
+
status = IRQ_HANDLED;
}
@@ -111,7 +114,10 @@ v3d_irq(int irq, void *arg)
to_v3d_fence(v3d->render_job->base.irq_fence);
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
+
+ v3d->render_job = NULL;
dma_fence_signal(&fence->base);
+
status = IRQ_HANDLED;
}
@@ -120,7 +126,10 @@ v3d_irq(int irq, void *arg)
to_v3d_fence(v3d->csd_job->base.irq_fence);
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
+
+ v3d->csd_job = NULL;
dma_fence_signal(&fence->base);
+
status = IRQ_HANDLED;
}
@@ -156,7 +165,10 @@ v3d_hub_irq(int irq, void *arg)
to_v3d_fence(v3d->tfu_job->base.irq_fence);
trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
+
+ v3d->tfu_job = NULL;
dma_fence_signal(&fence->base);
+
status = IRQ_HANDLED;
}
diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c
index 45a3f7e7b3f6..cea057704c00 100644
--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c
@@ -261,7 +261,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
pm_runtime_no_callbacks(&pdev->dev);
/* switch to first parent as active master */
- i2c_demux_activate_master(priv, 0);
+ err = i2c_demux_activate_master(priv, 0);
+ if (err)
+ goto err_rollback;
err = device_create_file(&pdev->dev, &dev_attr_available_masters);
if (err)
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index cc81b35ca47a..4226e307ab27 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -1139,7 +1139,7 @@ static int at91_ts_register(struct at91_adc_state *st,
return ret;
err:
- input_free_device(st->ts_input);
+ input_free_device(input);
return ret;
}
diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c
index 4b706949a67f..b8a506209c35 100644
--- a/drivers/iio/adc/ti-ads124s08.c
+++ b/drivers/iio/adc/ti-ads124s08.c
@@ -182,9 +182,9 @@ static int ads124s_reset(struct iio_dev *indio_dev)
struct ads124s_private *priv = iio_priv(indio_dev);
if (priv->reset_gpio) {
- gpiod_set_value(priv->reset_gpio, 0);
+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
udelay(200);
- gpiod_set_value(priv->reset_gpio, 1);
+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
} else {
return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET);
}
diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c
index 55a2d619d6dd..f0f16bc68865 100644
--- a/drivers/iio/adc/ti-ads8688.c
+++ b/drivers/iio/adc/ti-ads8688.c
@@ -384,7 +384,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
/* Ensure naturally aligned timestamp */
- u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8);
+ u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { };
int i, j = 0;
for (i = 0; i < indio_dev->masklength; i++) {
diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c
index 17606eca42b4..0615d34d908b 100644
--- a/drivers/iio/dummy/iio_simple_dummy_buffer.c
+++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c
@@ -48,7 +48,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
int len = 0;
u16 *data;
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+ data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (!data)
goto done;
diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c
index 45e2b5b33072..891969a805b7 100644
--- a/drivers/iio/gyro/fxas21002c_core.c
+++ b/drivers/iio/gyro/fxas21002c_core.c
@@ -664,14 +664,21 @@ static irqreturn_t fxas21002c_trigger_handler(int irq, void *p)
int ret;
mutex_lock(&data->lock);
- ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB,
- data->buffer, CHANNEL_SCAN_MAX * sizeof(s16));
+ ret = fxas21002c_pm_get(data);
if (ret < 0)
goto out_unlock;
+ ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB,
+ data->buffer, CHANNEL_SCAN_MAX * sizeof(s16));
+ if (ret < 0)
+ goto out_pm_put;
+
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
data->timestamp);
+out_pm_put:
+ fxas21002c_pm_put(data);
+
out_unlock:
mutex_unlock(&data->lock);
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
index c7d19f9ca765..fb01b64d356a 100644
--- a/drivers/iio/imu/kmx61.c
+++ b/drivers/iio/imu/kmx61.c
@@ -1198,7 +1198,7 @@ static irqreturn_t kmx61_trigger_handler(int irq, void *p)
struct kmx61_data *data = kmx61_get_data(indio_dev);
int bit, ret, i = 0;
u8 base;
- s16 buffer[8];
+ s16 buffer[8] = { };
if (indio_dev == data->acc_indio_dev)
base = KMX61_ACC_XOUT_L;
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 730c821b5221..6374d5091555 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -466,7 +466,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev)
return chans;
error_free_chans:
- for (i = 0; i < nummaps; i++)
+ for (i = 0; i < mapind; i++)
iio_device_put(chans[i].indio_dev);
kfree(chans);
error_ret:
diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c
index 6c83f9e54e2e..940b80c81d52 100644
--- a/drivers/iio/light/vcnl4035.c
+++ b/drivers/iio/light/vcnl4035.c
@@ -105,7 +105,7 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct vcnl4035_data *data = iio_priv(indio_dev);
/* Ensure naturally aligned timestamp */
- u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8);
+ u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8) = { };
int ret;
ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer);
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
index 7f2e5a8942a4..df60b3d91dad 100644
--- a/drivers/iio/pressure/zpa2326.c
+++ b/drivers/iio/pressure/zpa2326.c
@@ -585,6 +585,8 @@ static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev,
} sample;
int err;
+ memset(&sample, 0, sizeof(sample));
+
if (test_bit(0, indio_dev->active_scan_mask)) {
/* Get current pressure from hardware FIFO. */
err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 239471cf7e4c..00b973e0f79f 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -128,6 +128,7 @@ static const struct xpad_device {
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
{ 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
+ { 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
@@ -344,6 +345,7 @@ static const struct xpad_device {
{ 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
{ 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
{ 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
+ { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 },
{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index cb7f9b46ce65..c22ef6483c40 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -84,7 +84,7 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
- 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
+ 0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85,
0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 181325c7a827..d84570969b03 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1268,7 +1268,7 @@ void gic_s2idle_wake(void)
static int gic_cpu_pm_notifier(struct notifier_block *self,
unsigned long cmd, void *v)
{
- if (cmd == CPU_PM_EXIT) {
+ if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
if (gic_dist_security_disabled())
gic_enable_redist(true);
gic_cpu_sys_reg_init();
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
index a412b5d5d0fa..a2aadfdc4772 100644
--- a/drivers/irqchip/irq-sunxi-nmi.c
+++ b/drivers/irqchip/irq-sunxi-nmi.c
@@ -200,7 +200,8 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit;
gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
- gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED;
+ gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED |
+ IRQCHIP_SKIP_SET_WAKE;
gc->chip_types[0].regs.ack = reg_offs->pend;
gc->chip_types[0].regs.mask = reg_offs->enable;
gc->chip_types[0].regs.type = reg_offs->ctrl;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 1ce0d5b52746..9e4332233531 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2325,10 +2325,9 @@ static struct thin_c *get_first_thin(struct pool *pool)
struct thin_c *tc = NULL;
rcu_read_lock();
- if (!list_empty(&pool->active_thins)) {
- tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list);
+ tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list);
+ if (tc)
thin_get(tc);
- }
rcu_read_unlock();
return tc;
diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c
index 185dc60360b5..4d434d89eadd 100644
--- a/drivers/md/persistent-data/dm-array.c
+++ b/drivers/md/persistent-data/dm-array.c
@@ -907,23 +907,27 @@ static int load_ablock(struct dm_array_cursor *c)
if (c->block)
unlock_ablock(c->info, c->block);
- c->block = NULL;
- c->ab = NULL;
c->index = 0;
r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
if (r) {
DMERR("dm_btree_cursor_get_value failed");
- dm_btree_cursor_end(&c->cursor);
+ goto out;
} else {
r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
if (r) {
DMERR("get_ablock failed");
- dm_btree_cursor_end(&c->cursor);
+ goto out;
}
}
+ return 0;
+
+out:
+ dm_btree_cursor_end(&c->cursor);
+ c->block = NULL;
+ c->ab = NULL;
return r;
}
@@ -946,10 +950,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin);
void dm_array_cursor_end(struct dm_array_cursor *c)
{
- if (c->block) {
+ if (c->block)
unlock_ablock(c->info, c->block);
- dm_btree_cursor_end(&c->cursor);
- }
+
+ dm_btree_cursor_end(&c->cursor);
}
EXPORT_SYMBOL_GPL(dm_array_cursor_end);
@@ -989,6 +993,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
}
count -= remaining;
+ c->index += (remaining - 1);
r = dm_array_cursor_next(c);
} while (!r);
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index ad22b51765d4..1cabe000f51a 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -19,6 +19,8 @@ static void init_codecs(struct venus_core *core)
struct venus_caps *caps = core->caps, *cap;
unsigned long bit;
+ core->codecs_count = 0;
+
if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM)
return;
@@ -62,7 +64,7 @@ fill_buf_mode(struct venus_caps *cap, const void *data, unsigned int num)
cap->cap_bufs_mode_dynamic = true;
}
-static void
+static int
parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
{
struct hfi_buffer_alloc_mode_supported *mode = data;
@@ -70,7 +72,7 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
u32 *type;
if (num_entries > MAX_ALLOC_MODE_ENTRIES)
- return;
+ return -EINVAL;
type = mode->data;
@@ -82,6 +84,8 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
type++;
}
+
+ return sizeof(*mode);
}
static void fill_profile_level(struct venus_caps *cap, const void *data,
@@ -96,7 +100,7 @@ static void fill_profile_level(struct venus_caps *cap, const void *data,
cap->num_pl += num;
}
-static void
+static int
parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
{
struct hfi_profile_level_supported *pl = data;
@@ -104,12 +108,14 @@ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
struct hfi_profile_level pl_arr[HFI_MAX_PROFILE_COUNT] = {};
if (pl->profile_count > HFI_MAX_PROFILE_COUNT)
- return;
+ return -EINVAL;
memcpy(pl_arr, proflevel, pl->profile_count * sizeof(*proflevel));
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
fill_profile_level, pl_arr, pl->profile_count);
+
+ return pl->profile_count * sizeof(*proflevel) + sizeof(u32);
}
static void
@@ -124,7 +130,7 @@ fill_caps(struct venus_caps *cap, const void *data, unsigned int num)
cap->num_caps += num;
}
-static void
+static int
parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
{
struct hfi_capabilities *caps = data;
@@ -133,12 +139,14 @@ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
struct hfi_capability caps_arr[MAX_CAP_ENTRIES] = {};
if (num_caps > MAX_CAP_ENTRIES)
- return;
+ return -EINVAL;
memcpy(caps_arr, cap, num_caps * sizeof(*cap));
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
fill_caps, caps_arr, num_caps);
+
+ return sizeof(*caps);
}
static void fill_raw_fmts(struct venus_caps *cap, const void *fmts,
@@ -153,7 +161,7 @@ static void fill_raw_fmts(struct venus_caps *cap, const void *fmts,
cap->num_fmts += num_fmts;
}
-static void
+static int
parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
{
struct hfi_uncompressed_format_supported *fmt = data;
@@ -162,7 +170,8 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {};
u32 entries = fmt->format_entries;
unsigned int i = 0;
- u32 num_planes;
+ u32 num_planes = 0;
+ u32 size;
while (entries) {
num_planes = pinfo->num_planes;
@@ -172,7 +181,7 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
i++;
if (i >= MAX_FMT_ENTRIES)
- return;
+ return -EINVAL;
if (pinfo->num_planes > MAX_PLANES)
break;
@@ -184,9 +193,13 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
fill_raw_fmts, rawfmts, i);
+ size = fmt->format_entries * (sizeof(*constr) * num_planes + 2 * sizeof(u32))
+ + 2 * sizeof(u32);
+
+ return size;
}
-static void parse_codecs(struct venus_core *core, void *data)
+static int parse_codecs(struct venus_core *core, void *data)
{
struct hfi_codec_supported *codecs = data;
@@ -198,21 +211,27 @@ static void parse_codecs(struct venus_core *core, void *data)
core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;
core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC;
}
+
+ return sizeof(*codecs);
}
-static void parse_max_sessions(struct venus_core *core, const void *data)
+static int parse_max_sessions(struct venus_core *core, const void *data)
{
const struct hfi_max_sessions_supported *sessions = data;
core->max_sessions_supported = sessions->max_sessions;
+
+ return sizeof(*sessions);
}
-static void parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
+static int parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
{
struct hfi_codec_mask_supported *mask = data;
*codecs = mask->codecs;
*domain = mask->video_domains;
+
+ return sizeof(*mask);
}
static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain)
@@ -246,46 +265,76 @@ static void parser_fini(struct venus_inst *inst, u32 codecs, u32 domain)
u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
u32 size)
{
- unsigned int words_count = size >> 2;
- u32 *word = buf, *data, codecs = 0, domain = 0;
+ u32 *words = buf, *payload, codecs = 0, domain = 0;
+ u32 *frame_size = buf + size;
+ u32 rem_bytes = size;
+ int ret;
if (size % 4)
return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
parser_init(inst, &codecs, &domain);
- while (words_count) {
- data = word + 1;
+ while (words < frame_size) {
+ payload = words + 1;
- switch (*word) {
+ switch (*words) {
case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
- parse_codecs(core, data);
+ if (rem_bytes <= sizeof(struct hfi_codec_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_codecs(core, payload);
+ if (ret < 0)
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
init_codecs(core);
break;
case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED:
- parse_max_sessions(core, data);
+ if (rem_bytes <= sizeof(struct hfi_max_sessions_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_max_sessions(core, payload);
break;
case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
- parse_codecs_mask(&codecs, &domain, data);
+ if (rem_bytes <= sizeof(struct hfi_codec_mask_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_codecs_mask(&codecs, &domain, payload);
break;
case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
- parse_raw_formats(core, codecs, domain, data);
+ if (rem_bytes <= sizeof(struct hfi_uncompressed_format_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_raw_formats(core, codecs, domain, payload);
break;
case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
- parse_caps(core, codecs, domain, data);
+ if (rem_bytes <= sizeof(struct hfi_capabilities))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_caps(core, codecs, domain, payload);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
- parse_profile_level(core, codecs, domain, data);
+ if (rem_bytes <= sizeof(struct hfi_profile_level_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_profile_level(core, codecs, domain, payload);
break;
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
- parse_alloc_mode(core, codecs, domain, data);
+ if (rem_bytes <= sizeof(struct hfi_buffer_alloc_mode_supported))
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ ret = parse_alloc_mode(core, codecs, domain, payload);
break;
default:
+ ret = sizeof(u32);
break;
}
- word++;
- words_count--;
+ if (ret < 0)
+ return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+ words += ret / sizeof(u32);
+ rem_bytes -= ret;
}
parser_fini(inst, codecs, domain);
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 306082e25943..1b37d77bf998 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -188,6 +188,9 @@ static int venus_write_queue(struct venus_hfi_device *hdev,
/* ensure rd/wr indices's are read from memory */
rmb();
+ if (qsize > IFACEQ_QUEUE_SIZE / 4)
+ return -EINVAL;
+
if (wr_idx >= rd_idx)
empty_space = qsize - (wr_idx - rd_idx);
else
@@ -256,6 +259,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev,
wr_idx = qhdr->write_idx;
qsize = qhdr->q_size;
+ if (qsize > IFACEQ_QUEUE_SIZE / 4)
+ return -EINVAL;
+
/* make sure data is valid before using it */
rmb();
@@ -970,18 +976,26 @@ static void venus_sfr_print(struct venus_hfi_device *hdev)
{
struct device *dev = hdev->core->dev;
struct hfi_sfr *sfr = hdev->sfr.kva;
+ u32 size;
void *p;
if (!sfr)
return;
- p = memchr(sfr->data, '\0', sfr->buf_size);
+ size = sfr->buf_size;
+ if (!size)
+ return;
+
+ if (size > ALIGNED_SFR_SIZE)
+ size = ALIGNED_SFR_SIZE;
+
+ p = memchr(sfr->data, '\0', size);
/*
* SFR isn't guaranteed to be NULL terminated since SYS_ERROR indicates
* that Venus is in the process of crashing.
*/
if (!p)
- sfr->data[sfr->buf_size - 1] = '\0';
+ sfr->data[size - 1] = '\0';
dev_err_ratelimited(dev, "SFR message from FW: %s\n", sfr->data);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index 0a15c617c702..fa56ef029315 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -855,7 +855,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
struct xgbe_phy_data *phy_data = pdata->phy_data;
unsigned int phy_id = phy_data->phydev->phy_id;
@@ -877,14 +876,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
phy_write(phy_data->phydev, 0x04, 0x0d01);
phy_write(phy_data->phydev, 0x00, 0x9140);
- linkmode_set_bit_array(phy_10_100_features_array,
- ARRAY_SIZE(phy_10_100_features_array),
- supported);
- linkmode_set_bit_array(phy_gbit_features_array,
- ARRAY_SIZE(phy_gbit_features_array),
- supported);
-
- linkmode_copy(phy_data->phydev->supported, supported);
+ linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
phy_support_asym_pause(phy_data->phydev);
@@ -896,7 +888,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
struct xgbe_phy_data *phy_data = pdata->phy_data;
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
unsigned int phy_id = phy_data->phydev->phy_id;
@@ -960,13 +951,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
reg = phy_read(phy_data->phydev, 0x00);
phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
- linkmode_set_bit_array(phy_10_100_features_array,
- ARRAY_SIZE(phy_10_100_features_array),
- supported);
- linkmode_set_bit_array(phy_gbit_features_array,
- ARRAY_SIZE(phy_gbit_features_array),
- supported);
- linkmode_copy(phy_data->phydev->supported, supported);
+ linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
phy_support_asym_pause(phy_data->phydev);
netif_dbg(pdata, drv, pdata->netdev,
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 7ff388ecc7e3..409b636c7647 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -454,7 +454,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
map_id_full = be64_to_cpu(cbe->map_ptr);
map_id = map_id_full;
- if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
+ if (size_add(pkt_size, data_size) > INT_MAX ||
+ len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
return -EINVAL;
if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
return -EINVAL;
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index f17619c545ae..9280601961c7 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -60,15 +60,15 @@
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
{
- int idx, idx2;
+ int idx, idx2, index;
u32 hi_val = 0;
idx = start / 32;
idx2 = (start + bits - 1) / 32;
/* Check if bits to be fetched exceed a word */
if (idx != idx2) {
- idx2 = 2 - idx2; /* flip */
- hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
+ index = 2 - idx2; /* flip */
+ hi_val = ale_entry[index] << ((idx2 * 32) - start);
}
start -= idx * 32;
idx = 2 - idx; /* flip */
@@ -78,16 +78,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
u32 value)
{
- int idx, idx2;
+ int idx, idx2, index;
value &= BITMASK(bits);
idx = start / 32;
idx2 = (start + bits - 1) / 32;
/* Check if bits to be set exceed a word */
if (idx != idx2) {
- idx2 = 2 - idx2; /* flip */
- ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
- ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
+ index = 2 - idx2; /* flip */
+ ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
+ ale_entry[index] |= (value >> ((idx2 * 32) - start));
}
start -= idx * 32;
idx = 2 - idx; /* flip */
diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
index fdbdc22fe4e5..d394e2b65054 100644
--- a/drivers/net/ieee802154/ca8210.c
+++ b/drivers/net/ieee802154/ca8210.c
@@ -3124,7 +3124,11 @@ static int ca8210_probe(struct spi_device *spi_device)
spi_set_drvdata(priv->spi, priv);
if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
cascoda_api_upstream = ca8210_test_int_driver_write;
- ca8210_test_interface_init(priv);
+ ret = ca8210_test_interface_init(priv);
+ if (ret) {
+ dev_crit(&spi_device->dev, "ca8210_test_interface_init failed\n");
+ goto error;
+ }
} else {
cascoda_api_upstream = NULL;
}
diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c
index 10d580c3dea3..dff011bf324b 100644
--- a/drivers/net/xen-netback/hash.c
+++ b/drivers/net/xen-netback/hash.c
@@ -51,7 +51,8 @@ static void xenvif_add_hash(struct xenvif *vif, const u8 *tag,
found = false;
oldest = NULL;
- list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) {
+ list_for_each_entry_rcu(entry, &vif->hash.cache.list, link,
+ lockdep_is_held(&vif->hash.cache.lock)) {
/* Make sure we don't add duplicate entries */
if (entry->len == len &&
memcmp(entry->tag, tag, len) == 0)
@@ -94,7 +95,7 @@ static u32 xenvif_new_hash(struct xenvif *vif, const u8 *data,
static void xenvif_flush_hash(struct xenvif *vif)
{
- struct xenvif_hash_cache_entry *entry;
+ struct xenvif_hash_cache_entry *entry, *n;
unsigned long flags;
if (xenvif_hash_cache_size == 0)
@@ -102,7 +103,7 @@ static void xenvif_flush_hash(struct xenvif *vif)
spin_lock_irqsave(&vif->hash.cache.lock, flags);
- list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) {
+ list_for_each_entry_safe(entry, n, &vif->hash.cache.list, link) {
list_del_rcu(&entry->link);
vif->hash.cache.count--;
kfree_rcu(entry, rcu);
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 32008d85172b..40afe3d0599d 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
*/
id->nsfeat |= 1 << 4;
/* NPWG = Namespace Preferred Write Granularity. 0's based */
- id->npwg = lpp0b;
+ id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev));
/* NPWA = Namespace Preferred Write Alignment. 0's based */
id->npwa = id->npwg;
/* NPDG = Namespace Preferred Deallocate Granularity. 0's based */
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index c801fe727f09..c94a0d2c4516 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -1094,11 +1094,12 @@ EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
* of_phy_provider_unregister to unregister the phy provider.
*/
void devm_of_phy_provider_unregister(struct device *dev,
- struct phy_provider *phy_provider) {
+ struct phy_provider *phy_provider)
+{
int r;
- r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
- phy_provider);
+ r = devres_release(dev, devm_phy_provider_release, devm_phy_match,
+ phy_provider);
dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
}
EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index 68401a824bc2..68e52b8191c9 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -3189,6 +3189,7 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
{
int rc;
uint32_t size, i;
+ struct event_req *req, *tmp;
size = mhi_dev_get_evt_ring_size(mhi, ch->ch_id);
@@ -3207,7 +3208,14 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
* they were allocated with a different size
*/
if (ch->evt_buf_size) {
- kfree(ch->ereqs);
+ list_for_each_entry_safe(req, tmp, &ch->event_req_buffers, list) {
+ list_del(&req->list);
+ kfree(req);
+ }
+ list_for_each_entry_safe(req, tmp, &ch->flush_event_req_buffers, list) {
+ list_del(&req->list);
+ kfree(req);
+ }
kfree(ch->tr_events);
}
/*
@@ -3221,14 +3229,8 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
mhi_log(MHI_MSG_INFO,
"ch_id:%d evt buf size is %d\n", ch->ch_id, ch->evt_buf_size);
- /* Allocate event requests */
- ch->ereqs = kcalloc(ch->evt_req_size, sizeof(*ch->ereqs), GFP_KERNEL);
- if (!ch->ereqs) {
- mhi_log(MHI_MSG_ERROR,
- "Failed to alloc ereqs for ch_id:%d\n", ch->ch_id);
- rc = -ENOMEM;
- goto free_ereqs;
- }
+ INIT_LIST_HEAD(&ch->event_req_buffers);
+ INIT_LIST_HEAD(&ch->flush_event_req_buffers);
/* Allocate buffers to queue transfer completion events */
ch->tr_events = kcalloc(ch->evt_buf_size, sizeof(*ch->tr_events),
@@ -3241,11 +3243,13 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
goto free_ereqs;
}
- /* Organize event flush requests into a linked list */
- INIT_LIST_HEAD(&ch->event_req_buffers);
- INIT_LIST_HEAD(&ch->flush_event_req_buffers);
- for (i = 0; i < ch->evt_req_size; ++i)
- list_add_tail(&ch->ereqs[i].list, &ch->event_req_buffers);
+ /* Allocate event requests */
+ for (i = 0; i < ch->evt_req_size; ++i) {
+ req = kzalloc(sizeof(struct event_req), GFP_KERNEL);
+ if (!req)
+ goto free_ereqs;
+ list_add_tail(&req->list, &ch->event_req_buffers);
+ }
ch->curr_ereq =
container_of(ch->event_req_buffers.next,
@@ -3263,8 +3267,13 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
return 0;
free_ereqs:
- kfree(ch->ereqs);
- ch->ereqs = NULL;
+ if (!list_empty(&ch->event_req_buffers)) {
+ list_for_each_entry_safe(req, tmp, &ch->event_req_buffers, list) {
+ list_del(&req->list);
+ kfree(req);
+ }
+ }
+ kfree(ch->tr_events);
ch->evt_buf_size = 0;
ch->evt_req_size = 0;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 51f53638629c..9ef242d2a2c9 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3746,7 +3746,7 @@ iscsi_if_rx(struct sk_buff *skb)
}
do {
/*
- * special case for GET_STATS:
+ * special case for GET_STATS, GET_CHAP and GET_HOST_STATS:
* on success - sending reply and stats from
* inside of if_recv_msg(),
* on error - fall through.
@@ -3755,6 +3755,8 @@ iscsi_if_rx(struct sk_buff *skb)
break;
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
break;
+ if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err)
+ break;
err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
ev, sizeof(*ev));
if (err == -EAGAIN && --retries < 0) {
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index cc836610e21e..001a3470b3aa 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -390,7 +390,6 @@ sg_release(struct inode *inode, struct file *filp)
mutex_lock(&sdp->open_rel_lock);
scsi_autopm_put_device(sdp->device);
- kref_put(&sfp->f_ref, sg_remove_sfp);
sdp->open_cnt--;
/* possibly many open()s waiting on exlude clearing, start many;
@@ -402,6 +401,7 @@ sg_release(struct inode *inode, struct file *filp)
wake_up_interruptible(&sdp->open_wait);
}
mutex_unlock(&sdp->open_rel_lock);
+ kref_put(&sfp->f_ref, sg_remove_sfp);
return 0;
}
diff --git a/drivers/staging/fw-api/fw/htt.h b/drivers/staging/fw-api/fw/htt.h
index ba5b42d6e3e6..e9d34066ff72 100644
--- a/drivers/staging/fw-api/fw/htt.h
+++ b/drivers/staging/fw-api/fw/htt.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -265,9 +265,10 @@
* 3.135 Add HTT_HOST4_TO_FW_RXBUF_RING def.
* 3.136 Add htt_ext_present flag in htt_tx_tcl_global_seq_metadata.
* 3.137 Add more HTT_SDWF_MSDUQ_CFG_IND_ERROR codes.
+ * 3.138 Add T2H MLO_LATENCY_REQ, H2T _RESP msg defs.
*/
#define HTT_CURRENT_VERSION_MAJOR 3
-#define HTT_CURRENT_VERSION_MINOR 137
+#define HTT_CURRENT_VERSION_MINOR 138
#define HTT_NUM_TX_FRAG_DESC 1024
@@ -839,6 +840,10 @@ typedef enum {
HTT_STATS_PDEV_RTT_DELAY_TAG = 205, /* htt_stats_pdev_rtt_delay_tlv */
HTT_STATS_PDEV_AOA_TAG = 206, /* htt_stats_pdev_aoa_tlv */
HTT_STATS_PDEV_FTM_TPCCAL_TAG = 207, /* htt_stats_pdev_ftm_tpccal_tlv */
+ HTT_STATS_PDEV_UL_MUMIMO_GRP_STATS_TAG = 208, /* htt_stats_pdev_ulmumimo_grp_stats_tlv */
+ HTT_STATS_PDEV_UL_MUMIMO_DENYLIST_STATS_TAG = 209, /* htt_stats_pdev_ulmumimo_denylist_stats_tlv */
+ HTT_STATS_PDEV_UL_MUMIMO_SEQ_TERM_STATS_TAG = 210, /* htt_stats_pdev_ulmumimo_seq_term_stats_tlv */
+ HTT_STATS_PDEV_UL_MUMIMO_HIST_INELIGIBILITY_TAG = 211, /* htt_stats_pdev_ulmumimo_hist_ineligibility_tlv */
HTT_STATS_MAX_TAG,
} htt_stats_tlv_tag_t;
@@ -913,6 +918,7 @@ enum htt_h2t_msg_type {
HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG = 0x25,
HTT_H2T_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP = 0x26,
HTT_H2T_MSG_TYPE_SDWF_MSDUQ_RECFG_REQ = 0x27,
+ HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP = 0x28,
/* keep this last */
HTT_H2T_NUM_MSGS
@@ -11495,6 +11501,89 @@ PREPACK struct htt_h2t_sdwf_msduq_recfg_req {
((_var) |= ((_val) << HTT_H2T_SDWF_MSDUQ_RECFG_REQUEST_COOKIE_S)); \
} while (0)
+/**
+ * @brief host -> target report MLO latency stats to FW periodically
+ *
+ * MSG_TYPE => HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP
+ *
+ * @details
+ *
+ * |31 24|23 16|15 8|7 0|
+ * |----------------+----------------+----------------+----------------|
+ * | avg latency ms | vdev id | msg type |
+ * |----------------+----------------+----------------+----------------|
+ * | num of tx MSDUs | avg latency jitter ms |
+ * |-------------------------------------------------------------------|
+ *
+ * @details
+ * struct htt_h2t_mlo_latency_stats:
+ *
+ * The message is interpreted as follows:
+ * dword0 - b'7:0 - msg_type: Identifies mlo latency stats to fw
+ * This will be set to 0x28
+ * (HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP)
+ * b'15:8 - vdev id : Indicate which vdev in the pdev is chosen
+ * as primary
+ * b'31:16 - avg latency ms: Indicate average MLO latency in a period
+ * dword1 - b'15:0 - min jitter ms: Indicate avg jitter of MLO latency in a
+ * period
+ * b'31:16 - num of tx packet : Indicate how many MSDUs are sent in a
+ * period
+ */
+
+/* HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP */
+PREPACK struct htt_h2t_mlo_latency_stats {
+ A_UINT32 msg_type: 8, /* bits 7:0 */
+ vdev_id: 8, /* bits 15:8 */
+ avg_latency_ms: 16; /* bits 31:16 */
+ A_UINT32 avg_jitter_ms: 16, /* bits 15:0 */
+ num_of_tx_pkt: 16; /* bits 31:16 */
+} POSTPACK;
+
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_M 0x0000FF00
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S 8
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_GET(_var) \
+ (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_M) >> \
+ HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S)
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID, _val); \
+ ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S)); \
+ } while (0)
+
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_M 0xFFFF0000
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S 16
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_GET(_var) \
+ (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_M) >> \
+ HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S)
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS, _val); \
+ ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S)); \
+ } while (0)
+
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_M 0x0000FFFF
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S 0
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_GET(_var) \
+ (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_M) >> \
+ HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S)
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS, _val); \
+ ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S)); \
+ } while (0)
+
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_M 0xFFFF0000
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S 16
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_GET(_var) \
+ (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_M) >> \
+ HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S)
+#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT, _val); \
+ ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S)); \
+ } while (0)
+
/*=== target -> host messages ===============================================*/
@@ -11569,6 +11658,7 @@ enum htt_t2h_msg_type {
HTT_T2H_MSG_TYPE_TX_LATENCY_STATS_PERIODIC_IND = 0x3a,
HTT_T2H_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP_DONE = 0x3b,
HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND = 0x3c,
+ HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ = 0x3d,
HTT_T2H_MSG_TYPE_TEST,
@@ -15328,7 +15418,7 @@ typedef enum {
} while (0)
#define HTT_RX_ADDBA_EXTN_WIN_SIZE_GET(word) \
- (((word) & HTT_RX_ADDBA_WIN_SIZE_M) >> HTT_RX_ADDBA_WIN_SIZE_S)
+ (((word) & HTT_RX_ADDBA_EXTN_WIN_SIZE_M) >> HTT_RX_ADDBA_EXTN_WIN_SIZE_S)
#define HTT_RX_ADDBA_EXTN_BYTES 8
@@ -23290,6 +23380,73 @@ PREPACK struct htt_t2h_sdwf_msduq_cfg_ind {
((_var) |= ((_val) << HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND_REQUEST_COOKIE_S)); \
} while (0)
+/**
+ * @brief target -> host request for MLO latency stats
+ *
+ * MSG_TYPE => HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ
+ *
+ * @details
+ *
+ * |31 24|23 16| 15 |14 8|7 0|
+ * |----------------+----------------+------+---------+----------------|
+ * | periodic interval |enable| vdev id | msg type |
+ * |-------------------------------------------------------------------|
+ *
+ * @details
+ * struct htt_t2h_mlo_latency_req_t:
+ *
+ * The message is interpreted as follows:
+ * dword0 - b'7:0 - msg_type: Identifies a request for MLO latency stats
+ * This will be set to 0x3d
+ * (HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ)
+ * b'14:8 - vdev id : Indicate which vdev in the pdev is chosen
+ * as primary
+ * b'15 - enable: Indicate if request of MLO latency stats is
+ * enabled
+ * b'31:16 - periodic interval: Indicate the interval in ms of
+ * reporting MLO latency stats
+ */
+
+/* HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ */
+PREPACK struct htt_t2h_mlo_latency_req_t {
+ A_UINT32 msg_type: 8, /* bits 7:0 */
+ vdev_id: 7, /* bits 14:8 */
+ enable: 1, /* bits 15 */
+ periodic_intvl: 16; /* bits 31:16 */
+} POSTPACK;
+
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_M 0x00007F00
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S 8
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_GET(_var) \
+ (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_M) >> \
+ HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S)
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID, _val); \
+ ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S)); \
+ } while (0)
+
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_M 0x00008000
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S 15
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_GET(_var) \
+ (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_M) >> \
+ HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S)
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE, _val); \
+ ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S)); \
+ } while (0)
+
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_M 0xFFFF0000
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S 16
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_GET(_var) \
+ (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_M) >> \
+ HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S)
+#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_SET(_var, _val) \
+ do { \
+ HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL, _val); \
+ ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S)); \
+ } while (0)
#endif
diff --git a/drivers/staging/fw-api/fw/htt_ppdu_stats.h b/drivers/staging/fw-api/fw/htt_ppdu_stats.h
index 1fd2698551cd..d1575d7c91ba 100644
--- a/drivers/staging/fw-api/fw/htt_ppdu_stats.h
+++ b/drivers/staging/fw-api/fw/htt_ppdu_stats.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -922,6 +922,8 @@ typedef struct {
* part of existing DL/UL data sequence
*/
A_UINT32 is_combined_ul_bsrp_trigger;
+ /* Flag to indicate if the channel chosen is 320_1 / 320_2 */
+ A_UINT32 chan_type_320mhz;
} htt_ppdu_stats_common_tlv;
#define HTT_PPDU_STATS_USER_COMMON_TLV_TID_NUM_M 0x000000ff
diff --git a/drivers/staging/fw-api/fw/htt_stats.h b/drivers/staging/fw-api/fw/htt_stats.h
index c0eccd71a494..5a57e7f9f171 100644
--- a/drivers/staging/fw-api/fw/htt_stats.h
+++ b/drivers/staging/fw-api/fw/htt_stats.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -818,6 +818,17 @@ enum htt_dbg_ext_stats_type {
*/
HTT_DBG_EXT_STATS_PDEV_FTM_TPCCAL = 73,
+ /** HTT_DBG_EXT_STATS_PDEV_UL_MUMIMO_ELIGIBLE
+ * PARAMS:
+ * - No Params
+ * RESP MSG:
+ * - htt_stats_pdev_ul_mumimo_grp_stats_tlv
+ * - htt_stats_pdev_ul_mumimo_denylist_stats_tlv
+ * - htt_stats_pdev_ul_mumimo_seq_term_stats_tlv
+ * - htt_stats_pdev_ul_mumimo_hist_ineligibility_tlv
+ */
+ HTT_DBG_EXT_STATS_PDEV_UL_MUMIMO_ELIGIBLE = 74,
+
/* keep this last */
HTT_DBG_NUM_EXT_STATS = 256,
@@ -2858,6 +2869,11 @@ typedef enum {
HTT_TX_MUMIMO_GRP_INVALID_GROUP_INELIGIBLE,
HTT_TX_MUMIMO_GRP_INVALID,
HTT_TX_MUMIMO_GRP_INVALID_GROUP_EFF_MU_TPUT_OMBPS,
+ HTT_TX_MUMIMO_GRP_INVALID_GRP,
+ HTT_TX_MUMIMO_GRP_INVALID_TOTAL_NSS_LESS_THAN_GROUP_SIZE,
+ HTT_TX_MUMIMO_GRP_INSUFFICIENT_CANDIDATES_UL_MU_1SS_RATE,
+ HTT_TX_MUMIMO_GRP_MU_GRP_NOT_NEEDED,
+
HTT_TX_MUMIMO_GRP_INVALID_MAX_REASON_CODE,
} htt_tx_mumimo_grp_invalid_reason_code_stats;
@@ -4765,6 +4781,19 @@ typedef struct {
A_UINT32 g1_compl_fail;
A_UINT32 g2_success;
A_UINT32 g2_compl_fail;
+ /* enqueue */
+ A_UINT32 m1_enq_success;
+ A_UINT32 m1_enq_fail;
+ A_UINT32 m2_enq_success;
+ A_UINT32 m2_enq_fail;
+ A_UINT32 m3_enq_success;
+ A_UINT32 m3_enq_fail;
+ A_UINT32 m4_enq_success;
+ A_UINT32 m4_enq_fail;
+ A_UINT32 g1_enq_success;
+ A_UINT32 g1_enq_fail;
+ A_UINT32 g2_enq_success;
+ A_UINT32 g2_enq_fail;
} htt_stats_tx_de_eapol_packets_tlv;
/* preserve old name alias for new name consistent with the tag name */
typedef htt_stats_tx_de_eapol_packets_tlv htt_tx_de_eapol_packets_stats_tlv;
@@ -7561,6 +7590,15 @@ typedef struct {
A_UINT32 cv_corr_upload_total_num_users[HTT_TX_CV_CORR_MAX_NUM_COLUMNS];
/** number of streams present in uploaded CV Correlation results buffer */
A_UINT32 cv_corr_upload_total_num_streams[HTT_TX_CV_CORR_MAX_NUM_COLUMNS];
+
+ /** Total number of times lookahead sounding done for DL MU */
+ A_UINT32 lookahead_sounding_dl_cnt;
+ /** Total number of times lookahead sounding done for DL MU based on number of users */
+ A_UINT32 lookahead_snd_dl_num_users[HTT_TX_PDEV_STATS_NUM_BE_MUMIMO_USER_STATS];
+ /** Total number of times lookahead sounding done for UL MU */
+ A_UINT32 lookahead_sounding_ul_cnt;
+ /** Total number of times lookahead sounding done for UL MU based on number of users */
+ A_UINT32 lookahead_snd_ul_num_users[HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS];
} htt_stats_tx_sounding_stats_tlv;
/* preserve old name alias for new name consistent with the tag name */
typedef htt_stats_tx_sounding_stats_tlv htt_tx_sounding_stats_tlv;
@@ -9063,6 +9101,111 @@ typedef struct {
A_INT32 phase_in_degree[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM][HTT_STATS_PDEV_AOA_MAX_CHAINS];
} htt_stats_pdev_aoa_tlv;
+/* STATS_TYPE: HTT_DBG_EXT_STATS_PDEV_ULMUMIMO_ELIGIBLE
+ * TLV_TAGS:
+ * HTT_STATS_PDEV_UL_MUMIMO_GRP_STATS_TAG
+ * HTT_STATS_PDEV_UL_MUMIMO_DENYLIST_STATS_TAG
+ * HTT_STATS_PDEV_UL_MUMIMO_SEQ_TERM_STATS_TAG
+ * HTT_STATS_PDEV_UL_MUMIMO_HIST_INELIGIBILITY_TAG
+ */
+
+typedef enum {
+ HTT_STATS_CANDIDATE_MU_NOT_COMPATIBLE = 1,
+ HTT_STATS_CANDIDATE_SKIP_NR_INDEX,
+ HTT_STATS_CANDIDATE_SKIP_BASIC_CHECKS_INELIGIBLE,
+ HTT_STATS_CANDIDATE_SKIP_ZERO_NSS,
+ HTT_STATS_CANDIDATE_SKIP_MCS_THRESHOLD_LIMIT,
+ HTT_STATS_CANDIDATE_SKIP_POWER_IMBALANCED,
+ HTT_STATS_CANDIDATE_SKIP_NULL_MU_RC,
+ HTT_STATS_CANDIDATE_SKIP_CV_CORR_SKIP_PEER,
+ HTT_STATS_CANDIDATE_SKIP_SEND_BAR_SET_FOR_AC_MUMIMO,
+
+ HTT_STATS_CANDIDATE_SKIP_REASON_MAX
+} htt_stats_candidate_sched_compatible_code;
+
+typedef struct {
+ htt_tlv_hdr_t tlv_hdr;
+ /* Current Pdev id */
+ A_UINT32 pdev_id;
+ /* Group eligibility count */
+ A_UINT32 mu_grp_eligible[HTT_STATS_MAX_MUMIMO_GRP_SZ];
+ /* Group ineligibility */
+ A_UINT32 mu_grp_ineligible[HTT_STATS_MAX_MUMIMO_GRP_SZ];
+ /* Group Invalid reason */
+ A_UINT32 mu_grp_invalid[HTT_TX_NUM_MUMIMO_GRP_INVALID_WORDS];
+ /* mu_grp_candidate_skip:
+ * Sched_compatibility reason codes as listed by
+ * htt_stats_candidate_sched_compatible code
+ */
+ A_UINT32 mu_grp_candidate_skip
+ [HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS]
+ [HTT_STATS_CANDIDATE_SKIP_REASON_MAX];
+ /* Group eligibility count for 1SS grouping */
+ A_UINT32 mu_grp_eligible_1ss[HTT_STATS_MAX_MUMIMO_GRP_SZ];
+ /* Group ineligibility fpr 1SS grouping */
+ A_UINT32 mu_grp_ineligible_1ss[HTT_STATS_MAX_MUMIMO_GRP_SZ];
+ /* Group Invalid reason for 1SS grouping */
+ A_UINT32 mu_grp_invalid_1ss[HTT_TX_NUM_MUMIMO_GRP_INVALID_WORDS];
+ /* Sched_compatibility reason code for 1SS grouping */
+ A_UINT32 mu_grp_candidate_skip_1ss
+ [HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS]
+ [HTT_STATS_CANDIDATE_SKIP_REASON_MAX];
+} htt_stats_pdev_ulmumimo_grp_stats_tlv;
+
+typedef struct {
+ htt_tlv_hdr_t tlv_hdr;
+
+ /* Num of times peer denylisted for MU-MIMO transmission */
+ A_UINT32 num_peer_denylist_cnt;
+ /* Num of times peer denylisted due to trigger bitmap failure */
+ A_UINT32 trig_bitmap_fail_cnt;
+ /* Num of times peer denylisted due to trigger consecutive failure */
+ A_UINT32 trig_consecutive_fail_cnt;
+} htt_stats_pdev_ulmumimo_denylist_stats_tlv;
+
+#define HTT_STATS_SEQ_EFFICIENCY_HISTOGRAM 10
+typedef struct {
+ htt_tlv_hdr_t tlv_hdr;
+
+ /* Num of times seq terminated for MU-MIMO transmission */
+ A_UINT32 num_terminate_seq;
+ /* Num of sequences terminated due to low qdepth */
+ A_UINT32 num_terminate_low_qdepth;
+ /* Number of sequences terminated due to sequence inefficient */
+ A_UINT32 num_terminate_seq_inefficient;
+ /* Histogram of sequence inefficiency */
+ A_UINT32 hist_seq_efficiency[HTT_STATS_SEQ_EFFICIENCY_HISTOGRAM];
+} htt_stats_pdev_ulmumimo_seq_term_stats_tlv;
+
+#define HTT_STATS_MAX_ULMUMIMO_TRIGGERS 6
+#define HTT_STATS_TXOP_HISTOGRAM_BINS 24
+#define HTT_STATS_ULMUMIMO_DUR_INTERVAL_US 500
+#define HTT_STATS_ULMUMIMO_MIN_PPDU_DUR_US 1000
+#define HTT_STATS_MAX_PPDU_DURATION_BINS 10
+typedef struct {
+ htt_tlv_hdr_t tlv_hdr;
+
+ /* Number of ULMUMIMO triggers */
+ A_UINT32 num_triggers[HTT_STATS_MAX_ULMUMIMO_TRIGGERS];
+ /* Txop duration history from 0 to 12 ms with interval of 500us */
+ A_UINT32 txop_history [HTT_STATS_TXOP_HISTOGRAM_BINS];
+ /* ppdu_duration_hist:
+ * PPDU Duration History (histogram)
+ * Num PPDUs from 1 to 6
+ * 0 to 6 ms with interval of 500us
+ */
+ A_UINT32 ppdu_duration_hist
+ [HTT_STATS_MAX_ULMUMIMO_TRIGGERS][HTT_STATS_MAX_PPDU_DURATION_BINS];
+ /* Ineligible Count for ULMUMIMO based on avg qdepth and txtime criteria */
+ A_UINT32 ineligible_count;
+ /* history_ineligibility:
+ * History based ineligibility counter for ULMUMIMO.
+ * Checks for 8 eligible instances of ULMUMIMO in the past 32 instances.
+ */
+ A_UINT32 history_ineligibility;
+} htt_stats_pdev_ulmumimo_hist_ineligibility_tlv;
+
+
/* RTT VREG MASK */
#define HTT_STATS_RTT_CHAN_CAPTURE_MASK 0x00000001
#define HTT_STATS_RTT_HW_FAC_MASK 0x00000002
diff --git a/drivers/staging/fw-api/fw/wlan_module_ids.h b/drivers/staging/fw-api/fw/wlan_module_ids.h
index d1abb8186655..981bbaef3451 100644
--- a/drivers/staging/fw-api/fw/wlan_module_ids.h
+++ b/drivers/staging/fw-api/fw/wlan_module_ids.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -191,9 +191,11 @@ typedef enum {
WLAN_MODULE_PHYLIB_RRI, /* 0x94 */
WLAN_MODULE_PHYLIB_SSCAN, /* 0x95 */
WLAN_MODULE_PHYLIB_RSVD, /* 0x96 */
+
WLAN_MODULE_USD, /* 0x97 */
WLAN_MODULE_C2C, /* 0x98 */
-
+ WLAN_MODULE_VBSS, /* 0x99 */
+ WLAN_MODULE_OPT_DATA, /* 0x9a */
WLAN_MODULE_ID_MAX,
WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX,
diff --git a/drivers/staging/fw-api/fw/wmi_services.h b/drivers/staging/fw-api/fw/wmi_services.h
index fda83ef79812..b82c7bd1fc45 100644
--- a/drivers/staging/fw-api/fw/wmi_services.h
+++ b/drivers/staging/fw-api/fw/wmi_services.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -694,6 +694,7 @@ typedef enum {
WMI_SERVICE_TWT_P2P_GO_CONCURRENCY_SUPPORT = 435, /* Indicates FW supports TWT in P2P GO concurrency mode */
WMI_SERVICE_UMAC_MIGRATION_SUPPORT = 436, /* Indicates that FW supports UMAC migration */
WMI_SERVICE_STA_TWT_STATS_EXT = 437, /* FW supports additional info in TWT stats and ADD COMPLETION Event */
+ WMI_SERVICE_OPT_DP_DIAG_SUPPORT = 438, /* FW supports diag QDATA feature */
WMI_MAX_EXT2_SERVICE
diff --git a/drivers/staging/fw-api/fw/wmi_tlv_defs.h b/drivers/staging/fw-api/fw/wmi_tlv_defs.h
index ece35c747408..e8c306dbcb7f 100644
--- a/drivers/staging/fw-api/fw/wmi_tlv_defs.h
+++ b/drivers/staging/fw-api/fw/wmi_tlv_defs.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2010-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1475,6 +1475,7 @@ typedef enum {
WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_pn_info,
WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_sn_info,
WMITLV_TAG_STRUC_wmi_vdev_vbss_config_event_fixed_param,
+ WMITLV_TAG_STRUC_wmi_stats_ext_event_vdev_ext2_t,
} WMITLV_TAG_ID;
/*
* IMPORTANT: Please add _ALL_ WMI Commands Here.
@@ -2370,6 +2371,7 @@ typedef enum {
OP(WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID) \
OP(WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID) \
OP(WMI_VDEV_VBSS_CONFIG_EVENTID) \
+ OP(WMI_OPT_DP_DIAG_EVENTID) \
/* add new EVT_LIST elements above this line */
@@ -5482,7 +5484,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_MULTIPLE_PEER_GROUP_CMDID);
/* RTT 11az PASN authentication status cmd */
#define WMITLV_TABLE_WMI_RTT_PASN_AUTH_STATUS_CMD(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, wmi_rtt_pasn_auth_status_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
- WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_auth_status_param, pasn_auth_status_param, WMITLV_SIZE_VAR)
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_auth_status_param, pasn_auth_status_param, WMITLV_SIZE_VAR) \
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, cookie, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_RTT_PASN_AUTH_STATUS_CMD);
/* RTT 11az PASN deauthentication cmd */
@@ -6245,6 +6248,10 @@ WMITLV_CREATE_PARAM_STRUC(WMI_READ_DATA_FROM_FLASH_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_DIAG_EVENTID);
+#define WMITLV_TABLE_WMI_OPT_DP_DIAG_EVENTID(id,op,buf,len)\
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR)
+WMITLV_CREATE_PARAM_STRUC(WMI_OPT_DP_DIAG_EVENTID);
+
/* IGTK Offload Event */
#define WMITLV_TABLE_WMI_GTK_OFFLOAD_STATUS_EVENTID(id,op,buf,len)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, fixed_param, WMITLV_SIZE_FIX)
@@ -6731,7 +6738,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ESTIMATED_LINKSPEED_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_stats_ext_event_fixed_param, wmi_stats_ext_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_partner_link_stats, partner_link_stats, WMITLV_SIZE_VAR) \
- WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, partner_link_data, WMITLV_SIZE_VAR)
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, partner_link_data, WMITLV_SIZE_VAR) \
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_stats_ext_event_vdev_ext2_t, stats_ext2_data, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_STATS_EXT_EVENTID);
#define WMITLV_TABLE_WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID(id,op,buf,len) \
@@ -7628,7 +7636,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID);
#define WMITLV_TABLE_WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rtt_pasn_peer_create_req_event_fixed_param, \
wmi_rtt_pasn_peer_create_req_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
- WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_peer_create_req_param, rtt_pasn_peer_param, WMITLV_SIZE_VAR)
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_peer_create_req_param, rtt_pasn_peer_param, WMITLV_SIZE_VAR) \
+ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, cookie, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID);
/* RTT 11az PASN peer delete event */
diff --git a/drivers/staging/fw-api/fw/wmi_unified.h b/drivers/staging/fw-api/fw/wmi_unified.h
index 4d231e1a5fdd..70eaf1826cf7 100644
--- a/drivers/staging/fw-api/fw/wmi_unified.h
+++ b/drivers/staging/fw-api/fw/wmi_unified.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2010-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2407,6 +2407,9 @@ typedef enum {
/* WMI event to send scan cached results */
WMI_SCAN_CACHE_RESULT_EVENTID,
+ /** WMI event for FW diagnostic data sent to host */
+ WMI_OPT_DP_DIAG_EVENTID,
+
/* GPIO Event */
WMI_GPIO_INPUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GPIO),
@@ -5467,6 +5470,12 @@ typedef struct {
#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_OPT_DP_CTRL_REPLENISH_REFILL_RX_BUFFER_SUPPORT_SET(host_service_flags, val) \
WMI_SET_BITS(host_service_flags, 17, 1, val)
+/* This bit is used to inform FW VBSS is enabled */
+#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_VBSS_ENABLED_GET(host_service_flags) \
+ WMI_GET_BITS(host_service_flags, 18, 1)
+#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_VBSS_ENABLED_SET(host_service_flags, val) \
+ WMI_SET_BITS(host_service_flags, 18, 1, val)
+
#define WMI_RSRC_CFG_CARRIER_CFG_CHARTER_ENABLE_GET(carrier_config) \
WMI_GET_BITS(carrier_config, 0, 1)
#define WMI_RSRC_CFG_CARRIER_CFG_CHARTER_ENABLE_SET(carrier_config, val) \
@@ -5539,6 +5548,7 @@ typedef enum {
WMI_VENDOR1_REQ1_VERSION_4_00 = 5,
WMI_VENDOR1_REQ1_VERSION_4_10 = 6,
WMI_VENDOR1_REQ1_VERSION_4_20 = 7,
+ WMI_VENDOR1_REQ1_VERSION_4_40 = 8,
} WMI_VENDOR1_REQ1_VERSION;
typedef enum {
@@ -17038,6 +17048,8 @@ typedef struct {
#define WMI_MLO_FLAGS_SET_START_AS_ACTIVE(mlo_flags, value) WMI_SET_BITS(mlo_flags, 17, 1, value)
#define WMI_MLO_FLAGS_GET_IEEE_LINK_ID_VALID(mlo_flags) WMI_GET_BITS(mlo_flags, 18, 1)
#define WMI_MLO_FLAGS_SET_IEEE_LINK_ID_VALID(mlo_flags, value) WMI_SET_BITS(mlo_flags, 18, 1, value)
+#define WMI_MLO_FLAGS_GET_IEEE_LINK_ID_VALID_PARTNER(mlo_flags) WMI_GET_BITS(mlo_flags, 19, 1)
+#define WMI_MLO_FLAGS_SET_IEEE_LINK_ID_VALID_PARTNER(mlo_flags, value) WMI_SET_BITS(mlo_flags, 19, 1, value)
/* this structure used for passing MLO flags */
typedef struct {
@@ -17068,7 +17080,8 @@ typedef struct {
mlo_link_del_cancel:1, /* rollback of previous dynamic link deletion */
start_as_active:1, /* indicate link should be started in active status */
mlo_ieee_link_id_valid:1, /* indicate if the ieee_link_id in wmi_vdev_start_mlo_params is valid */
- unused: 13;
+ mlo_ieee_link_id_valid_partner:1, /* indicate if the ieee_link_id in wmi_partner_link_params is valid */
+ unused: 12;
};
A_UINT32 mlo_flags;
};
@@ -17086,6 +17099,12 @@ typedef struct {
A_UINT32 hw_link_id; /** hw_link_id: Unique link id across SOCs, got as part of QMI handshake */
wmi_mac_addr vdev_macaddr; /** VDEV MAC address */
wmi_mlo_flags mlo_flags;
+ /** ieee_link_id:
+ * Link ID for partner link.
+ * This field must be ignored unless the mlo_ieee_link_id_valid_partner
+ * flag is set in mlo_flags.
+ */
+ A_UINT32 ieee_link_id;
} wmi_partner_link_params;
/* this TLV structure used for pass mlo parameters on vdev create*/
@@ -21386,6 +21405,15 @@ typedef struct {
#define WMI_PEER_PARAM_UL_OFDMA_RTD 0x2B
+/*
+ * Send unsolicited probe response to a connected STA.
+ * 0: Send immediately and stop.
+ * XX: Send every XX ms continuously.
+ * 0xFFFFFFFF: Stop sending immediately.
+ */
+#define WMI_PEER_PARAM_UNSOL_PROBE_RESP_INTVL 0x2C
+
+
typedef struct {
A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param */
/** unique id identifying the VDEV, generated by the caller */
@@ -22678,6 +22706,7 @@ enum {
WMI_AUTH_RSNA_8021X_SHA384,
WMI_AUTH_WPA3_SAE_SHA384,
WMI_AUTH_FT_RSNA_SAE_SHA384,
+ WMI_AUTH_FT_RSNA_PSK_SHA384,
};
typedef enum {
@@ -30265,6 +30294,7 @@ typedef struct {
#define WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS 32
#define WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32 1
+#define WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX 4
typedef enum wmi_stats_ext_event_vdev_ext_bw_counters {
WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_20MHz = 0,
@@ -30328,6 +30358,22 @@ typedef struct wmi_stats_ext_event_vdev_ext {
A_UINT32 opaque_dbg[WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32];
} wmi_stats_ext_event_vdev_ext_t;
+typedef struct {
+ A_UINT32 tlv_header; /* tag = WMITLV_TAG_STRUC_wmi_stats_ext_event_vdev_ext2_t */
+ /* Set of TX BW counters */
+ A_UINT32 tx_mcs_mpdu[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS];
+ /* Set of TX BW counters */
+ A_UINT32 tx_bw_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX];
+ /* Set of TX NSS counters */
+ A_UINT32 tx_nss_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX];
+ /* Set of RX BW counters */
+ A_UINT32 rx_mcs_mpdu[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS];
+ /* Set of RX BW counters */
+ A_UINT32 rx_bw_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX];
+ /* Set of RX NSS counters */
+ A_UINT32 rx_nss_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX];
+} wmi_stats_ext_event_vdev_ext2_t;
+
typedef enum {
/** Default: no replay required. */
WMI_PEER_DELETE_NO_REPLAY = 0,
@@ -37725,6 +37771,9 @@ typedef enum {
WMI_THERMAL_CLIENT_APPS = 1,
WMI_THERMAL_CLIENT_WPSS = 2,
WMI_THERMAL_CLIENT_FW = 3,
+ /* WMI_THERMAL_CLIENT_DDR_BWM: client is for DDR bandwidth mitigation */
+ WMI_THERMAL_CLIENT_DDR_BWM = 4,
+
WMI_THERMAL_CLIENT_MAX
} WMI_THERMAL_MITIGATION_CLIENTS;
@@ -41740,6 +41789,8 @@ typedef struct {
#define WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_SET(detail,val) WMI_SET_BITS(detail, 16, 8, val)
#define WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET(detail) WMI_GET_BITS(detail, 24, 3)
#define WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_SET(detail,val) WMI_SET_BITS(detail, 24, 3, val)
+#define WMI_ROAM_NEIGHBOR_REPORT_INFO_TX_STATUS_INFO_GET(detail) WMI_GET_BITS(detail, 27, 4)
+#define WMI_ROAM_NEIGHBOR_REPORT_INFO_TX_STATUS_INFO_SET(detail,val) WMI_SET_BITS(detail, 27, 4, val)
typedef struct {
A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_neighbor_report_info_tlv_param */
@@ -41774,7 +41825,9 @@ typedef struct {
* wmi_mlo_band_info enum constants
* Refer to WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET,SET
* macros.
- * [31:27] : reserved
+ * [30:27] : neighbor report request TX STATUS, possible values listed in
+ * WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS
+ * [31] : reserved
* Refer to the above WMI_ROAM_NEIGHBOR_REPORT_INFO_*_GET,_SET macros for
* reading and writing these bitfields.
*/
@@ -41926,9 +41979,19 @@ typedef enum {
} WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE;
typedef enum {
- WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK = 0,
- WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK,
- WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK = 0,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK = 1,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL = 2,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_DROP =
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FILTERED = 3,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TXOP_ABORT = 4,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_TID_DEL = 5,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_SW_ABORT = 6,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_MIG_DROP = 7,
+ WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_MLO_TID_MIG = 8,
+
+ /* max allowed value is 15, due to this enum's use in a 4-bit bitfield */
} WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS;
typedef struct {
@@ -47654,6 +47717,8 @@ typedef struct {
A_UINT32 mode;
/* max num of user to decode */
A_UINT32 max_num_user;
+ /* UL MU sniffer enable */
+ A_UINT32 ul_snif_enable;
/**
* TLV (tag length value) parameters follow setting MU sniffer command
* structure. The TLV's are:
@@ -47930,6 +47995,7 @@ typedef struct {
#define WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_SET(flag,val) WMI_SET_BITS(flag, 0, 2, val)
#define WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET(flag) WMI_GET_BITS(flag, 2, 1)
#define WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_SET(flag,val) WMI_SET_BITS(flag, 2, 1, val)
+#define WMI_MAX_PASN_PASSPHRASE_LEN 64
typedef struct {
A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rtt_pasn_peer_create_req_event_fixed_param */
@@ -47939,6 +48005,7 @@ typedef struct {
* The following TLV will follow this fixed_param TLV:
*
* wmi_rtt_pasn_peer_create_req_param rtt_pasn_peer_param[]
+ * A_UINT8 cookie[]
*/
} wmi_rtt_pasn_peer_create_req_event_fixed_param;
@@ -47956,6 +48023,18 @@ typedef struct {
* and flush old cache( if it exists) for dest_mac_addr with old self_mac_addr.
* Bits 31:3: Reserved
*/
+ /* Authentication modes */
+ A_UINT32 akm;
+ /* pairwise cipher suite selector */
+ A_UINT32 cipher_suite;
+ /* PMKID */
+ A_UINT8 pmk_id[WMI_MAX_PMKID_LEN];
+ /* passphrase length */
+ A_UINT32 passphrase_len;
+ /* passphrase */
+ A_UINT8 passphrase[WMI_MAX_PASN_PASSPHRASE_LEN];
+ /* comeback cookie length */
+ A_UINT32 cookie_len;
} wmi_rtt_pasn_peer_create_req_param;
@@ -47965,6 +48044,7 @@ typedef struct {
* The following TLV will follow this fixed_param TLV:
*
* wmi_rtt_pasn_auth_status_param pasn_auth_status_param[]
+ * A_UINT8 cookie[]
*/
} wmi_rtt_pasn_auth_status_cmd_fixed_param;
@@ -47976,6 +48056,14 @@ typedef struct {
A_UINT32 status;
/* Source address used for doing PASN authentication */
wmi_mac_addr source_mac_addr;
+ /* Authentication modes */
+ A_UINT32 akm;
+ /* pairwise cipher suite selector */
+ A_UINT32 cipher_suite;
+ /* PASN comeback timeout */
+ A_INT32 timeout_value;
+ /* comeback cookie length */
+ A_UINT32 cookie_len;
} wmi_rtt_pasn_auth_status_param;
@@ -49611,15 +49699,17 @@ typedef struct {
#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_BACKGROUND_S 2
/* bits 3-15 are reserved for new non-interactive traffic types */
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_M 0x00080000
-#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_S 19
-/* bits 20-31 are reserved for new interactive traffic types */
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_M 0x00080000
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_S 19
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_APERIODIC_BURST_TRAFFIC_1_M 0x00100000
+#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_APERIODIC_BURST_TRAFFIC_1_S 20
+/* bits 21-31 are reserved for new interactive traffic types */
typedef struct {
A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_active_traffic_map_cmd_fixed_param */
diff --git a/drivers/staging/fw-api/fw/wmi_version.h b/drivers/staging/fw-api/fw/wmi_version.h
index 37f5972c4b92..145e8fcc2aa4 100644
--- a/drivers/staging/fw-api/fw/wmi_version.h
+++ b/drivers/staging/fw-api/fw/wmi_version.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -37,7 +37,7 @@
#define __WMI_VER_MINOR_ 0
/** WMI revision number has to be incremented when there is a
* change that may or may not break compatibility. */
-#define __WMI_REVISION_ 1564
+#define __WMI_REVISION_ 1575
/** The Version Namespace should not be normally changed. Only
* host and firmware of the same WMI namespace will work
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index d4e04f439865..8097f3fe4688 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -158,7 +158,7 @@ static int ad9832_write_frequency(struct ad9832_state *st,
static int ad9832_write_phase(struct ad9832_state *st,
unsigned long addr, unsigned long phase)
{
- if (phase > BIT(AD9832_PHASE_BITS))
+ if (phase >= BIT(AD9832_PHASE_BITS))
return -EINVAL;
st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) |
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 2e661a905a57..ecf74a65a6f0 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -132,7 +132,7 @@ static int ad9834_write_frequency(struct ad9834_state *st,
static int ad9834_write_phase(struct ad9834_state *st,
unsigned long addr, unsigned long phase)
{
- if (phase > BIT(AD9834_PHASE_BITS))
+ if (phase >= BIT(AD9834_PHASE_BITS))
return -EINVAL;
st->data = cpu_to_be16(addr | phase);
diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
index ba9d4ec9f554..5ffa66dabe3d 100644
--- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
@@ -21134,7 +21134,10 @@ static void hdd_set_wapi_crypto_key_mgmt_param(struct hdd_adapter *adapter)
if (adapter->wapi_info.wapi_auth_mode == WAPI_AUTH_MODE_CERT)
HDD_SET_BIT(set_val, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT);
+ /* Set AKM and original AKM type */
wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT, set_val);
+ wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT,
+ set_val);
set_val = 0;
HDD_SET_BIT(set_val, WLAN_CRYPTO_CIPHER_WAPI_SMS4);
diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h
index a57de3022392..c8f76c9a8572 100644
--- a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h
+++ b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h
@@ -32,9 +32,9 @@
#define QWLAN_VERSION_MAJOR 2
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 8
-#define QWLAN_VERSION_EXTRA "Y"
+#define QWLAN_VERSION_EXTRA "Z"
#define QWLAN_VERSION_BUILD 34
-#define QWLAN_VERSIONSTR "2.0.8.34Y"
+#define QWLAN_VERSIONSTR "2.0.8.34Z"
#endif /* QWLAN_VERSION_H */
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index f27b4aecff3d..759f567538e2 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1337,11 +1337,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
return -EINVAL;
+ alts = usblp->protocol[protocol].alt_setting;
+ if (alts < 0)
+ return -EINVAL;
+
/* Don't unnecessarily set the interface if there's a single alt. */
if (usblp->intf->num_altsetting > 1) {
- alts = usblp->protocol[protocol].alt_setting;
- if (alts < 0)
- return -EINVAL;
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
if (r < 0) {
printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fc0ee8de5602..431a5a8bf010 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2596,13 +2596,13 @@ int usb_new_device(struct usb_device *udev)
err = sysfs_create_link(&udev->dev.kobj,
&port_dev->dev.kobj, "port");
if (err)
- goto fail;
+ goto out_del_dev;
err = sysfs_create_link(&port_dev->dev.kobj,
&udev->dev.kobj, "device");
if (err) {
sysfs_remove_link(&udev->dev.kobj, "port");
- goto fail;
+ goto out_del_dev;
}
if (!test_and_set_bit(port1, hub->child_usage_bits))
@@ -2614,6 +2614,8 @@ int usb_new_device(struct usb_device *udev)
pm_runtime_put_sync_autosuspend(&udev->dev);
return err;
+out_del_dev:
+ device_del(&udev->dev);
fail:
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
pm_runtime_disable(&udev->dev);
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 86e8585a5512..f01b0103fe12 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -294,10 +294,11 @@ static int usb_port_runtime_suspend(struct device *dev)
static void usb_port_shutdown(struct device *dev)
{
struct usb_port *port_dev = to_usb_port(dev);
+ struct usb_device *udev = port_dev->child;
- if (port_dev->child) {
- usb_disable_usb2_hardware_lpm(port_dev->child);
- usb_unlocked_disable_lpm(port_dev->child);
+ if (udev && !udev->port_is_suspended) {
+ usb_disable_usb2_hardware_lpm(udev);
+ usb_unlocked_disable_lpm(udev);
}
}
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index 2a06550c97c6..0831cc7059f9 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -43,7 +43,7 @@ out:
int dwc3_host_init(struct dwc3 *dwc)
{
- struct property_entry props[6];
+ struct property_entry props[7];
struct platform_device *xhci;
int ret, irq;
struct resource *res;
@@ -88,6 +88,8 @@ int dwc3_host_init(struct dwc3 *dwc)
memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
+ props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-sg-trb-cache-size-quirk");
+
if (dwc->usb3_lpm_capable)
props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable");
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index c12a7317dac3..ec2dea6fe270 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -2103,7 +2103,7 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
ffs_log("enter: state %d setup_state %d flag %lu", ffs->state,
ffs->setup_state, ffs->flags);
- if (WARN_ON(ffs->state != FFS_ACTIVE
+ if ((ffs->state != FFS_ACTIVE
|| test_and_set_bit(FFS_FL_BOUND, &ffs->flags)))
return -EBADFD;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 524bf63d5e9b..ed18301187bd 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -309,6 +309,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (device_property_read_bool(tmpdev, "quirk-broken-port-ped"))
xhci->quirks |= XHCI_BROKEN_PORT_PED;
+ if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk"))
+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
+
device_property_read_u32(tmpdev, "imod-interval-ns",
&xhci->imod_interval);
}
@@ -336,6 +339,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)))
hcd->skip_phy_initialization = 1;
+ if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
+
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
goto disable_usb_phy;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ffa1f22069c7..992736350d0b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3380,7 +3380,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
full_len = urb->transfer_buffer_length;
/* If we have scatter/gather list, we use it. */
- if (urb->num_sgs) {
+ if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) {
num_sgs = urb->num_mapped_sgs;
sg = urb->sg;
addr = (u64) sg_dma_address(sg);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index b8f688efb2c1..667b703d5147 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1349,6 +1349,112 @@ EXPORT_SYMBOL_GPL(xhci_resume);
/*-------------------------------------------------------------------------*/
+static int xhci_map_temp_buffer(struct usb_hcd *hcd, struct urb *urb)
+{
+ void *temp;
+ int ret = 0;
+ unsigned int buf_len;
+ enum dma_data_direction dir;
+
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ buf_len = urb->transfer_buffer_length;
+
+ temp = kzalloc_node(buf_len, GFP_ATOMIC,
+ dev_to_node(hcd->self.sysdev));
+ if (!temp)
+ return -ENOMEM;
+
+ if (usb_urb_dir_out(urb))
+ sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+ temp, buf_len, 0);
+
+ urb->transfer_buffer = temp;
+ urb->transfer_dma = dma_map_single(hcd->self.sysdev,
+ urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ dir);
+
+ if (dma_mapping_error(hcd->self.sysdev,
+ urb->transfer_dma)) {
+ ret = -EAGAIN;
+ kfree(temp);
+ } else {
+ urb->transfer_flags |= URB_DMA_MAP_SINGLE;
+ }
+
+ return ret;
+}
+
+static bool xhci_urb_temp_buffer_required(struct usb_hcd *hcd,
+ struct urb *urb)
+{
+ bool ret = false;
+ unsigned int i;
+ unsigned int len = 0;
+ unsigned int trb_size;
+ unsigned int max_pkt;
+ struct scatterlist *sg;
+ struct scatterlist *tail_sg;
+
+ tail_sg = urb->sg;
+ max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+
+ if (!urb->num_sgs)
+ return ret;
+
+ if (urb->dev->speed >= USB_SPEED_SUPER)
+ trb_size = TRB_CACHE_SIZE_SS;
+ else
+ trb_size = TRB_CACHE_SIZE_HS;
+
+ if (urb->transfer_buffer_length != 0 &&
+ !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+ for_each_sg(urb->sg, sg, urb->num_sgs, i) {
+ len = len + sg->length;
+ if (i > trb_size - 2) {
+ len = len - tail_sg->length;
+ if (len < max_pkt) {
+ ret = true;
+ break;
+ }
+
+ tail_sg = sg_next(tail_sg);
+ }
+ }
+ }
+ return ret;
+}
+
+static void xhci_unmap_temp_buf(struct usb_hcd *hcd, struct urb *urb)
+{
+ unsigned int len;
+ unsigned int buf_len;
+ enum dma_data_direction dir;
+
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+ buf_len = urb->transfer_buffer_length;
+
+ if (IS_ENABLED(CONFIG_HAS_DMA) &&
+ (urb->transfer_flags & URB_DMA_MAP_SINGLE))
+ dma_unmap_single(hcd->self.sysdev,
+ urb->transfer_dma,
+ urb->transfer_buffer_length,
+ dir);
+
+ if (usb_urb_dir_in(urb))
+ len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs,
+ urb->transfer_buffer,
+ buf_len,
+ 0);
+
+ urb->transfer_flags &= ~URB_DMA_MAP_SINGLE;
+ kfree(urb->transfer_buffer);
+ urb->transfer_buffer = NULL;
+}
+
+
+
/*
* Bypass the DMA mapping if URB is suitable for Immediate Transfer (IDT),
* we'll copy the actual data into the TRB address register. This is limited to
@@ -1358,12 +1464,37 @@ EXPORT_SYMBOL_GPL(xhci_resume);
static int xhci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags)
{
+ struct xhci_hcd *xhci;
+
+ xhci = hcd_to_xhci(hcd);
+
if (xhci_urb_suitable_for_idt(urb))
return 0;
+ if (xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) {
+ if (xhci_urb_temp_buffer_required(hcd, urb))
+ return xhci_map_temp_buffer(hcd, urb);
+ }
return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
}
+static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+{
+ struct xhci_hcd *xhci;
+ bool unmap_temp_buf = false;
+
+ xhci = hcd_to_xhci(hcd);
+
+ if (urb->num_sgs && (urb->transfer_flags & URB_DMA_MAP_SINGLE))
+ unmap_temp_buf = true;
+
+ if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf)
+ xhci_unmap_temp_buf(hcd, urb);
+ else
+ usb_hcd_unmap_urb_for_dma(hcd, urb);
+}
+
+
/**
* xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
* HCDs. Find the index for an endpoint given its descriptor. Use the return
@@ -5598,6 +5729,7 @@ static const struct hc_driver xhci_hc_driver = {
* managing i/o requests and associated device resources
*/
.map_urb_for_dma = xhci_map_urb_for_dma,
+ .unmap_urb_for_dma = xhci_unmap_urb_for_dma,
.urb_enqueue = xhci_urb_enqueue,
.urb_dequeue = xhci_urb_dequeue,
.alloc_dev = xhci_alloc_dev,
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a1f13c96aa07..1003a02f40c1 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1338,6 +1338,10 @@ enum xhci_setup_dev {
#define TRB_SIA (1<<31)
#define TRB_FRAME_ID(p) (((p) & 0x7ff) << 20)
+/* TRB cache size for xHC with TRB cache */
+#define TRB_CACHE_SIZE_HS 8
+#define TRB_CACHE_SIZE_SS 16
+
struct xhci_generic_trb {
__le32 field[4];
};
@@ -1891,6 +1895,7 @@ struct xhci_hcd {
#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35)
#define XHCI_SKIP_PHY_INIT BIT_ULL(37)
#define XHCI_DISABLE_SPARSE BIT_ULL(38)
+#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
#define XHCI_NO_SOFT_RETRY BIT_ULL(40)
unsigned int num_active_eps;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 5353fa7e5969..39c9d1f857fc 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -224,6 +224,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
+ { USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 3ae4ac4d9857..79f8e3a043fc 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -621,7 +621,7 @@ static void option_instat_callback(struct urb *urb);
/* MeiG Smart Technology products */
#define MEIGSMART_VENDOR_ID 0x2dee
-/* MeiG Smart SRM825L based on Qualcomm 315 */
+/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
#define MEIGSMART_PRODUCT_SLM320 0x4d41
@@ -2405,6 +2405,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
@@ -2412,6 +2413,7 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(1) },
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
.driver_info = NCTRL(3) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2949, 0x8700, 0xff) }, /* Neoway N723-EA */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index d172e8642d4a..5501898dfcfb 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -555,7 +555,7 @@ static void qt2_process_read_urb(struct urb *urb)
newport = *(ch + 3);
- if (newport > serial->num_ports) {
+ if (newport >= serial->num_ports) {
dev_err(&port->dev,
"%s - port change to invalid port: %i\n",
__func__, newport);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 606a68bd8059..a6dc2faae85d 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -255,6 +255,13 @@ UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 ),
+/* Added by Lubomir Rintel , a very fine chap */
+UNUSUAL_DEV( 0x0421, 0x06c2, 0x0000, 0x0406,
+ "Nokia",
+ "Nokia 208",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_MAX_SECTORS_64 ),
+
#ifdef NO_SDDR09
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index 46a72fe39719..9165bf6ad018 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -405,6 +405,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
{
unsigned int done = 0;
+ if (off >= reg->size)
+ return -EINVAL;
+
+ count = min_t(size_t, count, reg->size - off);
+
if (!reg->ioaddr) {
reg->ioaddr =
ioremap_nocache(reg->addr, reg->size);
@@ -482,6 +487,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
{
unsigned int done = 0;
+ if (off >= reg->size)
+ return -EINVAL;
+
+ count = min_t(size_t, count, reg->size - off);
+
if (!reg->ioaddr) {
reg->ioaddr =
ioremap_nocache(reg->addr, reg->size);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ac45109be691..223b789b4bf6 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -629,6 +629,7 @@ enum {
*/
#define EXT4_EX_NOCACHE 0x40000000
#define EXT4_EX_FORCE_CACHE 0x20000000
+#define EXT4_EX_NOFAIL 0x10000000
/*
* Flags used by ext4_free_blocks
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0d692025f923..5c0ef7a04169 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -304,11 +304,14 @@ ext4_force_split_extent_at(handle_t *handle, struct inode *inode,
{
struct ext4_ext_path *path = *ppath;
int unwritten = ext4_ext_is_unwritten(path[path->p_depth].p_ext);
+ int flags = EXT4_EX_NOCACHE | EXT4_GET_BLOCKS_PRE_IO;
+
+ if (nofail)
+ flags |= EXT4_GET_BLOCKS_METADATA_NOFAIL | EXT4_EX_NOFAIL;
return ext4_split_extent_at(handle, inode, ppath, lblk, unwritten ?
EXT4_EXT_MARK_UNWRIT1|EXT4_EXT_MARK_UNWRIT2 : 0,
- EXT4_EX_NOCACHE | EXT4_GET_BLOCKS_PRE_IO |
- (nofail ? EXT4_GET_BLOCKS_METADATA_NOFAIL:0));
+ flags);
}
/*
@@ -572,9 +575,13 @@ __read_extent_tree_block(const char *function, unsigned int line,
struct buffer_head *bh;
int err;
ext4_fsblk_t pblk;
+ gfp_t gfp_flags = __GFP_MOVABLE | GFP_NOFS;
+
+ if (flags & EXT4_EX_NOFAIL)
+ gfp_flags |= __GFP_NOFAIL;
pblk = ext4_idx_pblock(idx);
- bh = sb_getblk_gfp(inode->i_sb, pblk, __GFP_MOVABLE | GFP_NOFS);
+ bh = sb_getblk_gfp(inode->i_sb, pblk, gfp_flags);
if (unlikely(!bh))
return ERR_PTR(-ENOMEM);
@@ -919,6 +926,10 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
struct ext4_ext_path *path = orig_path ? *orig_path : NULL;
short int depth, i, ppos = 0;
int ret;
+ gfp_t gfp_flags = GFP_NOFS;
+
+ if (flags & EXT4_EX_NOFAIL)
+ gfp_flags |= __GFP_NOFAIL;
eh = ext_inode_hdr(inode);
depth = ext_depth(inode);
@@ -939,7 +950,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
if (!path) {
/* account possible depth increase */
path = kcalloc(depth + 2, sizeof(struct ext4_ext_path),
- GFP_NOFS);
+ gfp_flags);
if (unlikely(!path))
return ERR_PTR(-ENOMEM);
path[0].p_maxdepth = depth + 1;
@@ -1088,9 +1099,13 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
ext4_fsblk_t newblock, oldblock;
__le32 border;
ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
+ gfp_t gfp_flags = GFP_NOFS;
int err = 0;
size_t ext_size = 0;
+ if (flags & EXT4_EX_NOFAIL)
+ gfp_flags |= __GFP_NOFAIL;
+
/* make decision: where to split? */
/* FIXME: now decision is simplest: at current extent */
@@ -1124,7 +1139,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
* We need this to handle errors and free blocks
* upon them.
*/
- ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), GFP_NOFS);
+ ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), gfp_flags);
if (!ablocks)
return -ENOMEM;
@@ -2110,7 +2125,7 @@ prepend:
if (next != EXT_MAX_BLOCKS) {
ext_debug("next leaf block - %u\n", next);
BUG_ON(npath != NULL);
- npath = ext4_find_extent(inode, next, NULL, 0);
+ npath = ext4_find_extent(inode, next, NULL, gb_flags);
if (IS_ERR(npath))
return PTR_ERR(npath);
BUG_ON(npath->p_depth != path->p_depth);
@@ -3018,7 +3033,8 @@ again:
ext4_fsblk_t pblk;
/* find extent for or closest extent to this block */
- path = ext4_find_extent(inode, end, NULL, EXT4_EX_NOCACHE);
+ path = ext4_find_extent(inode, end, NULL,
+ EXT4_EX_NOCACHE | EXT4_EX_NOFAIL);
if (IS_ERR(path)) {
ext4_journal_stop(handle);
return PTR_ERR(path);
@@ -3104,7 +3120,7 @@ again:
le16_to_cpu(path[k].p_hdr->eh_entries)+1;
} else {
path = kcalloc(depth + 1, sizeof(struct ext4_ext_path),
- GFP_NOFS);
+ GFP_NOFS | __GFP_NOFAIL);
if (path == NULL) {
ext4_journal_stop(handle);
return -ENOMEM;
@@ -3424,6 +3440,25 @@ static int ext4_split_extent_at(handle_t *handle,
if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
goto out;
+ /*
+ * Update path is required because previous ext4_ext_insert_extent()
+ * may have freed or reallocated the path. Using EXT4_EX_NOFAIL
+ * guarantees that ext4_find_extent() will not return -ENOMEM,
+ * otherwise -ENOMEM will cause a retry in do_writepages(), and a
+ * WARN_ON may be triggered in ext4_da_update_reserve_space() due to
+ * an incorrect ee_len causing the i_reserved_data_blocks exception.
+ */
+ path = ext4_find_extent(inode, ee_block, ppath,
+ flags | EXT4_EX_NOFAIL);
+ if (IS_ERR(path)) {
+ EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
+ split, PTR_ERR(path));
+ return PTR_ERR(path);
+ }
+ depth = ext_depth(inode);
+ ex = path[depth].p_ext;
+ *ppath = path;
+
if (EXT4_EXT_MAY_ZEROOUT & split_flag) {
if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
if (split_flag & EXT4_EXT_DATA_VALID1) {
@@ -3472,7 +3507,7 @@ fix_extent_len:
ext4_ext_dirty(handle, inode, path + path->p_depth);
return err;
out:
- ext4_ext_show_leaf(inode, path);
+ ext4_ext_show_leaf(inode, *ppath);
return err;
}
@@ -3528,7 +3563,7 @@ static int ext4_split_extent(handle_t *handle,
* Update path is required because previous ext4_split_extent_at() may
* result in split of original leaf or extent zeroout.
*/
- path = ext4_find_extent(inode, map->m_lblk, ppath, 0);
+ path = ext4_find_extent(inode, map->m_lblk, ppath, flags);
if (IS_ERR(path))
return PTR_ERR(path);
depth = ext_depth(inode);
@@ -4650,7 +4685,14 @@ retry:
}
if (err)
return err;
- return ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
+retry_remove_space:
+ err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
+ if (err == -ENOMEM) {
+ cond_resched();
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
+ goto retry_remove_space;
+ }
+ return err;
}
static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 7027239e2765..0d95b82703c8 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -890,9 +890,14 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
ATTR_GID | ATTR_TIMES_SET))))
return -EPERM;
- if ((attr->ia_valid & ATTR_SIZE) &&
- !f2fs_is_compress_backend_ready(inode))
- return -EOPNOTSUPP;
+ if ((attr->ia_valid & ATTR_SIZE)) {
+ if (!f2fs_is_compress_backend_ready(inode))
+ return -EOPNOTSUPP;
+ if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED) &&
+ !IS_ALIGNED(attr->ia_size,
+ F2FS_BLK_TO_BYTES(F2FS_I(inode)->i_cluster_size)))
+ return -EINVAL;
+ }
err = setattr_prepare(dentry, attr);
if (err)
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 69c52edf5713..22c1b29c0551 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -271,6 +271,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask,
error = filemap_fdatawait(inode->i_mapping);
if (error)
goto out;
+ truncate_inode_pages(inode->i_mapping, 0);
if (new_flags & GFS2_DIF_JDATA)
gfs2_ordered_del_inode(ip);
}
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index bcf820ce0e02..f82444fbbedc 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -419,11 +419,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
goto bail_no_root;
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
if (!res) {
- if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {
+ if (fd.entrylength != sizeof(rec.dir)) {
res = -EIO;
goto bail_hfs_find;
}
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
+ if (rec.type != HFS_CDR_DIR)
+ res = -EIO;
}
if (res)
goto bail_hfs_find;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 255026497b8c..8c435c11664d 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -770,9 +770,9 @@ start_journal_io:
/*
* If the journal is not located on the file system device,
* then we must flush the file system device before we issue
- * the commit record
+ * the commit record and update the journal tail sequence.
*/
- if (commit_transaction->t_need_data_flush &&
+ if ((commit_transaction->t_need_data_flush || update_tail) &&
(journal->j_fs_dev != journal->j_dev) &&
(journal->j_flags & JBD2_BARRIER))
blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index eda83487c9ec..1ce3780e8b49 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -881,7 +881,7 @@ static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid)
int status = 0;
trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type);
- if (!sb_has_quota_loaded(sb, type)) {
+ if (!sb_has_quota_active(sb, type)) {
status = -ESRCH;
goto out;
}
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 7a1c8da9e44b..77d5aa90338f 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -815,7 +815,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
struct ocfs2_quota_chunk *chunk;
struct ocfs2_local_disk_chunk *dchunk;
int mark_clean = 1, len;
- int status;
+ int status = 0;
iput(oinfo->dqi_gqinode);
ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
@@ -857,17 +857,15 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
oinfo->dqi_libh,
olq_update_info,
info);
- if (status < 0) {
+ if (status < 0)
mlog_errno(status);
- goto out;
- }
-
out:
ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
brelse(oinfo->dqi_libh);
brelse(oinfo->dqi_lqi_bh);
kfree(oinfo);
- return 0;
+ info->dqi_priv = NULL;
+ return status;
}
static void olq_set_dquot(struct buffer_head *bh, void *private)
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 0ff2f1ddf9ef..fc70107740ab 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -397,6 +397,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
if (buflen == 0)
return acc;
}
+
+ cond_resched();
}
return acc;
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 005f9a8ecdc8..d234fcfc5b96 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -534,6 +534,7 @@ extern void __init hrtimers_init(void);
extern void sysrq_timer_list_show(void);
int hrtimers_prepare_cpu(unsigned int cpu);
+int hrtimers_cpu_starting(unsigned int cpu);
#ifdef CONFIG_HOTPLUG_CPU
int hrtimers_dead_cpu(unsigned int cpu);
#else
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 7e0fdcf905d2..a4af5e14dffe 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -43,8 +43,16 @@ typedef struct poll_table_struct {
static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
- if (p && p->_qproc && wait_address)
+ if (p && p->_qproc && wait_address) {
p->_qproc(filp, wait_address, p);
+ /*
+ * This memory barrier is paired in the wq_has_sleeper().
+ * See the comment above prepare_to_wait(), we need to
+ * ensure that subsequent tests in this thread can't be
+ * reordered with __add_wait_queue() in _qproc() paths.
+ */
+ smp_mb();
+ }
}
/*
diff --git a/include/linux/udp.h b/include/linux/udp.h
index ae58ff3b6b5b..a220880019d6 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -131,6 +131,24 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,
}
}
+DECLARE_STATIC_KEY_FALSE(udp_encap_needed_key);
+#if IS_ENABLED(CONFIG_IPV6)
+DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key);
+#endif
+
+static inline bool udp_encap_needed(void)
+{
+ if (static_branch_unlikely(&udp_encap_needed_key))
+ return true;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (static_branch_unlikely(&udpv6_encap_needed_key))
+ return true;
+#endif
+
+ return false;
+}
+
static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
{
if (!skb_is_gso(skb))
@@ -142,6 +160,16 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist)
return true;
+ /* GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CSUM bits might still
+ * land in a tunnel as the socket check in udp_gro_receive cannot be
+ * foolproof.
+ */
+ if (udp_encap_needed() &&
+ READ_ONCE(udp_sk(sk)->encap_rcv) &&
+ !(skb_shinfo(skb)->gso_type &
+ (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP_TUNNEL_CSUM)))
+ return true;
+
return false;
}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 097e6835c62d..382a5725ee6a 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -713,13 +713,12 @@ struct usb_device {
unsigned long active_duration;
-#ifdef CONFIG_PM
unsigned long connect_time;
unsigned do_remote_wakeup:1;
unsigned reset_resume:1;
unsigned port_is_suspended:1;
-#endif
+
struct wusb_dev *wusb_dev;
int slot_id;
enum usb_device_removable removable;
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index ca8ec43770a9..91e9db289303 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -498,9 +498,7 @@ extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
-#ifdef CONFIG_PM
extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
-#endif
#endif /* CONFIG_USB_PCI */
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 94165cafa6bc..c9f9ed10bf21 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -299,7 +299,7 @@ static inline int inet_csk_reqsk_queue_len(const struct sock *sk)
static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
{
- return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog;
+ return inet_csk_reqsk_queue_len(sk) > READ_ONCE(sk->sk_max_ack_backlog);
}
bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req);
diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh
index 0a07ad2df805..b7c74a1a363a 100755
--- a/kernel/gen_kheaders.sh
+++ b/kernel/gen_kheaders.sh
@@ -87,6 +87,7 @@ find $cpio_dir -type f -print0 |
# pre-sorted, as --sort=name might not be available.
find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \
tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
+ --exclude=".__afs*" --exclude=".nfs*" \
--owner=0 --group=0 --numeric-owner --no-recursion --mode=u=rw,go=r,a+X \
-Jcf $tarfile -C $cpio_dir/ -T - > /dev/null
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 1e4a23a463a1..a221f10a46e1 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -2073,6 +2073,15 @@ int hrtimers_prepare_cpu(unsigned int cpu)
}
cpu_base->cpu = cpu;
+ hrtimer_cpu_base_init_expiry_lock(cpu_base);
+ return 0;
+}
+
+int hrtimers_cpu_starting(unsigned int cpu)
+{
+ struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
+
+ /* Clear out any left over state from a CPU down operation */
cpu_base->active_bases = 0;
cpu_base->hres_active = 0;
cpu_base->hang_detected = 0;
@@ -2080,7 +2089,6 @@ int hrtimers_prepare_cpu(unsigned int cpu)
cpu_base->softirq_next_timer = NULL;
cpu_base->expires_next = KTIME_MAX;
cpu_base->softirq_expires_next = KTIME_MAX;
- hrtimer_cpu_base_init_expiry_lock(cpu_base);
return 0;
}
@@ -2198,6 +2206,7 @@ void hrtimer_quiesce_cpu(void *cpup)
void __init hrtimers_init(void)
{
hrtimers_prepare_cpu(smp_processor_id());
+ hrtimers_cpu_starting(smp_processor_id());
open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq);
}
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 40ab2aea7b31..7431ec077273 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -55,11 +55,11 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
goto drop;
rcu_read_lock();
- proto = find_snap_client(skb_transport_header(skb));
+ proto = find_snap_client(skb->data);
if (proto) {
/* Pass the frame on. */
- skb->transport_header += 5;
skb_pull_rcsum(skb, 5);
+ skb_reset_transport_header(skb);
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
}
rcu_read_unlock();
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 920e901a247a..ec96deb55786 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1527,11 +1527,17 @@ static inline int skb_alloc_rx_flag(const struct sk_buff *skb)
struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
{
- int headerlen = skb_headroom(skb);
- unsigned int size = skb_end_offset(skb) + skb->data_len;
- struct sk_buff *n = __alloc_skb(size, gfp_mask,
- skb_alloc_rx_flag(skb), NUMA_NO_NODE);
+ struct sk_buff *n;
+ unsigned int size;
+ int headerlen;
+ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
+ return NULL;
+
+ headerlen = skb_headroom(skb);
+ size = skb_end_offset(skb) + skb->data_len;
+ n = __alloc_skb(size, gfp_mask,
+ skb_alloc_rx_flag(skb), NUMA_NO_NODE);
if (!n)
return NULL;
@@ -1803,12 +1809,17 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
/*
* Allocate the copy buffer
*/
- struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom,
- gfp_mask, skb_alloc_rx_flag(skb),
- NUMA_NO_NODE);
- int oldheadroom = skb_headroom(skb);
int head_copy_len, head_copy_off;
+ struct sk_buff *n;
+ int oldheadroom;
+ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
+ return NULL;
+
+ oldheadroom = skb_headroom(skb);
+ n = __alloc_skb(newheadroom + skb->len + newtailroom,
+ gfp_mask, skb_alloc_rx_flag(skb),
+ NUMA_NO_NODE);
if (!n)
return NULL;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index c3a378ef95aa..cbefbe6d07ae 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -602,7 +602,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
by tcp. Feel free to propose better solution.
--ANK (980728)
*/
- if (np->rxopt.all)
+ if (np->rxopt.all && sk->sk_state != DCCP_LISTEN)
opt_skb = skb_clone_and_charge_r(skb, sk);
if (sk->sk_state == DCCP_OPEN) { /* Fast path */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1dd7eac67cb5..96937b6f36b7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -540,6 +540,13 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
}
DEFINE_STATIC_KEY_FALSE(udp_encap_needed_key);
+EXPORT_SYMBOL(udp_encap_needed_key);
+
+#if IS_ENABLED(CONFIG_IPV6)
+DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key);
+EXPORT_SYMBOL(udpv6_encap_needed_key);
+#endif
+
void udp_encap_enable(void)
{
static_branch_inc(&udp_encap_needed_key);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 0c1aacf6e312..0ff68f00a535 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -512,11 +512,19 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
unsigned int off = skb_gro_offset(skb);
int flush = 1;
- /* we can do L4 aggregation only if the packet can't land in a tunnel
- * otherwise we could corrupt the inner stream
+ /* We can do L4 aggregation only if the packet can't land in a tunnel
+ * otherwise we could corrupt the inner stream. Detecting such packets
+ * cannot be foolproof and the aggregation might still happen in some
+ * cases. Such packets should be caught in udp_unexpected_gso later.
*/
NAPI_GRO_CB(skb)->is_flist = 0;
if (!sk || !udp_sk(sk)->gro_receive) {
+ /* If the packet was locally encapsulated in a UDP tunnel that
+ * wasn't detected above, do not GRO.
+ */
+ if (skb->encapsulation)
+ goto out;
+
if (skb->dev->features & NETIF_F_GRO_FRAGLIST)
NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1;
@@ -660,13 +668,7 @@ INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff)
skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
- if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
- skb->csum_level++;
- } else {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->csum_level = 0;
- }
+ __skb_incr_checksum_unnecessary(skb);
return 0;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2264a87a41d1..6063a595443f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -173,7 +173,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
struct inet6_dev *rt_idev = rt->rt6i_idev;
struct net_device *rt_dev = rt->dst.dev;
- if (rt_idev->dev == dev) {
+ if (rt_idev && rt_idev->dev == dev) {
rt->rt6i_idev = in6_dev_get(loopback_dev);
in6_dev_put(rt_idev);
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index faa432f96e17..971109454890 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1393,7 +1393,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
by tcp. Feel free to propose better solution.
--ANK (980728)
*/
- if (np->rxopt.all)
+ if (np->rxopt.all && sk->sk_state != TCP_LISTEN)
opt_skb = skb_clone_and_charge_r(skb, sk);
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
@@ -1430,8 +1430,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
if (nsk != sk) {
if (tcp_child_process(sk, nsk, skb))
goto reset;
- if (opt_skb)
- __kfree_skb(opt_skb);
return 0;
}
} else
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e6fdb842e89d..2b4f2c626d37 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -413,7 +413,7 @@ csum_copy_err:
goto try_again;
}
-DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key);
+DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key);
void udpv6_encap_enable(void)
{
static_branch_inc(&udpv6_encap_needed_key);
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 6e06c90fa318..ad20e304f634 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -156,13 +156,7 @@ INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff)
skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
- if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
- skb->csum_level++;
- } else {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->csum_level = 0;
- }
+ __skb_incr_checksum_unnecessary(skb);
return 0;
}
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index a08240fe68a7..22514ab060f8 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -688,6 +688,10 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
ASSERT_RTNL();
mutex_lock(&sdata->local->iflist_mtx);
+ if (list_empty(&sdata->local->interfaces)) {
+ mutex_unlock(&sdata->local->iflist_mtx);
+ return;
+ }
list_del_rcu(&sdata->list);
mutex_unlock(&sdata->local->iflist_mtx);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 87398af2715a..117c7b038591 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -354,7 +354,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
[TCA_FLOW_KEYS] = { .type = NLA_U32 },
[TCA_FLOW_MODE] = { .type = NLA_U32 },
[TCA_FLOW_BASECLASS] = { .type = NLA_U32 },
- [TCA_FLOW_RSHIFT] = { .type = NLA_U32 },
+ [TCA_FLOW_RSHIFT] = NLA_POLICY_MAX(NLA_U32,
+ 31 /* BITS_PER_U32 - 1 */),
[TCA_FLOW_ADDEND] = { .type = NLA_U32 },
[TCA_FLOW_MASK] = { .type = NLA_U32 },
[TCA_FLOW_XOR] = { .type = NLA_U32 },
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index b8dc03a7487e..178044a845df 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1593,6 +1593,10 @@ replay:
q = qdisc_lookup(dev, tcm->tcm_handle);
if (!q)
goto create_n_graft;
+ if (q->parent != tcm->tcm_parent) {
+ NL_SET_ERR_MSG(extack, "Cannot move an existing qdisc to a different parent");
+ return -EINVAL;
+ }
if (n->nlmsg_flags & NLM_F_EXCL) {
NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot override");
return -EEXIST;
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 56f4c1621e44..9de91f69032d 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -38,6 +38,9 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch,
{
unsigned int prev_backlog;
+ if (unlikely(sch->limit == 0))
+ return qdisc_drop(skb, sch, to_free);
+
if (likely(sch->q.qlen < sch->limit))
return qdisc_enqueue_tail(skb, sch);
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 238cf1737576..7777c0096a38 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -326,7 +326,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- struct net *net = current->nsproxy->net_ns;
+ struct net *net = container_of(ctl->data, struct net, sctp.auth_enable);
struct ctl_table tbl;
bool changed = false;
char *none = "none";
@@ -372,7 +372,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- struct net *net = current->nsproxy->net_ns;
+ struct net *net = container_of(ctl->data, struct net, sctp.rto_min);
unsigned int min = *(unsigned int *) ctl->extra1;
unsigned int max = *(unsigned int *) ctl->extra2;
struct ctl_table tbl;
@@ -401,7 +401,7 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- struct net *net = current->nsproxy->net_ns;
+ struct net *net = container_of(ctl->data, struct net, sctp.rto_max);
unsigned int min = *(unsigned int *) ctl->extra1;
unsigned int max = *(unsigned int *) ctl->extra2;
struct ctl_table tbl;
@@ -441,7 +441,8 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- struct net *net = current->nsproxy->net_ns;
+ struct net *net = container_of(ctl->data, struct net,
+ sctp.sctp_hmac_alg);
struct ctl_table tbl;
int new_value, ret;
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 910da98d6bfb..03f608da594e 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -425,7 +425,7 @@ int tls_tx_records(struct sock *sk, int flags)
tx_err:
if (rc < 0 && rc != -EAGAIN)
- tls_err_abort(sk, -EBADMSG);
+ tls_err_abort(sk, rc);
return rc;
}
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index dfc536cd9d2f..7b03ff158d78 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1400,6 +1400,7 @@ config SND_SOC_WM8993
config SND_SOC_WM8994
tristate
+ depends on MFD_WM8994
config SND_SOC_WM8995
tristate
diff --git a/techpack/audio/asoc/codecs/wcdcal-hwdep.c b/techpack/audio/asoc/codecs/wcdcal-hwdep.c
index 7e2b984a9304..a0455fdd104b 100644
--- a/techpack/audio/asoc/codecs/wcdcal-hwdep.c
+++ b/techpack/audio/asoc/codecs/wcdcal-hwdep.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015, 2017-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#include
@@ -60,17 +61,17 @@ static int wcdcal_hwdep_ioctl_shared(struct snd_hwdep *hw,
struct firmware_cal **fw = fw_data->fw;
void *data;
- if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
- pr_err("%s: codec didn't set this %d!!\n",
- __func__, fw_user.cal_type);
- return -EFAULT;
- }
if (fw_user.cal_type >= WCD9XXX_MAX_CAL ||
fw_user.cal_type < WCD9XXX_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
+ if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
+ pr_err("%s: codec didn't set this %d!!\n",
+ __func__, fw_user.cal_type);
+ return -EFAULT;
+ }
if (fw_user.size > cal_size_info[fw_user.cal_type] ||
fw_user.size <= 0) {
pr_err("%s: incorrect firmware size %d for %s\n",
diff --git a/techpack/audio/dsp/q6afecal-hwdep.c b/techpack/audio/dsp/q6afecal-hwdep.c
index ef194ff6ac39..401de1e93b19 100644
--- a/techpack/audio/dsp/q6afecal-hwdep.c
+++ b/techpack/audio/dsp/q6afecal-hwdep.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015, 2017 - 2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include
#include
@@ -61,17 +62,17 @@ static int q6afecal_hwdep_ioctl_shared(struct snd_hwdep *hw,
struct firmware_cal **fw = fw_data->fw;
void *data;
- if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
- pr_err("%s: q6afe didn't set this %d!!\n",
- __func__, fw_user.cal_type);
- return -EFAULT;
- }
if (fw_user.cal_type >= Q6AFE_MAX_CAL ||
fw_user.cal_type < Q6AFE_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
+ if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
+ pr_err("%s: q6afe didn't set this %d!!\n",
+ __func__, fw_user.cal_type);
+ return -EFAULT;
+ }
if (fw_user.size > cal_size_info[fw_user.cal_type] ||
fw_user.size <= 0) {
pr_err("%s: incorrect firmware size %d for %s\n",
diff --git a/techpack/display/msm/sde/sde_encoder.c b/techpack/display/msm/sde/sde_encoder.c
index b67e4d537499..9b3684a9ba4c 100644
--- a/techpack/display/msm/sde/sde_encoder.c
+++ b/techpack/display/msm/sde/sde_encoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark
@@ -1434,6 +1434,7 @@ static int _sde_encoder_update_rsc_client(
void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
{
struct sde_encoder_virt *sde_enc;
+ struct sde_kms *sde_kms = NULL;
int i;
if (!drm_enc) {
@@ -1441,6 +1442,12 @@ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
return;
}
+ sde_kms = sde_encoder_get_kms(drm_enc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid kms\n");
+ return;
+ }
+
sde_enc = to_sde_encoder_virt(drm_enc);
SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
@@ -1450,7 +1457,7 @@ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
if (phys && phys->ops.irq_control)
phys->ops.irq_control(phys, enable);
}
- sde_kms_cpu_vote_for_irq(sde_encoder_get_kms(drm_enc), enable);
+ sde_kms_cpu_vote_for_irq(sde_kms, enable);
}