mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
Merge 220883fba3 ("HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check") into android14-6.1-lts
Steps on the way to 6.1.129 Change-Id: I12ddac7329f6db60e21f195f3e500ac786f2db7c Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -27,7 +27,7 @@ properties:
|
|||||||
description: |
|
description: |
|
||||||
For multicolor LED support this property should be defined as either
|
For multicolor LED support this property should be defined as either
|
||||||
LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in
|
LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in
|
||||||
include/linux/leds/common.h.
|
include/dt-bindings/leds/common.h.
|
||||||
enum: [ 8, 9 ]
|
enum: [ 8, 9 ]
|
||||||
|
|
||||||
required:
|
required:
|
||||||
|
|||||||
@@ -50,15 +50,15 @@ properties:
|
|||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 1
|
maximum: 1
|
||||||
|
|
||||||
rohm,charger-sense-resistor-ohms:
|
rohm,charger-sense-resistor-micro-ohms:
|
||||||
minimum: 10000000
|
minimum: 10000
|
||||||
maximum: 50000000
|
maximum: 50000
|
||||||
description: |
|
description: |
|
||||||
BD71827 and BD71828 have SAR ADC for measuring charging currents.
|
BD71815 has SAR ADC for measuring charging currents. External sense
|
||||||
External sense resistor (RSENSE in data sheet) should be used. If
|
resistor (RSENSE in data sheet) should be used. If something other
|
||||||
something other but 30MOhm resistor is used the resistance value
|
but a 30 mOhm resistor is used the resistance value should be given
|
||||||
should be given here in Ohms.
|
here in micro Ohms.
|
||||||
default: 30000000
|
default: 30000
|
||||||
|
|
||||||
regulators:
|
regulators:
|
||||||
$ref: ../regulator/rohm,bd71815-regulator.yaml
|
$ref: ../regulator/rohm,bd71815-regulator.yaml
|
||||||
@@ -67,7 +67,7 @@ properties:
|
|||||||
|
|
||||||
gpio-reserved-ranges:
|
gpio-reserved-ranges:
|
||||||
description: |
|
description: |
|
||||||
Usage of BD71828 GPIO pins can be changed via OTP. This property can be
|
Usage of BD71815 GPIO pins can be changed via OTP. This property can be
|
||||||
used to mark the pins which should not be configured for GPIO. Please see
|
used to mark the pins which should not be configured for GPIO. Please see
|
||||||
the ../gpio/gpio.txt for more information.
|
the ../gpio/gpio.txt for more information.
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ examples:
|
|||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
rohm,charger-sense-resistor-ohms = <10000000>;
|
rohm,charger-sense-resistor-micro-ohms = <10000>;
|
||||||
|
|
||||||
regulators {
|
regulators {
|
||||||
buck1: buck1 {
|
buck1: buck1 {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ properties:
|
|||||||
"#address-cells":
|
"#address-cells":
|
||||||
const: 1
|
const: 1
|
||||||
description: |
|
description: |
|
||||||
The cell is the slot ID if a function subnode is used.
|
The cell is the SDIO function number if a function subnode is used.
|
||||||
|
|
||||||
"#size-cells":
|
"#size-cells":
|
||||||
const: 0
|
const: 0
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ properties:
|
|||||||
$ref: "regulator.yaml#"
|
$ref: "regulator.yaml#"
|
||||||
unevaluatedProperties: false
|
unevaluatedProperties: false
|
||||||
|
|
||||||
properties:
|
|
||||||
regulator-compatible:
|
|
||||||
pattern: "^vbuck[1-4]$"
|
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
@@ -52,7 +48,6 @@ examples:
|
|||||||
|
|
||||||
regulators {
|
regulators {
|
||||||
vbuck1 {
|
vbuck1 {
|
||||||
regulator-compatible = "vbuck1";
|
|
||||||
regulator-min-microvolt = <300000>;
|
regulator-min-microvolt = <300000>;
|
||||||
regulator-max-microvolt = <1193750>;
|
regulator-max-microvolt = <1193750>;
|
||||||
regulator-enable-ramp-delay = <256>;
|
regulator-enable-ramp-delay = <256>;
|
||||||
@@ -60,7 +55,6 @@ examples:
|
|||||||
};
|
};
|
||||||
|
|
||||||
vbuck3 {
|
vbuck3 {
|
||||||
regulator-compatible = "vbuck3";
|
|
||||||
regulator-min-microvolt = <300000>;
|
regulator-min-microvolt = <300000>;
|
||||||
regulator-max-microvolt = <1193750>;
|
regulator-max-microvolt = <1193750>;
|
||||||
regulator-enable-ramp-delay = <256>;
|
regulator-enable-ramp-delay = <256>;
|
||||||
|
|||||||
@@ -366,19 +366,25 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||||||
result = sysfs_create_link(&pdev->dev.kobj,
|
result = sysfs_create_link(&pdev->dev.kobj,
|
||||||
&cdev->device.kobj,
|
&cdev->device.kobj,
|
||||||
"thermal_cooling");
|
"thermal_cooling");
|
||||||
if (result)
|
if (result) {
|
||||||
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
|
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
|
||||||
|
goto err_unregister;
|
||||||
|
}
|
||||||
|
|
||||||
result = sysfs_create_link(&cdev->device.kobj,
|
result = sysfs_create_link(&cdev->device.kobj,
|
||||||
&pdev->dev.kobj,
|
&pdev->dev.kobj,
|
||||||
"device");
|
"device");
|
||||||
if (result) {
|
if (result) {
|
||||||
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
|
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
|
||||||
goto err_end;
|
goto err_remove_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_remove_link:
|
||||||
|
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
|
||||||
|
err_unregister:
|
||||||
|
thermal_cooling_device_unregister(cdev);
|
||||||
err_end:
|
err_end:
|
||||||
if (fan->acpi4)
|
if (fan->acpi4)
|
||||||
acpi_fan_delete_attributes(device);
|
acpi_fan_delete_attributes(device);
|
||||||
|
|||||||
@@ -321,6 +321,9 @@ static int ipmb_probe(struct i2c_client *client)
|
|||||||
ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL,
|
ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL,
|
||||||
"%s%d", "ipmb-",
|
"%s%d", "ipmb-",
|
||||||
client->adapter->nr);
|
client->adapter->nr);
|
||||||
|
if (!ipmb_dev->miscdev.name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ipmb_dev->miscdev.fops = &ipmb_fops;
|
ipmb_dev->miscdev.fops = &ipmb_fops;
|
||||||
ipmb_dev->miscdev.parent = &client->dev;
|
ipmb_dev->miscdev.parent = &client->dev;
|
||||||
ret = misc_register(&ipmb_dev->miscdev);
|
ret = misc_register(&ipmb_dev->miscdev);
|
||||||
|
|||||||
@@ -398,8 +398,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r
|
|||||||
|
|
||||||
static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||||
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
|
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
|
||||||
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
|
"arm_pll_out", "sys_pll1_out", "sys_pll2_out",
|
||||||
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
|
"sys_pll3_out", "dummy", "dummy", "osc_24m",
|
||||||
|
"dummy", "osc_32k"};
|
||||||
|
|
||||||
static struct clk_hw **hws;
|
static struct clk_hw **hws;
|
||||||
static struct clk_hw_onecell_data *clk_hw_data;
|
static struct clk_hw_onecell_data *clk_hw_data;
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s0_clk_src",
|
.name = "gcc_qupv3_wrap0_s0_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
|
||||||
@@ -471,7 +471,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s1_clk_src",
|
.name = "gcc_qupv3_wrap0_s1_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
|
||||||
@@ -487,7 +487,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s2_clk_src",
|
.name = "gcc_qupv3_wrap0_s2_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
|
||||||
@@ -503,7 +503,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s3_clk_src",
|
.name = "gcc_qupv3_wrap0_s3_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
|
||||||
@@ -519,7 +519,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s4_clk_src",
|
.name = "gcc_qupv3_wrap0_s4_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
|
||||||
@@ -535,7 +535,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s5_clk_src",
|
.name = "gcc_qupv3_wrap0_s5_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
|
||||||
@@ -551,7 +551,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s6_clk_src",
|
.name = "gcc_qupv3_wrap0_s6_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
|
||||||
@@ -567,7 +567,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap0_s7_clk_src",
|
.name = "gcc_qupv3_wrap0_s7_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
|
||||||
@@ -583,7 +583,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s0_clk_src",
|
.name = "gcc_qupv3_wrap1_s0_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
|
||||||
@@ -599,7 +599,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s1_clk_src",
|
.name = "gcc_qupv3_wrap1_s1_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
|
||||||
@@ -615,7 +615,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s2_clk_src",
|
.name = "gcc_qupv3_wrap1_s2_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
|
||||||
@@ -631,7 +631,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s3_clk_src",
|
.name = "gcc_qupv3_wrap1_s3_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
|
||||||
@@ -647,7 +647,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s4_clk_src",
|
.name = "gcc_qupv3_wrap1_s4_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
|
||||||
@@ -663,7 +663,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s5_clk_src",
|
.name = "gcc_qupv3_wrap1_s5_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
|
||||||
@@ -679,7 +679,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s6_clk_src",
|
.name = "gcc_qupv3_wrap1_s6_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
|
||||||
@@ -695,7 +695,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
|
|||||||
.name = "gcc_qupv3_wrap1_s7_clk_src",
|
.name = "gcc_qupv3_wrap1_s7_clk_src",
|
||||||
.parent_data = gcc_parent_data_0,
|
.parent_data = gcc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
|
static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
|
||||||
|
|||||||
@@ -2072,7 +2072,7 @@ static const struct hid_device_id mt_devices[] = {
|
|||||||
I2C_DEVICE_ID_GOODIX_01E8) },
|
I2C_DEVICE_ID_GOODIX_01E8) },
|
||||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
||||||
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
||||||
I2C_DEVICE_ID_GOODIX_01E8) },
|
I2C_DEVICE_ID_GOODIX_01E9) },
|
||||||
|
|
||||||
/* GoodTouch panels */
|
/* GoodTouch panels */
|
||||||
{ .driver_data = MT_CLS_NSMU,
|
{ .driver_data = MT_CLS_NSMU,
|
||||||
|
|||||||
@@ -170,6 +170,14 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
|
|||||||
ep = &usbif->cur_altsetting->endpoint[1];
|
ep = &usbif->cur_altsetting->endpoint[1];
|
||||||
b_ep = ep->desc.bEndpointAddress;
|
b_ep = ep->desc.bEndpointAddress;
|
||||||
|
|
||||||
|
/* Are the expected endpoints present? */
|
||||||
|
u8 ep_addr[1] = {b_ep};
|
||||||
|
|
||||||
|
if (!usb_check_int_endpoints(usbif, ep_addr)) {
|
||||||
|
hid_err(hdev, "Unexpected non-int endpoint\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
|
for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
|
||||||
memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);
|
memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);
|
||||||
|
|
||||||
|
|||||||
@@ -440,6 +440,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
|
|||||||
}
|
}
|
||||||
gpio_ext_pdev = of_find_device_by_node(gpio_ext_np);
|
gpio_ext_pdev = of_find_device_by_node(gpio_ext_np);
|
||||||
if (!gpio_ext_pdev) {
|
if (!gpio_ext_pdev) {
|
||||||
|
of_node_put(gpio_ext_np);
|
||||||
dev_err(dev, "Failed to find platform device for gpio-ext\n");
|
dev_err(dev, "Failed to find platform device for gpio-ext\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1171,6 +1171,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (netdev_has_upper_dev(port_dev, dev)) {
|
||||||
|
NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface");
|
||||||
|
netdev_err(dev, "Device %s is already a lower device of the team interface\n",
|
||||||
|
portname);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
|
if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
|
||||||
vlan_uses_dev(dev)) {
|
vlan_uses_dev(dev)) {
|
||||||
NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");
|
NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");
|
||||||
|
|||||||
@@ -3795,6 +3795,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
|
|||||||
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
|
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
|
||||||
&rbm);
|
&rbm);
|
||||||
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
|
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
|
||||||
|
rbm != HAL_RX_BUF_RBM_SW1_BM &&
|
||||||
rbm != HAL_RX_BUF_RBM_SW3_BM) {
|
rbm != HAL_RX_BUF_RBM_SW3_BM) {
|
||||||
ab->soc_stats.invalid_rbm++;
|
ab->soc_stats.invalid_rbm++;
|
||||||
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
|
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
|
||||||
|
|||||||
@@ -371,7 +371,8 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
|
|||||||
|
|
||||||
ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
|
ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
|
||||||
wbm_desc->buf_addr_info.info1);
|
wbm_desc->buf_addr_info.info1);
|
||||||
if (ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
|
if (ret_buf_mgr != HAL_RX_BUF_RBM_SW1_BM &&
|
||||||
|
ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
|
||||||
ab->soc_stats.invalid_rbm++;
|
ab->soc_stats.invalid_rbm++;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1585,7 +1585,10 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
|
n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
|
||||||
wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
|
wcn->chan_survey = devm_kcalloc(wcn->dev,
|
||||||
|
n_channels,
|
||||||
|
sizeof(struct wcn36xx_chan_survey),
|
||||||
|
GFP_KERNEL);
|
||||||
if (!wcn->chan_survey) {
|
if (!wcn->chan_survey) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out_wq;
|
goto out_wq;
|
||||||
|
|||||||
@@ -452,8 +452,7 @@ static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
|
|||||||
/* <1> timer */
|
/* <1> timer */
|
||||||
timer_setup(&rtlpriv->works.watchdog_timer,
|
timer_setup(&rtlpriv->works.watchdog_timer,
|
||||||
rtl_watch_dog_timer_callback, 0);
|
rtl_watch_dog_timer_callback, 0);
|
||||||
timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
|
|
||||||
rtl_easy_concurrent_retrytimer_callback, 0);
|
|
||||||
/* <2> work queue */
|
/* <2> work queue */
|
||||||
rtlpriv->works.hw = hw;
|
rtlpriv->works.hw = hw;
|
||||||
rtlpriv->works.rtl_wq = wq;
|
rtlpriv->works.rtl_wq = wq;
|
||||||
@@ -576,9 +575,15 @@ static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,
|
|||||||
|
|
||||||
void rtl_deinit_core(struct ieee80211_hw *hw)
|
void rtl_deinit_core(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
|
||||||
rtl_c2hcmd_launcher(hw, 0);
|
rtl_c2hcmd_launcher(hw, 0);
|
||||||
rtl_free_entries_from_scan_list(hw);
|
rtl_free_entries_from_scan_list(hw);
|
||||||
rtl_free_entries_from_ack_queue(hw, false);
|
rtl_free_entries_from_ack_queue(hw, false);
|
||||||
|
if (rtlpriv->works.rtl_wq) {
|
||||||
|
destroy_workqueue(rtlpriv->works.rtl_wq);
|
||||||
|
rtlpriv->works.rtl_wq = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtl_deinit_core);
|
EXPORT_SYMBOL_GPL(rtl_deinit_core);
|
||||||
|
|
||||||
@@ -2366,19 +2371,6 @@ static void rtl_c2hcmd_wq_callback(struct work_struct *work)
|
|||||||
rtl_c2hcmd_launcher(hw, 1);
|
rtl_c2hcmd_launcher(hw, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct rtl_priv *rtlpriv =
|
|
||||||
from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer);
|
|
||||||
struct ieee80211_hw *hw = rtlpriv->hw;
|
|
||||||
struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
|
|
||||||
|
|
||||||
if (buddy_priv == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
*
|
*
|
||||||
* frame process functions
|
* frame process functions
|
||||||
@@ -2724,9 +2716,6 @@ MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
|
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
|
||||||
|
|
||||||
struct rtl_global_var rtl_global_var = {};
|
|
||||||
EXPORT_SYMBOL_GPL(rtl_global_var);
|
|
||||||
|
|
||||||
static int __init rtl_core_module_init(void)
|
static int __init rtl_core_module_init(void)
|
||||||
{
|
{
|
||||||
BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION);
|
BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION);
|
||||||
@@ -2740,10 +2729,6 @@ static int __init rtl_core_module_init(void)
|
|||||||
/* add debugfs */
|
/* add debugfs */
|
||||||
rtl_debugfs_add_topdir();
|
rtl_debugfs_add_topdir();
|
||||||
|
|
||||||
/* init some global vars */
|
|
||||||
INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
|
|
||||||
spin_lock_init(&rtl_global_var.glb_list_lock);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,8 +124,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
|
|||||||
u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
|
u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
|
||||||
void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
|
void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
|
||||||
u8 rtl_tid_to_ac(u8 tid);
|
u8 rtl_tid_to_ac(u8 tid);
|
||||||
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t);
|
|
||||||
extern struct rtl_global_var rtl_global_var;
|
|
||||||
void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
|
void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -295,46 +295,6 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
|
|
||||||
struct rtl_priv **buddy_priv)
|
|
||||||
{
|
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
||||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
|
||||||
struct rtl_priv *tpriv = NULL, *iter;
|
|
||||||
struct rtl_pci_priv *tpcipriv = NULL;
|
|
||||||
|
|
||||||
if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) {
|
|
||||||
list_for_each_entry(iter, &rtlpriv->glb_var->glb_priv_list,
|
|
||||||
list) {
|
|
||||||
tpcipriv = (struct rtl_pci_priv *)iter->priv;
|
|
||||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
|
||||||
"pcipriv->ndis_adapter.funcnumber %x\n",
|
|
||||||
pcipriv->ndis_adapter.funcnumber);
|
|
||||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
|
||||||
"tpcipriv->ndis_adapter.funcnumber %x\n",
|
|
||||||
tpcipriv->ndis_adapter.funcnumber);
|
|
||||||
|
|
||||||
if (pcipriv->ndis_adapter.busnumber ==
|
|
||||||
tpcipriv->ndis_adapter.busnumber &&
|
|
||||||
pcipriv->ndis_adapter.devnumber ==
|
|
||||||
tpcipriv->ndis_adapter.devnumber &&
|
|
||||||
pcipriv->ndis_adapter.funcnumber !=
|
|
||||||
tpcipriv->ndis_adapter.funcnumber) {
|
|
||||||
tpriv = iter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
|
||||||
"find_buddy_priv %d\n", tpriv != NULL);
|
|
||||||
|
|
||||||
if (tpriv)
|
|
||||||
*buddy_priv = tpriv;
|
|
||||||
|
|
||||||
return tpriv != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtl_pci_parse_configuration(struct pci_dev *pdev,
|
static void rtl_pci_parse_configuration(struct pci_dev *pdev,
|
||||||
struct ieee80211_hw *hw)
|
struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
@@ -443,11 +403,6 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
|
|||||||
if (!rtlpriv->rtlhal.earlymode_enable)
|
if (!rtlpriv->rtlhal.earlymode_enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rtlpriv->dm.supp_phymode_switch &&
|
|
||||||
(rtlpriv->easy_concurrent_ctl.switch_in_process ||
|
|
||||||
(rtlpriv->buddy_priv &&
|
|
||||||
rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process)))
|
|
||||||
return;
|
|
||||||
/* we just use em for BE/BK/VI/VO */
|
/* we just use em for BE/BK/VI/VO */
|
||||||
for (tid = 7; tid >= 0; tid--) {
|
for (tid = 7; tid >= 0; tid--) {
|
||||||
u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];
|
u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];
|
||||||
@@ -1702,8 +1657,6 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
|
|||||||
synchronize_irq(rtlpci->pdev->irq);
|
synchronize_irq(rtlpci->pdev->irq);
|
||||||
tasklet_kill(&rtlpriv->works.irq_tasklet);
|
tasklet_kill(&rtlpriv->works.irq_tasklet);
|
||||||
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
||||||
|
|
||||||
destroy_workqueue(rtlpriv->works.rtl_wq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
|
static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
|
||||||
@@ -2018,7 +1971,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
|
|||||||
pcipriv->ndis_adapter.amd_l1_patch);
|
pcipriv->ndis_adapter.amd_l1_patch);
|
||||||
|
|
||||||
rtl_pci_parse_configuration(pdev, hw);
|
rtl_pci_parse_configuration(pdev, hw);
|
||||||
list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2165,7 +2117,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
|||||||
rtlpriv->rtlhal.interface = INTF_PCI;
|
rtlpriv->rtlhal.interface = INTF_PCI;
|
||||||
rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
|
rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
|
||||||
rtlpriv->intf_ops = &rtl_pci_ops;
|
rtlpriv->intf_ops = &rtl_pci_ops;
|
||||||
rtlpriv->glb_var = &rtl_global_var;
|
|
||||||
rtl_efuse_ops_init(hw);
|
rtl_efuse_ops_init(hw);
|
||||||
|
|
||||||
/* MEM map */
|
/* MEM map */
|
||||||
@@ -2216,7 +2167,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
|||||||
if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
|
if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
|
||||||
pr_err("Can't init_sw_vars\n");
|
pr_err("Can't init_sw_vars\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto fail3;
|
goto fail2;
|
||||||
}
|
}
|
||||||
rtlpriv->cfg->ops->init_sw_leds(hw);
|
rtlpriv->cfg->ops->init_sw_leds(hw);
|
||||||
|
|
||||||
@@ -2234,14 +2185,14 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
|||||||
err = rtl_pci_init(hw, pdev);
|
err = rtl_pci_init(hw, pdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("Failed to init PCI\n");
|
pr_err("Failed to init PCI\n");
|
||||||
goto fail3;
|
goto fail4;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ieee80211_register_hw(hw);
|
err = ieee80211_register_hw(hw);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("Can't register mac80211 hw.\n");
|
pr_err("Can't register mac80211 hw.\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto fail3;
|
goto fail5;
|
||||||
}
|
}
|
||||||
rtlpriv->mac80211.mac80211_registered = 1;
|
rtlpriv->mac80211.mac80211_registered = 1;
|
||||||
|
|
||||||
@@ -2264,16 +2215,19 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
|||||||
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
|
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail3:
|
fail5:
|
||||||
pci_set_drvdata(pdev, NULL);
|
rtl_pci_deinit(hw);
|
||||||
|
fail4:
|
||||||
rtl_deinit_core(hw);
|
rtl_deinit_core(hw);
|
||||||
|
fail3:
|
||||||
|
wait_for_completion(&rtlpriv->firmware_loading_complete);
|
||||||
|
rtlpriv->cfg->ops->deinit_sw_vars(hw);
|
||||||
|
|
||||||
fail2:
|
fail2:
|
||||||
if (rtlpriv->io.pci_mem_start != 0)
|
if (rtlpriv->io.pci_mem_start != 0)
|
||||||
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
|
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
|
||||||
|
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
complete(&rtlpriv->firmware_loading_complete);
|
|
||||||
|
|
||||||
fail1:
|
fail1:
|
||||||
if (hw)
|
if (hw)
|
||||||
@@ -2324,7 +2278,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
|
|||||||
if (rtlpci->using_msi)
|
if (rtlpci->using_msi)
|
||||||
pci_disable_msi(rtlpci->pdev);
|
pci_disable_msi(rtlpci->pdev);
|
||||||
|
|
||||||
list_del(&rtlpriv->list);
|
|
||||||
if (rtlpriv->io.pci_mem_start != 0) {
|
if (rtlpriv->io.pci_mem_start != 0) {
|
||||||
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
|
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
@@ -2384,7 +2337,6 @@ const struct rtl_intf_ops rtl_pci_ops = {
|
|||||||
.read_efuse_byte = read_efuse_byte,
|
.read_efuse_byte = read_efuse_byte,
|
||||||
.adapter_start = rtl_pci_start,
|
.adapter_start = rtl_pci_start,
|
||||||
.adapter_stop = rtl_pci_stop,
|
.adapter_stop = rtl_pci_stop,
|
||||||
.check_buddy_priv = rtl_pci_check_buddy_priv,
|
|
||||||
.adapter_tx = rtl_pci_tx,
|
.adapter_tx = rtl_pci_tx,
|
||||||
.flush = rtl_pci_flush,
|
.flush = rtl_pci_flush,
|
||||||
.reset_trx_ring = rtl_pci_reset_trx_ring,
|
.reset_trx_ring = rtl_pci_reset_trx_ring,
|
||||||
|
|||||||
@@ -67,22 +67,23 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
|
|||||||
|
|
||||||
rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
|
rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
|
||||||
"Firmware callback routine entered!\n");
|
"Firmware callback routine entered!\n");
|
||||||
complete(&rtlpriv->firmware_loading_complete);
|
|
||||||
if (!firmware) {
|
if (!firmware) {
|
||||||
pr_err("Firmware %s not available\n", fw_name);
|
pr_err("Firmware %s not available\n", fw_name);
|
||||||
rtlpriv->max_fw_size = 0;
|
rtlpriv->max_fw_size = 0;
|
||||||
return;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (firmware->size > rtlpriv->max_fw_size) {
|
if (firmware->size > rtlpriv->max_fw_size) {
|
||||||
pr_err("Firmware is too big!\n");
|
pr_err("Firmware is too big!\n");
|
||||||
rtlpriv->max_fw_size = 0;
|
rtlpriv->max_fw_size = 0;
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
return;
|
goto exit;
|
||||||
}
|
}
|
||||||
pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
|
pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
|
||||||
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
|
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
|
||||||
pfirmware->sz_fw_tmpbufferlen = firmware->size;
|
pfirmware->sz_fw_tmpbufferlen = firmware->size;
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
|
exit:
|
||||||
|
complete(&rtlpriv->firmware_loading_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
|
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
|
||||||
|
|||||||
@@ -679,11 +679,6 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
|
|||||||
tasklet_kill(&rtlusb->rx_work_tasklet);
|
tasklet_kill(&rtlusb->rx_work_tasklet);
|
||||||
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
||||||
|
|
||||||
if (rtlpriv->works.rtl_wq) {
|
|
||||||
destroy_workqueue(rtlpriv->works.rtl_wq);
|
|
||||||
rtlpriv->works.rtl_wq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
skb_queue_purge(&rtlusb->rx_queue);
|
skb_queue_purge(&rtlusb->rx_queue);
|
||||||
|
|
||||||
while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
|
while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
|
||||||
@@ -1073,19 +1068,22 @@ int rtl_usb_probe(struct usb_interface *intf,
|
|||||||
err = ieee80211_register_hw(hw);
|
err = ieee80211_register_hw(hw);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("Can't register mac80211 hw.\n");
|
pr_err("Can't register mac80211 hw.\n");
|
||||||
goto error_out;
|
goto error_init_vars;
|
||||||
}
|
}
|
||||||
rtlpriv->mac80211.mac80211_registered = 1;
|
rtlpriv->mac80211.mac80211_registered = 1;
|
||||||
|
|
||||||
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
|
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_init_vars:
|
||||||
|
wait_for_completion(&rtlpriv->firmware_loading_complete);
|
||||||
|
rtlpriv->cfg->ops->deinit_sw_vars(hw);
|
||||||
error_out:
|
error_out:
|
||||||
|
rtl_usb_deinit(hw);
|
||||||
rtl_deinit_core(hw);
|
rtl_deinit_core(hw);
|
||||||
error_out2:
|
error_out2:
|
||||||
_rtl_usb_io_handler_release(hw);
|
_rtl_usb_io_handler_release(hw);
|
||||||
usb_put_dev(udev);
|
usb_put_dev(udev);
|
||||||
complete(&rtlpriv->firmware_loading_complete);
|
|
||||||
kfree(rtlpriv->usb_data);
|
kfree(rtlpriv->usb_data);
|
||||||
ieee80211_free_hw(hw);
|
ieee80211_free_hw(hw);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|||||||
@@ -2300,7 +2300,6 @@ struct rtl_hal_ops {
|
|||||||
u32 regaddr, u32 bitmask, u32 data);
|
u32 regaddr, u32 bitmask, u32 data);
|
||||||
void (*linked_set_reg)(struct ieee80211_hw *hw);
|
void (*linked_set_reg)(struct ieee80211_hw *hw);
|
||||||
void (*chk_switch_dmdp)(struct ieee80211_hw *hw);
|
void (*chk_switch_dmdp)(struct ieee80211_hw *hw);
|
||||||
void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw);
|
|
||||||
void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw);
|
void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw);
|
||||||
bool (*phy_rf6052_config)(struct ieee80211_hw *hw);
|
bool (*phy_rf6052_config)(struct ieee80211_hw *hw);
|
||||||
void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw,
|
void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw,
|
||||||
@@ -2336,8 +2335,6 @@ struct rtl_intf_ops {
|
|||||||
void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
|
void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
|
||||||
int (*adapter_start)(struct ieee80211_hw *hw);
|
int (*adapter_start)(struct ieee80211_hw *hw);
|
||||||
void (*adapter_stop)(struct ieee80211_hw *hw);
|
void (*adapter_stop)(struct ieee80211_hw *hw);
|
||||||
bool (*check_buddy_priv)(struct ieee80211_hw *hw,
|
|
||||||
struct rtl_priv **buddy_priv);
|
|
||||||
|
|
||||||
int (*adapter_tx)(struct ieee80211_hw *hw,
|
int (*adapter_tx)(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
@@ -2465,7 +2462,6 @@ struct rtl_works {
|
|||||||
|
|
||||||
/*timer */
|
/*timer */
|
||||||
struct timer_list watchdog_timer;
|
struct timer_list watchdog_timer;
|
||||||
struct timer_list dualmac_easyconcurrent_retrytimer;
|
|
||||||
struct timer_list fw_clockoff_timer;
|
struct timer_list fw_clockoff_timer;
|
||||||
struct timer_list fast_antenna_training_timer;
|
struct timer_list fast_antenna_training_timer;
|
||||||
/*task */
|
/*task */
|
||||||
@@ -2498,14 +2494,6 @@ struct rtl_debug {
|
|||||||
#define MIMO_PS_DYNAMIC 1
|
#define MIMO_PS_DYNAMIC 1
|
||||||
#define MIMO_PS_NOLIMIT 3
|
#define MIMO_PS_NOLIMIT 3
|
||||||
|
|
||||||
struct rtl_dualmac_easy_concurrent_ctl {
|
|
||||||
enum band_type currentbandtype_backfordmdp;
|
|
||||||
bool close_bbandrf_for_dmsp;
|
|
||||||
bool change_to_dmdp;
|
|
||||||
bool change_to_dmsp;
|
|
||||||
bool switch_in_process;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rtl_dmsp_ctl {
|
struct rtl_dmsp_ctl {
|
||||||
bool activescan_for_slaveofdmsp;
|
bool activescan_for_slaveofdmsp;
|
||||||
bool scan_for_anothermac_fordmsp;
|
bool scan_for_anothermac_fordmsp;
|
||||||
@@ -2590,14 +2578,6 @@ struct dig_t {
|
|||||||
u32 rssi_max;
|
u32 rssi_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl_global_var {
|
|
||||||
/* from this list we can get
|
|
||||||
* other adapter's rtl_priv
|
|
||||||
*/
|
|
||||||
struct list_head glb_priv_list;
|
|
||||||
spinlock_t glb_list_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */
|
#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */
|
||||||
|
|
||||||
struct rtl_btc_info {
|
struct rtl_btc_info {
|
||||||
@@ -2743,10 +2723,7 @@ struct rtl_scan_list {
|
|||||||
struct rtl_priv {
|
struct rtl_priv {
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
struct completion firmware_loading_complete;
|
struct completion firmware_loading_complete;
|
||||||
struct list_head list;
|
|
||||||
struct rtl_priv *buddy_priv;
|
struct rtl_priv *buddy_priv;
|
||||||
struct rtl_global_var *glb_var;
|
|
||||||
struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl;
|
|
||||||
struct rtl_dmsp_ctl dmsp_ctl;
|
struct rtl_dmsp_ctl dmsp_ctl;
|
||||||
struct rtl_locks locks;
|
struct rtl_locks locks;
|
||||||
struct rtl_works works;
|
struct rtl_works works;
|
||||||
|
|||||||
@@ -950,7 +950,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
|
|||||||
|
|
||||||
ret = _of_opp_alloc_required_opps(opp_table, new_opp);
|
ret = _of_opp_alloc_required_opps(opp_table, new_opp);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_opp;
|
goto put_node;
|
||||||
|
|
||||||
if (!of_property_read_u32(np, "clock-latency-ns", &val))
|
if (!of_property_read_u32(np, "clock-latency-ns", &val))
|
||||||
new_opp->clock_latency_ns = val;
|
new_opp->clock_latency_ns = val;
|
||||||
@@ -1003,6 +1003,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
|
|||||||
|
|
||||||
free_required_opps:
|
free_required_opps:
|
||||||
_of_opp_free_required_opps(opp_table, new_opp);
|
_of_opp_free_required_opps(opp_table, new_opp);
|
||||||
|
put_node:
|
||||||
|
of_node_put(np);
|
||||||
free_opp:
|
free_opp:
|
||||||
_opp_free(new_opp);
|
_opp_free(new_opp);
|
||||||
|
|
||||||
|
|||||||
@@ -169,8 +169,12 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
|||||||
regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
|
regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
|
||||||
state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
|
state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
|
||||||
/* Keep PWM counter clock refcount in sync with PWM initial state */
|
/* Keep PWM counter clock refcount in sync with PWM initial state */
|
||||||
if (state->enabled)
|
if (state->enabled) {
|
||||||
clk_enable(priv->clk);
|
int ret = clk_enable(priv->clk);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
|
regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
|
||||||
presc = FIELD_GET(STM32_LPTIM_PRESC, val);
|
presc = FIELD_GET(STM32_LPTIM_PRESC, val);
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ int of_regulator_match(struct device *dev, struct device_node *node,
|
|||||||
"failed to parse DT for regulator %pOFn\n",
|
"failed to parse DT for regulator %pOFn\n",
|
||||||
child);
|
child);
|
||||||
of_node_put(child);
|
of_node_put(child);
|
||||||
return -EINVAL;
|
goto err_put;
|
||||||
}
|
}
|
||||||
match->of_node = of_node_get(child);
|
match->of_node = of_node_get(child);
|
||||||
count++;
|
count++;
|
||||||
@@ -444,6 +444,18 @@ int of_regulator_match(struct device *dev, struct device_node *node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
|
err_put:
|
||||||
|
for (i = 0; i < num_matches; i++) {
|
||||||
|
struct of_regulator_match *match = &matches[i];
|
||||||
|
|
||||||
|
match->init_data = NULL;
|
||||||
|
if (match->of_node) {
|
||||||
|
of_node_put(match->of_node);
|
||||||
|
match->of_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(of_regulator_match);
|
EXPORT_SYMBOL_GPL(of_regulator_match);
|
||||||
|
|
||||||
|
|||||||
@@ -379,12 +379,21 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
|
|||||||
{
|
{
|
||||||
struct spi_controller *ctlr = spi->master;
|
struct spi_controller *ctlr = spi->master;
|
||||||
struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
|
struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ctlr->busy)
|
if (ctlr->busy)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
clk_enable(qspi->refclk);
|
ret = clk_enable(qspi->refclk);
|
||||||
clk_enable(qspi->pclk);
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = clk_enable(qspi->pclk);
|
||||||
|
if (ret) {
|
||||||
|
clk_disable(qspi->refclk);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
|
zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
|
||||||
ZYNQ_QSPI_ENABLE_ENABLE_MASK);
|
ZYNQ_QSPI_ENABLE_ENABLE_MASK);
|
||||||
|
|
||||||
|
|||||||
@@ -2203,7 +2203,7 @@ struct net_device {
|
|||||||
void *atalk_ptr;
|
void *atalk_ptr;
|
||||||
#endif
|
#endif
|
||||||
#if IS_ENABLED(CONFIG_AX25)
|
#if IS_ENABLED(CONFIG_AX25)
|
||||||
void *ax25_ptr;
|
struct ax25_dev __rcu *ax25_ptr;
|
||||||
#endif
|
#endif
|
||||||
/* Android KMI hack to allow vendors to have their own wifi changes in modules */
|
/* Android KMI hack to allow vendors to have their own wifi changes in modules */
|
||||||
#ifdef __GENKSYMS__
|
#ifdef __GENKSYMS__
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ typedef struct ax25_dev {
|
|||||||
#endif
|
#endif
|
||||||
refcount_t refcount;
|
refcount_t refcount;
|
||||||
bool device_up;
|
bool device_up;
|
||||||
|
struct rcu_head rcu;
|
||||||
} ax25_dev;
|
} ax25_dev;
|
||||||
|
|
||||||
typedef struct ax25_cb {
|
typedef struct ax25_cb {
|
||||||
@@ -291,9 +292,8 @@ static inline void ax25_dev_hold(ax25_dev *ax25_dev)
|
|||||||
|
|
||||||
static inline void ax25_dev_put(ax25_dev *ax25_dev)
|
static inline void ax25_dev_put(ax25_dev *ax25_dev)
|
||||||
{
|
{
|
||||||
if (refcount_dec_and_test(&ax25_dev->refcount)) {
|
if (refcount_dec_and_test(&ax25_dev->refcount))
|
||||||
kfree(ax25_dev);
|
kfree_rcu(ax25_dev, rcu);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
|
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
@@ -336,9 +336,9 @@ void ax25_digi_invert(const ax25_digi *, ax25_digi *);
|
|||||||
extern spinlock_t ax25_dev_lock;
|
extern spinlock_t ax25_dev_lock;
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_AX25)
|
#if IS_ENABLED(CONFIG_AX25)
|
||||||
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
|
static inline ax25_dev *ax25_dev_ax25dev(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
return dev->ax25_ptr;
|
return rcu_dereference_rtnl(dev->ax25_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -96,30 +96,28 @@ static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr)
|
|||||||
|
|
||||||
/* can be called with or without local BH being disabled */
|
/* can be called with or without local BH being disabled */
|
||||||
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
|
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
|
||||||
const struct inetpeer_addr *daddr,
|
const struct inetpeer_addr *daddr);
|
||||||
int create);
|
|
||||||
|
|
||||||
static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
|
static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
|
||||||
__be32 v4daddr,
|
__be32 v4daddr,
|
||||||
int vif, int create)
|
int vif)
|
||||||
{
|
{
|
||||||
struct inetpeer_addr daddr;
|
struct inetpeer_addr daddr;
|
||||||
|
|
||||||
daddr.a4.addr = v4daddr;
|
daddr.a4.addr = v4daddr;
|
||||||
daddr.a4.vif = vif;
|
daddr.a4.vif = vif;
|
||||||
daddr.family = AF_INET;
|
daddr.family = AF_INET;
|
||||||
return inet_getpeer(base, &daddr, create);
|
return inet_getpeer(base, &daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
|
static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
|
||||||
const struct in6_addr *v6daddr,
|
const struct in6_addr *v6daddr)
|
||||||
int create)
|
|
||||||
{
|
{
|
||||||
struct inetpeer_addr daddr;
|
struct inetpeer_addr daddr;
|
||||||
|
|
||||||
daddr.a6 = *v6daddr;
|
daddr.a6 = *v6daddr;
|
||||||
daddr.family = AF_INET6;
|
daddr.family = AF_INET6;
|
||||||
return inet_getpeer(base, &daddr, create);
|
return inet_getpeer(base, &daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a,
|
static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
|
|||||||
|
|
||||||
if (unlikely(sg_policy->limits_changed)) {
|
if (unlikely(sg_policy->limits_changed)) {
|
||||||
sg_policy->limits_changed = false;
|
sg_policy->limits_changed = false;
|
||||||
sg_policy->need_freq_update = true;
|
sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time,
|
|||||||
unsigned int next_freq)
|
unsigned int next_freq)
|
||||||
{
|
{
|
||||||
if (sg_policy->need_freq_update)
|
if (sg_policy->need_freq_update)
|
||||||
sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS);
|
sg_policy->need_freq_update = false;
|
||||||
else if (sg_policy->next_freq == next_freq)
|
else if (sg_policy->next_freq == next_freq)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ einval_put:
|
|||||||
goto out_put;
|
goto out_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev)
|
static void ax25_fillin_cb_from_dev(ax25_cb *ax25, const ax25_dev *ax25_dev)
|
||||||
{
|
{
|
||||||
ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
|
ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
|
||||||
ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
|
ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
|
||||||
@@ -677,22 +677,22 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtnl_lock();
|
rcu_read_lock();
|
||||||
dev = __dev_get_by_name(&init_net, devname);
|
dev = dev_get_by_name_rcu(&init_net, devname);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
rtnl_unlock();
|
rcu_read_unlock();
|
||||||
res = -ENODEV;
|
res = -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ax25->ax25_dev = ax25_dev_ax25dev(dev);
|
ax25->ax25_dev = ax25_dev_ax25dev(dev);
|
||||||
if (!ax25->ax25_dev) {
|
if (!ax25->ax25_dev) {
|
||||||
rtnl_unlock();
|
rcu_read_unlock();
|
||||||
res = -ENODEV;
|
res = -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ax25_fillin_cb(ax25, ax25->ax25_dev);
|
ax25_fillin_cb(ax25, ax25->ax25_dev);
|
||||||
rtnl_unlock();
|
rcu_read_unlock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ void ax25_dev_device_up(struct net_device *dev)
|
|||||||
|
|
||||||
spin_lock_bh(&ax25_dev_lock);
|
spin_lock_bh(&ax25_dev_lock);
|
||||||
list_add(&ax25_dev->list, &ax25_dev_list);
|
list_add(&ax25_dev->list, &ax25_dev_list);
|
||||||
dev->ax25_ptr = ax25_dev;
|
rcu_assign_pointer(dev->ax25_ptr, ax25_dev);
|
||||||
spin_unlock_bh(&ax25_dev_lock);
|
spin_unlock_bh(&ax25_dev_lock);
|
||||||
|
|
||||||
ax25_register_dev_sysctl(ax25_dev);
|
ax25_register_dev_sysctl(ax25_dev);
|
||||||
@@ -122,7 +122,7 @@ void ax25_dev_device_down(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->ax25_ptr = NULL;
|
RCU_INIT_POINTER(dev->ax25_ptr, NULL);
|
||||||
spin_unlock_bh(&ax25_dev_lock);
|
spin_unlock_bh(&ax25_dev_lock);
|
||||||
netdev_put(dev, &ax25_dev->dev_tracker);
|
netdev_put(dev, &ax25_dev->dev_tracker);
|
||||||
ax25_dev_put(ax25_dev);
|
ax25_dev_put(ax25_dev);
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
|
|||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
dev = skb->dev;
|
dev = skb->dev;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
|
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
goto put;
|
goto put;
|
||||||
@@ -202,7 +203,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
|
|||||||
ax25_queue_xmit(skb, dev);
|
ax25_queue_xmit(skb, dev);
|
||||||
|
|
||||||
put:
|
put:
|
||||||
|
rcu_read_unlock();
|
||||||
ax25_route_lock_unuse();
|
ax25_route_lock_unuse();
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,14 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr
|
|||||||
* specified.
|
* specified.
|
||||||
*/
|
*/
|
||||||
if (paclen == 0) {
|
if (paclen == 0) {
|
||||||
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
|
rcu_read_lock();
|
||||||
|
ax25_dev = ax25_dev_ax25dev(dev);
|
||||||
|
if (!ax25_dev) {
|
||||||
|
rcu_read_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
paclen = ax25_dev->values[AX25_VALUES_PACLEN];
|
paclen = ax25_dev->values[AX25_VALUES_PACLEN];
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -53,13 +57,19 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr
|
|||||||
return ax25; /* It already existed */
|
return ax25; /* It already existed */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
|
rcu_read_lock();
|
||||||
|
ax25_dev = ax25_dev_ax25dev(dev);
|
||||||
|
if (!ax25_dev) {
|
||||||
|
rcu_read_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ax25 = ax25_create_cb()) == NULL)
|
if ((ax25 = ax25_create_cb()) == NULL) {
|
||||||
|
rcu_read_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
ax25_fillin_cb(ax25, ax25_dev);
|
ax25_fillin_cb(ax25, ax25_dev);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
ax25->source_addr = *src;
|
ax25->source_addr = *src;
|
||||||
ax25->dest_addr = *dest;
|
ax25->dest_addr = *dest;
|
||||||
@@ -358,7 +368,9 @@ void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
{
|
{
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
|
skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
ptr = skb_push(skb, 1);
|
ptr = skb_push(skb, 1);
|
||||||
*ptr = 0x00; /* KISS */
|
*ptr = 0x00; /* KISS */
|
||||||
|
|||||||
@@ -406,6 +406,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
|||||||
ax25_route_lock_unuse();
|
ax25_route_lock_unuse();
|
||||||
return -EHOSTUNREACH;
|
return -EHOSTUNREACH;
|
||||||
}
|
}
|
||||||
|
rcu_read_lock();
|
||||||
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
|
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
|
||||||
err = -EHOSTUNREACH;
|
err = -EHOSTUNREACH;
|
||||||
goto put;
|
goto put;
|
||||||
@@ -442,6 +443,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
put:
|
put:
|
||||||
|
rcu_read_unlock();
|
||||||
ax25_route_lock_unuse();
|
ax25_route_lock_unuse();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,7 +310,6 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
|
|||||||
struct dst_entry *dst = &rt->dst;
|
struct dst_entry *dst = &rt->dst;
|
||||||
struct inet_peer *peer;
|
struct inet_peer *peer;
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
int vif;
|
|
||||||
|
|
||||||
if (icmpv4_mask_allow(net, type, code))
|
if (icmpv4_mask_allow(net, type, code))
|
||||||
goto out;
|
goto out;
|
||||||
@@ -319,12 +318,12 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
|
|||||||
if (dst->dev && (dst->dev->flags&IFF_LOOPBACK))
|
if (dst->dev && (dst->dev->flags&IFF_LOOPBACK))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
vif = l3mdev_master_ifindex(dst->dev);
|
rcu_read_lock();
|
||||||
peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1);
|
peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr,
|
||||||
|
l3mdev_master_ifindex_rcu(dst->dev));
|
||||||
rc = inet_peer_xrlim_allow(peer,
|
rc = inet_peer_xrlim_allow(peer,
|
||||||
READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
|
READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
|
||||||
if (peer)
|
rcu_read_unlock();
|
||||||
inet_putpeer(peer);
|
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
|
|||||||
{
|
{
|
||||||
struct rb_node **pp, *parent, *next;
|
struct rb_node **pp, *parent, *next;
|
||||||
struct inet_peer *p;
|
struct inet_peer *p;
|
||||||
|
u32 now;
|
||||||
|
|
||||||
pp = &base->rb_root.rb_node;
|
pp = &base->rb_root.rb_node;
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
@@ -111,8 +112,9 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
|
|||||||
p = rb_entry(parent, struct inet_peer, rb_node);
|
p = rb_entry(parent, struct inet_peer, rb_node);
|
||||||
cmp = inetpeer_addr_cmp(daddr, &p->daddr);
|
cmp = inetpeer_addr_cmp(daddr, &p->daddr);
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
if (!refcount_inc_not_zero(&p->refcnt))
|
now = jiffies;
|
||||||
break;
|
if (READ_ONCE(p->dtime) != now)
|
||||||
|
WRITE_ONCE(p->dtime, now);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
if (gc_stack) {
|
if (gc_stack) {
|
||||||
@@ -158,9 +160,6 @@ static void inet_peer_gc(struct inet_peer_base *base,
|
|||||||
for (i = 0; i < gc_cnt; i++) {
|
for (i = 0; i < gc_cnt; i++) {
|
||||||
p = gc_stack[i];
|
p = gc_stack[i];
|
||||||
|
|
||||||
/* The READ_ONCE() pairs with the WRITE_ONCE()
|
|
||||||
* in inet_putpeer()
|
|
||||||
*/
|
|
||||||
delta = (__u32)jiffies - READ_ONCE(p->dtime);
|
delta = (__u32)jiffies - READ_ONCE(p->dtime);
|
||||||
|
|
||||||
if (delta < ttl || !refcount_dec_if_one(&p->refcnt))
|
if (delta < ttl || !refcount_dec_if_one(&p->refcnt))
|
||||||
@@ -176,31 +175,23 @@ static void inet_peer_gc(struct inet_peer_base *base,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must be called under RCU : No refcount change is done here. */
|
||||||
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
|
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
|
||||||
const struct inetpeer_addr *daddr,
|
const struct inetpeer_addr *daddr)
|
||||||
int create)
|
|
||||||
{
|
{
|
||||||
struct inet_peer *p, *gc_stack[PEER_MAX_GC];
|
struct inet_peer *p, *gc_stack[PEER_MAX_GC];
|
||||||
struct rb_node **pp, *parent;
|
struct rb_node **pp, *parent;
|
||||||
unsigned int gc_cnt, seq;
|
unsigned int gc_cnt, seq;
|
||||||
int invalidated;
|
|
||||||
|
|
||||||
/* Attempt a lockless lookup first.
|
/* Attempt a lockless lookup first.
|
||||||
* Because of a concurrent writer, we might not find an existing entry.
|
* Because of a concurrent writer, we might not find an existing entry.
|
||||||
*/
|
*/
|
||||||
rcu_read_lock();
|
|
||||||
seq = read_seqbegin(&base->lock);
|
seq = read_seqbegin(&base->lock);
|
||||||
p = lookup(daddr, base, seq, NULL, &gc_cnt, &parent, &pp);
|
p = lookup(daddr, base, seq, NULL, &gc_cnt, &parent, &pp);
|
||||||
invalidated = read_seqretry(&base->lock, seq);
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
/* If no writer did a change during our lookup, we can return early. */
|
|
||||||
if (!create && !invalidated)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* retry an exact lookup, taking the lock before.
|
/* retry an exact lookup, taking the lock before.
|
||||||
* At least, nodes should be hot in our cache.
|
* At least, nodes should be hot in our cache.
|
||||||
*/
|
*/
|
||||||
@@ -209,12 +200,12 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
|
|||||||
|
|
||||||
gc_cnt = 0;
|
gc_cnt = 0;
|
||||||
p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp);
|
p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp);
|
||||||
if (!p && create) {
|
if (!p) {
|
||||||
p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC);
|
p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC);
|
||||||
if (p) {
|
if (p) {
|
||||||
p->daddr = *daddr;
|
p->daddr = *daddr;
|
||||||
p->dtime = (__u32)jiffies;
|
p->dtime = (__u32)jiffies;
|
||||||
refcount_set(&p->refcnt, 2);
|
refcount_set(&p->refcnt, 1);
|
||||||
atomic_set(&p->rid, 0);
|
atomic_set(&p->rid, 0);
|
||||||
p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
|
p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
|
||||||
p->rate_tokens = 0;
|
p->rate_tokens = 0;
|
||||||
@@ -239,15 +230,9 @@ EXPORT_SYMBOL_GPL(inet_getpeer);
|
|||||||
|
|
||||||
void inet_putpeer(struct inet_peer *p)
|
void inet_putpeer(struct inet_peer *p)
|
||||||
{
|
{
|
||||||
/* The WRITE_ONCE() pairs with itself (we run lockless)
|
|
||||||
* and the READ_ONCE() in inet_peer_gc()
|
|
||||||
*/
|
|
||||||
WRITE_ONCE(p->dtime, (__u32)jiffies);
|
|
||||||
|
|
||||||
if (refcount_dec_and_test(&p->refcnt))
|
if (refcount_dec_and_test(&p->refcnt))
|
||||||
call_rcu(&p->rcu, inetpeer_free_rcu);
|
call_rcu(&p->rcu, inetpeer_free_rcu);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(inet_putpeer);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check transmit rate limitation for given message.
|
* Check transmit rate limitation for given message.
|
||||||
|
|||||||
@@ -82,15 +82,20 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb,
|
|||||||
static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
|
static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
|
||||||
{
|
{
|
||||||
struct ipq *qp = container_of(q, struct ipq, q);
|
struct ipq *qp = container_of(q, struct ipq, q);
|
||||||
struct net *net = q->fqdir->net;
|
|
||||||
|
|
||||||
const struct frag_v4_compare_key *key = a;
|
const struct frag_v4_compare_key *key = a;
|
||||||
|
struct net *net = q->fqdir->net;
|
||||||
|
struct inet_peer *p = NULL;
|
||||||
|
|
||||||
q->key.v4 = *key;
|
q->key.v4 = *key;
|
||||||
qp->ecn = 0;
|
qp->ecn = 0;
|
||||||
qp->peer = q->fqdir->max_dist ?
|
if (q->fqdir->max_dist) {
|
||||||
inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif, 1) :
|
rcu_read_lock();
|
||||||
NULL;
|
p = inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif);
|
||||||
|
if (p && !refcount_inc_not_zero(&p->refcnt))
|
||||||
|
p = NULL;
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
qp->peer = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ip4_frag_free(struct inet_frag_queue *q)
|
static void ip4_frag_free(struct inet_frag_queue *q)
|
||||||
|
|||||||
@@ -882,11 +882,11 @@ void ip_rt_send_redirect(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
log_martians = IN_DEV_LOG_MARTIANS(in_dev);
|
log_martians = IN_DEV_LOG_MARTIANS(in_dev);
|
||||||
vif = l3mdev_master_ifindex_rcu(rt->dst.dev);
|
vif = l3mdev_master_ifindex_rcu(rt->dst.dev);
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
net = dev_net(rt->dst.dev);
|
net = dev_net(rt->dst.dev);
|
||||||
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif, 1);
|
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
|
rcu_read_unlock();
|
||||||
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
|
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
|
||||||
rt_nexthop(rt, ip_hdr(skb)->daddr));
|
rt_nexthop(rt, ip_hdr(skb)->daddr));
|
||||||
return;
|
return;
|
||||||
@@ -905,7 +905,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
|
|||||||
*/
|
*/
|
||||||
if (peer->n_redirects >= ip_rt_redirect_number) {
|
if (peer->n_redirects >= ip_rt_redirect_number) {
|
||||||
peer->rate_last = jiffies;
|
peer->rate_last = jiffies;
|
||||||
goto out_put_peer;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for load limit; set rate_last to the latest sent
|
/* Check for load limit; set rate_last to the latest sent
|
||||||
@@ -926,8 +926,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
|
|||||||
&ip_hdr(skb)->saddr, inet_iif(skb),
|
&ip_hdr(skb)->saddr, inet_iif(skb),
|
||||||
&ip_hdr(skb)->daddr, &gw);
|
&ip_hdr(skb)->daddr, &gw);
|
||||||
}
|
}
|
||||||
out_put_peer:
|
out_unlock:
|
||||||
inet_putpeer(peer);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip_error(struct sk_buff *skb)
|
static int ip_error(struct sk_buff *skb)
|
||||||
@@ -987,9 +987,9 @@ static int ip_error(struct sk_buff *skb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr,
|
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr,
|
||||||
l3mdev_master_ifindex(skb->dev), 1);
|
l3mdev_master_ifindex_rcu(skb->dev));
|
||||||
|
|
||||||
send = true;
|
send = true;
|
||||||
if (peer) {
|
if (peer) {
|
||||||
now = jiffies;
|
now = jiffies;
|
||||||
@@ -1001,8 +1001,9 @@ static int ip_error(struct sk_buff *skb)
|
|||||||
peer->rate_tokens -= ip_rt_error_cost;
|
peer->rate_tokens -= ip_rt_error_cost;
|
||||||
else
|
else
|
||||||
send = false;
|
send = false;
|
||||||
inet_putpeer(peer);
|
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (send)
|
if (send)
|
||||||
icmp_send(skb, ICMP_DEST_UNREACH, code, 0);
|
icmp_send(skb, ICMP_DEST_UNREACH, code, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -219,10 +219,10 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
|
|||||||
if (rt->rt6i_dst.plen < 128)
|
if (rt->rt6i_dst.plen < 128)
|
||||||
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
|
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
|
||||||
|
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr, 1);
|
rcu_read_lock();
|
||||||
|
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
|
||||||
res = inet_peer_xrlim_allow(peer, tmo);
|
res = inet_peer_xrlim_allow(peer, tmo);
|
||||||
if (peer)
|
rcu_read_unlock();
|
||||||
inet_putpeer(peer);
|
|
||||||
}
|
}
|
||||||
dst_release(dst);
|
dst_release(dst);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -610,15 +610,15 @@ int ip6_forward(struct sk_buff *skb)
|
|||||||
else
|
else
|
||||||
target = &hdr->daddr;
|
target = &hdr->daddr;
|
||||||
|
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1);
|
rcu_read_lock();
|
||||||
|
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr);
|
||||||
|
|
||||||
/* Limit redirects both by destination (here)
|
/* Limit redirects both by destination (here)
|
||||||
and by source (inside ndisc_send_redirect)
|
and by source (inside ndisc_send_redirect)
|
||||||
*/
|
*/
|
||||||
if (inet_peer_xrlim_allow(peer, 1*HZ))
|
if (inet_peer_xrlim_allow(peer, 1*HZ))
|
||||||
ndisc_send_redirect(skb, target);
|
ndisc_send_redirect(skb, target);
|
||||||
if (peer)
|
rcu_read_unlock();
|
||||||
inet_putpeer(peer);
|
|
||||||
} else {
|
} else {
|
||||||
int addrtype = ipv6_addr_type(&hdr->saddr);
|
int addrtype = ipv6_addr_type(&hdr->saddr);
|
||||||
|
|
||||||
|
|||||||
@@ -1721,10 +1721,12 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
|
|||||||
"Redirect: destination is not a neighbour\n");
|
"Redirect: destination is not a neighbour\n");
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1);
|
|
||||||
|
rcu_read_lock();
|
||||||
|
peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr);
|
||||||
ret = inet_peer_xrlim_allow(peer, 1*HZ);
|
ret = inet_peer_xrlim_allow(peer, 1*HZ);
|
||||||
if (peer)
|
rcu_read_unlock();
|
||||||
inet_putpeer(peer);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto release;
|
goto release;
|
||||||
|
|
||||||
|
|||||||
@@ -77,12 +77,6 @@
|
|||||||
#define SFQ_EMPTY_SLOT 0xffff
|
#define SFQ_EMPTY_SLOT 0xffff
|
||||||
#define SFQ_DEFAULT_HASH_DIVISOR 1024
|
#define SFQ_DEFAULT_HASH_DIVISOR 1024
|
||||||
|
|
||||||
/* We use 16 bits to store allot, and want to handle packets up to 64K
|
|
||||||
* Scale allot by 8 (1<<3) so that no overflow occurs.
|
|
||||||
*/
|
|
||||||
#define SFQ_ALLOT_SHIFT 3
|
|
||||||
#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT)
|
|
||||||
|
|
||||||
/* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */
|
/* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */
|
||||||
typedef u16 sfq_index;
|
typedef u16 sfq_index;
|
||||||
|
|
||||||
@@ -104,7 +98,7 @@ struct sfq_slot {
|
|||||||
sfq_index next; /* next slot in sfq RR chain */
|
sfq_index next; /* next slot in sfq RR chain */
|
||||||
struct sfq_head dep; /* anchor in dep[] chains */
|
struct sfq_head dep; /* anchor in dep[] chains */
|
||||||
unsigned short hash; /* hash value (index in ht[]) */
|
unsigned short hash; /* hash value (index in ht[]) */
|
||||||
short allot; /* credit for this slot */
|
int allot; /* credit for this slot */
|
||||||
|
|
||||||
unsigned int backlog;
|
unsigned int backlog;
|
||||||
struct red_vars vars;
|
struct red_vars vars;
|
||||||
@@ -120,7 +114,6 @@ struct sfq_sched_data {
|
|||||||
siphash_key_t perturbation;
|
siphash_key_t perturbation;
|
||||||
u8 cur_depth; /* depth of longest slot */
|
u8 cur_depth; /* depth of longest slot */
|
||||||
u8 flags;
|
u8 flags;
|
||||||
unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
|
|
||||||
struct tcf_proto __rcu *filter_list;
|
struct tcf_proto __rcu *filter_list;
|
||||||
struct tcf_block *block;
|
struct tcf_block *block;
|
||||||
sfq_index *ht; /* Hash table ('divisor' slots) */
|
sfq_index *ht; /* Hash table ('divisor' slots) */
|
||||||
@@ -456,7 +449,7 @@ enqueue:
|
|||||||
*/
|
*/
|
||||||
q->tail = slot;
|
q->tail = slot;
|
||||||
/* We could use a bigger initial quantum for new flows */
|
/* We could use a bigger initial quantum for new flows */
|
||||||
slot->allot = q->scaled_quantum;
|
slot->allot = q->quantum;
|
||||||
}
|
}
|
||||||
if (++sch->q.qlen <= q->limit)
|
if (++sch->q.qlen <= q->limit)
|
||||||
return NET_XMIT_SUCCESS;
|
return NET_XMIT_SUCCESS;
|
||||||
@@ -493,7 +486,7 @@ next_slot:
|
|||||||
slot = &q->slots[a];
|
slot = &q->slots[a];
|
||||||
if (slot->allot <= 0) {
|
if (slot->allot <= 0) {
|
||||||
q->tail = slot;
|
q->tail = slot;
|
||||||
slot->allot += q->scaled_quantum;
|
slot->allot += q->quantum;
|
||||||
goto next_slot;
|
goto next_slot;
|
||||||
}
|
}
|
||||||
skb = slot_dequeue_head(slot);
|
skb = slot_dequeue_head(slot);
|
||||||
@@ -512,7 +505,7 @@ next_slot:
|
|||||||
}
|
}
|
||||||
q->tail->next = next_a;
|
q->tail->next = next_a;
|
||||||
} else {
|
} else {
|
||||||
slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb));
|
slot->allot -= qdisc_pkt_len(skb);
|
||||||
}
|
}
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
@@ -595,7 +588,7 @@ drop:
|
|||||||
q->tail->next = x;
|
q->tail->next = x;
|
||||||
}
|
}
|
||||||
q->tail = slot;
|
q->tail = slot;
|
||||||
slot->allot = q->scaled_quantum;
|
slot->allot = q->quantum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sch->q.qlen -= dropped;
|
sch->q.qlen -= dropped;
|
||||||
@@ -608,6 +601,7 @@ static void sfq_perturbation(struct timer_list *t)
|
|||||||
struct Qdisc *sch = q->sch;
|
struct Qdisc *sch = q->sch;
|
||||||
spinlock_t *root_lock;
|
spinlock_t *root_lock;
|
||||||
siphash_key_t nkey;
|
siphash_key_t nkey;
|
||||||
|
int period;
|
||||||
|
|
||||||
get_random_bytes(&nkey, sizeof(nkey));
|
get_random_bytes(&nkey, sizeof(nkey));
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
@@ -618,12 +612,17 @@ static void sfq_perturbation(struct timer_list *t)
|
|||||||
sfq_rehash(sch);
|
sfq_rehash(sch);
|
||||||
spin_unlock(root_lock);
|
spin_unlock(root_lock);
|
||||||
|
|
||||||
if (q->perturb_period)
|
/* q->perturb_period can change under us from
|
||||||
mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
|
* sfq_change() and sfq_destroy().
|
||||||
|
*/
|
||||||
|
period = READ_ONCE(q->perturb_period);
|
||||||
|
if (period)
|
||||||
|
mod_timer(&q->perturb_timer, jiffies + period);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
|
static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct sfq_sched_data *q = qdisc_priv(sch);
|
struct sfq_sched_data *q = qdisc_priv(sch);
|
||||||
struct tc_sfq_qopt *ctl = nla_data(opt);
|
struct tc_sfq_qopt *ctl = nla_data(opt);
|
||||||
@@ -641,14 +640,10 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
|
|||||||
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
|
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* slot->allot is a short, make sure quantum is not too big. */
|
if ((int)ctl->quantum < 0) {
|
||||||
if (ctl->quantum) {
|
NL_SET_ERR_MSG_MOD(extack, "invalid quantum");
|
||||||
unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum);
|
return -EINVAL;
|
||||||
|
|
||||||
if (scaled <= 0 || scaled > SHRT_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
|
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
|
||||||
ctl_v1->Wlog, ctl_v1->Scell_log, NULL))
|
ctl_v1->Wlog, ctl_v1->Scell_log, NULL))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -657,12 +652,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
|
|||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
sch_tree_lock(sch);
|
if (ctl->limit == 1) {
|
||||||
if (ctl->quantum) {
|
NL_SET_ERR_MSG_MOD(extack, "invalid limit");
|
||||||
q->quantum = ctl->quantum;
|
return -EINVAL;
|
||||||
q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
|
|
||||||
}
|
}
|
||||||
q->perturb_period = ctl->perturb_period * HZ;
|
sch_tree_lock(sch);
|
||||||
|
if (ctl->quantum)
|
||||||
|
q->quantum = ctl->quantum;
|
||||||
|
WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ);
|
||||||
if (ctl->flows)
|
if (ctl->flows)
|
||||||
q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
|
q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
|
||||||
if (ctl->divisor) {
|
if (ctl->divisor) {
|
||||||
@@ -724,7 +721,7 @@ static void sfq_destroy(struct Qdisc *sch)
|
|||||||
struct sfq_sched_data *q = qdisc_priv(sch);
|
struct sfq_sched_data *q = qdisc_priv(sch);
|
||||||
|
|
||||||
tcf_block_put(q->block);
|
tcf_block_put(q->block);
|
||||||
q->perturb_period = 0;
|
WRITE_ONCE(q->perturb_period, 0);
|
||||||
del_timer_sync(&q->perturb_timer);
|
del_timer_sync(&q->perturb_timer);
|
||||||
sfq_free(q->ht);
|
sfq_free(q->ht);
|
||||||
sfq_free(q->slots);
|
sfq_free(q->slots);
|
||||||
@@ -757,12 +754,11 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
|
|||||||
q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
|
q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
|
||||||
q->maxflows = SFQ_DEFAULT_FLOWS;
|
q->maxflows = SFQ_DEFAULT_FLOWS;
|
||||||
q->quantum = psched_mtu(qdisc_dev(sch));
|
q->quantum = psched_mtu(qdisc_dev(sch));
|
||||||
q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
|
|
||||||
q->perturb_period = 0;
|
q->perturb_period = 0;
|
||||||
get_random_bytes(&q->perturbation, sizeof(q->perturbation));
|
get_random_bytes(&q->perturbation, sizeof(q->perturbation));
|
||||||
|
|
||||||
if (opt) {
|
if (opt) {
|
||||||
int err = sfq_change(sch, opt);
|
int err = sfq_change(sch, opt, extack);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -873,7 +869,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
|
|||||||
if (idx != SFQ_EMPTY_SLOT) {
|
if (idx != SFQ_EMPTY_SLOT) {
|
||||||
const struct sfq_slot *slot = &q->slots[idx];
|
const struct sfq_slot *slot = &q->slots[idx];
|
||||||
|
|
||||||
xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
|
xstats.allot = slot->allot;
|
||||||
qs.qlen = slot->qlen;
|
qs.qlen = slot->qlen;
|
||||||
qs.backlog = slot->backlog;
|
qs.backlog = slot->backlog;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent,
|
|||||||
unsigned int cpu);
|
unsigned int cpu);
|
||||||
static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
|
static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
|
||||||
unsigned int cpu);
|
unsigned int cpu);
|
||||||
static struct timespec time_start, time_end;
|
static struct timespec *time_start, *time_end;
|
||||||
|
|
||||||
static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
|
static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
|
||||||
{
|
{
|
||||||
@@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
|
|||||||
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
|
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
|
||||||
mperf_cstates[id].name, mperf_diff, tsc_diff);
|
mperf_cstates[id].name, mperf_diff, tsc_diff);
|
||||||
} else if (max_freq_mode == MAX_FREQ_SYSFS) {
|
} else if (max_freq_mode == MAX_FREQ_SYSFS) {
|
||||||
timediff = max_frequency * timespec_diff_us(time_start, time_end);
|
timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]);
|
||||||
*percent = 100.0 * mperf_diff / timediff;
|
*percent = 100.0 * mperf_diff / timediff;
|
||||||
dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
|
dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
|
||||||
mperf_cstates[id].name, mperf_diff, timediff);
|
mperf_cstates[id].name, mperf_diff, timediff);
|
||||||
@@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
|
|||||||
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
if (max_freq_mode == MAX_FREQ_TSC_REF) {
|
||||||
/* Calculate max_freq from TSC count */
|
/* Calculate max_freq from TSC count */
|
||||||
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
|
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
|
||||||
time_diff = timespec_diff_us(time_start, time_end);
|
time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]);
|
||||||
max_frequency = tsc_diff / time_diff;
|
max_frequency = tsc_diff / time_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,9 +226,8 @@ static int mperf_start(void)
|
|||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time_start);
|
|
||||||
|
|
||||||
for (cpu = 0; cpu < cpu_count; cpu++) {
|
for (cpu = 0; cpu < cpu_count; cpu++) {
|
||||||
|
clock_gettime(CLOCK_REALTIME, &time_start[cpu]);
|
||||||
mperf_get_tsc(&tsc_at_measure_start[cpu]);
|
mperf_get_tsc(&tsc_at_measure_start[cpu]);
|
||||||
mperf_init_stats(cpu);
|
mperf_init_stats(cpu);
|
||||||
}
|
}
|
||||||
@@ -243,9 +242,9 @@ static int mperf_stop(void)
|
|||||||
for (cpu = 0; cpu < cpu_count; cpu++) {
|
for (cpu = 0; cpu < cpu_count; cpu++) {
|
||||||
mperf_measure_stats(cpu);
|
mperf_measure_stats(cpu);
|
||||||
mperf_get_tsc(&tsc_at_measure_end[cpu]);
|
mperf_get_tsc(&tsc_at_measure_end[cpu]);
|
||||||
|
clock_gettime(CLOCK_REALTIME, &time_end[cpu]);
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time_end);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void)
|
|||||||
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
|
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
|
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
|
||||||
|
time_start = calloc(cpu_count, sizeof(struct timespec));
|
||||||
|
time_end = calloc(cpu_count, sizeof(struct timespec));
|
||||||
mperf_monitor.name_len = strlen(mperf_monitor.name);
|
mperf_monitor.name_len = strlen(mperf_monitor.name);
|
||||||
return &mperf_monitor;
|
return &mperf_monitor;
|
||||||
}
|
}
|
||||||
@@ -361,6 +362,8 @@ void mperf_unregister(void)
|
|||||||
free(aperf_current_count);
|
free(aperf_current_count);
|
||||||
free(tsc_at_measure_start);
|
free(tsc_at_measure_start);
|
||||||
free(tsc_at_measure_end);
|
free(tsc_at_measure_end);
|
||||||
|
free(time_start);
|
||||||
|
free(time_end);
|
||||||
free(is_valid);
|
free(is_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user