mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge ac84e82f78 ("Merge tag 'block-5.17-2022-03-04' of git://git.kernel.dk/linux-block") into android-mainline
Steps on the way to 5.17-rc7 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib2491e50a3267a1e4b11755fc51ccc6f83a389db
This commit is contained in:
@@ -21475,7 +21475,6 @@ THE REST
|
||||
M: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Buried alive in reporters
|
||||
Q: http://patchwork.kernel.org/project/LKML/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
F: *
|
||||
F: */
|
||||
|
||||
@@ -803,7 +803,7 @@ early_param("coherentio", setcoherentio);
|
||||
|
||||
static int __init setnocoherentio(char *str)
|
||||
{
|
||||
dma_default_coherent = true;
|
||||
dma_default_coherent = false;
|
||||
pr_info("Software DMA cache coherency (command line)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -351,6 +351,9 @@ asmlinkage void start_secondary(void)
|
||||
cpu = smp_processor_id();
|
||||
cpu_data[cpu].udelay_val = loops_per_jiffy;
|
||||
|
||||
set_cpu_sibling_map(cpu);
|
||||
set_cpu_core_map(cpu);
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_coherent_mask);
|
||||
notify_cpu_starting(cpu);
|
||||
|
||||
@@ -362,9 +365,6 @@ asmlinkage void start_secondary(void)
|
||||
/* The CPU is running and counters synchronised, now mark it online */
|
||||
set_cpu_online(cpu, true);
|
||||
|
||||
set_cpu_sibling_map(cpu);
|
||||
set_cpu_core_map(cpu);
|
||||
|
||||
calculate_cpu_foreign_map();
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void *detect_magic __initdata = detect_memory_region;
|
||||
#define MT7621_MEM_TEST_PATTERN 0xaa5555aa
|
||||
|
||||
static u32 detect_magic __initdata;
|
||||
|
||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
{
|
||||
@@ -58,24 +60,32 @@ phys_addr_t mips_cpc_default_phys_base(void)
|
||||
panic("Cannot detect cpc address");
|
||||
}
|
||||
|
||||
static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
|
||||
{
|
||||
void *dm = (void *)KSEG1ADDR(&detect_magic);
|
||||
|
||||
if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
|
||||
return true;
|
||||
__raw_writel(MT7621_MEM_TEST_PATTERN, dm);
|
||||
if (__raw_readl(dm) != __raw_readl(dm + size))
|
||||
return false;
|
||||
__raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
|
||||
return __raw_readl(dm) == __raw_readl(dm + size);
|
||||
}
|
||||
|
||||
static void __init mt7621_memory_detect(void)
|
||||
{
|
||||
void *dm = &detect_magic;
|
||||
phys_addr_t size;
|
||||
|
||||
for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
|
||||
if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
|
||||
break;
|
||||
for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
|
||||
if (mt7621_addr_wraparound_test(size)) {
|
||||
memblock_add(MT7621_LOWMEM_BASE, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size == 256 * SZ_1M) &&
|
||||
(CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
|
||||
__builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
|
||||
memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
|
||||
memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
|
||||
} else {
|
||||
memblock_add(MT7621_LOWMEM_BASE, size);
|
||||
}
|
||||
memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
|
||||
memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
|
||||
}
|
||||
|
||||
void __init ralink_of_remap(void)
|
||||
|
||||
@@ -113,7 +113,8 @@
|
||||
compatible = "canaan,k210-plic", "sifive,plic-1.0.0";
|
||||
reg = <0xC000000 0x4000000>;
|
||||
interrupt-controller;
|
||||
interrupts-extended = <&cpu0_intc 11>, <&cpu1_intc 11>;
|
||||
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
|
||||
<&cpu1_intc 11>, <&cpu1_intc 9>;
|
||||
riscv,ndev = <65>;
|
||||
};
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ extern phys_addr_t phys_ram_base;
|
||||
((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
|
||||
|
||||
#define is_linear_mapping(x) \
|
||||
((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < kernel_map.virt_addr))
|
||||
((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE))
|
||||
|
||||
#define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
|
||||
#define kernel_mapping_pa_to_va(y) ({ \
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
#define KERNEL_LINK_ADDR PAGE_OFFSET
|
||||
#define KERN_VIRT_SIZE (UL(-1))
|
||||
#else
|
||||
|
||||
#define ADDRESS_SPACE_END (UL(-1))
|
||||
|
||||
@@ -24,6 +24,9 @@ obj-$(CONFIG_KASAN) += kasan_init.o
|
||||
ifdef CONFIG_KASAN
|
||||
KASAN_SANITIZE_kasan_init.o := n
|
||||
KASAN_SANITIZE_init.o := n
|
||||
ifdef CONFIG_DEBUG_VIRTUAL
|
||||
KASAN_SANITIZE_physaddr.o := n
|
||||
endif
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
|
||||
|
||||
@@ -125,7 +125,6 @@ void __init mem_init(void)
|
||||
else
|
||||
swiotlb_force = SWIOTLB_NO_FORCE;
|
||||
#endif
|
||||
high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
|
||||
memblock_free_all();
|
||||
|
||||
print_vm_layout();
|
||||
@@ -195,6 +194,7 @@ static void __init setup_bootmem(void)
|
||||
|
||||
min_low_pfn = PFN_UP(phys_ram_base);
|
||||
max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end);
|
||||
high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
|
||||
|
||||
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
|
||||
set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
|
||||
|
||||
@@ -113,8 +113,11 @@ static void __init kasan_populate_pud(pgd_t *pgd,
|
||||
base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
|
||||
} else {
|
||||
base_pud = (pud_t *)pgd_page_vaddr(*pgd);
|
||||
if (base_pud == lm_alias(kasan_early_shadow_pud))
|
||||
if (base_pud == lm_alias(kasan_early_shadow_pud)) {
|
||||
base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
|
||||
memcpy(base_pud, (void *)kasan_early_shadow_pud,
|
||||
sizeof(pud_t) * PTRS_PER_PUD);
|
||||
}
|
||||
}
|
||||
|
||||
pudp = base_pud + pud_index(vaddr);
|
||||
@@ -202,8 +205,7 @@ asmlinkage void __init kasan_early_init(void)
|
||||
|
||||
for (i = 0; i < PTRS_PER_PTE; ++i)
|
||||
set_pte(kasan_early_shadow_pte + i,
|
||||
mk_pte(virt_to_page(kasan_early_shadow_page),
|
||||
PAGE_KERNEL));
|
||||
pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL));
|
||||
|
||||
for (i = 0; i < PTRS_PER_PMD; ++i)
|
||||
set_pmd(kasan_early_shadow_pmd + i,
|
||||
|
||||
@@ -8,12 +8,10 @@
|
||||
|
||||
phys_addr_t __virt_to_phys(unsigned long x)
|
||||
{
|
||||
phys_addr_t y = x - PAGE_OFFSET;
|
||||
|
||||
/*
|
||||
* Boundary checking aginst the kernel linear mapping space.
|
||||
*/
|
||||
WARN(y >= KERN_VIRT_SIZE,
|
||||
WARN(!is_linear_mapping(x) && !is_kernel_mapping(x),
|
||||
"virt_to_phys used for non-linear address: %pK (%pS)\n",
|
||||
(void *)x, (void *)x);
|
||||
|
||||
|
||||
@@ -1676,6 +1676,8 @@ static int fs_init(struct fs_dev *dev)
|
||||
dev->hw_base = pci_resource_start(pci_dev, 0);
|
||||
|
||||
dev->base = ioremap(dev->hw_base, 0x1000);
|
||||
if (!dev->base)
|
||||
return 1;
|
||||
|
||||
reset_chip (dev);
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct charlcd *lcd, char *esc)
|
||||
if (buf[1] > 7)
|
||||
return 1;
|
||||
|
||||
i = 0;
|
||||
i = 2;
|
||||
shift = 0;
|
||||
value = 0;
|
||||
while (*esc && i < LCD2S_CHARACTER_SIZE + 2) {
|
||||
@@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
|
||||
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
|
||||
return -EIO;
|
||||
|
||||
lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL);
|
||||
if (!lcd2s)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Test, if the display is responding */
|
||||
err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF);
|
||||
if (err < 0)
|
||||
@@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
|
||||
if (!lcd)
|
||||
return -ENOMEM;
|
||||
|
||||
lcd2s = kzalloc(sizeof(struct lcd2s_data), GFP_KERNEL);
|
||||
if (!lcd2s) {
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
lcd->drvdata = lcd2s;
|
||||
lcd2s->i2c = i2c;
|
||||
lcd2s->charlcd = lcd;
|
||||
@@ -321,26 +319,24 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
|
||||
err = device_property_read_u32(&i2c->dev, "display-height-chars",
|
||||
&lcd->height);
|
||||
if (err)
|
||||
goto fail2;
|
||||
goto fail1;
|
||||
|
||||
err = device_property_read_u32(&i2c->dev, "display-width-chars",
|
||||
&lcd->width);
|
||||
if (err)
|
||||
goto fail2;
|
||||
goto fail1;
|
||||
|
||||
lcd->ops = &lcd2s_ops;
|
||||
|
||||
err = charlcd_register(lcd2s->charlcd);
|
||||
if (err)
|
||||
goto fail2;
|
||||
goto fail1;
|
||||
|
||||
i2c_set_clientdata(i2c, lcd2s);
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
kfree(lcd2s);
|
||||
fail1:
|
||||
kfree(lcd);
|
||||
charlcd_free(lcd2s->charlcd);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -349,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_client *i2c)
|
||||
struct lcd2s_data *lcd2s = i2c_get_clientdata(i2c);
|
||||
|
||||
charlcd_unregister(lcd2s->charlcd);
|
||||
kfree(lcd2s->charlcd);
|
||||
charlcd_free(lcd2s->charlcd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -777,7 +777,8 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
ret = !vm->evicting;
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
return ret;
|
||||
|
||||
return ret && list_empty(&vm->evicted);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@ config DRM_HDLCD
|
||||
depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST)
|
||||
depends on COMMON_CLK
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_GEM_CMA_HELPER
|
||||
help
|
||||
Choose this option if you have an ARM High Definition Colour LCD
|
||||
controller.
|
||||
|
||||
@@ -1802,6 +1802,7 @@ static inline void ti_sn_gpio_unregister(void) {}
|
||||
|
||||
static void ti_sn65dsi86_runtime_disable(void *data)
|
||||
{
|
||||
pm_runtime_dont_use_autosuspend(data);
|
||||
pm_runtime_disable(data);
|
||||
}
|
||||
|
||||
@@ -1861,11 +1862,11 @@ static int ti_sn65dsi86_probe(struct i2c_client *client,
|
||||
"failed to get reference clock\n");
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_set_autosuspend_delay(pdata->dev, 500);
|
||||
pm_runtime_use_autosuspend(pdata->dev);
|
||||
ret = devm_add_action_or_reset(dev, ti_sn65dsi86_runtime_disable, dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
pm_runtime_set_autosuspend_delay(pdata->dev, 500);
|
||||
pm_runtime_use_autosuspend(pdata->dev);
|
||||
|
||||
ti_sn65dsi86_debugfs_init(pdata);
|
||||
|
||||
|
||||
@@ -2330,6 +2330,9 @@ EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
|
||||
void drm_connector_set_vrr_capable_property(
|
||||
struct drm_connector *connector, bool capable)
|
||||
{
|
||||
if (!connector->vrr_capable_property)
|
||||
return;
|
||||
|
||||
drm_object_property_set_value(&connector->base,
|
||||
connector->vrr_capable_property,
|
||||
capable);
|
||||
|
||||
@@ -678,7 +678,6 @@ static int decon_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct decon_context *ctx;
|
||||
struct device_node *i80_if_timings;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
if (!dev->of_node)
|
||||
@@ -728,16 +727,11 @@ static int decon_probe(struct platform_device *pdev)
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
ctx->i80_if ? "lcd_sys" : "vsync");
|
||||
if (!res) {
|
||||
dev_err(dev, "irq request failed.\n");
|
||||
ret = -ENXIO;
|
||||
ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
|
||||
if (ret < 0)
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, res->start, decon_irq_handler,
|
||||
0, "drm_decon", ctx);
|
||||
ret = devm_request_irq(dev, ret, decon_irq_handler, 0, "drm_decon", ctx);
|
||||
if (ret) {
|
||||
dev_err(dev, "irq request failed.\n");
|
||||
goto err_iounmap;
|
||||
|
||||
@@ -1334,8 +1334,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
|
||||
int ret;
|
||||
int te_gpio_irq;
|
||||
|
||||
dsi->te_gpio = devm_gpiod_get_optional(dsi->dev, "te", GPIOD_IN);
|
||||
if (IS_ERR(dsi->te_gpio)) {
|
||||
dsi->te_gpio = gpiod_get_optional(panel, "te", GPIOD_IN);
|
||||
if (!dsi->te_gpio) {
|
||||
return 0;
|
||||
} else if (IS_ERR(dsi->te_gpio)) {
|
||||
dev_err(dsi->dev, "gpio request failed with %ld\n",
|
||||
PTR_ERR(dsi->te_gpio));
|
||||
return PTR_ERR(dsi->te_gpio);
|
||||
|
||||
@@ -1267,7 +1267,6 @@ static int fimc_probe(struct platform_device *pdev)
|
||||
struct exynos_drm_ipp_formats *formats;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct fimc_context *ctx;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
int i, j, num_limits, num_formats;
|
||||
|
||||
@@ -1330,14 +1329,12 @@ static int fimc_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(ctx->regs);
|
||||
|
||||
/* resource irq */
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to request irq resource.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_irq(dev, res->start, fimc_irq_handler,
|
||||
0, dev_name(dev), ctx);
|
||||
ret = devm_request_irq(dev, ret, fimc_irq_handler,
|
||||
0, dev_name(dev), ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to request irq.\n");
|
||||
return ret;
|
||||
|
||||
@@ -1133,7 +1133,6 @@ static int fimd_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct fimd_context *ctx;
|
||||
struct device_node *i80_if_timings;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
if (!dev->of_node)
|
||||
@@ -1206,15 +1205,11 @@ static int fimd_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ctx->regs))
|
||||
return PTR_ERR(ctx->regs);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
ctx->i80_if ? "lcd_sys" : "vsync");
|
||||
if (!res) {
|
||||
dev_err(dev, "irq request failed.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_irq(dev, res->start, fimd_irq_handler,
|
||||
0, "drm_fimd", ctx);
|
||||
ret = devm_request_irq(dev, ret, fimd_irq_handler, 0, "drm_fimd", ctx);
|
||||
if (ret) {
|
||||
dev_err(dev, "irq request failed.\n");
|
||||
return ret;
|
||||
|
||||
@@ -1220,7 +1220,6 @@ static int gsc_probe(struct platform_device *pdev)
|
||||
struct gsc_driverdata *driver_data;
|
||||
struct exynos_drm_ipp_formats *formats;
|
||||
struct gsc_context *ctx;
|
||||
struct resource *res;
|
||||
int num_formats, ret, i, j;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
@@ -1275,13 +1274,10 @@ static int gsc_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(ctx->regs);
|
||||
|
||||
/* resource irq */
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to request irq resource.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
ctx->irq = platform_get_irq(pdev, 0);
|
||||
if (ctx->irq < 0)
|
||||
return ctx->irq;
|
||||
|
||||
ctx->irq = res->start;
|
||||
ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0,
|
||||
dev_name(dev), ctx);
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -809,19 +809,17 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(dev, "get interrupt resource failed.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
ret = platform_get_irq(mixer_ctx->pdev, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mixer_ctx->irq = ret;
|
||||
|
||||
ret = devm_request_irq(dev, res->start, mixer_irq_handler,
|
||||
0, "drm_mixer", mixer_ctx);
|
||||
ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
|
||||
0, "drm_mixer", mixer_ctx);
|
||||
if (ret) {
|
||||
dev_err(dev, "request interrupt failed.\n");
|
||||
return ret;
|
||||
}
|
||||
mixer_ctx->irq = res->start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id)
|
||||
{
|
||||
u32 request[] = {
|
||||
GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
|
||||
SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2),
|
||||
SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1),
|
||||
id,
|
||||
};
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
|
||||
/* Comet Lake V PCH is based on KBP, which is SPT compatible */
|
||||
return PCH_SPT;
|
||||
case INTEL_PCH_ICP_DEVICE_ID_TYPE:
|
||||
case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
|
||||
drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n");
|
||||
drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv));
|
||||
return PCH_ICP;
|
||||
@@ -123,7 +124,6 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
|
||||
!IS_GEN9_BC(dev_priv));
|
||||
return PCH_TGP;
|
||||
case INTEL_PCH_JSP_DEVICE_ID_TYPE:
|
||||
case INTEL_PCH_JSP2_DEVICE_ID_TYPE:
|
||||
drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
|
||||
drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
|
||||
return PCH_JSP;
|
||||
|
||||
@@ -50,11 +50,11 @@ enum intel_pch {
|
||||
#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680
|
||||
#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380
|
||||
#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480
|
||||
#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880
|
||||
#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00
|
||||
#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080
|
||||
#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380
|
||||
#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80
|
||||
#define INTEL_PCH_JSP2_DEVICE_ID_TYPE 0x3880
|
||||
#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80
|
||||
#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180
|
||||
#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
|
||||
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
||||
extern void amd_iommu_apply_erratum_63(u16 devid);
|
||||
extern void amd_iommu_restart_event_logging(struct amd_iommu *iommu);
|
||||
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
|
||||
extern int amd_iommu_init_devices(void);
|
||||
extern void amd_iommu_uninit_devices(void);
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
#define PASID_MASK 0x0000ffff
|
||||
|
||||
/* MMIO status bits */
|
||||
#define MMIO_STATUS_EVT_OVERFLOW_INT_MASK (1 << 0)
|
||||
#define MMIO_STATUS_EVT_INT_MASK (1 << 1)
|
||||
#define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2)
|
||||
#define MMIO_STATUS_PPR_INT_MASK (1 << 6)
|
||||
|
||||
@@ -657,6 +657,16 @@ static int __init alloc_command_buffer(struct amd_iommu *iommu)
|
||||
return iommu->cmd_buf ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function restarts event logging in case the IOMMU experienced
|
||||
* an event log buffer overflow.
|
||||
*/
|
||||
void amd_iommu_restart_event_logging(struct amd_iommu *iommu)
|
||||
{
|
||||
iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
|
||||
iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function resets the command buffer if the IOMMU stopped fetching
|
||||
* commands from it.
|
||||
|
||||
@@ -492,18 +492,18 @@ static void v1_free_pgtable(struct io_pgtable *iop)
|
||||
|
||||
dom = container_of(pgtable, struct protection_domain, iop);
|
||||
|
||||
/* Update data structure */
|
||||
amd_iommu_domain_clr_pt_root(dom);
|
||||
|
||||
/* Make changes visible to IOMMUs */
|
||||
amd_iommu_domain_update(dom);
|
||||
|
||||
/* Page-table is not visible to IOMMU anymore, so free it */
|
||||
BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
|
||||
pgtable->mode > PAGE_MODE_6_LEVEL);
|
||||
|
||||
free_sub_pt(pgtable->root, pgtable->mode, &freelist);
|
||||
|
||||
/* Update data structure */
|
||||
amd_iommu_domain_clr_pt_root(dom);
|
||||
|
||||
/* Make changes visible to IOMMUs */
|
||||
amd_iommu_domain_update(dom);
|
||||
|
||||
put_pages_list(&freelist);
|
||||
}
|
||||
|
||||
|
||||
@@ -764,7 +764,8 @@ amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu) { }
|
||||
#endif /* !CONFIG_IRQ_REMAP */
|
||||
|
||||
#define AMD_IOMMU_INT_MASK \
|
||||
(MMIO_STATUS_EVT_INT_MASK | \
|
||||
(MMIO_STATUS_EVT_OVERFLOW_INT_MASK | \
|
||||
MMIO_STATUS_EVT_INT_MASK | \
|
||||
MMIO_STATUS_PPR_INT_MASK | \
|
||||
MMIO_STATUS_GALOG_INT_MASK)
|
||||
|
||||
@@ -774,7 +775,7 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
|
||||
u32 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
|
||||
|
||||
while (status & AMD_IOMMU_INT_MASK) {
|
||||
/* Enable EVT and PPR and GA interrupts again */
|
||||
/* Enable interrupt sources again */
|
||||
writel(AMD_IOMMU_INT_MASK,
|
||||
iommu->mmio_base + MMIO_STATUS_OFFSET);
|
||||
|
||||
@@ -795,6 +796,11 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status & MMIO_STATUS_EVT_OVERFLOW_INT_MASK) {
|
||||
pr_info_ratelimited("IOMMU event log overflow\n");
|
||||
amd_iommu_restart_event_logging(iommu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware bug: ERBT1312
|
||||
* When re-enabling interrupt (by writing 1
|
||||
|
||||
@@ -2738,7 +2738,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
|
||||
spin_unlock_irqrestore(&device_domain_lock, flags);
|
||||
|
||||
/* PASID table is mandatory for a PCI device in scalable mode. */
|
||||
if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
|
||||
if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
|
||||
ret = intel_pasid_alloc_table(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "PASID table allocation failed\n");
|
||||
|
||||
@@ -808,8 +808,10 @@ static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
|
||||
return NULL;
|
||||
|
||||
mc = platform_get_drvdata(pdev);
|
||||
if (!mc)
|
||||
if (!mc) {
|
||||
put_device(&pdev->dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mc->smmu;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,9 @@ static int com20020pci_probe(struct pci_dev *pdev,
|
||||
return -ENOMEM;
|
||||
|
||||
ci = (struct com20020_pci_card_info *)id->driver_data;
|
||||
if (!ci)
|
||||
return -EINVAL;
|
||||
|
||||
priv->ci = ci;
|
||||
mm = &ci->misc_map;
|
||||
|
||||
|
||||
@@ -1715,15 +1715,15 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
|
||||
netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll,
|
||||
RCANFD_NAPI_WEIGHT);
|
||||
spin_lock_init(&priv->tx_lock);
|
||||
devm_can_led_init(ndev);
|
||||
gpriv->ch[priv->channel] = priv;
|
||||
err = register_candev(ndev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"register_candev() failed, error %d\n", err);
|
||||
goto fail_candev;
|
||||
}
|
||||
spin_lock_init(&priv->tx_lock);
|
||||
devm_can_led_init(ndev);
|
||||
gpriv->ch[priv->channel] = priv;
|
||||
dev_info(&pdev->dev, "device registered (channel %u)\n", priv->channel);
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1787,7 +1787,7 @@ static int es58x_open(struct net_device *netdev)
|
||||
struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
|
||||
int ret;
|
||||
|
||||
if (atomic_inc_return(&es58x_dev->opened_channel_cnt) == 1) {
|
||||
if (!es58x_dev->opened_channel_cnt) {
|
||||
ret = es58x_alloc_rx_urbs(es58x_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1805,12 +1805,13 @@ static int es58x_open(struct net_device *netdev)
|
||||
if (ret)
|
||||
goto free_urbs;
|
||||
|
||||
es58x_dev->opened_channel_cnt++;
|
||||
netif_start_queue(netdev);
|
||||
|
||||
return ret;
|
||||
|
||||
free_urbs:
|
||||
if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
|
||||
if (!es58x_dev->opened_channel_cnt)
|
||||
es58x_free_urbs(es58x_dev);
|
||||
netdev_err(netdev, "%s: Could not open the network device: %pe\n",
|
||||
__func__, ERR_PTR(ret));
|
||||
@@ -1845,7 +1846,8 @@ static int es58x_stop(struct net_device *netdev)
|
||||
|
||||
es58x_flush_pending_tx_msg(netdev);
|
||||
|
||||
if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
|
||||
es58x_dev->opened_channel_cnt--;
|
||||
if (!es58x_dev->opened_channel_cnt)
|
||||
es58x_free_urbs(es58x_dev);
|
||||
|
||||
return 0;
|
||||
@@ -2215,7 +2217,6 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf,
|
||||
init_usb_anchor(&es58x_dev->tx_urbs_idle);
|
||||
init_usb_anchor(&es58x_dev->tx_urbs_busy);
|
||||
atomic_set(&es58x_dev->tx_urbs_idle_cnt, 0);
|
||||
atomic_set(&es58x_dev->opened_channel_cnt, 0);
|
||||
usb_set_intfdata(intf, es58x_dev);
|
||||
|
||||
es58x_dev->rx_pipe = usb_rcvbulkpipe(es58x_dev->udev,
|
||||
|
||||
@@ -373,8 +373,6 @@ struct es58x_operators {
|
||||
* queue wake/stop logic should prevent this URB from getting
|
||||
* empty. Please refer to es58x_get_tx_urb() for more details.
|
||||
* @tx_urbs_idle_cnt: number of urbs in @tx_urbs_idle.
|
||||
* @opened_channel_cnt: number of channels opened (c.f. es58x_open()
|
||||
* and es58x_stop()).
|
||||
* @ktime_req_ns: kernel timestamp when es58x_set_realtime_diff_ns()
|
||||
* was called.
|
||||
* @realtime_diff_ns: difference in nanoseconds between the clocks of
|
||||
@@ -384,6 +382,10 @@ struct es58x_operators {
|
||||
* in RX branches.
|
||||
* @rx_max_packet_size: Maximum length of bulk-in URB.
|
||||
* @num_can_ch: Number of CAN channel (i.e. number of elements of @netdev).
|
||||
* @opened_channel_cnt: number of channels opened. Free of race
|
||||
* conditions because its two users (net_device_ops:ndo_open()
|
||||
* and net_device_ops:ndo_close()) guarantee that the network
|
||||
* stack big kernel lock (a.k.a. rtnl_mutex) is being hold.
|
||||
* @rx_cmd_buf_len: Length of @rx_cmd_buf.
|
||||
* @rx_cmd_buf: The device might split the URB commands in an
|
||||
* arbitrary amount of pieces. This buffer is used to concatenate
|
||||
@@ -406,7 +408,6 @@ struct es58x_device {
|
||||
struct usb_anchor tx_urbs_busy;
|
||||
struct usb_anchor tx_urbs_idle;
|
||||
atomic_t tx_urbs_idle_cnt;
|
||||
atomic_t opened_channel_cnt;
|
||||
|
||||
u64 ktime_req_ns;
|
||||
s64 realtime_diff_ns;
|
||||
@@ -415,6 +416,7 @@ struct es58x_device {
|
||||
|
||||
u16 rx_max_packet_size;
|
||||
u8 num_can_ch;
|
||||
u8 opened_channel_cnt;
|
||||
|
||||
u16 rx_cmd_buf_len;
|
||||
union es58x_urb_cmd rx_cmd_buf;
|
||||
|
||||
@@ -191,8 +191,8 @@ struct gs_can {
|
||||
struct gs_usb {
|
||||
struct gs_can *canch[GS_MAX_INTF];
|
||||
struct usb_anchor rx_submitted;
|
||||
atomic_t active_channels;
|
||||
struct usb_device *udev;
|
||||
u8 active_channels;
|
||||
};
|
||||
|
||||
/* 'allocate' a tx context.
|
||||
@@ -589,7 +589,7 @@ static int gs_can_open(struct net_device *netdev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (atomic_add_return(1, &parent->active_channels) == 1) {
|
||||
if (!parent->active_channels) {
|
||||
for (i = 0; i < GS_MAX_RX_URBS; i++) {
|
||||
struct urb *urb;
|
||||
u8 *buf;
|
||||
@@ -690,6 +690,7 @@ static int gs_can_open(struct net_device *netdev)
|
||||
|
||||
dev->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
parent->active_channels++;
|
||||
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
||||
netif_start_queue(netdev);
|
||||
|
||||
@@ -705,7 +706,8 @@ static int gs_can_close(struct net_device *netdev)
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
/* Stop polling */
|
||||
if (atomic_dec_and_test(&parent->active_channels))
|
||||
parent->active_channels--;
|
||||
if (!parent->active_channels)
|
||||
usb_kill_anchored_urbs(&parent->rx_submitted);
|
||||
|
||||
/* Stop sending URBs */
|
||||
@@ -984,8 +986,6 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
|
||||
init_usb_anchor(&dev->rx_submitted);
|
||||
|
||||
atomic_set(&dev->active_channels, 0);
|
||||
|
||||
usb_set_intfdata(intf, dev);
|
||||
dev->udev = interface_to_usbdev(intf);
|
||||
|
||||
|
||||
@@ -8216,7 +8216,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
||||
rc = dma_set_coherent_mask(&pdev->dev, persist_dma_mask);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev,
|
||||
"pci_set_consistent_dma_mask failed, aborting\n");
|
||||
"dma_set_coherent_mask failed, aborting\n");
|
||||
goto err_out_unmap;
|
||||
}
|
||||
} else if ((rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) != 0) {
|
||||
|
||||
@@ -3613,6 +3613,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
|
||||
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
|
||||
adapter->params.pci.vpd_cap_addr =
|
||||
pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD);
|
||||
if (!adapter->params.pci.vpd_cap_addr)
|
||||
return -ENODEV;
|
||||
ret = get_vpd_params(adapter, &adapter->params.vpd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -2212,6 +2212,19 @@ static const char *reset_reason_to_string(enum ibmvnic_reset_reason reason)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the init_done completion and return code values. We
|
||||
* can get a transport event just after registering the CRQ and the
|
||||
* tasklet will use this to communicate the transport event. To ensure
|
||||
* we don't miss the notification/error, initialize these _before_
|
||||
* regisering the CRQ.
|
||||
*/
|
||||
static inline void reinit_init_done(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
reinit_completion(&adapter->init_done);
|
||||
adapter->init_done_rc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* do_reset returns zero if we are able to keep processing reset events, or
|
||||
* non-zero if we hit a fatal error and must halt.
|
||||
@@ -2318,6 +2331,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
||||
*/
|
||||
adapter->state = VNIC_PROBED;
|
||||
|
||||
reinit_init_done(adapter);
|
||||
|
||||
if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM) {
|
||||
rc = init_crq_queue(adapter);
|
||||
} else if (adapter->reset_reason == VNIC_RESET_MOBILITY) {
|
||||
@@ -2461,7 +2476,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
|
||||
*/
|
||||
adapter->state = VNIC_PROBED;
|
||||
|
||||
reinit_completion(&adapter->init_done);
|
||||
reinit_init_done(adapter);
|
||||
|
||||
rc = init_crq_queue(adapter);
|
||||
if (rc) {
|
||||
netdev_err(adapter->netdev,
|
||||
@@ -2602,23 +2618,82 @@ out:
|
||||
static void __ibmvnic_reset(struct work_struct *work)
|
||||
{
|
||||
struct ibmvnic_adapter *adapter;
|
||||
bool saved_state = false;
|
||||
unsigned int timeout = 5000;
|
||||
struct ibmvnic_rwi *tmprwi;
|
||||
bool saved_state = false;
|
||||
struct ibmvnic_rwi *rwi;
|
||||
unsigned long flags;
|
||||
u32 reset_state;
|
||||
struct device *dev;
|
||||
bool need_reset;
|
||||
int num_fails = 0;
|
||||
u32 reset_state;
|
||||
int rc = 0;
|
||||
|
||||
adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
|
||||
dev = &adapter->vdev->dev;
|
||||
|
||||
if (test_and_set_bit_lock(0, &adapter->resetting)) {
|
||||
/* Wait for ibmvnic_probe() to complete. If probe is taking too long
|
||||
* or if another reset is in progress, defer work for now. If probe
|
||||
* eventually fails it will flush and terminate our work.
|
||||
*
|
||||
* Three possibilities here:
|
||||
* 1. Adpater being removed - just return
|
||||
* 2. Timed out on probe or another reset in progress - delay the work
|
||||
* 3. Completed probe - perform any resets in queue
|
||||
*/
|
||||
if (adapter->state == VNIC_PROBING &&
|
||||
!wait_for_completion_timeout(&adapter->probe_done, timeout)) {
|
||||
dev_err(dev, "Reset thread timed out on probe");
|
||||
queue_delayed_work(system_long_wq,
|
||||
&adapter->ibmvnic_delayed_reset,
|
||||
IBMVNIC_RESET_DELAY);
|
||||
return;
|
||||
}
|
||||
|
||||
/* adapter is done with probe (i.e state is never VNIC_PROBING now) */
|
||||
if (adapter->state == VNIC_REMOVING)
|
||||
return;
|
||||
|
||||
/* ->rwi_list is stable now (no one else is removing entries) */
|
||||
|
||||
/* ibmvnic_probe() may have purged the reset queue after we were
|
||||
* scheduled to process a reset so there maybe no resets to process.
|
||||
* Before setting the ->resetting bit though, we have to make sure
|
||||
* that there is infact a reset to process. Otherwise we may race
|
||||
* with ibmvnic_open() and end up leaving the vnic down:
|
||||
*
|
||||
* __ibmvnic_reset() ibmvnic_open()
|
||||
* ----------------- --------------
|
||||
*
|
||||
* set ->resetting bit
|
||||
* find ->resetting bit is set
|
||||
* set ->state to IBMVNIC_OPEN (i.e
|
||||
* assume reset will open device)
|
||||
* return
|
||||
* find reset queue empty
|
||||
* return
|
||||
*
|
||||
* Neither performed vnic login/open and vnic stays down
|
||||
*
|
||||
* If we hold the lock and conditionally set the bit, either we
|
||||
* or ibmvnic_open() will complete the open.
|
||||
*/
|
||||
need_reset = false;
|
||||
spin_lock(&adapter->rwi_lock);
|
||||
if (!list_empty(&adapter->rwi_list)) {
|
||||
if (test_and_set_bit_lock(0, &adapter->resetting)) {
|
||||
queue_delayed_work(system_long_wq,
|
||||
&adapter->ibmvnic_delayed_reset,
|
||||
IBMVNIC_RESET_DELAY);
|
||||
} else {
|
||||
need_reset = true;
|
||||
}
|
||||
}
|
||||
spin_unlock(&adapter->rwi_lock);
|
||||
|
||||
if (!need_reset)
|
||||
return;
|
||||
|
||||
rwi = get_next_rwi(adapter);
|
||||
while (rwi) {
|
||||
spin_lock_irqsave(&adapter->state_lock, flags);
|
||||
@@ -2735,12 +2810,23 @@ static void __ibmvnic_delayed_reset(struct work_struct *work)
|
||||
__ibmvnic_reset(&adapter->ibmvnic_reset);
|
||||
}
|
||||
|
||||
static void flush_reset_queue(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
struct list_head *entry, *tmp_entry;
|
||||
|
||||
if (!list_empty(&adapter->rwi_list)) {
|
||||
list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) {
|
||||
list_del(entry);
|
||||
kfree(list_entry(entry, struct ibmvnic_rwi, list));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
|
||||
enum ibmvnic_reset_reason reason)
|
||||
{
|
||||
struct list_head *entry, *tmp_entry;
|
||||
struct ibmvnic_rwi *rwi, *tmp;
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct ibmvnic_rwi *rwi, *tmp;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
@@ -2759,13 +2845,6 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (adapter->state == VNIC_PROBING) {
|
||||
netdev_warn(netdev, "Adapter reset during probe\n");
|
||||
adapter->init_done_rc = -EAGAIN;
|
||||
ret = EAGAIN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmp, &adapter->rwi_list, list) {
|
||||
if (tmp->reset_reason == reason) {
|
||||
netdev_dbg(netdev, "Skipping matching reset, reason=%s\n",
|
||||
@@ -2783,10 +2862,9 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
|
||||
/* if we just received a transport event,
|
||||
* flush reset queue and process this reset
|
||||
*/
|
||||
if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) {
|
||||
list_for_each_safe(entry, tmp_entry, &adapter->rwi_list)
|
||||
list_del(entry);
|
||||
}
|
||||
if (adapter->force_reset_recovery)
|
||||
flush_reset_queue(adapter);
|
||||
|
||||
rwi->reset_reason = reason;
|
||||
list_add_tail(&rwi->list, &adapter->rwi_list);
|
||||
netdev_dbg(adapter->netdev, "Scheduling reset (reason %s)\n",
|
||||
@@ -5321,9 +5399,9 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
||||
}
|
||||
|
||||
if (!completion_done(&adapter->init_done)) {
|
||||
complete(&adapter->init_done);
|
||||
if (!adapter->init_done_rc)
|
||||
adapter->init_done_rc = -EAGAIN;
|
||||
complete(&adapter->init_done);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -5346,6 +5424,13 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
||||
adapter->fw_done_rc = -EIO;
|
||||
complete(&adapter->fw_done);
|
||||
}
|
||||
|
||||
/* if we got here during crq-init, retry crq-init */
|
||||
if (!completion_done(&adapter->init_done)) {
|
||||
adapter->init_done_rc = -EAGAIN;
|
||||
complete(&adapter->init_done);
|
||||
}
|
||||
|
||||
if (!completion_done(&adapter->stats_done))
|
||||
complete(&adapter->stats_done);
|
||||
if (test_bit(0, &adapter->resetting))
|
||||
@@ -5662,10 +5747,6 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
|
||||
|
||||
adapter->from_passive_init = false;
|
||||
|
||||
if (reset)
|
||||
reinit_completion(&adapter->init_done);
|
||||
|
||||
adapter->init_done_rc = 0;
|
||||
rc = ibmvnic_send_crq_init(adapter);
|
||||
if (rc) {
|
||||
dev_err(dev, "Send crq init failed with error %d\n", rc);
|
||||
@@ -5679,12 +5760,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
|
||||
|
||||
if (adapter->init_done_rc) {
|
||||
release_crq_queue(adapter);
|
||||
dev_err(dev, "CRQ-init failed, %d\n", adapter->init_done_rc);
|
||||
return adapter->init_done_rc;
|
||||
}
|
||||
|
||||
if (adapter->from_passive_init) {
|
||||
adapter->state = VNIC_OPEN;
|
||||
adapter->from_passive_init = false;
|
||||
dev_err(dev, "CRQ-init failed, passive-init\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5724,6 +5807,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
struct ibmvnic_adapter *adapter;
|
||||
struct net_device *netdev;
|
||||
unsigned char *mac_addr_p;
|
||||
unsigned long flags;
|
||||
bool init_success;
|
||||
int rc;
|
||||
|
||||
@@ -5768,6 +5852,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
spin_lock_init(&adapter->rwi_lock);
|
||||
spin_lock_init(&adapter->state_lock);
|
||||
mutex_init(&adapter->fw_lock);
|
||||
init_completion(&adapter->probe_done);
|
||||
init_completion(&adapter->init_done);
|
||||
init_completion(&adapter->fw_done);
|
||||
init_completion(&adapter->reset_done);
|
||||
@@ -5778,6 +5863,33 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
|
||||
init_success = false;
|
||||
do {
|
||||
reinit_init_done(adapter);
|
||||
|
||||
/* clear any failovers we got in the previous pass
|
||||
* since we are reinitializing the CRQ
|
||||
*/
|
||||
adapter->failover_pending = false;
|
||||
|
||||
/* If we had already initialized CRQ, we may have one or
|
||||
* more resets queued already. Discard those and release
|
||||
* the CRQ before initializing the CRQ again.
|
||||
*/
|
||||
release_crq_queue(adapter);
|
||||
|
||||
/* Since we are still in PROBING state, __ibmvnic_reset()
|
||||
* will not access the ->rwi_list and since we released CRQ,
|
||||
* we won't get _new_ transport events. But there maybe an
|
||||
* ongoing ibmvnic_reset() call. So serialize access to
|
||||
* rwi_list. If we win the race, ibvmnic_reset() could add
|
||||
* a reset after we purged but thats ok - we just may end
|
||||
* up with an extra reset (i.e similar to having two or more
|
||||
* resets in the queue at once).
|
||||
* CHECK.
|
||||
*/
|
||||
spin_lock_irqsave(&adapter->rwi_lock, flags);
|
||||
flush_reset_queue(adapter);
|
||||
spin_unlock_irqrestore(&adapter->rwi_lock, flags);
|
||||
|
||||
rc = init_crq_queue(adapter);
|
||||
if (rc) {
|
||||
dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
|
||||
@@ -5809,12 +5921,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
goto ibmvnic_dev_file_err;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
rc = register_netdev(netdev);
|
||||
if (rc) {
|
||||
dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
|
||||
goto ibmvnic_register_fail;
|
||||
}
|
||||
dev_info(&dev->dev, "ibmvnic registered\n");
|
||||
|
||||
if (init_success) {
|
||||
adapter->state = VNIC_PROBED;
|
||||
@@ -5827,6 +5933,16 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
|
||||
adapter->wait_for_reset = false;
|
||||
adapter->last_reset_time = jiffies;
|
||||
|
||||
rc = register_netdev(netdev);
|
||||
if (rc) {
|
||||
dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
|
||||
goto ibmvnic_register_fail;
|
||||
}
|
||||
dev_info(&dev->dev, "ibmvnic registered\n");
|
||||
|
||||
complete(&adapter->probe_done);
|
||||
|
||||
return 0;
|
||||
|
||||
ibmvnic_register_fail:
|
||||
@@ -5841,6 +5957,17 @@ ibmvnic_stats_fail:
|
||||
ibmvnic_init_fail:
|
||||
release_sub_crqs(adapter, 1);
|
||||
release_crq_queue(adapter);
|
||||
|
||||
/* cleanup worker thread after releasing CRQ so we don't get
|
||||
* transport events (i.e new work items for the worker thread).
|
||||
*/
|
||||
adapter->state = VNIC_REMOVING;
|
||||
complete(&adapter->probe_done);
|
||||
flush_work(&adapter->ibmvnic_reset);
|
||||
flush_delayed_work(&adapter->ibmvnic_delayed_reset);
|
||||
|
||||
flush_reset_queue(adapter);
|
||||
|
||||
mutex_destroy(&adapter->fw_lock);
|
||||
free_netdev(netdev);
|
||||
|
||||
|
||||
@@ -930,6 +930,7 @@ struct ibmvnic_adapter {
|
||||
|
||||
struct ibmvnic_tx_pool *tx_pool;
|
||||
struct ibmvnic_tx_pool *tso_pool;
|
||||
struct completion probe_done;
|
||||
struct completion init_done;
|
||||
int init_done_rc;
|
||||
|
||||
|
||||
@@ -630,6 +630,7 @@ struct e1000_phy_info {
|
||||
bool disable_polarity_correction;
|
||||
bool is_mdix;
|
||||
bool polarity_correction;
|
||||
bool reset_disable;
|
||||
bool speed_downgraded;
|
||||
bool autoneg_wait_to_complete;
|
||||
};
|
||||
|
||||
@@ -2050,6 +2050,10 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
|
||||
bool blocked = false;
|
||||
int i = 0;
|
||||
|
||||
/* Check the PHY (LCD) reset flag */
|
||||
if (hw->phy.reset_disable)
|
||||
return true;
|
||||
|
||||
while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
|
||||
(i++ < 30))
|
||||
usleep_range(10000, 11000);
|
||||
@@ -4136,9 +4140,9 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
|
||||
if (!(data & valid_csum_mask)) {
|
||||
e_dbg("NVM Checksum Invalid\n");
|
||||
e_dbg("NVM Checksum valid bit not set\n");
|
||||
|
||||
if (hw->mac.type < e1000_pch_cnp) {
|
||||
if (hw->mac.type < e1000_pch_tgp) {
|
||||
data |= valid_csum_mask;
|
||||
ret_val = e1000_write_nvm(hw, word, 1, &data);
|
||||
if (ret_val)
|
||||
|
||||
@@ -271,6 +271,7 @@
|
||||
#define I217_CGFREG_ENABLE_MTA_RESET 0x0002
|
||||
#define I217_MEMPWR PHY_REG(772, 26)
|
||||
#define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
|
||||
#define I217_MEMPWR_MOEM 0x1000
|
||||
|
||||
/* Receive Address Initial CRC Calculation */
|
||||
#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
|
||||
|
||||
@@ -6987,8 +6987,21 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
|
||||
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u16 phy_data;
|
||||
int rc;
|
||||
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
|
||||
hw->mac.type >= e1000_pch_adp) {
|
||||
/* Mask OEM Bits / Gig Disable / Restart AN (772_26[12] = 1) */
|
||||
e1e_rphy(hw, I217_MEMPWR, &phy_data);
|
||||
phy_data |= I217_MEMPWR_MOEM;
|
||||
e1e_wphy(hw, I217_MEMPWR, phy_data);
|
||||
|
||||
/* Disable LCD reset */
|
||||
hw->phy.reset_disable = true;
|
||||
}
|
||||
|
||||
e1000e_flush_lpic(pdev);
|
||||
|
||||
e1000e_pm_freeze(dev);
|
||||
@@ -7010,6 +7023,8 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
|
||||
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u16 phy_data;
|
||||
int rc;
|
||||
|
||||
/* Introduce S0ix implementation */
|
||||
@@ -7020,6 +7035,17 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
|
||||
hw->mac.type >= e1000_pch_adp) {
|
||||
/* Unmask OEM Bits / Gig Disable / Restart AN 772_26[12] = 0 */
|
||||
e1e_rphy(hw, I217_MEMPWR, &phy_data);
|
||||
phy_data &= ~I217_MEMPWR_MOEM;
|
||||
e1e_wphy(hw, I217_MEMPWR, phy_data);
|
||||
|
||||
/* Enable LCD reset */
|
||||
hw->phy.reset_disable = false;
|
||||
}
|
||||
|
||||
return e1000e_pm_thaw(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,10 @@ enum iavf_state_t {
|
||||
__IAVF_RUNNING, /* opened, working */
|
||||
};
|
||||
|
||||
enum iavf_critical_section_t {
|
||||
__IAVF_IN_REMOVE_TASK, /* device being removed */
|
||||
};
|
||||
|
||||
#define IAVF_CLOUD_FIELD_OMAC 0x01
|
||||
#define IAVF_CLOUD_FIELD_IMAC 0x02
|
||||
#define IAVF_CLOUD_FIELD_IVLAN 0x04
|
||||
@@ -246,7 +250,6 @@ struct iavf_adapter {
|
||||
struct list_head mac_filter_list;
|
||||
struct mutex crit_lock;
|
||||
struct mutex client_lock;
|
||||
struct mutex remove_lock;
|
||||
/* Lock to protect accesses to MAC and VLAN lists */
|
||||
spinlock_t mac_vlan_list_lock;
|
||||
char misc_vector_name[IFNAMSIZ + 9];
|
||||
@@ -284,6 +287,7 @@ struct iavf_adapter {
|
||||
#define IAVF_FLAG_LEGACY_RX BIT(15)
|
||||
#define IAVF_FLAG_REINIT_ITR_NEEDED BIT(16)
|
||||
#define IAVF_FLAG_QUEUES_DISABLED BIT(17)
|
||||
#define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18)
|
||||
/* duplicates for common code */
|
||||
#define IAVF_FLAG_DCB_ENABLED 0
|
||||
/* flags for admin queue service task */
|
||||
|
||||
@@ -302,8 +302,9 @@ static irqreturn_t iavf_msix_aq(int irq, void *data)
|
||||
rd32(hw, IAVF_VFINT_ICR01);
|
||||
rd32(hw, IAVF_VFINT_ICR0_ENA1);
|
||||
|
||||
/* schedule work on the private workqueue */
|
||||
queue_work(iavf_wq, &adapter->adminq_task);
|
||||
if (adapter->state != __IAVF_REMOVE)
|
||||
/* schedule work on the private workqueue */
|
||||
queue_work(iavf_wq, &adapter->adminq_task);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -1136,8 +1137,7 @@ void iavf_down(struct iavf_adapter *adapter)
|
||||
rss->state = IAVF_ADV_RSS_DEL_REQUEST;
|
||||
spin_unlock_bh(&adapter->adv_rss_lock);
|
||||
|
||||
if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) &&
|
||||
adapter->state != __IAVF_RESETTING) {
|
||||
if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
|
||||
/* cancel any current operation */
|
||||
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
||||
/* Schedule operations to close down the HW. Don't wait
|
||||
@@ -2374,17 +2374,22 @@ static void iavf_watchdog_task(struct work_struct *work)
|
||||
struct iavf_hw *hw = &adapter->hw;
|
||||
u32 reg_val;
|
||||
|
||||
if (!mutex_trylock(&adapter->crit_lock))
|
||||
if (!mutex_trylock(&adapter->crit_lock)) {
|
||||
if (adapter->state == __IAVF_REMOVE)
|
||||
return;
|
||||
|
||||
goto restart_watchdog;
|
||||
}
|
||||
|
||||
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
|
||||
iavf_change_state(adapter, __IAVF_COMM_FAILED);
|
||||
|
||||
if (adapter->flags & IAVF_FLAG_RESET_NEEDED &&
|
||||
adapter->state != __IAVF_RESETTING) {
|
||||
iavf_change_state(adapter, __IAVF_RESETTING);
|
||||
if (adapter->flags & IAVF_FLAG_RESET_NEEDED) {
|
||||
adapter->aq_required = 0;
|
||||
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
queue_work(iavf_wq, &adapter->reset_task);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (adapter->state) {
|
||||
@@ -2419,6 +2424,15 @@ static void iavf_watchdog_task(struct work_struct *work)
|
||||
msecs_to_jiffies(1));
|
||||
return;
|
||||
case __IAVF_INIT_FAILED:
|
||||
if (test_bit(__IAVF_IN_REMOVE_TASK,
|
||||
&adapter->crit_section)) {
|
||||
/* Do not update the state and do not reschedule
|
||||
* watchdog task, iavf_remove should handle this state
|
||||
* as it can loop forever
|
||||
*/
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return;
|
||||
}
|
||||
if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
|
||||
dev_err(&adapter->pdev->dev,
|
||||
"Failed to communicate with PF; waiting before retry\n");
|
||||
@@ -2435,6 +2449,17 @@ static void iavf_watchdog_task(struct work_struct *work)
|
||||
queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ);
|
||||
return;
|
||||
case __IAVF_COMM_FAILED:
|
||||
if (test_bit(__IAVF_IN_REMOVE_TASK,
|
||||
&adapter->crit_section)) {
|
||||
/* Set state to __IAVF_INIT_FAILED and perform remove
|
||||
* steps. Remove IAVF_FLAG_PF_COMMS_FAILED so the task
|
||||
* doesn't bring the state back to __IAVF_COMM_FAILED.
|
||||
*/
|
||||
iavf_change_state(adapter, __IAVF_INIT_FAILED);
|
||||
adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return;
|
||||
}
|
||||
reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
|
||||
IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
|
||||
if (reg_val == VIRTCHNL_VFR_VFACTIVE ||
|
||||
@@ -2507,7 +2532,8 @@ static void iavf_watchdog_task(struct work_struct *work)
|
||||
schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5));
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
restart_watchdog:
|
||||
queue_work(iavf_wq, &adapter->adminq_task);
|
||||
if (adapter->state >= __IAVF_DOWN)
|
||||
queue_work(iavf_wq, &adapter->adminq_task);
|
||||
if (adapter->aq_required)
|
||||
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
||||
msecs_to_jiffies(20));
|
||||
@@ -2601,13 +2627,13 @@ static void iavf_reset_task(struct work_struct *work)
|
||||
/* When device is being removed it doesn't make sense to run the reset
|
||||
* task, just return in such a case.
|
||||
*/
|
||||
if (mutex_is_locked(&adapter->remove_lock))
|
||||
return;
|
||||
if (!mutex_trylock(&adapter->crit_lock)) {
|
||||
if (adapter->state != __IAVF_REMOVE)
|
||||
queue_work(iavf_wq, &adapter->reset_task);
|
||||
|
||||
if (iavf_lock_timeout(&adapter->crit_lock, 200)) {
|
||||
schedule_work(&adapter->reset_task);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!mutex_trylock(&adapter->client_lock))
|
||||
usleep_range(500, 1000);
|
||||
if (CLIENT_ENABLED(adapter)) {
|
||||
@@ -2662,6 +2688,7 @@ static void iavf_reset_task(struct work_struct *work)
|
||||
reg_val);
|
||||
iavf_disable_vf(adapter);
|
||||
mutex_unlock(&adapter->client_lock);
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return; /* Do not attempt to reinit. It's dead, Jim. */
|
||||
}
|
||||
|
||||
@@ -2670,8 +2697,7 @@ continue_reset:
|
||||
* ndo_open() returning, so we can't assume it means all our open
|
||||
* tasks have finished, since we're not holding the rtnl_lock here.
|
||||
*/
|
||||
running = ((adapter->state == __IAVF_RUNNING) ||
|
||||
(adapter->state == __IAVF_RESETTING));
|
||||
running = adapter->state == __IAVF_RUNNING;
|
||||
|
||||
if (running) {
|
||||
netdev->flags &= ~IFF_UP;
|
||||
@@ -2826,13 +2852,19 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
|
||||
goto out;
|
||||
|
||||
if (!mutex_trylock(&adapter->crit_lock)) {
|
||||
if (adapter->state == __IAVF_REMOVE)
|
||||
return;
|
||||
|
||||
queue_work(iavf_wq, &adapter->adminq_task);
|
||||
goto out;
|
||||
}
|
||||
|
||||
event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
|
||||
event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
|
||||
if (!event.msg_buf)
|
||||
goto out;
|
||||
|
||||
if (iavf_lock_timeout(&adapter->crit_lock, 200))
|
||||
goto freedom;
|
||||
do {
|
||||
ret = iavf_clean_arq_element(hw, &event, &pending);
|
||||
v_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
|
||||
@@ -2848,6 +2880,24 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
} while (pending);
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
|
||||
if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) {
|
||||
if (adapter->netdev_registered ||
|
||||
!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) {
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
|
||||
rtnl_lock();
|
||||
netdev_update_features(netdev);
|
||||
rtnl_unlock();
|
||||
/* Request VLAN offload settings */
|
||||
if (VLAN_V2_ALLOWED(adapter))
|
||||
iavf_set_vlan_offload_features
|
||||
(adapter, 0, netdev->features);
|
||||
|
||||
iavf_set_queue_vlan_tag_loc(adapter);
|
||||
}
|
||||
|
||||
adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES;
|
||||
}
|
||||
if ((adapter->flags &
|
||||
(IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) ||
|
||||
adapter->state == __IAVF_RESETTING)
|
||||
@@ -3800,11 +3850,12 @@ static int iavf_close(struct net_device *netdev)
|
||||
struct iavf_adapter *adapter = netdev_priv(netdev);
|
||||
int status;
|
||||
|
||||
if (adapter->state <= __IAVF_DOWN_PENDING)
|
||||
return 0;
|
||||
mutex_lock(&adapter->crit_lock);
|
||||
|
||||
while (!mutex_trylock(&adapter->crit_lock))
|
||||
usleep_range(500, 1000);
|
||||
if (adapter->state <= __IAVF_DOWN_PENDING) {
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
|
||||
if (CLIENT_ENABLED(adapter))
|
||||
@@ -3853,8 +3904,11 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
iavf_notify_client_l2_params(&adapter->vsi);
|
||||
adapter->flags |= IAVF_FLAG_SERVICE_CLIENT_REQUESTED;
|
||||
}
|
||||
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
||||
queue_work(iavf_wq, &adapter->reset_task);
|
||||
|
||||
if (netif_running(netdev)) {
|
||||
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
||||
queue_work(iavf_wq, &adapter->reset_task);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4431,7 +4485,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
*/
|
||||
mutex_init(&adapter->crit_lock);
|
||||
mutex_init(&adapter->client_lock);
|
||||
mutex_init(&adapter->remove_lock);
|
||||
mutex_init(&hw->aq.asq_mutex);
|
||||
mutex_init(&hw->aq.arq_mutex);
|
||||
|
||||
@@ -4547,7 +4600,6 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
|
||||
static void iavf_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
|
||||
enum iavf_state_t prev_state = adapter->last_state;
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct iavf_fdir_fltr *fdir, *fdirtmp;
|
||||
struct iavf_vlan_filter *vlf, *vlftmp;
|
||||
@@ -4556,14 +4608,30 @@ static void iavf_remove(struct pci_dev *pdev)
|
||||
struct iavf_cloud_filter *cf, *cftmp;
|
||||
struct iavf_hw *hw = &adapter->hw;
|
||||
int err;
|
||||
/* Indicate we are in remove and not to run reset_task */
|
||||
mutex_lock(&adapter->remove_lock);
|
||||
cancel_work_sync(&adapter->reset_task);
|
||||
|
||||
set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
|
||||
/* Wait until port initialization is complete.
|
||||
* There are flows where register/unregister netdev may race.
|
||||
*/
|
||||
while (1) {
|
||||
mutex_lock(&adapter->crit_lock);
|
||||
if (adapter->state == __IAVF_RUNNING ||
|
||||
adapter->state == __IAVF_DOWN ||
|
||||
adapter->state == __IAVF_INIT_FAILED) {
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
usleep_range(500, 1000);
|
||||
}
|
||||
cancel_delayed_work_sync(&adapter->watchdog_task);
|
||||
cancel_delayed_work_sync(&adapter->client_task);
|
||||
|
||||
if (adapter->netdev_registered) {
|
||||
unregister_netdev(netdev);
|
||||
rtnl_lock();
|
||||
unregister_netdevice(netdev);
|
||||
adapter->netdev_registered = false;
|
||||
rtnl_unlock();
|
||||
}
|
||||
if (CLIENT_ALLOWED(adapter)) {
|
||||
err = iavf_lan_del_device(adapter);
|
||||
@@ -4572,6 +4640,10 @@ static void iavf_remove(struct pci_dev *pdev)
|
||||
err);
|
||||
}
|
||||
|
||||
mutex_lock(&adapter->crit_lock);
|
||||
dev_info(&adapter->pdev->dev, "Remove device\n");
|
||||
iavf_change_state(adapter, __IAVF_REMOVE);
|
||||
|
||||
iavf_request_reset(adapter);
|
||||
msleep(50);
|
||||
/* If the FW isn't responding, kick it once, but only once. */
|
||||
@@ -4579,37 +4651,24 @@ static void iavf_remove(struct pci_dev *pdev)
|
||||
iavf_request_reset(adapter);
|
||||
msleep(50);
|
||||
}
|
||||
if (iavf_lock_timeout(&adapter->crit_lock, 5000))
|
||||
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
|
||||
|
||||
dev_info(&adapter->pdev->dev, "Removing device\n");
|
||||
iavf_misc_irq_disable(adapter);
|
||||
/* Shut down all the garbage mashers on the detention level */
|
||||
iavf_change_state(adapter, __IAVF_REMOVE);
|
||||
cancel_work_sync(&adapter->reset_task);
|
||||
cancel_delayed_work_sync(&adapter->watchdog_task);
|
||||
cancel_work_sync(&adapter->adminq_task);
|
||||
cancel_delayed_work_sync(&adapter->client_task);
|
||||
|
||||
adapter->aq_required = 0;
|
||||
adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
|
||||
|
||||
iavf_free_all_tx_resources(adapter);
|
||||
iavf_free_all_rx_resources(adapter);
|
||||
iavf_misc_irq_disable(adapter);
|
||||
iavf_free_misc_irq(adapter);
|
||||
|
||||
/* In case we enter iavf_remove from erroneous state, free traffic irqs
|
||||
* here, so as to not cause a kernel crash, when calling
|
||||
* iavf_reset_interrupt_capability.
|
||||
*/
|
||||
if ((adapter->last_state == __IAVF_RESETTING &&
|
||||
prev_state != __IAVF_DOWN) ||
|
||||
(adapter->last_state == __IAVF_RUNNING &&
|
||||
!(netdev->flags & IFF_UP)))
|
||||
iavf_free_traffic_irqs(adapter);
|
||||
|
||||
iavf_reset_interrupt_capability(adapter);
|
||||
iavf_free_q_vectors(adapter);
|
||||
|
||||
cancel_delayed_work_sync(&adapter->watchdog_task);
|
||||
|
||||
cancel_work_sync(&adapter->adminq_task);
|
||||
|
||||
iavf_free_rss(adapter);
|
||||
|
||||
if (hw->aq.asq.count)
|
||||
@@ -4621,8 +4680,6 @@ static void iavf_remove(struct pci_dev *pdev)
|
||||
mutex_destroy(&adapter->client_lock);
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
mutex_destroy(&adapter->crit_lock);
|
||||
mutex_unlock(&adapter->remove_lock);
|
||||
mutex_destroy(&adapter->remove_lock);
|
||||
|
||||
iounmap(hw->hw_addr);
|
||||
pci_release_regions(pdev);
|
||||
|
||||
@@ -2146,29 +2146,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
|
||||
sizeof(adapter->vlan_v2_caps)));
|
||||
|
||||
iavf_process_config(adapter);
|
||||
|
||||
/* unlock crit_lock before acquiring rtnl_lock as other
|
||||
* processes holding rtnl_lock could be waiting for the same
|
||||
* crit_lock
|
||||
*/
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
/* VLAN capabilities can change during VFR, so make sure to
|
||||
* update the netdev features with the new capabilities
|
||||
*/
|
||||
rtnl_lock();
|
||||
netdev_update_features(netdev);
|
||||
rtnl_unlock();
|
||||
if (iavf_lock_timeout(&adapter->crit_lock, 10000))
|
||||
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
|
||||
__FUNCTION__);
|
||||
|
||||
/* Request VLAN offload settings */
|
||||
if (VLAN_V2_ALLOWED(adapter))
|
||||
iavf_set_vlan_offload_features(adapter, 0,
|
||||
netdev->features);
|
||||
|
||||
iavf_set_queue_vlan_tag_loc(adapter);
|
||||
|
||||
adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES;
|
||||
}
|
||||
break;
|
||||
case VIRTCHNL_OP_ENABLE_QUEUES:
|
||||
|
||||
@@ -746,8 +746,6 @@ s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = igc_write_phy_reg_mdic(hw, offset, data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
hw->phy.ops.release(hw);
|
||||
} else {
|
||||
ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
|
||||
@@ -779,8 +777,6 @@ s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = igc_read_phy_reg_mdic(hw, offset, data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
hw->phy.ops.release(hw);
|
||||
} else {
|
||||
ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
|
||||
|
||||
@@ -390,12 +390,14 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget)
|
||||
u32 cmd_type;
|
||||
|
||||
while (budget-- > 0) {
|
||||
if (unlikely(!ixgbe_desc_unused(xdp_ring)) ||
|
||||
!netif_carrier_ok(xdp_ring->netdev)) {
|
||||
if (unlikely(!ixgbe_desc_unused(xdp_ring))) {
|
||||
work_done = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!netif_carrier_ok(xdp_ring->netdev))
|
||||
break;
|
||||
|
||||
if (!xsk_tx_peek_desc(pool, &desc))
|
||||
break;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/hrtimer.h>
|
||||
|
||||
#include "sparx5_main_regs.h"
|
||||
|
||||
/* Target chip type */
|
||||
enum spx5_target_chiptype {
|
||||
SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */
|
||||
|
||||
@@ -58,16 +58,6 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
int ret;
|
||||
|
||||
/* Make the port a member of the VLAN */
|
||||
set_bit(port->portno, sparx5->vlan_mask[vid]);
|
||||
ret = sparx5_vlant_set_mask(sparx5, vid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Default ingress vlan classification */
|
||||
if (pvid)
|
||||
port->pvid = vid;
|
||||
|
||||
/* Untagged egress vlan classification */
|
||||
if (untagged && port->vid != vid) {
|
||||
if (port->vid) {
|
||||
@@ -79,6 +69,16 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
|
||||
port->vid = vid;
|
||||
}
|
||||
|
||||
/* Make the port a member of the VLAN */
|
||||
set_bit(port->portno, sparx5->vlan_mask[vid]);
|
||||
ret = sparx5_vlant_set_mask(sparx5, vid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Default ingress vlan classification */
|
||||
if (pvid)
|
||||
port->pvid = vid;
|
||||
|
||||
sparx5_vlan_port_apply(sparx5, port);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2285,18 +2285,18 @@ static int __init sxgbe_cmdline_opt(char *str)
|
||||
char *opt;
|
||||
|
||||
if (!str || !*str)
|
||||
return -EINVAL;
|
||||
return 1;
|
||||
while ((opt = strsep(&str, ",")) != NULL) {
|
||||
if (!strncmp(opt, "eee_timer:", 10)) {
|
||||
if (kstrtoint(opt + 10, 0, &eee_timer))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
pr_err("%s: ERROR broken module parameter conversion\n", __func__);
|
||||
return -EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("sxgbeeth=", sxgbe_cmdline_opt);
|
||||
|
||||
@@ -163,9 +163,9 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
|
||||
/* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
|
||||
spin_lock_bh(&mcdi->iface_lock);
|
||||
++mcdi->seqno;
|
||||
seqno = mcdi->seqno & SEQ_MASK;
|
||||
spin_unlock_bh(&mcdi->iface_lock);
|
||||
|
||||
seqno = mcdi->seqno & SEQ_MASK;
|
||||
xflags = 0;
|
||||
if (mcdi->mode == MCDI_MODE_EVENTS)
|
||||
xflags |= MCDI_HEADER_XFLAGS_EVREQ;
|
||||
|
||||
@@ -2262,6 +2262,23 @@ static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan)
|
||||
stmmac_stop_tx(priv, priv->ioaddr, chan);
|
||||
}
|
||||
|
||||
static void stmmac_enable_all_dma_irq(struct stmmac_priv *priv)
|
||||
{
|
||||
u32 rx_channels_count = priv->plat->rx_queues_to_use;
|
||||
u32 tx_channels_count = priv->plat->tx_queues_to_use;
|
||||
u32 dma_csr_ch = max(rx_channels_count, tx_channels_count);
|
||||
u32 chan;
|
||||
|
||||
for (chan = 0; chan < dma_csr_ch; chan++) {
|
||||
struct stmmac_channel *ch = &priv->channel[chan];
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ch->lock, flags);
|
||||
stmmac_enable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
|
||||
spin_unlock_irqrestore(&ch->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_start_all_dma - start all RX and TX DMA channels
|
||||
* @priv: driver private structure
|
||||
@@ -2904,8 +2921,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
|
||||
stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
|
||||
|
||||
/* DMA CSR Channel configuration */
|
||||
for (chan = 0; chan < dma_csr_ch; chan++)
|
||||
for (chan = 0; chan < dma_csr_ch; chan++) {
|
||||
stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
|
||||
stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
|
||||
}
|
||||
|
||||
/* DMA RX Channel Configuration */
|
||||
for (chan = 0; chan < rx_channels_count; chan++) {
|
||||
@@ -3761,6 +3780,7 @@ static int stmmac_open(struct net_device *dev)
|
||||
|
||||
stmmac_enable_all_queues(priv);
|
||||
netif_tx_start_all_queues(priv->dev);
|
||||
stmmac_enable_all_dma_irq(priv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -6510,8 +6530,10 @@ int stmmac_xdp_open(struct net_device *dev)
|
||||
}
|
||||
|
||||
/* DMA CSR Channel configuration */
|
||||
for (chan = 0; chan < dma_csr_ch; chan++)
|
||||
for (chan = 0; chan < dma_csr_ch; chan++) {
|
||||
stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
|
||||
stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
|
||||
}
|
||||
|
||||
/* Adjust Split header */
|
||||
sph_en = (priv->hw->rx_csum > 0) && priv->sph;
|
||||
@@ -6572,6 +6594,7 @@ int stmmac_xdp_open(struct net_device *dev)
|
||||
stmmac_enable_all_queues(priv);
|
||||
netif_carrier_on(dev);
|
||||
netif_tx_start_all_queues(dev);
|
||||
stmmac_enable_all_dma_irq(priv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -7451,6 +7474,7 @@ int stmmac_resume(struct device *dev)
|
||||
stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
|
||||
|
||||
stmmac_enable_all_queues(priv);
|
||||
stmmac_enable_all_dma_irq(priv);
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
rtnl_unlock();
|
||||
@@ -7467,7 +7491,7 @@ static int __init stmmac_cmdline_opt(char *str)
|
||||
char *opt;
|
||||
|
||||
if (!str || !*str)
|
||||
return -EINVAL;
|
||||
return 1;
|
||||
while ((opt = strsep(&str, ",")) != NULL) {
|
||||
if (!strncmp(opt, "debug:", 6)) {
|
||||
if (kstrtoint(opt + 6, 0, &debug))
|
||||
@@ -7498,11 +7522,11 @@ static int __init stmmac_cmdline_opt(char *str)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
pr_err("%s: ERROR broken module parameter conversion", __func__);
|
||||
return -EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("stmmaceth=", stmmac_cmdline_opt);
|
||||
|
||||
@@ -2,7 +2,9 @@ config QCOM_IPA
|
||||
tristate "Qualcomm IPA support"
|
||||
depends on NET && QCOM_SMEM
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on INTERCONNECT
|
||||
depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
|
||||
depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
|
||||
select QCOM_MDT_LOADER if ARCH_QCOM
|
||||
select QCOM_SCM
|
||||
select QCOM_QMI_HELPERS
|
||||
|
||||
@@ -5,3 +5,4 @@ obj-$(CONFIG_IPW2200) += ipw2x00/
|
||||
obj-$(CONFIG_IWLEGACY) += iwlegacy/
|
||||
|
||||
obj-$(CONFIG_IWLWIFI) += iwlwifi/
|
||||
obj-$(CONFIG_IWLMEI) += iwlwifi/
|
||||
|
||||
@@ -553,8 +553,7 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
|
||||
.has_he = true,
|
||||
.he_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE |
|
||||
IEEE80211_HE_MAC_CAP0_TWT_REQ,
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE,
|
||||
.mac_cap_info[1] =
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
|
||||
IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
@@ -1857,7 +1858,6 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
|
||||
void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct dentry *bcast_dir __maybe_unused;
|
||||
char buf[100];
|
||||
|
||||
spin_lock_init(&mvm->drv_stats_lock);
|
||||
|
||||
@@ -1939,6 +1939,11 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
|
||||
* Create a symlink with mac80211. It will be removed when mac80211
|
||||
* exists (before the opmode exists which removes the target.)
|
||||
*/
|
||||
snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent);
|
||||
debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
|
||||
if (!IS_ERR(mvm->debugfs_dir)) {
|
||||
char buf[100];
|
||||
|
||||
snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent);
|
||||
debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir,
|
||||
buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,6 @@ static const u8 he_if_types_ext_capa_sta[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
|
||||
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
|
||||
};
|
||||
|
||||
static const struct wiphy_iftype_ext_capab he_iftypes_ext_capa[] = {
|
||||
|
||||
@@ -71,12 +71,13 @@ static int iwl_mvm_vendor_host_get_ownership(struct wiphy *wiphy,
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_mvm_mei_get_ownership(mvm);
|
||||
ret = iwl_mvm_mei_get_ownership(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct wiphy_vendor_command iwl_mvm_vendor_commands[] = {
|
||||
|
||||
@@ -842,6 +842,28 @@ static int xennet_close(struct net_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xennet_destroy_queues(struct netfront_info *info)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
|
||||
struct netfront_queue *queue = &info->queues[i];
|
||||
|
||||
if (netif_running(info->netdev))
|
||||
napi_disable(&queue->napi);
|
||||
netif_napi_del(&queue->napi);
|
||||
}
|
||||
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
}
|
||||
|
||||
static void xennet_uninit(struct net_device *dev)
|
||||
{
|
||||
struct netfront_info *np = netdev_priv(dev);
|
||||
xennet_destroy_queues(np);
|
||||
}
|
||||
|
||||
static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -1611,6 +1633,7 @@ static int xennet_xdp(struct net_device *dev, struct netdev_bpf *xdp)
|
||||
}
|
||||
|
||||
static const struct net_device_ops xennet_netdev_ops = {
|
||||
.ndo_uninit = xennet_uninit,
|
||||
.ndo_open = xennet_open,
|
||||
.ndo_stop = xennet_close,
|
||||
.ndo_start_xmit = xennet_start_xmit,
|
||||
@@ -2103,22 +2126,6 @@ error:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void xennet_destroy_queues(struct netfront_info *info)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
|
||||
struct netfront_queue *queue = &info->queues[i];
|
||||
|
||||
if (netif_running(info->netdev))
|
||||
napi_disable(&queue->napi);
|
||||
netif_napi_del(&queue->napi);
|
||||
}
|
||||
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int xennet_create_page_pool(struct netfront_queue *queue)
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
#include "../core.h"
|
||||
#include "pinctrl-sunxi.h"
|
||||
|
||||
/*
|
||||
* These lock classes tell lockdep that GPIO IRQs are in a different
|
||||
* category than their parents, so it won't report false recursion.
|
||||
*/
|
||||
static struct lock_class_key sunxi_pinctrl_irq_lock_class;
|
||||
static struct lock_class_key sunxi_pinctrl_irq_request_class;
|
||||
|
||||
static struct irq_chip sunxi_pinctrl_edge_irq_chip;
|
||||
static struct irq_chip sunxi_pinctrl_level_irq_chip;
|
||||
|
||||
@@ -837,7 +844,8 @@ static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
|
||||
|
||||
return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, offset, true);
|
||||
return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL,
|
||||
chip->base + offset, true);
|
||||
}
|
||||
|
||||
static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
@@ -890,7 +898,8 @@ static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
|
||||
struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
|
||||
|
||||
sunxi_pinctrl_gpio_set(chip, offset, value);
|
||||
return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, offset, false);
|
||||
return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL,
|
||||
chip->base + offset, false);
|
||||
}
|
||||
|
||||
static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
|
||||
@@ -1555,6 +1564,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
|
||||
for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
|
||||
int irqno = irq_create_mapping(pctl->domain, i);
|
||||
|
||||
irq_set_lockdep_class(irqno, &sunxi_pinctrl_irq_lock_class,
|
||||
&sunxi_pinctrl_irq_request_class);
|
||||
irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
|
||||
handle_edge_irq);
|
||||
irq_set_chip_data(irqno, pctl);
|
||||
|
||||
@@ -607,7 +607,7 @@ ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
|
||||
}
|
||||
|
||||
static void
|
||||
__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
|
||||
__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u32 adj_val)
|
||||
{
|
||||
u32 select, ctrl;
|
||||
|
||||
@@ -615,7 +615,7 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
|
||||
iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select);
|
||||
|
||||
iowrite32(adj_val, &bp->reg->offset_ns);
|
||||
iowrite32(adj_val & 0x7f, &bp->reg->offset_window_ns);
|
||||
iowrite32(NSEC_PER_SEC, &bp->reg->offset_window_ns);
|
||||
|
||||
ctrl = OCP_CTRL_ADJUST_OFFSET | OCP_CTRL_ENABLE;
|
||||
iowrite32(ctrl, &bp->reg->ctrl);
|
||||
@@ -624,6 +624,22 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
|
||||
iowrite32(select >> 16, &bp->reg->select);
|
||||
}
|
||||
|
||||
static void
|
||||
ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
|
||||
spin_lock_irqsave(&bp->lock, flags);
|
||||
err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
|
||||
if (likely(!err)) {
|
||||
timespec64_add_ns(&ts, delta_ns);
|
||||
__ptp_ocp_settime_locked(bp, &ts);
|
||||
}
|
||||
spin_unlock_irqrestore(&bp->lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
|
||||
{
|
||||
@@ -631,6 +647,11 @@ ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
|
||||
unsigned long flags;
|
||||
u32 adj_ns, sign;
|
||||
|
||||
if (delta_ns > NSEC_PER_SEC || -delta_ns > NSEC_PER_SEC) {
|
||||
ptp_ocp_adjtime_coarse(bp, delta_ns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sign = delta_ns < 0 ? BIT(31) : 0;
|
||||
adj_ns = sign ? -delta_ns : delta_ns;
|
||||
|
||||
|
||||
@@ -419,11 +419,12 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
|
||||
for (i = 0; i < tz->trips; i++) {
|
||||
|
||||
enum thermal_trip_type type;
|
||||
int temp, hyst;
|
||||
int temp, hyst = 0;
|
||||
|
||||
tz->ops->get_trip_type(tz, i, &type);
|
||||
tz->ops->get_trip_temp(tz, i, &temp);
|
||||
tz->ops->get_trip_hyst(tz, i, &hyst);
|
||||
if (tz->ops->get_trip_hyst)
|
||||
tz->ops->get_trip_hyst(tz, i, &hyst);
|
||||
|
||||
if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) ||
|
||||
|
||||
@@ -254,7 +254,7 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object,
|
||||
ret = cachefiles_inject_write_error();
|
||||
if (ret == 0)
|
||||
ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE,
|
||||
new_size, dio_size);
|
||||
new_size, dio_size - new_size);
|
||||
if (ret < 0) {
|
||||
trace_cachefiles_io_error(object, file_inode(file), ret,
|
||||
cachefiles_trace_fallocate_error);
|
||||
|
||||
@@ -101,7 +101,11 @@ static inline struct sk_buff *nf_hook_egress(struct sk_buff *skb, int *rc,
|
||||
nf_hook_state_init(&state, NF_NETDEV_EGRESS,
|
||||
NFPROTO_NETDEV, dev, NULL, NULL,
|
||||
dev_net(dev), NULL);
|
||||
|
||||
/* nf assumes rcu_read_lock, not just read_lock_bh */
|
||||
rcu_read_lock();
|
||||
ret = nf_hook_slow(skb, &state, e, 0);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ret == 1) {
|
||||
return skb;
|
||||
|
||||
@@ -308,6 +308,11 @@ static inline bool rfkill_blocked(struct rfkill *rfkill)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool rfkill_soft_blocked(struct rfkill *rfkill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline enum rfkill_type rfkill_find_type(const char *name)
|
||||
{
|
||||
return RFKILL_TYPE_ALL;
|
||||
|
||||
@@ -506,8 +506,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
|
||||
|
||||
tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
|
||||
if (IS_ERR(tmp)) {
|
||||
kfree_skb(skb);
|
||||
return tmp;
|
||||
return skb;
|
||||
}
|
||||
|
||||
len -= tmp->len;
|
||||
|
||||
@@ -1489,6 +1489,14 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
/* Extended advertising support */
|
||||
#define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
|
||||
|
||||
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 1789:
|
||||
*
|
||||
* C24: Mandatory if the LE Controller supports Connection State and either
|
||||
* LE Feature (LL Privacy) or LE Feature (Extended Advertising) is supported
|
||||
*/
|
||||
#define use_enhanced_conn_complete(dev) (ll_privacy_capable(dev) || \
|
||||
ext_adv_capable(dev))
|
||||
|
||||
/* ----- HCI protocols ----- */
|
||||
#define HCI_PROTO_DEFER 0x01
|
||||
|
||||
|
||||
@@ -475,9 +475,9 @@ int igmp6_late_init(void);
|
||||
void igmp6_cleanup(void);
|
||||
void igmp6_late_cleanup(void);
|
||||
|
||||
int igmp6_event_query(struct sk_buff *skb);
|
||||
void igmp6_event_query(struct sk_buff *skb);
|
||||
|
||||
int igmp6_event_report(struct sk_buff *skb);
|
||||
void igmp6_event_report(struct sk_buff *skb);
|
||||
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
||||
@@ -96,6 +96,7 @@ enum flow_offload_xmit_type {
|
||||
FLOW_OFFLOAD_XMIT_NEIGH,
|
||||
FLOW_OFFLOAD_XMIT_XFRM,
|
||||
FLOW_OFFLOAD_XMIT_DIRECT,
|
||||
FLOW_OFFLOAD_XMIT_TC,
|
||||
};
|
||||
|
||||
#define NF_FLOW_TABLE_ENCAP_MAX 2
|
||||
@@ -127,7 +128,7 @@ struct flow_offload_tuple {
|
||||
struct { } __hash;
|
||||
|
||||
u8 dir:2,
|
||||
xmit_type:2,
|
||||
xmit_type:3,
|
||||
encap_num:2,
|
||||
in_vlan_ingress:2;
|
||||
u16 mtu;
|
||||
@@ -142,6 +143,9 @@ struct flow_offload_tuple {
|
||||
u8 h_source[ETH_ALEN];
|
||||
u8 h_dest[ETH_ALEN];
|
||||
} out;
|
||||
struct {
|
||||
u32 iifidx;
|
||||
} tc;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(void);
|
||||
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
|
||||
|
||||
void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
||||
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
||||
void nf_queue_entry_free(struct nf_queue_entry *entry);
|
||||
|
||||
static inline void init_hashrandom(u32 *jhash_initval)
|
||||
|
||||
@@ -1568,7 +1568,6 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
|
||||
void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
|
||||
u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
|
||||
int xfrm_init_replay(struct xfrm_state *x);
|
||||
u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
||||
u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
||||
int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
|
||||
int xfrm_init_state(struct xfrm_state *x);
|
||||
@@ -1679,14 +1678,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_bundles,
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap);
|
||||
struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
|
||||
struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
|
||||
u32 if_id);
|
||||
struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
|
||||
struct xfrm_migrate *m,
|
||||
struct xfrm_encap_tmpl *encap);
|
||||
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
struct xfrm_migrate *m, int num_bundles,
|
||||
struct xfrm_kmaddress *k, struct net *net,
|
||||
struct xfrm_encap_tmpl *encap);
|
||||
struct xfrm_encap_tmpl *encap, u32 if_id);
|
||||
#endif
|
||||
|
||||
int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
|
||||
|
||||
@@ -511,6 +511,12 @@ struct xfrm_user_offload {
|
||||
int ifindex;
|
||||
__u8 flags;
|
||||
};
|
||||
/* This flag was exposed without any kernel code that supporting it.
|
||||
* Unfortunately, strongswan has the code that uses sets this flag,
|
||||
* which makes impossible to reuse this bit.
|
||||
*
|
||||
* So leave it here to make sure that it won't be reused by mistake.
|
||||
*/
|
||||
#define XFRM_OFFLOAD_IPV6 1
|
||||
#define XFRM_OFFLOAD_INBOUND 2
|
||||
|
||||
|
||||
@@ -310,10 +310,20 @@ record_it:
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void blk_trace_free(struct blk_trace *bt)
|
||||
static void blk_trace_free(struct request_queue *q, struct blk_trace *bt)
|
||||
{
|
||||
relay_close(bt->rchan);
|
||||
debugfs_remove(bt->dir);
|
||||
|
||||
/*
|
||||
* If 'bt->dir' is not set, then both 'dropped' and 'msg' are created
|
||||
* under 'q->debugfs_dir', thus lookup and remove them.
|
||||
*/
|
||||
if (!bt->dir) {
|
||||
debugfs_remove(debugfs_lookup("dropped", q->debugfs_dir));
|
||||
debugfs_remove(debugfs_lookup("msg", q->debugfs_dir));
|
||||
} else {
|
||||
debugfs_remove(bt->dir);
|
||||
}
|
||||
free_percpu(bt->sequence);
|
||||
free_percpu(bt->msg_data);
|
||||
kfree(bt);
|
||||
@@ -335,10 +345,10 @@ static void put_probe_ref(void)
|
||||
mutex_unlock(&blk_probe_mutex);
|
||||
}
|
||||
|
||||
static void blk_trace_cleanup(struct blk_trace *bt)
|
||||
static void blk_trace_cleanup(struct request_queue *q, struct blk_trace *bt)
|
||||
{
|
||||
synchronize_rcu();
|
||||
blk_trace_free(bt);
|
||||
blk_trace_free(q, bt);
|
||||
put_probe_ref();
|
||||
}
|
||||
|
||||
@@ -352,7 +362,7 @@ static int __blk_trace_remove(struct request_queue *q)
|
||||
return -EINVAL;
|
||||
|
||||
if (bt->trace_state != Blktrace_running)
|
||||
blk_trace_cleanup(bt);
|
||||
blk_trace_cleanup(q, bt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -572,7 +582,7 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret)
|
||||
blk_trace_free(bt);
|
||||
blk_trace_free(q, bt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1616,7 +1626,7 @@ static int blk_trace_remove_queue(struct request_queue *q)
|
||||
|
||||
put_probe_ref();
|
||||
synchronize_rcu();
|
||||
blk_trace_free(bt);
|
||||
blk_trace_free(q, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1647,7 +1657,7 @@ static int blk_trace_setup_queue(struct request_queue *q,
|
||||
return 0;
|
||||
|
||||
free_bt:
|
||||
blk_trace_free(bt);
|
||||
blk_trace_free(q, bt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -591,8 +591,10 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
|
||||
return ret;
|
||||
|
||||
/* Don't even allow crazy sizes */
|
||||
if (WARN_ON_ONCE(size > INT_MAX))
|
||||
if (unlikely(size > INT_MAX)) {
|
||||
WARN_ON_ONCE(!(flags & __GFP_NOWARN));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return __vmalloc_node(size, 1, flags, node,
|
||||
__builtin_return_address(0));
|
||||
|
||||
@@ -149,22 +149,25 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
|
||||
struct net *net = dev_net(net_dev);
|
||||
struct net_device *parent_dev;
|
||||
struct net *parent_net;
|
||||
int iflink;
|
||||
bool ret;
|
||||
|
||||
/* check if this is a batman-adv mesh interface */
|
||||
if (batadv_softif_is_valid(net_dev))
|
||||
return true;
|
||||
|
||||
/* no more parents..stop recursion */
|
||||
if (dev_get_iflink(net_dev) == 0 ||
|
||||
dev_get_iflink(net_dev) == net_dev->ifindex)
|
||||
iflink = dev_get_iflink(net_dev);
|
||||
if (iflink == 0)
|
||||
return false;
|
||||
|
||||
parent_net = batadv_getlink_net(net_dev, net);
|
||||
|
||||
/* iflink to itself, most likely physical device */
|
||||
if (net == parent_net && iflink == net_dev->ifindex)
|
||||
return false;
|
||||
|
||||
/* recurse over the parent device */
|
||||
parent_dev = __dev_get_by_index((struct net *)parent_net,
|
||||
dev_get_iflink(net_dev));
|
||||
parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
|
||||
/* if we got a NULL parent_dev there is something broken.. */
|
||||
if (!parent_dev) {
|
||||
pr_err("Cannot find parent device\n");
|
||||
@@ -214,14 +217,15 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
|
||||
struct net_device *real_netdev = NULL;
|
||||
struct net *real_net;
|
||||
struct net *net;
|
||||
int ifindex;
|
||||
int iflink;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!netdev)
|
||||
return NULL;
|
||||
|
||||
if (netdev->ifindex == dev_get_iflink(netdev)) {
|
||||
iflink = dev_get_iflink(netdev);
|
||||
if (iflink == 0) {
|
||||
dev_hold(netdev);
|
||||
return netdev;
|
||||
}
|
||||
@@ -231,9 +235,16 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
|
||||
goto out;
|
||||
|
||||
net = dev_net(hard_iface->soft_iface);
|
||||
ifindex = dev_get_iflink(netdev);
|
||||
real_net = batadv_getlink_net(netdev, net);
|
||||
real_netdev = dev_get_by_index(real_net, ifindex);
|
||||
|
||||
/* iflink to itself, most likely physical device */
|
||||
if (net == real_net && netdev->ifindex == iflink) {
|
||||
real_netdev = netdev;
|
||||
dev_hold(real_netdev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
real_netdev = dev_get_by_index(real_net, iflink);
|
||||
|
||||
out:
|
||||
batadv_hardif_put(hard_iface);
|
||||
|
||||
@@ -2738,6 +2738,7 @@ void hci_release_dev(struct hci_dev *hdev)
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
ida_simple_remove(&hci_index_ida, hdev->id);
|
||||
kfree_skb(hdev->sent_cmd);
|
||||
kfree(hdev);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_release_dev);
|
||||
|
||||
@@ -1841,6 +1841,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
|
||||
struct bdaddr_list *b, *t;
|
||||
u8 num_entries = 0;
|
||||
bool pend_conn, pend_report;
|
||||
u8 filter_policy;
|
||||
int err;
|
||||
|
||||
/* Pause advertising if resolving list can be used as controllers are
|
||||
@@ -1927,6 +1928,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
|
||||
err = -EINVAL;
|
||||
|
||||
done:
|
||||
filter_policy = err ? 0x00 : 0x01;
|
||||
|
||||
/* Enable address resolution when LL Privacy is enabled. */
|
||||
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
|
||||
if (err)
|
||||
@@ -1937,7 +1940,7 @@ done:
|
||||
hci_resume_advertising_sync(hdev);
|
||||
|
||||
/* Select filter policy to use accept list */
|
||||
return err ? 0x00 : 0x01;
|
||||
return filter_policy;
|
||||
}
|
||||
|
||||
/* Returns true if an le connection is in the scanning state */
|
||||
@@ -3262,10 +3265,10 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
|
||||
if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
|
||||
events[0] |= 0x40; /* LE Data Length Change */
|
||||
|
||||
/* If the controller supports LL Privacy feature, enable
|
||||
* the corresponding event.
|
||||
/* If the controller supports LL Privacy feature or LE Extended Adv,
|
||||
* enable the corresponding event.
|
||||
*/
|
||||
if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
|
||||
if (use_enhanced_conn_complete(hdev))
|
||||
events[1] |= 0x02; /* LE Enhanced Connection Complete */
|
||||
|
||||
/* If the controller supports Extended Scanner Filter
|
||||
@@ -4106,9 +4109,9 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||
hci_inquiry_cache_flush(hdev);
|
||||
hci_pend_le_actions_clear(hdev);
|
||||
hci_conn_hash_flush(hdev);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
/* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
|
||||
smp_unregister(hdev);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
hci_sock_dev_event(hdev, HCI_DEV_DOWN);
|
||||
|
||||
@@ -5185,7 +5188,7 @@ int hci_le_ext_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN,
|
||||
plen, data,
|
||||
HCI_EV_LE_ENHANCED_CONN_COMPLETE,
|
||||
HCI_CMD_TIMEOUT, NULL);
|
||||
conn->conn_timeout, NULL);
|
||||
}
|
||||
|
||||
int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
|
||||
@@ -5270,9 +5273,18 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
|
||||
cp.min_ce_len = cpu_to_le16(0x0000);
|
||||
cp.max_ce_len = cpu_to_le16(0x0000);
|
||||
|
||||
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261:
|
||||
*
|
||||
* If this event is unmasked and the HCI_LE_Connection_Complete event
|
||||
* is unmasked, only the HCI_LE_Enhanced_Connection_Complete event is
|
||||
* sent when a new connection has been created.
|
||||
*/
|
||||
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN,
|
||||
sizeof(cp), &cp, HCI_EV_LE_CONN_COMPLETE,
|
||||
HCI_CMD_TIMEOUT, NULL);
|
||||
sizeof(cp), &cp,
|
||||
use_enhanced_conn_complete(hdev) ?
|
||||
HCI_EV_LE_ENHANCED_CONN_COMPLETE :
|
||||
HCI_EV_LE_CONN_COMPLETE,
|
||||
conn->conn_timeout, NULL);
|
||||
|
||||
done:
|
||||
/* Re-enable advertising after the connection attempt is finished. */
|
||||
|
||||
@@ -1218,7 +1218,13 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
|
||||
static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_mode *cp = cmd->param;
|
||||
struct mgmt_mode *cp;
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
|
||||
return;
|
||||
|
||||
cp = cmd->param;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
@@ -1242,7 +1248,7 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
|
||||
mgmt_status(err));
|
||||
}
|
||||
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
}
|
||||
|
||||
static int set_powered_sync(struct hci_dev *hdev, void *data)
|
||||
@@ -1281,7 +1287,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_SET_POWERED, hdev, data, len);
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
@@ -1290,6 +1296,9 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
|
||||
mgmt_set_powered_complete);
|
||||
|
||||
if (err < 0)
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
failed:
|
||||
hci_dev_unlock(hdev);
|
||||
return err;
|
||||
@@ -1383,6 +1392,10 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (err) {
|
||||
@@ -1402,7 +1415,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
||||
new_settings(hdev, cmd->sk);
|
||||
|
||||
done:
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
@@ -1511,7 +1524,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
@@ -1538,6 +1551,9 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
err = hci_cmd_sync_queue(hdev, set_discoverable_sync, cmd,
|
||||
mgmt_set_discoverable_complete);
|
||||
|
||||
if (err < 0)
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
failed:
|
||||
hci_dev_unlock(hdev);
|
||||
return err;
|
||||
@@ -1550,6 +1566,10 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (err) {
|
||||
@@ -1562,7 +1582,9 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
||||
new_settings(hdev, cmd->sk);
|
||||
|
||||
done:
|
||||
mgmt_pending_free(cmd);
|
||||
if (cmd)
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
@@ -1634,7 +1656,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
@@ -1654,6 +1676,9 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
err = hci_cmd_sync_queue(hdev, set_connectable_sync, cmd,
|
||||
mgmt_set_connectable_complete);
|
||||
|
||||
if (err < 0)
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
failed:
|
||||
hci_dev_unlock(hdev);
|
||||
return err;
|
||||
@@ -1774,6 +1799,10 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
||||
u8 enable = cp->val;
|
||||
bool changed;
|
||||
|
||||
/* Make sure cmd still outstanding. */
|
||||
if (cmd != pending_find(MGMT_OP_SET_SSP, hdev))
|
||||
return;
|
||||
|
||||
if (err) {
|
||||
u8 mgmt_err = mgmt_status(err);
|
||||
|
||||
@@ -3321,6 +3350,9 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
|
||||
return;
|
||||
|
||||
if (status) {
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
||||
status);
|
||||
@@ -3493,6 +3525,9 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
|
||||
struct sk_buff *skb = cmd->skb;
|
||||
u8 status = mgmt_status(err);
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
|
||||
return;
|
||||
|
||||
if (!status) {
|
||||
if (!skb)
|
||||
status = MGMT_STATUS_FAILED;
|
||||
@@ -3759,13 +3794,6 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (pending_find(MGMT_OP_SET_WIDEBAND_SPEECH, hdev)) {
|
||||
err = mgmt_cmd_status(sk, hdev->id,
|
||||
MGMT_OP_SET_WIDEBAND_SPEECH,
|
||||
MGMT_STATUS_BUSY);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (hdev_is_powered(hdev) &&
|
||||
!!cp->val != hci_dev_test_flag(hdev,
|
||||
HCI_WIDEBAND_SPEECH_ENABLED)) {
|
||||
@@ -5036,12 +5064,6 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
|
||||
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
||||
MGMT_STATUS_BUSY);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
|
||||
if (!cmd)
|
||||
err = -ENOMEM;
|
||||
@@ -5261,11 +5283,16 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
|
||||
cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
|
||||
cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
|
||||
return;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
||||
cmd->param, 1);
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
|
||||
DISCOVERY_FINDING);
|
||||
@@ -5327,7 +5354,7 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
|
||||
else
|
||||
hdev->discovery.limited = false;
|
||||
|
||||
cmd = mgmt_pending_new(sk, op, hdev, data, len);
|
||||
cmd = mgmt_pending_add(sk, op, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
@@ -5336,7 +5363,7 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
|
||||
err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
|
||||
start_discovery_complete);
|
||||
if (err < 0) {
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -5430,7 +5457,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_START_SERVICE_DISCOVERY,
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_START_SERVICE_DISCOVERY,
|
||||
hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
@@ -5463,7 +5490,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
||||
err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
|
||||
start_discovery_complete);
|
||||
if (err < 0) {
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -5495,11 +5522,14 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
|
||||
return;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
||||
cmd->param, 1);
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
if (!err)
|
||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
@@ -5535,7 +5565,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cmd = mgmt_pending_new(sk, MGMT_OP_STOP_DISCOVERY, hdev, data, len);
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, data, len);
|
||||
if (!cmd) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
@@ -5544,7 +5574,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
err = hci_cmd_sync_queue(hdev, stop_discovery_sync, cmd,
|
||||
stop_discovery_complete);
|
||||
if (err < 0) {
|
||||
mgmt_pending_free(cmd);
|
||||
mgmt_pending_remove(cmd);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -7474,6 +7504,9 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
|
||||
u8 status = mgmt_status(err);
|
||||
u16 eir_len;
|
||||
|
||||
if (cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
|
||||
return;
|
||||
|
||||
if (!status) {
|
||||
if (!skb)
|
||||
status = MGMT_STATUS_FAILED;
|
||||
@@ -7969,11 +8002,7 @@ static bool requested_adv_flags_are_valid(struct hci_dev *hdev, u32 adv_flags)
|
||||
|
||||
static bool adv_busy(struct hci_dev *hdev)
|
||||
{
|
||||
return (pending_find(MGMT_OP_ADD_ADVERTISING, hdev) ||
|
||||
pending_find(MGMT_OP_REMOVE_ADVERTISING, hdev) ||
|
||||
pending_find(MGMT_OP_SET_LE, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_EXT_ADV_PARAMS, hdev) ||
|
||||
pending_find(MGMT_OP_ADD_EXT_ADV_DATA, hdev));
|
||||
return pending_find(MGMT_OP_SET_LE, hdev);
|
||||
}
|
||||
|
||||
static void add_adv_complete(struct hci_dev *hdev, struct sock *sk, u8 instance,
|
||||
@@ -8563,9 +8592,7 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (pending_find(MGMT_OP_ADD_ADVERTISING, hdev) ||
|
||||
pending_find(MGMT_OP_REMOVE_ADVERTISING, hdev) ||
|
||||
pending_find(MGMT_OP_SET_LE, hdev)) {
|
||||
if (pending_find(MGMT_OP_SET_LE, hdev)) {
|
||||
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADVERTISING,
|
||||
MGMT_STATUS_BUSY);
|
||||
goto unlock;
|
||||
|
||||
@@ -77,11 +77,12 @@ int mgmt_send_event_skb(unsigned short channel, struct sk_buff *skb, int flag,
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
struct mgmt_hdr *hdr;
|
||||
int len = skb->len;
|
||||
int len;
|
||||
|
||||
if (!skb)
|
||||
return -EINVAL;
|
||||
|
||||
len = skb->len;
|
||||
hdev = bt_cb(skb)->mgmt.hdev;
|
||||
|
||||
/* Time stamp */
|
||||
|
||||
@@ -3877,6 +3877,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
|
||||
list_skb = list_skb->next;
|
||||
|
||||
err = 0;
|
||||
delta_truesize += nskb->truesize;
|
||||
if (skb_shared(nskb)) {
|
||||
tmp = skb_clone(nskb, GFP_ATOMIC);
|
||||
if (tmp) {
|
||||
@@ -3901,7 +3902,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
|
||||
tail = nskb;
|
||||
|
||||
delta_len += nskb->len;
|
||||
delta_truesize += nskb->truesize;
|
||||
|
||||
skb_push(nskb, -skb_network_offset(nskb) + offset);
|
||||
|
||||
|
||||
@@ -1153,7 +1153,7 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
|
||||
struct sk_psock *psock;
|
||||
struct bpf_prog *prog;
|
||||
int ret = __SK_DROP;
|
||||
int len = skb->len;
|
||||
int len = orig_len;
|
||||
|
||||
/* clone here so sk_eat_skb() in tcp_read_sock does not drop our data */
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
|
||||
@@ -2073,8 +2073,52 @@ u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
|
||||
|
||||
static void dcbnl_flush_dev(struct net_device *dev)
|
||||
{
|
||||
struct dcb_app_type *itr, *tmp;
|
||||
|
||||
spin_lock_bh(&dcb_lock);
|
||||
|
||||
list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
|
||||
if (itr->ifindex == dev->ifindex) {
|
||||
list_del(&itr->list);
|
||||
kfree(itr);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&dcb_lock);
|
||||
}
|
||||
|
||||
static int dcbnl_netdevice_event(struct notifier_block *nb,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UNREGISTER:
|
||||
if (!dev->dcbnl_ops)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
dcbnl_flush_dev(dev);
|
||||
|
||||
return NOTIFY_OK;
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
static struct notifier_block dcbnl_nb __read_mostly = {
|
||||
.notifier_call = dcbnl_netdevice_event,
|
||||
};
|
||||
|
||||
static int __init dcbnl_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = register_netdevice_notifier(&dcbnl_nb);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
|
||||
rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
|
||||
|
||||
|
||||
@@ -1261,7 +1261,7 @@ int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
|
||||
info.tag_ops = tag_ops;
|
||||
err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_unwind_tagger;
|
||||
|
||||
err = dsa_tree_bind_tag_proto(dst, tag_ops);
|
||||
if (err)
|
||||
|
||||
@@ -671,7 +671,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
|
||||
u32 padto;
|
||||
|
||||
padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
|
||||
padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
|
||||
if (skb->len < padto)
|
||||
esp.tfclen = padto - skb->len;
|
||||
}
|
||||
|
||||
@@ -1684,11 +1684,13 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
|
||||
if (!copied)
|
||||
copied = used;
|
||||
break;
|
||||
} else if (used <= len) {
|
||||
seq += used;
|
||||
copied += used;
|
||||
offset += used;
|
||||
}
|
||||
if (WARN_ON_ONCE(used > len))
|
||||
used = len;
|
||||
seq += used;
|
||||
copied += used;
|
||||
offset += used;
|
||||
|
||||
/* If recv_actor drops the lock (e.g. TCP splice
|
||||
* receive) the skb pointer might be invalid when
|
||||
* getting here: tcp_collapse might have deleted it
|
||||
|
||||
@@ -3754,6 +3754,7 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister)
|
||||
struct inet6_dev *idev;
|
||||
struct inet6_ifaddr *ifa, *tmp;
|
||||
bool keep_addr = false;
|
||||
bool was_ready;
|
||||
int state, i;
|
||||
|
||||
ASSERT_RTNL();
|
||||
@@ -3819,7 +3820,10 @@ restart:
|
||||
|
||||
addrconf_del_rs_timer(idev);
|
||||
|
||||
/* Step 2: clear flags for stateless addrconf */
|
||||
/* Step 2: clear flags for stateless addrconf, repeated down
|
||||
* detection
|
||||
*/
|
||||
was_ready = idev->if_flags & IF_READY;
|
||||
if (!unregister)
|
||||
idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
|
||||
|
||||
@@ -3893,7 +3897,7 @@ restart:
|
||||
if (unregister) {
|
||||
ipv6_ac_destroy_dev(idev);
|
||||
ipv6_mc_destroy_dev(idev);
|
||||
} else {
|
||||
} else if (was_ready) {
|
||||
ipv6_mc_down(idev);
|
||||
}
|
||||
|
||||
|
||||
@@ -707,7 +707,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
|
||||
u32 padto;
|
||||
|
||||
padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
|
||||
padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
|
||||
if (skb->len < padto)
|
||||
esp.tfclen = padto - skb->len;
|
||||
}
|
||||
|
||||
@@ -1408,8 +1408,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
|
||||
if (np->frag_size)
|
||||
mtu = np->frag_size;
|
||||
}
|
||||
if (mtu < IPV6_MIN_MTU)
|
||||
return -EINVAL;
|
||||
cork->base.fragsize = mtu;
|
||||
cork->base.gso_size = ipc6->gso_size;
|
||||
cork->base.tx_flags = 0;
|
||||
@@ -1471,8 +1469,6 @@ static int __ip6_append_data(struct sock *sk,
|
||||
|
||||
fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
|
||||
(opt ? opt->opt_nflen : 0);
|
||||
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
|
||||
sizeof(struct frag_hdr);
|
||||
|
||||
headersize = sizeof(struct ipv6hdr) +
|
||||
(opt ? opt->opt_flen + opt->opt_nflen : 0) +
|
||||
@@ -1480,6 +1476,13 @@ static int __ip6_append_data(struct sock *sk,
|
||||
sizeof(struct frag_hdr) : 0) +
|
||||
rt->rt6i_nfheader_len;
|
||||
|
||||
if (mtu < fragheaderlen ||
|
||||
((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr))
|
||||
goto emsgsize;
|
||||
|
||||
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
|
||||
sizeof(struct frag_hdr);
|
||||
|
||||
/* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
|
||||
* the first fragment
|
||||
*/
|
||||
|
||||
@@ -1371,27 +1371,23 @@ static void mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld,
|
||||
}
|
||||
|
||||
/* called with rcu_read_lock() */
|
||||
int igmp6_event_query(struct sk_buff *skb)
|
||||
void igmp6_event_query(struct sk_buff *skb)
|
||||
{
|
||||
struct inet6_dev *idev = __in6_dev_get(skb->dev);
|
||||
|
||||
if (!idev)
|
||||
return -EINVAL;
|
||||
|
||||
if (idev->dead) {
|
||||
kfree_skb(skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!idev || idev->dead)
|
||||
goto out;
|
||||
|
||||
spin_lock_bh(&idev->mc_query_lock);
|
||||
if (skb_queue_len(&idev->mc_query_queue) < MLD_MAX_SKBS) {
|
||||
__skb_queue_tail(&idev->mc_query_queue, skb);
|
||||
if (!mod_delayed_work(mld_wq, &idev->mc_query_work, 0))
|
||||
in6_dev_hold(idev);
|
||||
skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&idev->mc_query_lock);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void __mld_query_work(struct sk_buff *skb)
|
||||
@@ -1542,27 +1538,23 @@ static void mld_query_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* called with rcu_read_lock() */
|
||||
int igmp6_event_report(struct sk_buff *skb)
|
||||
void igmp6_event_report(struct sk_buff *skb)
|
||||
{
|
||||
struct inet6_dev *idev = __in6_dev_get(skb->dev);
|
||||
|
||||
if (!idev)
|
||||
return -EINVAL;
|
||||
|
||||
if (idev->dead) {
|
||||
kfree_skb(skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!idev || idev->dead)
|
||||
goto out;
|
||||
|
||||
spin_lock_bh(&idev->mc_report_lock);
|
||||
if (skb_queue_len(&idev->mc_report_queue) < MLD_MAX_SKBS) {
|
||||
__skb_queue_tail(&idev->mc_report_queue, skb);
|
||||
if (!mod_delayed_work(mld_wq, &idev->mc_report_work, 0))
|
||||
in6_dev_hold(idev);
|
||||
skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&idev->mc_report_lock);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void __mld_report_work(struct sk_buff *skb)
|
||||
|
||||
@@ -2623,7 +2623,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
|
||||
kma ? &k : NULL, net, NULL);
|
||||
kma ? &k : NULL, net, NULL, 0);
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007-2010, Intel Corporation
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2021 Intel Corporation
|
||||
* Copyright (C) 2018 - 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
@@ -626,6 +626,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_sta_flag(sta, WLAN_STA_MFP) &&
|
||||
!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
ht_dbg(sdata,
|
||||
"MFP STA not authorized - deny BA session request %pM tid %d\n",
|
||||
sta->sta.addr, tid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a
|
||||
* member of an IBSS, and has no other existing Block Ack agreement
|
||||
|
||||
@@ -376,7 +376,7 @@ struct ieee80211_mgd_auth_data {
|
||||
|
||||
u8 key[WLAN_KEY_LEN_WEP104];
|
||||
u8 key_len, key_idx;
|
||||
bool done;
|
||||
bool done, waiting;
|
||||
bool peer_confirmed;
|
||||
bool timeout_started;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define IEEE80211_AUTH_TIMEOUT_SAE (HZ * 2)
|
||||
#define IEEE80211_AUTH_MAX_TRIES 3
|
||||
#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
|
||||
#define IEEE80211_AUTH_WAIT_SAE_RETRY (HZ * 2)
|
||||
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
|
||||
#define IEEE80211_ASSOC_TIMEOUT_LONG (HZ / 2)
|
||||
#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
|
||||
@@ -3011,8 +3012,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
||||
(status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED ||
|
||||
(auth_transaction == 1 &&
|
||||
(status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||
status_code == WLAN_STATUS_SAE_PK))))
|
||||
status_code == WLAN_STATUS_SAE_PK)))) {
|
||||
/* waiting for userspace now */
|
||||
ifmgd->auth_data->waiting = true;
|
||||
ifmgd->auth_data->timeout =
|
||||
jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY;
|
||||
ifmgd->auth_data->timeout_started = true;
|
||||
run_again(sdata, ifmgd->auth_data->timeout);
|
||||
goto notify_driver;
|
||||
}
|
||||
|
||||
sdata_info(sdata, "%pM denied authentication (status %d)\n",
|
||||
mgmt->sa, status_code);
|
||||
@@ -4603,10 +4611,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&
|
||||
time_after(jiffies, ifmgd->auth_data->timeout)) {
|
||||
if (ifmgd->auth_data->done) {
|
||||
if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {
|
||||
/*
|
||||
* ok ... we waited for assoc but userspace didn't,
|
||||
* so let's just kill the auth data
|
||||
* ok ... we waited for assoc or continuation but
|
||||
* userspace didn't do it, so kill the auth data
|
||||
*/
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
} else if (ieee80211_auth(sdata)) {
|
||||
|
||||
@@ -2607,7 +2607,8 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
|
||||
* address, so that the authenticator (e.g. hostapd) will see
|
||||
* the frame, but bridge won't forward it anywhere else. Note
|
||||
* that due to earlier filtering, the only other address can
|
||||
* be the PAE group address.
|
||||
* be the PAE group address, unless the hardware allowed them
|
||||
* through in 802.3 offloaded mode.
|
||||
*/
|
||||
if (unlikely(skb->protocol == sdata->control_port_protocol &&
|
||||
!ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
|
||||
@@ -2922,13 +2923,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
||||
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
||||
return RX_CONTINUE;
|
||||
|
||||
ac = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
ac = ieee802_1d_to_ac[skb->priority];
|
||||
q = sdata->vif.hw_queue[ac];
|
||||
if (ieee80211_queue_stopped(&local->hw, q)) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
||||
return RX_DROP_MONITOR;
|
||||
}
|
||||
skb_set_queue_mapping(skb, q);
|
||||
skb_set_queue_mapping(skb, ac);
|
||||
|
||||
if (!--mesh_hdr->ttl) {
|
||||
if (!is_multicast_ether_addr(hdr->addr1))
|
||||
@@ -4514,12 +4515,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
|
||||
|
||||
/* deliver to local stack */
|
||||
skb->protocol = eth_type_trans(skb, fast_rx->dev);
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
if (rx->list)
|
||||
list_add_tail(&skb->list, rx->list);
|
||||
else
|
||||
netif_receive_skb(skb);
|
||||
|
||||
ieee80211_deliver_skb_to_local_stack(skb, rx);
|
||||
}
|
||||
|
||||
static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
|
||||
@@ -466,9 +466,12 @@ static bool mptcp_pending_data_fin(struct sock *sk, u64 *seq)
|
||||
static void mptcp_set_datafin_timeout(const struct sock *sk)
|
||||
{
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
u32 retransmits;
|
||||
|
||||
mptcp_sk(sk)->timer_ival = min(TCP_RTO_MAX,
|
||||
TCP_RTO_MIN << icsk->icsk_retransmits);
|
||||
retransmits = min_t(u32, icsk->icsk_retransmits,
|
||||
ilog2(TCP_RTO_MAX / TCP_RTO_MIN));
|
||||
|
||||
mptcp_sk(sk)->timer_ival = TCP_RTO_MIN << retransmits;
|
||||
}
|
||||
|
||||
static void __mptcp_set_timeout(struct sock *sk, long tout)
|
||||
@@ -3294,6 +3297,17 @@ static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v)
|
||||
return 0;
|
||||
|
||||
delta = msk->write_seq - v;
|
||||
if (__mptcp_check_fallback(msk) && msk->first) {
|
||||
struct tcp_sock *tp = tcp_sk(msk->first);
|
||||
|
||||
/* the first subflow is disconnected after close - see
|
||||
* __mptcp_close_ssk(). tcp_disconnect() moves the write_seq
|
||||
* so ignore that status, too.
|
||||
*/
|
||||
if (!((1 << msk->first->sk_state) &
|
||||
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE)))
|
||||
delta += READ_ONCE(tp->write_seq) - tp->snd_una;
|
||||
}
|
||||
if (delta > INT_MAX)
|
||||
delta = INT_MAX;
|
||||
|
||||
|
||||
@@ -428,14 +428,15 @@ static int __nf_register_net_hook(struct net *net, int pf,
|
||||
p = nf_entry_dereference(*pp);
|
||||
new_hooks = nf_hook_entries_grow(p, reg);
|
||||
|
||||
if (!IS_ERR(new_hooks))
|
||||
if (!IS_ERR(new_hooks)) {
|
||||
hooks_validate(new_hooks);
|
||||
rcu_assign_pointer(*pp, new_hooks);
|
||||
}
|
||||
|
||||
mutex_unlock(&nf_hook_mutex);
|
||||
if (IS_ERR(new_hooks))
|
||||
return PTR_ERR(new_hooks);
|
||||
|
||||
hooks_validate(new_hooks);
|
||||
#ifdef CONFIG_NETFILTER_INGRESS
|
||||
if (nf_ingress_hook(reg, pf))
|
||||
net_inc_ingress_queue();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user