mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
Linux 5.9
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAl+DdgYeHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGB1sH/0B4REolPPxiQsPL P45+a2POUU0SQK8NjkcYskQmJ6DnPKkJSXeUU8rzuI2rty5bWEzEBxdUSh064ZaM DGxkWrdhYNaLJuceNLlanBk3vrM3KwGkaJFSKLgsEXkmH86gl33ptA8nlQVbfc+4 FK4hRZs2J6Y5YRsuzPO8nzzHWs1CThZEcwNPOeIZrAnv+/13zyP/piZ+R/2gKYwy RVrVrzSTkTGJXotn6J17Sa02+CGv5UqdxOZFv7jimYJOmFT7KnGngNrJbh8aYWk7 vPTRUvGozh6NyYxtRI9LKGZy1yQ05Cl7N927CnFYzD235/eT7zaRDZe1e1JaIE8Z r2yxGCM= =ZIYP -----END PGP SIGNATURE----- Merge 5.9 into android-mainline Linux 5.9 Change-Id: Ic4308a3e2a4015058efdac52bd51794b604c8435 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
8de87f4d1c
4
.mailmap
4
.mailmap
|
|
@ -41,7 +41,8 @@ Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com>
|
|||
Andrew Vasquez <andrew.vasquez@qlogic.com>
|
||||
Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
|
||||
Andy Adamson <andros@citi.umich.edu>
|
||||
Antoine Tenart <antoine.tenart@free-electrons.com>
|
||||
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
|
||||
Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com>
|
||||
Antonio Ospite <ao2@ao2.it> <ao2@amarulasolutions.com>
|
||||
Archit Taneja <archit@ti.com>
|
||||
Ard Biesheuvel <ardb@kernel.org> <ard.biesheuvel@linaro.org>
|
||||
|
|
@ -188,6 +189,7 @@ Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com>
|
|||
Linas Vepstas <linas@austin.ibm.com>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
|
||||
<linux-hardening@vger.kernel.org> <kernel-hardening@lists.openwall.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||
Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Required properties:
|
|||
- "renesas,etheravb-r8a774a1" for the R8A774A1 SoC.
|
||||
- "renesas,etheravb-r8a774b1" for the R8A774B1 SoC.
|
||||
- "renesas,etheravb-r8a774c0" for the R8A774C0 SoC.
|
||||
- "renesas,etheravb-r8a774e1" for the R8A774E1 SoC.
|
||||
- "renesas,etheravb-r8a7795" for the R8A7795 SoC.
|
||||
- "renesas,etheravb-r8a7796" for the R8A77960 SoC.
|
||||
- "renesas,etheravb-r8a77961" for the R8A77961 SoC.
|
||||
|
|
|
|||
|
|
@ -1342,8 +1342,8 @@ follow::
|
|||
|
||||
In addition to read/modify/write the setup header of the struct
|
||||
boot_params as that of 16-bit boot protocol, the boot loader should
|
||||
also fill the additional fields of the struct boot_params as that
|
||||
described in zero-page.txt.
|
||||
also fill the additional fields of the struct boot_params as
|
||||
described in chapter :doc:`zero-page`.
|
||||
|
||||
After setting up the struct boot_params, the boot loader can load the
|
||||
32/64-bit kernel in the same way as that of 16-bit boot protocol.
|
||||
|
|
@ -1379,7 +1379,7 @@ can be calculated as follows::
|
|||
In addition to read/modify/write the setup header of the struct
|
||||
boot_params as that of 16-bit boot protocol, the boot loader should
|
||||
also fill the additional fields of the struct boot_params as described
|
||||
in zero-page.txt.
|
||||
in chapter :doc:`zero-page`.
|
||||
|
||||
After setting up the struct boot_params, the boot loader can load
|
||||
64-bit kernel in the same way as that of 16-bit boot protocol, but
|
||||
|
|
|
|||
33
MAINTAINERS
33
MAINTAINERS
|
|
@ -1460,6 +1460,11 @@ S: Odd Fixes
|
|||
F: drivers/amba/
|
||||
F: include/linux/amba/bus.h
|
||||
|
||||
ARM PRIMECELL CLCD PL110 DRIVER
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
S: Odd Fixes
|
||||
F: drivers/video/fbdev/amba-clcd.*
|
||||
|
||||
ARM PRIMECELL KMI PL050 DRIVER
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
S: Odd Fixes
|
||||
|
|
@ -1623,7 +1628,7 @@ N: meson
|
|||
|
||||
ARM/Annapurna Labs ALPINE ARCHITECTURE
|
||||
M: Tsahee Zidenberg <tsahee@annapurnalabs.com>
|
||||
M: Antoine Tenart <antoine.tenart@bootlin.com>
|
||||
M: Antoine Tenart <atenart@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: arch/arm/boot/dts/alpine*
|
||||
|
|
@ -7235,7 +7240,7 @@ F: drivers/staging/gasket/
|
|||
GCC PLUGINS
|
||||
M: Kees Cook <keescook@chromium.org>
|
||||
R: Emese Revfy <re.emese@gmail.com>
|
||||
L: kernel-hardening@lists.openwall.com
|
||||
L: linux-hardening@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/kbuild/gcc-plugins.rst
|
||||
F: scripts/Makefile.gcc-plugins
|
||||
|
|
@ -8680,7 +8685,7 @@ F: drivers/input/input-mt.c
|
|||
K: \b(ABS|SYN)_MT_
|
||||
|
||||
INSIDE SECURE CRYPTO DRIVER
|
||||
M: Antoine Tenart <antoine.tenart@bootlin.com>
|
||||
M: Antoine Tenart <atenart@kernel.org>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/crypto/inside-secure/
|
||||
|
|
@ -8759,7 +8764,8 @@ F: include/drm/i915*
|
|||
F: include/uapi/drm/i915_drm.h
|
||||
|
||||
INTEL ETHERNET DRIVERS
|
||||
M: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
M: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
M: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
L: intel-wired-lan@lists.osuosl.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
W: http://www.intel.com/support/feedback.htm
|
||||
|
|
@ -9803,7 +9809,7 @@ F: drivers/scsi/53c700*
|
|||
LEAKING_ADDRESSES
|
||||
M: Tobin C. Harding <me@tobin.cc>
|
||||
M: Tycho Andersen <tycho@tycho.pizza>
|
||||
L: kernel-hardening@lists.openwall.com
|
||||
L: linux-hardening@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tobin/leaks.git
|
||||
F: scripts/leaking_addresses.pl
|
||||
|
|
@ -12084,6 +12090,7 @@ NETWORKING [DSA]
|
|||
M: Andrew Lunn <andrew@lunn.ch>
|
||||
M: Vivien Didelot <vivien.didelot@gmail.com>
|
||||
M: Florian Fainelli <f.fainelli@gmail.com>
|
||||
M: Vladimir Oltean <olteanv@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/dsa/
|
||||
F: drivers/net/dsa/
|
||||
|
|
@ -16738,6 +16745,13 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
|
||||
F: drivers/gpio/gpio-dwapb.c
|
||||
|
||||
SYNOPSYS DESIGNWARE APB SSI DRIVER
|
||||
M: Serge Semin <fancer.lancer@gmail.com>
|
||||
L: linux-spi@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
|
||||
F: drivers/spi/spi-dw*
|
||||
|
||||
SYNOPSYS DESIGNWARE AXI DMAC DRIVER
|
||||
M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
|
||||
S: Maintained
|
||||
|
|
@ -18295,7 +18309,8 @@ F: drivers/gpu/vga/vga_switcheroo.c
|
|||
F: include/linux/vga_switcheroo.h
|
||||
|
||||
VIA RHINE NETWORK DRIVER
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
M: Kevin Brace <kevinbrace@bracecomputerlab.com>
|
||||
F: drivers/net/ethernet/via/via-rhine.c
|
||||
|
||||
VIA SD/MMC CARD CONTROLLER DRIVER
|
||||
|
|
@ -18900,10 +18915,10 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/mm
|
|||
F: arch/x86/mm/
|
||||
|
||||
X86 PLATFORM DRIVERS
|
||||
M: Darren Hart <dvhart@infradead.org>
|
||||
M: Andy Shevchenko <andy@infradead.org>
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
M: Mark Gross <mgross@linux.intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
S: Maintained
|
||||
T: git git://git.infradead.org/linux-platform-drivers-x86.git
|
||||
F: drivers/platform/olpc/
|
||||
F: drivers/platform/x86/
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc8
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static int xen_starting_cpu(unsigned int cpu)
|
|||
pr_info("Xen: initializing cpu%d\n", cpu);
|
||||
vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
|
||||
|
||||
info.mfn = virt_to_gfn(vcpup);
|
||||
info.mfn = percpu_to_gfn(vcpup);
|
||||
info.offset = xen_offset_in_page(vcpup);
|
||||
|
||||
err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, xen_vcpu_nr(cpu),
|
||||
|
|
|
|||
|
|
@ -788,7 +788,7 @@ SYM_FUNC_START_LOCAL(__xts_crypt8)
|
|||
|
||||
0: mov bskey, x21
|
||||
mov rounds, x22
|
||||
br x7
|
||||
br x16
|
||||
SYM_FUNC_END(__xts_crypt8)
|
||||
|
||||
.macro __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
|
||||
|
|
@ -806,7 +806,7 @@ SYM_FUNC_END(__xts_crypt8)
|
|||
uzp1 v30.4s, v30.4s, v25.4s
|
||||
ld1 {v25.16b}, [x24]
|
||||
|
||||
99: adr x7, \do8
|
||||
99: adr x16, \do8
|
||||
bl __xts_crypt8
|
||||
|
||||
ldp q16, q17, [sp, #.Lframe_local_offset]
|
||||
|
|
|
|||
|
|
@ -475,7 +475,6 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
case BPF_JMP | BPF_JSET | BPF_K:
|
||||
case BPF_JMP | BPF_JSET | BPF_X:
|
||||
true_cond = COND_NE;
|
||||
fallthrough;
|
||||
cond_branch:
|
||||
/* same targets, can avoid doing the test :) */
|
||||
if (filter[i].jt == filter[i].jf) {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,11 @@ SECTIONS
|
|||
/* Beginning of code and text segment */
|
||||
. = LOAD_OFFSET;
|
||||
_start = .;
|
||||
_stext = .;
|
||||
HEAD_TEXT_SECTION
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
|
||||
__init_begin = .;
|
||||
INIT_TEXT_SECTION(PAGE_SIZE)
|
||||
INIT_DATA_SECTION(16)
|
||||
. = ALIGN(8);
|
||||
__soc_early_init_table : {
|
||||
__soc_early_init_table_start = .;
|
||||
|
|
@ -55,6 +53,7 @@ SECTIONS
|
|||
. = ALIGN(SECTION_ALIGN);
|
||||
.text : {
|
||||
_text = .;
|
||||
_stext = .;
|
||||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
CPUIDLE_TEXT
|
||||
|
|
@ -67,6 +66,8 @@ SECTIONS
|
|||
_etext = .;
|
||||
}
|
||||
|
||||
INIT_DATA_SECTION(16)
|
||||
|
||||
/* Start of data section */
|
||||
_sdata = .;
|
||||
RO_DATA(SECTION_ALIGN)
|
||||
|
|
|
|||
|
|
@ -515,6 +515,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
|
|||
#else
|
||||
dtb_early_va = (void *)dtb_pa;
|
||||
#endif
|
||||
dtb_early_pa = dtb_pa;
|
||||
}
|
||||
|
||||
static inline void setup_vm_final(void)
|
||||
|
|
|
|||
|
|
@ -1904,6 +1904,8 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check;
|
|||
|
||||
static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
||||
{
|
||||
bool irq_state;
|
||||
|
||||
WARN_ON_ONCE(user_mode(regs));
|
||||
|
||||
/*
|
||||
|
|
@ -1914,7 +1916,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
|||
mce_check_crashing_cpu())
|
||||
return;
|
||||
|
||||
nmi_enter();
|
||||
irq_state = idtentry_enter_nmi(regs);
|
||||
/*
|
||||
* The call targets are marked noinstr, but objtool can't figure
|
||||
* that out because it's an indirect call. Annotate it.
|
||||
|
|
@ -1925,7 +1927,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
|
|||
if (regs->flags & X86_EFLAGS_IF)
|
||||
trace_hardirqs_on_prepare();
|
||||
instrumentation_end();
|
||||
nmi_exit();
|
||||
idtentry_exit_nmi(regs, irq_state);
|
||||
}
|
||||
|
||||
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
|
||||
|
|
|
|||
|
|
@ -305,8 +305,6 @@ int ibm_partition(struct parsed_partitions *state)
|
|||
if (!disk->fops->getgeo)
|
||||
goto out_exit;
|
||||
fn = symbol_get(dasd_biodasdinfo);
|
||||
if (!fn)
|
||||
goto out_exit;
|
||||
blocksize = bdev_logical_block_size(bdev);
|
||||
if (blocksize <= 0)
|
||||
goto out_symbol;
|
||||
|
|
@ -326,7 +324,7 @@ int ibm_partition(struct parsed_partitions *state)
|
|||
geo->start = get_start_sect(bdev);
|
||||
if (disk->fops->getgeo(bdev, geo))
|
||||
goto out_freeall;
|
||||
if (fn(disk, info)) {
|
||||
if (!fn || fn(disk, info)) {
|
||||
kfree(info);
|
||||
info = NULL;
|
||||
}
|
||||
|
|
@ -370,7 +368,8 @@ int ibm_partition(struct parsed_partitions *state)
|
|||
out_nogeo:
|
||||
kfree(info);
|
||||
out_symbol:
|
||||
symbol_put(dasd_biodasdinfo);
|
||||
if (fn)
|
||||
symbol_put(dasd_biodasdinfo);
|
||||
out_exit:
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -651,6 +651,7 @@ struct compat_cdrom_generic_command {
|
|||
compat_int_t stat;
|
||||
compat_caddr_t sense;
|
||||
unsigned char data_direction;
|
||||
unsigned char pad[3];
|
||||
compat_int_t quiet;
|
||||
compat_int_t timeout;
|
||||
compat_caddr_t reserved[1];
|
||||
|
|
|
|||
|
|
@ -1553,7 +1553,7 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
|
|||
* put_page(); and would cause either a VM_BUG directly, or
|
||||
* __page_cache_release a page that would actually still be referenced
|
||||
* by someone, leading to some obscure delayed Oops somewhere else. */
|
||||
if (drbd_disable_sendpage || (page_count(page) < 1) || PageSlab(page))
|
||||
if (drbd_disable_sendpage || !sendpage_ok(page))
|
||||
return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
|
||||
|
||||
msg_flags |= MSG_NOSIGNAL;
|
||||
|
|
|
|||
|
|
@ -824,8 +824,21 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
|
|||
ret = pca953x_irq_pending(chip, pending);
|
||||
mutex_unlock(&chip->i2c_lock);
|
||||
|
||||
for_each_set_bit(level, pending, gc->ngpio)
|
||||
handle_nested_irq(irq_find_mapping(gc->irq.domain, level));
|
||||
if (ret) {
|
||||
ret = 0;
|
||||
|
||||
for_each_set_bit(level, pending, gc->ngpio) {
|
||||
int nested_irq = irq_find_mapping(gc->irq.domain, level);
|
||||
|
||||
if (unlikely(nested_irq <= 0)) {
|
||||
dev_warn_ratelimited(gc->parent, "unmapped interrupt %d\n", level);
|
||||
continue;
|
||||
}
|
||||
|
||||
handle_nested_irq(nested_irq);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_RETVAL(ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static __poll_t lineevent_poll(struct file *file,
|
|||
|
||||
static ssize_t lineevent_get_size(void)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
|
||||
/* i386 has no padding after 'id' */
|
||||
if (in_ia32_syscall()) {
|
||||
struct compat_gpioeevent_data {
|
||||
|
|
|
|||
|
|
@ -694,12 +694,12 @@ static void soc15_reg_base_init(struct amdgpu_device *adev)
|
|||
* it doesn't support SRIOV. */
|
||||
if (amdgpu_discovery) {
|
||||
r = amdgpu_discovery_reg_base_init(adev);
|
||||
if (r) {
|
||||
DRM_WARN("failed to init reg base from ip discovery table, "
|
||||
"fallback to legacy init method\n");
|
||||
vega10_reg_base_init(adev);
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
DRM_WARN("failed to init reg base from ip discovery table, "
|
||||
"fallback to legacy init method\n");
|
||||
}
|
||||
vega10_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
vega20_reg_base_init(adev);
|
||||
|
|
|
|||
|
|
@ -1409,7 +1409,7 @@ static int dm_late_init(void *handle)
|
|||
if (dmcu)
|
||||
ret = dmcu_load_iram(dmcu, params);
|
||||
else if (adev->dm.dc->ctx->dmub_srv)
|
||||
ret = dmub_init_abm_config(adev->dm.dc->res_pool->abm, params);
|
||||
ret = dmub_init_abm_config(adev->dm.dc->res_pool, params);
|
||||
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parame
|
|||
params, ram_table, big_endian);
|
||||
}
|
||||
|
||||
bool dmub_init_abm_config(struct abm *abm,
|
||||
bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
struct dmcu_iram_parameters params)
|
||||
{
|
||||
struct iram_table_v_2_2 ram_table;
|
||||
|
|
@ -665,8 +665,13 @@ bool dmub_init_abm_config(struct abm *abm,
|
|||
bool result = false;
|
||||
uint32_t i, j = 0;
|
||||
|
||||
if (abm == NULL)
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[0] == NULL)
|
||||
return false;
|
||||
#else
|
||||
if (res_pool->abm == NULL)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
memset(&ram_table, 0, sizeof(ram_table));
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
|
@ -707,8 +712,14 @@ bool dmub_init_abm_config(struct abm *abm,
|
|||
|
||||
config.min_abm_backlight = ram_table.min_abm_backlight;
|
||||
|
||||
result = abm->funcs->init_abm_config(
|
||||
abm, (char *)(&config), sizeof(struct abm_config_table));
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
|
||||
if (res_pool->multiple_abms[0]) {
|
||||
result = res_pool->multiple_abms[0]->funcs->init_abm_config(
|
||||
res_pool->multiple_abms[0], (char *)(&config), sizeof(struct abm_config_table));
|
||||
} else
|
||||
#endif
|
||||
result = res_pool->abm->funcs->init_abm_config(
|
||||
res_pool->abm, (char *)(&config), sizeof(struct abm_config_table));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "dc/inc/hw/dmcu.h"
|
||||
#include "dc/inc/hw/abm.h"
|
||||
|
||||
struct resource_pool;
|
||||
|
||||
|
||||
enum abm_defines {
|
||||
abm_defines_max_level = 4,
|
||||
|
|
@ -45,7 +47,7 @@ struct dmcu_iram_parameters {
|
|||
|
||||
bool dmcu_load_iram(struct dmcu *dmcu,
|
||||
struct dmcu_iram_parameters params);
|
||||
bool dmub_init_abm_config(struct abm *abm,
|
||||
bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
struct dmcu_iram_parameters params);
|
||||
|
||||
#endif /* MODULES_POWER_POWER_HELPERS_H_ */
|
||||
|
|
|
|||
|
|
@ -2265,8 +2265,6 @@ static void navi10_fill_i2c_req(SwI2cRequest_t *req, bool write,
|
|||
{
|
||||
int i;
|
||||
|
||||
BUG_ON(numbytes > MAX_SW_I2C_COMMANDS);
|
||||
|
||||
req->I2CcontrollerPort = 0;
|
||||
req->I2CSpeed = 2;
|
||||
req->SlaveAddress = address;
|
||||
|
|
@ -2304,6 +2302,12 @@ static int navi10_i2c_read_data(struct i2c_adapter *control,
|
|||
struct smu_table_context *smu_table = &adev->smu.smu_table;
|
||||
struct smu_table *table = &smu_table->driver_table;
|
||||
|
||||
if (numbytes > MAX_SW_I2C_COMMANDS) {
|
||||
dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
|
||||
numbytes, MAX_SW_I2C_COMMANDS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
navi10_fill_i2c_req(&req, false, address, numbytes, data);
|
||||
|
||||
|
|
@ -2340,6 +2344,12 @@ static int navi10_i2c_write_data(struct i2c_adapter *control,
|
|||
SwI2cRequest_t req;
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
if (numbytes > MAX_SW_I2C_COMMANDS) {
|
||||
dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
|
||||
numbytes, MAX_SW_I2C_COMMANDS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
navi10_fill_i2c_req(&req, true, address, numbytes, data);
|
||||
|
||||
|
|
|
|||
|
|
@ -2445,8 +2445,6 @@ static void sienna_cichlid_fill_i2c_req(SwI2cRequest_t *req, bool write,
|
|||
{
|
||||
int i;
|
||||
|
||||
BUG_ON(numbytes > MAX_SW_I2C_COMMANDS);
|
||||
|
||||
req->I2CcontrollerPort = 0;
|
||||
req->I2CSpeed = 2;
|
||||
req->SlaveAddress = address;
|
||||
|
|
@ -2484,6 +2482,12 @@ static int sienna_cichlid_i2c_read_data(struct i2c_adapter *control,
|
|||
struct smu_table_context *smu_table = &adev->smu.smu_table;
|
||||
struct smu_table *table = &smu_table->driver_table;
|
||||
|
||||
if (numbytes > MAX_SW_I2C_COMMANDS) {
|
||||
dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
|
||||
numbytes, MAX_SW_I2C_COMMANDS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
sienna_cichlid_fill_i2c_req(&req, false, address, numbytes, data);
|
||||
|
||||
|
|
@ -2520,6 +2524,12 @@ static int sienna_cichlid_i2c_write_data(struct i2c_adapter *control,
|
|||
SwI2cRequest_t req;
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
if (numbytes > MAX_SW_I2C_COMMANDS) {
|
||||
dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
|
||||
numbytes, MAX_SW_I2C_COMMANDS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
sienna_cichlid_fill_i2c_req(&req, true, address, numbytes, data);
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ void
|
|||
nouveau_mem_del(struct ttm_mem_reg *reg)
|
||||
{
|
||||
struct nouveau_mem *mem = nouveau_mem(reg);
|
||||
if (!mem)
|
||||
return;
|
||||
nouveau_mem_fini(mem);
|
||||
kfree(reg->mm_node);
|
||||
reg->mm_node = NULL;
|
||||
|
|
|
|||
|
|
@ -3149,6 +3149,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
|||
case 0x168: device->chip = &nv168_chipset; break;
|
||||
default:
|
||||
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/i2c.h>
|
||||
|
|
@ -33,12 +34,17 @@
|
|||
#define REG_CTRL_ACK_IGNORE BIT(1)
|
||||
#define REG_CTRL_STATUS BIT(2)
|
||||
#define REG_CTRL_ERROR BIT(3)
|
||||
#define REG_CTRL_CLKDIV_SHIFT 12
|
||||
#define REG_CTRL_CLKDIV_MASK GENMASK(21, 12)
|
||||
#define REG_CTRL_CLKDIVEXT_SHIFT 28
|
||||
#define REG_CTRL_CLKDIVEXT_MASK GENMASK(29, 28)
|
||||
#define REG_CTRL_CLKDIV GENMASK(21, 12)
|
||||
#define REG_CTRL_CLKDIVEXT GENMASK(29, 28)
|
||||
|
||||
#define REG_SLV_ADDR GENMASK(7, 0)
|
||||
#define REG_SLV_SDA_FILTER GENMASK(10, 8)
|
||||
#define REG_SLV_SCL_FILTER GENMASK(13, 11)
|
||||
#define REG_SLV_SCL_LOW GENMASK(27, 16)
|
||||
#define REG_SLV_SCL_LOW_EN BIT(28)
|
||||
|
||||
#define I2C_TIMEOUT_MS 500
|
||||
#define FILTER_DELAY 15
|
||||
|
||||
enum {
|
||||
TOKEN_END = 0,
|
||||
|
|
@ -133,19 +139,24 @@ static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq)
|
|||
unsigned long clk_rate = clk_get_rate(i2c->clk);
|
||||
unsigned int div;
|
||||
|
||||
div = DIV_ROUND_UP(clk_rate, freq * i2c->data->div_factor);
|
||||
div = DIV_ROUND_UP(clk_rate, freq);
|
||||
div -= FILTER_DELAY;
|
||||
div = DIV_ROUND_UP(div, i2c->data->div_factor);
|
||||
|
||||
/* clock divider has 12 bits */
|
||||
if (div >= (1 << 12)) {
|
||||
if (div > GENMASK(11, 0)) {
|
||||
dev_err(i2c->dev, "requested bus frequency too low\n");
|
||||
div = (1 << 12) - 1;
|
||||
div = GENMASK(11, 0);
|
||||
}
|
||||
|
||||
meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK,
|
||||
(div & GENMASK(9, 0)) << REG_CTRL_CLKDIV_SHIFT);
|
||||
meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV,
|
||||
FIELD_PREP(REG_CTRL_CLKDIV, div & GENMASK(9, 0)));
|
||||
|
||||
meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT_MASK,
|
||||
(div >> 10) << REG_CTRL_CLKDIVEXT_SHIFT);
|
||||
meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT,
|
||||
FIELD_PREP(REG_CTRL_CLKDIVEXT, div >> 10));
|
||||
|
||||
/* Disable HIGH/LOW mode */
|
||||
meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, 0);
|
||||
|
||||
dev_dbg(i2c->dev, "%s: clk %lu, freq %u, div %u\n", __func__,
|
||||
clk_rate, freq, div);
|
||||
|
|
@ -280,7 +291,10 @@ static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg)
|
|||
token = (msg->flags & I2C_M_RD) ? TOKEN_SLAVE_ADDR_READ :
|
||||
TOKEN_SLAVE_ADDR_WRITE;
|
||||
|
||||
writel(msg->addr << 1, i2c->regs + REG_SLAVE_ADDR);
|
||||
|
||||
meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_ADDR,
|
||||
FIELD_PREP(REG_SLV_ADDR, msg->addr << 1));
|
||||
|
||||
meson_i2c_add_token(i2c, TOKEN_START);
|
||||
meson_i2c_add_token(i2c, token);
|
||||
}
|
||||
|
|
@ -357,16 +371,12 @@ static int meson_i2c_xfer_messages(struct i2c_adapter *adap,
|
|||
struct meson_i2c *i2c = adap->algo_data;
|
||||
int i, ret = 0;
|
||||
|
||||
clk_enable(i2c->clk);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1, atomic);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
clk_disable(i2c->clk);
|
||||
|
||||
return ret ?: i;
|
||||
}
|
||||
|
||||
|
|
@ -435,7 +445,7 @@ static int meson_i2c_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare(i2c->clk);
|
||||
ret = clk_prepare_enable(i2c->clk);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "can't prepare clock\n");
|
||||
return ret;
|
||||
|
|
@ -457,10 +467,14 @@ static int meson_i2c_probe(struct platform_device *pdev)
|
|||
|
||||
ret = i2c_add_adapter(&i2c->adap);
|
||||
if (ret < 0) {
|
||||
clk_unprepare(i2c->clk);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable filtering */
|
||||
meson_i2c_set_mask(i2c, REG_SLAVE_ADDR,
|
||||
REG_SLV_SDA_FILTER | REG_SLV_SCL_FILTER, 0);
|
||||
|
||||
meson_i2c_set_clk_div(i2c, timings.bus_freq_hz);
|
||||
|
||||
return 0;
|
||||
|
|
@ -471,7 +485,7 @@ static int meson_i2c_remove(struct platform_device *pdev)
|
|||
struct meson_i2c *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
i2c_del_adapter(&i2c->adap);
|
||||
clk_unprepare(i2c->clk);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,9 @@ static irqreturn_t owl_i2c_interrupt(int irq, void *_dev)
|
|||
fifostat = readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT);
|
||||
if (fifostat & OWL_I2C_FIFOSTAT_RNB) {
|
||||
i2c_dev->err = -ENXIO;
|
||||
/* Clear NACK error bit by writing "1" */
|
||||
owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOSTAT,
|
||||
OWL_I2C_FIFOSTAT_RNB, true);
|
||||
goto stop;
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +186,9 @@ static irqreturn_t owl_i2c_interrupt(int irq, void *_dev)
|
|||
stat = readl(i2c_dev->base + OWL_I2C_REG_STAT);
|
||||
if (stat & OWL_I2C_STAT_BEB) {
|
||||
i2c_dev->err = -EIO;
|
||||
/* Clear BUS error bit by writing "1" */
|
||||
owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_STAT,
|
||||
OWL_I2C_STAT_BEB, true);
|
||||
goto stop;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1320,9 +1320,10 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
|
|||
}
|
||||
EXPORT_SYMBOL(rdma_read_gid_attr_ndev_rcu);
|
||||
|
||||
static int get_lower_dev_vlan(struct net_device *lower_dev, void *data)
|
||||
static int get_lower_dev_vlan(struct net_device *lower_dev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
u16 *vlan_id = data;
|
||||
u16 *vlan_id = (u16 *)priv->data;
|
||||
|
||||
if (is_vlan_dev(lower_dev))
|
||||
*vlan_id = vlan_dev_vlan_id(lower_dev);
|
||||
|
|
@ -1348,6 +1349,9 @@ static int get_lower_dev_vlan(struct net_device *lower_dev, void *data)
|
|||
int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr,
|
||||
u16 *vlan_id, u8 *smac)
|
||||
{
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)vlan_id,
|
||||
};
|
||||
struct net_device *ndev;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -1368,7 +1372,7 @@ int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr,
|
|||
* the lower vlan device for this gid entry.
|
||||
*/
|
||||
netdev_walk_all_lower_dev_rcu(attr->ndev,
|
||||
get_lower_dev_vlan, vlan_id);
|
||||
get_lower_dev_vlan, &priv);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
|
|
|||
|
|
@ -2865,9 +2865,10 @@ struct iboe_prio_tc_map {
|
|||
bool found;
|
||||
};
|
||||
|
||||
static int get_lower_vlan_dev_tc(struct net_device *dev, void *data)
|
||||
static int get_lower_vlan_dev_tc(struct net_device *dev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct iboe_prio_tc_map *map = data;
|
||||
struct iboe_prio_tc_map *map = (struct iboe_prio_tc_map *)priv->data;
|
||||
|
||||
if (is_vlan_dev(dev))
|
||||
map->output_tc = get_vlan_ndev_tc(dev, map->input_prio);
|
||||
|
|
@ -2886,16 +2887,18 @@ static int iboe_tos_to_sl(struct net_device *ndev, int tos)
|
|||
{
|
||||
struct iboe_prio_tc_map prio_tc_map = {};
|
||||
int prio = rt_tos2priority(tos);
|
||||
struct netdev_nested_priv priv;
|
||||
|
||||
/* If VLAN device, get it directly from the VLAN netdev */
|
||||
if (is_vlan_dev(ndev))
|
||||
return get_vlan_ndev_tc(ndev, prio);
|
||||
|
||||
prio_tc_map.input_prio = prio;
|
||||
priv.data = (void *)&prio_tc_map;
|
||||
rcu_read_lock();
|
||||
netdev_walk_all_lower_dev_rcu(ndev,
|
||||
get_lower_vlan_dev_tc,
|
||||
&prio_tc_map);
|
||||
&priv);
|
||||
rcu_read_unlock();
|
||||
/* If map is found from lower device, use it; Otherwise
|
||||
* continue with the current netdevice to get priority to tc map.
|
||||
|
|
|
|||
|
|
@ -531,10 +531,11 @@ struct upper_list {
|
|||
struct net_device *upper;
|
||||
};
|
||||
|
||||
static int netdev_upper_walk(struct net_device *upper, void *data)
|
||||
static int netdev_upper_walk(struct net_device *upper,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct upper_list *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
struct list_head *upper_list = data;
|
||||
struct list_head *upper_list = (struct list_head *)priv->data;
|
||||
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
|
@ -553,12 +554,14 @@ static void handle_netdev_upper(struct ib_device *ib_dev, u8 port,
|
|||
struct net_device *ndev))
|
||||
{
|
||||
struct net_device *ndev = cookie;
|
||||
struct netdev_nested_priv priv;
|
||||
struct upper_list *upper_iter;
|
||||
struct upper_list *upper_temp;
|
||||
LIST_HEAD(upper_list);
|
||||
|
||||
priv.data = &upper_list;
|
||||
rcu_read_lock();
|
||||
netdev_walk_all_upper_dev_rcu(ndev, netdev_upper_walk, &upper_list);
|
||||
netdev_walk_all_upper_dev_rcu(ndev, netdev_upper_walk, &priv);
|
||||
rcu_read_unlock();
|
||||
|
||||
handle_netdev(ib_dev, port, ndev);
|
||||
|
|
|
|||
|
|
@ -342,9 +342,10 @@ struct ipoib_walk_data {
|
|||
struct net_device *result;
|
||||
};
|
||||
|
||||
static int ipoib_upper_walk(struct net_device *upper, void *_data)
|
||||
static int ipoib_upper_walk(struct net_device *upper,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct ipoib_walk_data *data = _data;
|
||||
struct ipoib_walk_data *data = (struct ipoib_walk_data *)priv->data;
|
||||
int ret = 0;
|
||||
|
||||
if (ipoib_is_dev_match_addr_rcu(data->addr, upper)) {
|
||||
|
|
@ -368,10 +369,12 @@ static int ipoib_upper_walk(struct net_device *upper, void *_data)
|
|||
static struct net_device *ipoib_get_net_dev_match_addr(
|
||||
const struct sockaddr *addr, struct net_device *dev)
|
||||
{
|
||||
struct netdev_nested_priv priv;
|
||||
struct ipoib_walk_data data = {
|
||||
.addr = addr,
|
||||
};
|
||||
|
||||
priv.data = (void *)&data;
|
||||
rcu_read_lock();
|
||||
if (ipoib_is_dev_match_addr_rcu(addr, dev)) {
|
||||
dev_hold(dev);
|
||||
|
|
@ -379,7 +382,7 @@ static struct net_device *ipoib_get_net_dev_match_addr(
|
|||
goto out;
|
||||
}
|
||||
|
||||
netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &data);
|
||||
netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &priv);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return data.result;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
|
|||
q->limits.discard_granularity = card->pref_erase << 9;
|
||||
/* granularity must not be greater than max. discard */
|
||||
if (card->pref_erase > max_discard)
|
||||
q->limits.discard_granularity = 0;
|
||||
q->limits.discard_granularity = SECTOR_SIZE;
|
||||
if (mmc_can_secure_erase_trim(card))
|
||||
blk_queue_flag_set(QUEUE_FLAG_SECERASE, q);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -942,9 +942,10 @@ struct alb_walk_data {
|
|||
bool strict_match;
|
||||
};
|
||||
|
||||
static int alb_upper_dev_walk(struct net_device *upper, void *_data)
|
||||
static int alb_upper_dev_walk(struct net_device *upper,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct alb_walk_data *data = _data;
|
||||
struct alb_walk_data *data = (struct alb_walk_data *)priv->data;
|
||||
bool strict_match = data->strict_match;
|
||||
struct bonding *bond = data->bond;
|
||||
struct slave *slave = data->slave;
|
||||
|
|
@ -983,6 +984,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
|
|||
bool strict_match)
|
||||
{
|
||||
struct bonding *bond = bond_get_bond_by_slave(slave);
|
||||
struct netdev_nested_priv priv;
|
||||
struct alb_walk_data data = {
|
||||
.strict_match = strict_match,
|
||||
.mac_addr = mac_addr,
|
||||
|
|
@ -990,6 +992,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
|
|||
.bond = bond,
|
||||
};
|
||||
|
||||
priv.data = (void *)&data;
|
||||
/* send untagged */
|
||||
alb_send_lp_vid(slave, mac_addr, 0, 0);
|
||||
|
||||
|
|
@ -997,7 +1000,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
|
|||
* for that device.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
netdev_walk_all_upper_dev_rcu(bond->dev, alb_upper_dev_walk, &data);
|
||||
netdev_walk_all_upper_dev_rcu(bond->dev, alb_upper_dev_walk, &priv);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1315,6 +1315,7 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
|
|||
|
||||
bond_dev->type = slave_dev->type;
|
||||
bond_dev->hard_header_len = slave_dev->hard_header_len;
|
||||
bond_dev->needed_headroom = slave_dev->needed_headroom;
|
||||
bond_dev->addr_len = slave_dev->addr_len;
|
||||
|
||||
memcpy(bond_dev->broadcast, slave_dev->broadcast,
|
||||
|
|
@ -2510,22 +2511,26 @@ static void bond_mii_monitor(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
static int bond_upper_dev_walk(struct net_device *upper, void *data)
|
||||
static int bond_upper_dev_walk(struct net_device *upper,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
__be32 ip = *((__be32 *)data);
|
||||
__be32 ip = *(__be32 *)priv->data;
|
||||
|
||||
return ip == bond_confirm_addr(upper, 0, ip);
|
||||
}
|
||||
|
||||
static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
|
||||
{
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)&ip,
|
||||
};
|
||||
bool ret = false;
|
||||
|
||||
if (ip == bond_confirm_addr(bond->dev, 0, ip))
|
||||
return true;
|
||||
|
||||
rcu_read_lock();
|
||||
if (netdev_walk_all_upper_dev_rcu(bond->dev, bond_upper_dev_walk, &ip))
|
||||
if (netdev_walk_all_upper_dev_rcu(bond->dev, bond_upper_dev_walk, &priv))
|
||||
ret = true;
|
||||
rcu_read_unlock();
|
||||
|
||||
|
|
|
|||
|
|
@ -387,8 +387,8 @@ EXPORT_SYMBOL(ksz_switch_alloc);
|
|||
int ksz_switch_register(struct ksz_device *dev,
|
||||
const struct ksz_dev_ops *ops)
|
||||
{
|
||||
struct device_node *port, *ports;
|
||||
phy_interface_t interface;
|
||||
struct device_node *port;
|
||||
unsigned int port_num;
|
||||
int ret;
|
||||
|
||||
|
|
@ -429,13 +429,17 @@ int ksz_switch_register(struct ksz_device *dev,
|
|||
ret = of_get_phy_mode(dev->dev->of_node, &interface);
|
||||
if (ret == 0)
|
||||
dev->compat_interface = interface;
|
||||
for_each_available_child_of_node(dev->dev->of_node, port) {
|
||||
if (of_property_read_u32(port, "reg", &port_num))
|
||||
continue;
|
||||
if (port_num >= dev->port_cnt)
|
||||
return -EINVAL;
|
||||
of_get_phy_mode(port, &dev->ports[port_num].interface);
|
||||
}
|
||||
ports = of_get_child_by_name(dev->dev->of_node, "ports");
|
||||
if (ports)
|
||||
for_each_available_child_of_node(ports, port) {
|
||||
if (of_property_read_u32(port, "reg",
|
||||
&port_num))
|
||||
continue;
|
||||
if (port_num >= dev->port_cnt)
|
||||
return -EINVAL;
|
||||
of_get_phy_mode(port,
|
||||
&dev->ports[port_num].interface);
|
||||
}
|
||||
dev->synclko_125 = of_property_read_bool(dev->dev->of_node,
|
||||
"microchip,synclko-125");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -685,12 +685,12 @@ static struct vcap_field vsc9959_vcap_is2_actions[] = {
|
|||
[VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
|
||||
[VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
|
||||
[VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
|
||||
[VCAP_IS2_ACT_PORT_MASK] = { 20, 11},
|
||||
[VCAP_IS2_ACT_REW_OP] = { 31, 9},
|
||||
[VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1},
|
||||
[VCAP_IS2_ACT_RSV] = { 41, 2},
|
||||
[VCAP_IS2_ACT_ACL_ID] = { 43, 6},
|
||||
[VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
|
||||
[VCAP_IS2_ACT_PORT_MASK] = { 20, 6},
|
||||
[VCAP_IS2_ACT_REW_OP] = { 26, 9},
|
||||
[VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 35, 1},
|
||||
[VCAP_IS2_ACT_RSV] = { 36, 2},
|
||||
[VCAP_IS2_ACT_ACL_ID] = { 38, 6},
|
||||
[VCAP_IS2_ACT_HIT_CNT] = { 44, 32},
|
||||
};
|
||||
|
||||
static const struct vcap_props vsc9959_vcap_props[] = {
|
||||
|
|
@ -1171,6 +1171,8 @@ static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
|
|||
*/
|
||||
static u16 vsc9959_wm_enc(u16 value)
|
||||
{
|
||||
WARN_ON(value >= 16 * BIT(8));
|
||||
|
||||
if (value >= BIT(8))
|
||||
return BIT(8) | (value / 16);
|
||||
|
||||
|
|
@ -1284,8 +1286,28 @@ void vsc9959_mdio_bus_free(struct ocelot *ocelot)
|
|||
static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
|
||||
u32 speed)
|
||||
{
|
||||
u8 tas_speed;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_10:
|
||||
tas_speed = OCELOT_SPEED_10;
|
||||
break;
|
||||
case SPEED_100:
|
||||
tas_speed = OCELOT_SPEED_100;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
tas_speed = OCELOT_SPEED_1000;
|
||||
break;
|
||||
case SPEED_2500:
|
||||
tas_speed = OCELOT_SPEED_2500;
|
||||
break;
|
||||
default:
|
||||
tas_speed = OCELOT_SPEED_1000;
|
||||
break;
|
||||
}
|
||||
|
||||
ocelot_rmw_rix(ocelot,
|
||||
QSYS_TAG_CONFIG_LINK_SPEED(speed),
|
||||
QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
|
||||
QSYS_TAG_CONFIG_LINK_SPEED_M,
|
||||
QSYS_TAG_CONFIG, port);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ static const struct vcap_props vsc9953_vcap_props[] = {
|
|||
.action_type_width = 1,
|
||||
.action_table = {
|
||||
[IS2_ACTION_TYPE_NORMAL] = {
|
||||
.width = 44,
|
||||
.width = 50, /* HIT_CNT not included */
|
||||
.count = 2
|
||||
},
|
||||
[IS2_ACTION_TYPE_SMAC_SIP] = {
|
||||
|
|
@ -911,6 +911,8 @@ static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
|
|||
*/
|
||||
static u16 vsc9953_wm_enc(u16 value)
|
||||
{
|
||||
WARN_ON(value >= 16 * BIT(9));
|
||||
|
||||
if (value >= BIT(9))
|
||||
return BIT(9) | (value / 16);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ struct basic_ring {
|
|||
u32 lastWrite;
|
||||
};
|
||||
|
||||
/* The Typoon transmit ring -- same as a basic ring, plus:
|
||||
/* The Typhoon transmit ring -- same as a basic ring, plus:
|
||||
* lastRead: where we're at in regard to cleaning up the ring
|
||||
* writeRegister: register to use for writing (different for Hi & Lo rings)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
obj-$(CONFIG_AQTION) += atlantic.o
|
||||
|
||||
ccflags-y += -I$(src)
|
||||
ccflags-y += -I$(srctree)/$(src)
|
||||
|
||||
atlantic-objs := aq_main.o \
|
||||
aq_nic.o \
|
||||
|
|
@ -33,4 +33,4 @@ atlantic-objs := aq_main.o \
|
|||
|
||||
atlantic-$(CONFIG_MACSEC) += aq_macsec.o
|
||||
|
||||
atlantic-$(CONFIG_PTP_1588_CLOCK) += aq_ptp.o
|
||||
atlantic-$(CONFIG_PTP_1588_CLOCK) += aq_ptp.o
|
||||
|
|
|
|||
|
|
@ -284,12 +284,12 @@
|
|||
#define CCM_REG_GR_ARB_TYPE 0xd015c
|
||||
/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed; that the Store channel priority is
|
||||
the compliment to 4 of the rest priorities - Aggregation channel; Load
|
||||
the complement to 4 of the rest priorities - Aggregation channel; Load
|
||||
(FIC0) channel and Load (FIC1). */
|
||||
#define CCM_REG_GR_LD0_PR 0xd0164
|
||||
/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed; that the Store channel priority is
|
||||
the compliment to 4 of the rest priorities - Aggregation channel; Load
|
||||
the complement to 4 of the rest priorities - Aggregation channel; Load
|
||||
(FIC0) channel and Load (FIC1). */
|
||||
#define CCM_REG_GR_LD1_PR 0xd0168
|
||||
/* [RW 2] General flags index. */
|
||||
|
|
@ -4489,11 +4489,11 @@
|
|||
#define TCM_REG_GR_ARB_TYPE 0x50114
|
||||
/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Store channel is the
|
||||
compliment of the other 3 groups. */
|
||||
complement of the other 3 groups. */
|
||||
#define TCM_REG_GR_LD0_PR 0x5011c
|
||||
/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Store channel is the
|
||||
compliment of the other 3 groups. */
|
||||
complement of the other 3 groups. */
|
||||
#define TCM_REG_GR_LD1_PR 0x50120
|
||||
/* [RW 4] The number of double REG-pairs; loaded from the STORM context and
|
||||
sent to STORM; for a specific connection type. The double REG-pairs are
|
||||
|
|
@ -5020,11 +5020,11 @@
|
|||
#define UCM_REG_GR_ARB_TYPE 0xe0144
|
||||
/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Store channel group is
|
||||
compliment to the others. */
|
||||
complement to the others. */
|
||||
#define UCM_REG_GR_LD0_PR 0xe014c
|
||||
/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Store channel group is
|
||||
compliment to the others. */
|
||||
complement to the others. */
|
||||
#define UCM_REG_GR_LD1_PR 0xe0150
|
||||
/* [RW 2] The queue index for invalidate counter flag decision. */
|
||||
#define UCM_REG_INV_CFLG_Q 0xe00e4
|
||||
|
|
@ -5523,11 +5523,11 @@
|
|||
#define XCM_REG_GR_ARB_TYPE 0x2020c
|
||||
/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Channel group is the
|
||||
compliment of the other 3 groups. */
|
||||
complement of the other 3 groups. */
|
||||
#define XCM_REG_GR_LD0_PR 0x20214
|
||||
/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
|
||||
highest priority is 3. It is supposed that the Channel group is the
|
||||
compliment of the other 3 groups. */
|
||||
complement of the other 3 groups. */
|
||||
#define XCM_REG_GR_LD1_PR 0x20218
|
||||
/* [RW 1] Input nig0 Interface enable. If 0 - the valid input is
|
||||
disregarded; acknowledge output is deasserted; all other signals are
|
||||
|
|
|
|||
|
|
@ -1219,7 +1219,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
|
|||
*/
|
||||
if (netdev->phydev) {
|
||||
netif_carrier_off(netdev);
|
||||
phy_start_aneg(netdev->phydev);
|
||||
phy_start(netdev->phydev);
|
||||
}
|
||||
|
||||
netif_wake_queue(netdev);
|
||||
|
|
@ -1247,8 +1247,10 @@ static int octeon_mgmt_stop(struct net_device *netdev)
|
|||
napi_disable(&p->napi);
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
if (netdev->phydev)
|
||||
if (netdev->phydev) {
|
||||
phy_stop(netdev->phydev);
|
||||
phy_disconnect(netdev->phydev);
|
||||
}
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@
|
|||
#define DPNI_VER_MAJOR 7
|
||||
#define DPNI_VER_MINOR 0
|
||||
#define DPNI_CMD_BASE_VERSION 1
|
||||
#define DPNI_CMD_2ND_VERSION 2
|
||||
#define DPNI_CMD_ID_OFFSET 4
|
||||
|
||||
#define DPNI_CMD(id) (((id) << DPNI_CMD_ID_OFFSET) | DPNI_CMD_BASE_VERSION)
|
||||
#define DPNI_CMD_V2(id) (((id) << DPNI_CMD_ID_OFFSET) | DPNI_CMD_2ND_VERSION)
|
||||
|
||||
#define DPNI_CMDID_OPEN DPNI_CMD(0x801)
|
||||
#define DPNI_CMDID_CLOSE DPNI_CMD(0x800)
|
||||
|
|
@ -45,7 +47,7 @@
|
|||
#define DPNI_CMDID_SET_MAX_FRAME_LENGTH DPNI_CMD(0x216)
|
||||
#define DPNI_CMDID_GET_MAX_FRAME_LENGTH DPNI_CMD(0x217)
|
||||
#define DPNI_CMDID_SET_LINK_CFG DPNI_CMD(0x21A)
|
||||
#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD(0x21B)
|
||||
#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD_V2(0x21B)
|
||||
|
||||
#define DPNI_CMDID_SET_MCAST_PROMISC DPNI_CMD(0x220)
|
||||
#define DPNI_CMDID_GET_MCAST_PROMISC DPNI_CMD(0x221)
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
|
|||
/* Return all Fs if nothing was there */
|
||||
if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) &&
|
||||
!priv->has_a011043) {
|
||||
dev_err(&bus->dev,
|
||||
dev_dbg(&bus->dev,
|
||||
"Error while reading PHY%d reg at %d.%hhu\n",
|
||||
phy_id, dev_addr, regnum);
|
||||
return 0xffff;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
config HINIC
|
||||
tristate "Huawei Intelligent PCIE Network Interface Card"
|
||||
depends on (PCI_MSI && (X86 || ARM64))
|
||||
select NET_DEVLINK
|
||||
help
|
||||
This driver supports HiNIC PCIE Ethernet cards.
|
||||
To compile this driver as part of the kernel, choose Y here.
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
|
|||
sizeof(port_mac_cmd),
|
||||
&port_mac_cmd, &out_size);
|
||||
if (err || out_size != sizeof(port_mac_cmd) ||
|
||||
(port_mac_cmd.status &&
|
||||
port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY &&
|
||||
port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
|
||||
(port_mac_cmd.status &&
|
||||
(port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
|
||||
port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
|
||||
dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
|
||||
err, port_mac_cmd.status, out_size);
|
||||
return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ static int hinic_set_mac(struct hinic_hwdev *hwdev, const u8 *mac_addr,
|
|||
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
|
||||
sizeof(mac_info), &mac_info, &out_size);
|
||||
if (err || out_size != sizeof(mac_info) ||
|
||||
(mac_info.status && mac_info.status != HINIC_PF_SET_VF_ALREADY &&
|
||||
mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
|
||||
(mac_info.status && mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
|
||||
dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x\n",
|
||||
err, mac_info.status, out_size);
|
||||
return -EIO;
|
||||
|
|
@ -503,8 +502,7 @@ struct hinic_sriov_info *hinic_get_sriov_info_by_pcidev(struct pci_dev *pdev)
|
|||
|
||||
static int hinic_check_mac_info(u8 status, u16 vlan_id)
|
||||
{
|
||||
if ((status && status != HINIC_MGMT_STATUS_EXIST &&
|
||||
status != HINIC_PF_SET_VF_ALREADY) ||
|
||||
if ((status && status != HINIC_MGMT_STATUS_EXIST) ||
|
||||
(vlan_id & CHECK_IPSU_15BIT &&
|
||||
status == HINIC_MGMT_STATUS_EXIST))
|
||||
return -EINVAL;
|
||||
|
|
@ -546,12 +544,6 @@ static int hinic_update_mac(struct hinic_hwdev *hwdev, u8 *old_mac,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mac_info.status == HINIC_PF_SET_VF_ALREADY) {
|
||||
dev_warn(&hwdev->hwif->pdev->dev,
|
||||
"PF has already set VF MAC. Ignore update operation\n");
|
||||
return HINIC_PF_SET_VF_ALREADY;
|
||||
}
|
||||
|
||||
if (mac_info.status == HINIC_MGMT_STATUS_EXIST)
|
||||
dev_warn(&hwdev->hwif->pdev->dev, "MAC is repeated. Ignore update operation\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -3806,8 +3806,8 @@ static int __maybe_unused iavf_suspend(struct device *dev_d)
|
|||
static int __maybe_unused iavf_resume(struct device *dev_d)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev_d);
|
||||
struct iavf_adapter *adapter = pci_get_drvdata(pdev);
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct iavf_adapter *adapter = netdev_priv(netdev);
|
||||
u32 err;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
|
|
|||
|
|
@ -2288,26 +2288,28 @@ void ice_set_safe_mode_caps(struct ice_hw *hw)
|
|||
{
|
||||
struct ice_hw_func_caps *func_caps = &hw->func_caps;
|
||||
struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
|
||||
u32 valid_func, rxq_first_id, txq_first_id;
|
||||
u32 msix_vector_first_id, max_mtu;
|
||||
struct ice_hw_common_caps cached_caps;
|
||||
u32 num_funcs;
|
||||
|
||||
/* cache some func_caps values that should be restored after memset */
|
||||
valid_func = func_caps->common_cap.valid_functions;
|
||||
txq_first_id = func_caps->common_cap.txq_first_id;
|
||||
rxq_first_id = func_caps->common_cap.rxq_first_id;
|
||||
msix_vector_first_id = func_caps->common_cap.msix_vector_first_id;
|
||||
max_mtu = func_caps->common_cap.max_mtu;
|
||||
cached_caps = func_caps->common_cap;
|
||||
|
||||
/* unset func capabilities */
|
||||
memset(func_caps, 0, sizeof(*func_caps));
|
||||
|
||||
#define ICE_RESTORE_FUNC_CAP(name) \
|
||||
func_caps->common_cap.name = cached_caps.name
|
||||
|
||||
/* restore cached values */
|
||||
func_caps->common_cap.valid_functions = valid_func;
|
||||
func_caps->common_cap.txq_first_id = txq_first_id;
|
||||
func_caps->common_cap.rxq_first_id = rxq_first_id;
|
||||
func_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
|
||||
func_caps->common_cap.max_mtu = max_mtu;
|
||||
ICE_RESTORE_FUNC_CAP(valid_functions);
|
||||
ICE_RESTORE_FUNC_CAP(txq_first_id);
|
||||
ICE_RESTORE_FUNC_CAP(rxq_first_id);
|
||||
ICE_RESTORE_FUNC_CAP(msix_vector_first_id);
|
||||
ICE_RESTORE_FUNC_CAP(max_mtu);
|
||||
ICE_RESTORE_FUNC_CAP(nvm_unified_update);
|
||||
ICE_RESTORE_FUNC_CAP(nvm_update_pending_nvm);
|
||||
ICE_RESTORE_FUNC_CAP(nvm_update_pending_orom);
|
||||
ICE_RESTORE_FUNC_CAP(nvm_update_pending_netlist);
|
||||
|
||||
/* one Tx and one Rx queue in safe mode */
|
||||
func_caps->common_cap.num_rxq = 1;
|
||||
|
|
@ -2318,22 +2320,25 @@ void ice_set_safe_mode_caps(struct ice_hw *hw)
|
|||
func_caps->guar_num_vsi = 1;
|
||||
|
||||
/* cache some dev_caps values that should be restored after memset */
|
||||
valid_func = dev_caps->common_cap.valid_functions;
|
||||
txq_first_id = dev_caps->common_cap.txq_first_id;
|
||||
rxq_first_id = dev_caps->common_cap.rxq_first_id;
|
||||
msix_vector_first_id = dev_caps->common_cap.msix_vector_first_id;
|
||||
max_mtu = dev_caps->common_cap.max_mtu;
|
||||
cached_caps = dev_caps->common_cap;
|
||||
num_funcs = dev_caps->num_funcs;
|
||||
|
||||
/* unset dev capabilities */
|
||||
memset(dev_caps, 0, sizeof(*dev_caps));
|
||||
|
||||
#define ICE_RESTORE_DEV_CAP(name) \
|
||||
dev_caps->common_cap.name = cached_caps.name
|
||||
|
||||
/* restore cached values */
|
||||
dev_caps->common_cap.valid_functions = valid_func;
|
||||
dev_caps->common_cap.txq_first_id = txq_first_id;
|
||||
dev_caps->common_cap.rxq_first_id = rxq_first_id;
|
||||
dev_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
|
||||
dev_caps->common_cap.max_mtu = max_mtu;
|
||||
ICE_RESTORE_DEV_CAP(valid_functions);
|
||||
ICE_RESTORE_DEV_CAP(txq_first_id);
|
||||
ICE_RESTORE_DEV_CAP(rxq_first_id);
|
||||
ICE_RESTORE_DEV_CAP(msix_vector_first_id);
|
||||
ICE_RESTORE_DEV_CAP(max_mtu);
|
||||
ICE_RESTORE_DEV_CAP(nvm_unified_update);
|
||||
ICE_RESTORE_DEV_CAP(nvm_update_pending_nvm);
|
||||
ICE_RESTORE_DEV_CAP(nvm_update_pending_orom);
|
||||
ICE_RESTORE_DEV_CAP(nvm_update_pending_netlist);
|
||||
dev_caps->num_funcs = num_funcs;
|
||||
|
||||
/* one Tx and one Rx queue per function in safe mode */
|
||||
|
|
|
|||
|
|
@ -289,7 +289,13 @@ ice_write_one_nvm_block(struct ice_pf *pf, u16 module, u32 offset,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write, HZ, &event);
|
||||
/* In most cases, firmware reports a write completion within a few
|
||||
* milliseconds. However, it has been observed that a completion might
|
||||
* take more than a second to complete in some cases. The timeout here
|
||||
* is conservative and is intended to prevent failure to update when
|
||||
* firmware is slow to respond.
|
||||
*/
|
||||
err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write, 15 * HZ, &event);
|
||||
if (err) {
|
||||
dev_err(dev, "Timed out waiting for firmware write completion for module 0x%02x, err %d\n",
|
||||
module, err);
|
||||
|
|
@ -513,7 +519,7 @@ static int ice_switch_flash_banks(struct ice_pf *pf, u8 activate_flags,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write_activate, HZ,
|
||||
err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write_activate, 30 * HZ,
|
||||
&event);
|
||||
if (err) {
|
||||
dev_err(dev, "Timed out waiting for firmware to switch active flash banks, err %d\n",
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ static int ice_get_free_slot(void *array, int size, int curr)
|
|||
* ice_vsi_delete - delete a VSI from the switch
|
||||
* @vsi: pointer to VSI being removed
|
||||
*/
|
||||
void ice_vsi_delete(struct ice_vsi *vsi)
|
||||
static void ice_vsi_delete(struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_pf *pf = vsi->back;
|
||||
struct ice_vsi_ctx *ctxt;
|
||||
|
|
@ -313,7 +313,7 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi)
|
|||
*
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
int ice_vsi_clear(struct ice_vsi *vsi)
|
||||
static int ice_vsi_clear(struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_pf *pf = NULL;
|
||||
struct device *dev;
|
||||
|
|
@ -563,7 +563,7 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi)
|
|||
* ice_vsi_put_qs - Release queues from VSI to PF
|
||||
* @vsi: the VSI that is going to release queues
|
||||
*/
|
||||
void ice_vsi_put_qs(struct ice_vsi *vsi)
|
||||
static void ice_vsi_put_qs(struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_pf *pf = vsi->back;
|
||||
int i;
|
||||
|
|
@ -1196,6 +1196,18 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi)
|
|||
{
|
||||
int i;
|
||||
|
||||
/* Avoid stale references by clearing map from vector to ring */
|
||||
if (vsi->q_vectors) {
|
||||
ice_for_each_q_vector(vsi, i) {
|
||||
struct ice_q_vector *q_vector = vsi->q_vectors[i];
|
||||
|
||||
if (q_vector) {
|
||||
q_vector->tx.ring = NULL;
|
||||
q_vector->rx.ring = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vsi->tx_rings) {
|
||||
for (i = 0; i < vsi->alloc_txq; i++) {
|
||||
if (vsi->tx_rings[i]) {
|
||||
|
|
@ -2291,7 +2303,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
|
|||
if (status) {
|
||||
dev_err(dev, "VSI %d failed lan queue config, error %s\n",
|
||||
vsi->vsi_num, ice_stat_str(status));
|
||||
goto unroll_vector_base;
|
||||
goto unroll_clear_rings;
|
||||
}
|
||||
|
||||
/* Add switch rule to drop all Tx Flow Control Frames, of look up
|
||||
|
|
|
|||
|
|
@ -45,10 +45,6 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
|
|||
|
||||
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
|
||||
|
||||
void ice_vsi_delete(struct ice_vsi *vsi);
|
||||
|
||||
int ice_vsi_clear(struct ice_vsi *vsi);
|
||||
|
||||
#ifdef CONFIG_DCB
|
||||
int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc);
|
||||
#endif /* CONFIG_DCB */
|
||||
|
|
@ -79,8 +75,6 @@ bool ice_is_reset_in_progress(unsigned long *state);
|
|||
void
|
||||
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio);
|
||||
|
||||
void ice_vsi_put_qs(struct ice_vsi *vsi);
|
||||
|
||||
void ice_vsi_dis_irq(struct ice_vsi *vsi);
|
||||
|
||||
void ice_vsi_free_irq(struct ice_vsi *vsi);
|
||||
|
|
|
|||
|
|
@ -3169,10 +3169,8 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
|
|||
return -EBUSY;
|
||||
|
||||
vsi = ice_pf_vsi_setup(pf, pf->hw.port_info);
|
||||
if (!vsi) {
|
||||
status = -ENOMEM;
|
||||
goto unroll_vsi_setup;
|
||||
}
|
||||
if (!vsi)
|
||||
return -ENOMEM;
|
||||
|
||||
status = ice_cfg_netdev(vsi);
|
||||
if (status) {
|
||||
|
|
@ -3219,12 +3217,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
|
|||
}
|
||||
|
||||
unroll_vsi_setup:
|
||||
if (vsi) {
|
||||
ice_vsi_free_q_vectors(vsi);
|
||||
ice_vsi_delete(vsi);
|
||||
ice_vsi_put_qs(vsi);
|
||||
ice_vsi_clear(vsi);
|
||||
}
|
||||
ice_vsi_release(vsi);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -4522,6 +4515,7 @@ static int __maybe_unused ice_suspend(struct device *dev)
|
|||
}
|
||||
ice_clear_interrupt_scheme(pf);
|
||||
|
||||
pci_save_state(pdev);
|
||||
pci_wake_from_d3(pdev, pf->wol_ena);
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -5396,9 +5396,10 @@ static int ixgbe_fwd_ring_up(struct ixgbe_adapter *adapter,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ixgbe_macvlan_up(struct net_device *vdev, void *data)
|
||||
static int ixgbe_macvlan_up(struct net_device *vdev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = data;
|
||||
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)priv->data;
|
||||
struct ixgbe_fwd_adapter *accel;
|
||||
|
||||
if (!netif_is_macvlan(vdev))
|
||||
|
|
@ -5415,8 +5416,12 @@ static int ixgbe_macvlan_up(struct net_device *vdev, void *data)
|
|||
|
||||
static void ixgbe_configure_dfwd(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)adapter,
|
||||
};
|
||||
|
||||
netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
||||
ixgbe_macvlan_up, adapter);
|
||||
ixgbe_macvlan_up, &priv);
|
||||
}
|
||||
|
||||
static void ixgbe_configure(struct ixgbe_adapter *adapter)
|
||||
|
|
@ -9023,9 +9028,10 @@ static void ixgbe_set_prio_tc_map(struct ixgbe_adapter *adapter)
|
|||
}
|
||||
|
||||
#endif /* CONFIG_IXGBE_DCB */
|
||||
static int ixgbe_reassign_macvlan_pool(struct net_device *vdev, void *data)
|
||||
static int ixgbe_reassign_macvlan_pool(struct net_device *vdev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = data;
|
||||
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)priv->data;
|
||||
struct ixgbe_fwd_adapter *accel;
|
||||
int pool;
|
||||
|
||||
|
|
@ -9062,13 +9068,16 @@ static int ixgbe_reassign_macvlan_pool(struct net_device *vdev, void *data)
|
|||
static void ixgbe_defrag_macvlan_pools(struct net_device *dev)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = netdev_priv(dev);
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)adapter,
|
||||
};
|
||||
|
||||
/* flush any stale bits out of the fwd bitmask */
|
||||
bitmap_clear(adapter->fwd_bitmask, 1, 63);
|
||||
|
||||
/* walk through upper devices reassigning pools */
|
||||
netdev_walk_all_upper_dev_rcu(dev, ixgbe_reassign_macvlan_pool,
|
||||
adapter);
|
||||
&priv);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -9242,14 +9251,18 @@ struct upper_walk_data {
|
|||
u8 queue;
|
||||
};
|
||||
|
||||
static int get_macvlan_queue(struct net_device *upper, void *_data)
|
||||
static int get_macvlan_queue(struct net_device *upper,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
if (netif_is_macvlan(upper)) {
|
||||
struct ixgbe_fwd_adapter *vadapter = macvlan_accel_priv(upper);
|
||||
struct upper_walk_data *data = _data;
|
||||
struct ixgbe_adapter *adapter = data->adapter;
|
||||
int ifindex = data->ifindex;
|
||||
struct ixgbe_adapter *adapter;
|
||||
struct upper_walk_data *data;
|
||||
int ifindex;
|
||||
|
||||
data = (struct upper_walk_data *)priv->data;
|
||||
ifindex = data->ifindex;
|
||||
adapter = data->adapter;
|
||||
if (vadapter && upper->ifindex == ifindex) {
|
||||
data->queue = adapter->rx_ring[vadapter->rx_base_queue]->reg_idx;
|
||||
data->action = data->queue;
|
||||
|
|
@ -9265,6 +9278,7 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
|
|||
{
|
||||
struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
|
||||
unsigned int num_vfs = adapter->num_vfs, vf;
|
||||
struct netdev_nested_priv priv;
|
||||
struct upper_walk_data data;
|
||||
struct net_device *upper;
|
||||
|
||||
|
|
@ -9284,8 +9298,9 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
|
|||
data.ifindex = ifindex;
|
||||
data.action = 0;
|
||||
data.queue = 0;
|
||||
priv.data = (void *)&data;
|
||||
if (netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
||||
get_macvlan_queue, &data)) {
|
||||
get_macvlan_queue, &priv)) {
|
||||
*action = data.action;
|
||||
*queue = data.queue;
|
||||
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ static int xrx200_tx_housekeeping(struct napi_struct *napi, int budget)
|
|||
int pkts = 0;
|
||||
int bytes = 0;
|
||||
|
||||
netif_tx_lock(net_dev);
|
||||
while (pkts < budget) {
|
||||
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->tx_free];
|
||||
|
||||
|
|
@ -268,6 +269,7 @@ static int xrx200_tx_housekeeping(struct napi_struct *napi, int budget)
|
|||
net_dev->stats.tx_bytes += bytes;
|
||||
netdev_completed_queue(ch->priv->net_dev, pkts, bytes);
|
||||
|
||||
netif_tx_unlock(net_dev);
|
||||
if (netif_queue_stopped(net_dev))
|
||||
netif_wake_queue(net_dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -3400,24 +3400,15 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp,
|
|||
txq->last_desc = txq->size - 1;
|
||||
|
||||
txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL);
|
||||
if (!txq->buf) {
|
||||
dma_free_coherent(pp->dev->dev.parent,
|
||||
txq->size * MVNETA_DESC_ALIGNED_SIZE,
|
||||
txq->descs, txq->descs_phys);
|
||||
if (!txq->buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Allocate DMA buffers for TSO MAC/IP/TCP headers */
|
||||
txq->tso_hdrs = dma_alloc_coherent(pp->dev->dev.parent,
|
||||
txq->size * TSO_HEADER_SIZE,
|
||||
&txq->tso_hdrs_phys, GFP_KERNEL);
|
||||
if (!txq->tso_hdrs) {
|
||||
kfree(txq->buf);
|
||||
dma_free_coherent(pp->dev->dev.parent,
|
||||
txq->size * MVNETA_DESC_ALIGNED_SIZE,
|
||||
txq->descs, txq->descs_phys);
|
||||
if (!txq->tso_hdrs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Setup XPS mapping */
|
||||
if (txq_number > 1)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
static const u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
|
||||
void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
|
||||
{
|
||||
void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);
|
||||
struct otx2_mbox_dev *mdev = &mbox->dev[devid];
|
||||
|
|
@ -26,13 +26,21 @@ void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
|
|||
tx_hdr = hw_mbase + mbox->tx_start;
|
||||
rx_hdr = hw_mbase + mbox->rx_start;
|
||||
|
||||
spin_lock(&mdev->mbox_lock);
|
||||
mdev->msg_size = 0;
|
||||
mdev->rsp_size = 0;
|
||||
tx_hdr->num_msgs = 0;
|
||||
tx_hdr->msg_size = 0;
|
||||
rx_hdr->num_msgs = 0;
|
||||
rx_hdr->msg_size = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__otx2_mbox_reset);
|
||||
|
||||
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
|
||||
{
|
||||
struct otx2_mbox_dev *mdev = &mbox->dev[devid];
|
||||
|
||||
spin_lock(&mdev->mbox_lock);
|
||||
__otx2_mbox_reset(mbox, devid);
|
||||
spin_unlock(&mdev->mbox_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_mbox_reset);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ struct mbox_msghdr {
|
|||
};
|
||||
|
||||
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
|
||||
void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
|
||||
void otx2_mbox_destroy(struct otx2_mbox *mbox);
|
||||
int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase,
|
||||
struct pci_dev *pdev, void __force *reg_base,
|
||||
|
|
|
|||
|
|
@ -463,6 +463,7 @@ void rvu_nix_freemem(struct rvu *rvu);
|
|||
int rvu_get_nixlf_count(struct rvu *rvu);
|
||||
void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf);
|
||||
int nix_get_nixlf(struct rvu *rvu, u16 pcifunc, int *nixlf, int *nix_blkaddr);
|
||||
int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
|
||||
|
||||
/* NPC APIs */
|
||||
int rvu_npc_init(struct rvu *rvu);
|
||||
|
|
@ -477,7 +478,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
|
|||
void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
|
||||
int nixlf, u64 chan);
|
||||
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc);
|
||||
void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable);
|
||||
int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include "npc.h"
|
||||
#include "cgx.h"
|
||||
|
||||
static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
|
||||
static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
|
||||
int type, int chan_id);
|
||||
|
||||
|
|
@ -2020,7 +2019,7 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
|
||||
int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
|
||||
{
|
||||
int err = 0, idx, next_idx, last_idx;
|
||||
struct nix_mce_list *mce_list;
|
||||
|
|
@ -2065,7 +2064,7 @@ static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
|
|||
|
||||
/* Disable MCAM entry in NPC */
|
||||
if (!mce_list->count) {
|
||||
rvu_npc_disable_bcast_entry(rvu, pcifunc);
|
||||
rvu_npc_enable_bcast_entry(rvu, pcifunc, false);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
|
|||
NIX_INTF_RX, &entry, true);
|
||||
}
|
||||
|
||||
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
|
||||
void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
int blkaddr, index;
|
||||
|
|
@ -543,7 +543,7 @@ void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
|
|||
pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
|
||||
|
||||
index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY);
|
||||
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
|
||||
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
|
||||
}
|
||||
|
||||
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
|
||||
|
|
@ -622,23 +622,35 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
|
|||
nixlf, NIXLF_UCAST_ENTRY);
|
||||
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
|
||||
|
||||
/* For PF, ena/dis promisc and bcast MCAM match entries */
|
||||
if (pcifunc & RVU_PFVF_FUNC_MASK)
|
||||
/* For PF, ena/dis promisc and bcast MCAM match entries.
|
||||
* For VFs add/delete from bcast list when RX multicast
|
||||
* feature is present.
|
||||
*/
|
||||
if (pcifunc & RVU_PFVF_FUNC_MASK && !rvu->hw->cap.nix_rx_multicast)
|
||||
return;
|
||||
|
||||
/* For bcast, enable/disable only if it's action is not
|
||||
* packet replication, incase if action is replication
|
||||
* then this PF's nixlf is removed from bcast replication
|
||||
* then this PF/VF's nixlf is removed from bcast replication
|
||||
* list.
|
||||
*/
|
||||
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
|
||||
index = npc_get_nixlf_mcam_index(mcam, pcifunc & ~RVU_PFVF_FUNC_MASK,
|
||||
nixlf, NIXLF_BCAST_ENTRY);
|
||||
bank = npc_get_bank(mcam, index);
|
||||
*(u64 *)&action = rvu_read64(rvu, blkaddr,
|
||||
NPC_AF_MCAMEX_BANKX_ACTION(index & (mcam->banksize - 1), bank));
|
||||
if (action.op != NIX_RX_ACTIONOP_MCAST)
|
||||
|
||||
/* VFs will not have BCAST entry */
|
||||
if (action.op != NIX_RX_ACTIONOP_MCAST &&
|
||||
!(pcifunc & RVU_PFVF_FUNC_MASK)) {
|
||||
npc_enable_mcam_entry(rvu, mcam,
|
||||
blkaddr, index, enable);
|
||||
} else {
|
||||
nix_update_bcast_mce_list(rvu, pcifunc, enable);
|
||||
/* Enable PF's BCAST entry for packet replication */
|
||||
rvu_npc_enable_bcast_entry(rvu, pcifunc, enable);
|
||||
}
|
||||
|
||||
if (enable)
|
||||
rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -370,8 +370,8 @@ static int otx2_forward_vf_mbox_msgs(struct otx2_nic *pf,
|
|||
dst_mbox = &pf->mbox;
|
||||
dst_size = dst_mbox->mbox.tx_size -
|
||||
ALIGN(sizeof(*mbox_hdr), MBOX_MSG_ALIGN);
|
||||
/* Check if msgs fit into destination area */
|
||||
if (mbox_hdr->msg_size > dst_size)
|
||||
/* Check if msgs fit into destination area and has valid size */
|
||||
if (mbox_hdr->msg_size > dst_size || !mbox_hdr->msg_size)
|
||||
return -EINVAL;
|
||||
|
||||
dst_mdev = &dst_mbox->mbox.dev[0];
|
||||
|
|
@ -526,10 +526,10 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
|
|||
|
||||
end:
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
|
||||
__otx2_mbox_reset(mbox, 0);
|
||||
mdev->msgs_acked++;
|
||||
}
|
||||
|
||||
otx2_mbox_reset(mbox, vf_idx);
|
||||
}
|
||||
|
||||
static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
|
||||
|
|
@ -803,10 +803,11 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work)
|
|||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
otx2_process_pfaf_mbox_msg(pf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
|
||||
__otx2_mbox_reset(mbox, 0);
|
||||
mdev->msgs_acked++;
|
||||
}
|
||||
|
||||
otx2_mbox_reset(mbox, 0);
|
||||
}
|
||||
|
||||
static void otx2_handle_link_event(struct otx2_nic *pf)
|
||||
|
|
@ -1560,10 +1561,13 @@ int otx2_open(struct net_device *netdev)
|
|||
|
||||
err = otx2_rxtx_enable(pf, true);
|
||||
if (err)
|
||||
goto err_free_cints;
|
||||
goto err_tx_stop_queues;
|
||||
|
||||
return 0;
|
||||
|
||||
err_tx_stop_queues:
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
netif_carrier_off(netdev);
|
||||
err_free_cints:
|
||||
otx2_free_cints(pf, qidx);
|
||||
vec = pci_irq_vector(pf->pdev,
|
||||
|
|
|
|||
|
|
@ -524,6 +524,7 @@ static void otx2_sqe_add_hdr(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
|
|||
sqe_hdr->ol3type = NIX_SENDL3TYPE_IP4_CKSUM;
|
||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
proto = ipv6_hdr(skb)->nexthdr;
|
||||
sqe_hdr->ol3type = NIX_SENDL3TYPE_IP6;
|
||||
}
|
||||
|
||||
if (proto == IPPROTO_TCP)
|
||||
|
|
|
|||
|
|
@ -99,10 +99,10 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
|
|||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
|
||||
__otx2_mbox_reset(mbox, 0);
|
||||
mdev->msgs_acked++;
|
||||
}
|
||||
|
||||
otx2_mbox_reset(mbox, 0);
|
||||
}
|
||||
|
||||
static int otx2vf_process_mbox_msg_up(struct otx2_nic *vf,
|
||||
|
|
|
|||
|
|
@ -69,12 +69,10 @@ enum {
|
|||
MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR = 0x10,
|
||||
};
|
||||
|
||||
static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
|
||||
struct mlx5_cmd_msg *in,
|
||||
struct mlx5_cmd_msg *out,
|
||||
void *uout, int uout_size,
|
||||
mlx5_cmd_cbk_t cbk,
|
||||
void *context, int page_queue)
|
||||
static struct mlx5_cmd_work_ent *
|
||||
cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in,
|
||||
struct mlx5_cmd_msg *out, void *uout, int uout_size,
|
||||
mlx5_cmd_cbk_t cbk, void *context, int page_queue)
|
||||
{
|
||||
gfp_t alloc_flags = cbk ? GFP_ATOMIC : GFP_KERNEL;
|
||||
struct mlx5_cmd_work_ent *ent;
|
||||
|
|
@ -83,6 +81,7 @@ static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
|
|||
if (!ent)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ent->idx = -EINVAL;
|
||||
ent->in = in;
|
||||
ent->out = out;
|
||||
ent->uout = uout;
|
||||
|
|
@ -91,10 +90,16 @@ static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
|
|||
ent->context = context;
|
||||
ent->cmd = cmd;
|
||||
ent->page_queue = page_queue;
|
||||
refcount_set(&ent->refcnt, 1);
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
static void cmd_free_ent(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
kfree(ent);
|
||||
}
|
||||
|
||||
static u8 alloc_token(struct mlx5_cmd *cmd)
|
||||
{
|
||||
u8 token;
|
||||
|
|
@ -109,7 +114,7 @@ static u8 alloc_token(struct mlx5_cmd *cmd)
|
|||
return token;
|
||||
}
|
||||
|
||||
static int alloc_ent(struct mlx5_cmd *cmd)
|
||||
static int cmd_alloc_index(struct mlx5_cmd *cmd)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
|
@ -123,7 +128,7 @@ static int alloc_ent(struct mlx5_cmd *cmd)
|
|||
return ret < cmd->max_reg_cmds ? ret : -ENOMEM;
|
||||
}
|
||||
|
||||
static void free_ent(struct mlx5_cmd *cmd, int idx)
|
||||
static void cmd_free_index(struct mlx5_cmd *cmd, int idx)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -132,6 +137,22 @@ static void free_ent(struct mlx5_cmd *cmd, int idx)
|
|||
spin_unlock_irqrestore(&cmd->alloc_lock, flags);
|
||||
}
|
||||
|
||||
static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
refcount_inc(&ent->refcnt);
|
||||
}
|
||||
|
||||
static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
if (!refcount_dec_and_test(&ent->refcnt))
|
||||
return;
|
||||
|
||||
if (ent->idx >= 0)
|
||||
cmd_free_index(ent->cmd, ent->idx);
|
||||
|
||||
cmd_free_ent(ent);
|
||||
}
|
||||
|
||||
static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx)
|
||||
{
|
||||
return cmd->cmd_buf + (idx << cmd->log_stride);
|
||||
|
|
@ -219,11 +240,6 @@ static void poll_timeout(struct mlx5_cmd_work_ent *ent)
|
|||
ent->ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void free_cmd(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
kfree(ent);
|
||||
}
|
||||
|
||||
static int verify_signature(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
struct mlx5_cmd_mailbox *next = ent->out->next;
|
||||
|
|
@ -837,11 +853,22 @@ static void cb_timeout_handler(struct work_struct *work)
|
|||
struct mlx5_core_dev *dev = container_of(ent->cmd, struct mlx5_core_dev,
|
||||
cmd);
|
||||
|
||||
mlx5_cmd_eq_recover(dev);
|
||||
|
||||
/* Maybe got handled by eq recover ? */
|
||||
if (!test_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state)) {
|
||||
mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, recovered after timeout\n", ent->idx,
|
||||
mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
|
||||
goto out; /* phew, already handled */
|
||||
}
|
||||
|
||||
ent->ret = -ETIMEDOUT;
|
||||
mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
|
||||
mlx5_command_str(msg_to_opcode(ent->in)),
|
||||
msg_to_opcode(ent->in));
|
||||
mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n",
|
||||
ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
|
||||
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
|
||||
|
||||
out:
|
||||
cmd_ent_put(ent); /* for the cmd_ent_get() took on schedule delayed work */
|
||||
}
|
||||
|
||||
static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
|
||||
|
|
@ -856,6 +883,32 @@ static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)
|
|||
return cmd->allowed_opcode == opcode;
|
||||
}
|
||||
|
||||
static int cmd_alloc_index_retry(struct mlx5_cmd *cmd)
|
||||
{
|
||||
unsigned long alloc_end = jiffies + msecs_to_jiffies(1000);
|
||||
int idx;
|
||||
|
||||
retry:
|
||||
idx = cmd_alloc_index(cmd);
|
||||
if (idx < 0 && time_before(jiffies, alloc_end)) {
|
||||
/* Index allocation can fail on heavy load of commands. This is a temporary
|
||||
* situation as the current command already holds the semaphore, meaning that
|
||||
* another command completion is being handled and it is expected to release
|
||||
* the entry index soon.
|
||||
*/
|
||||
cpu_relax();
|
||||
goto retry;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool mlx5_cmd_is_down(struct mlx5_core_dev *dev)
|
||||
{
|
||||
return pci_channel_offline(dev->pdev) ||
|
||||
dev->cmd.state != MLX5_CMDIF_STATE_UP ||
|
||||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
static void cmd_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
|
||||
|
|
@ -873,14 +926,14 @@ static void cmd_work_handler(struct work_struct *work)
|
|||
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
|
||||
down(sem);
|
||||
if (!ent->page_queue) {
|
||||
alloc_ret = alloc_ent(cmd);
|
||||
alloc_ret = cmd_alloc_index_retry(cmd);
|
||||
if (alloc_ret < 0) {
|
||||
mlx5_core_err_rl(dev, "failed to allocate command entry\n");
|
||||
if (ent->callback) {
|
||||
ent->callback(-EAGAIN, ent->context);
|
||||
mlx5_free_cmd_msg(dev, ent->out);
|
||||
free_msg(dev, ent->in);
|
||||
free_cmd(ent);
|
||||
cmd_ent_put(ent);
|
||||
} else {
|
||||
ent->ret = -EAGAIN;
|
||||
complete(&ent->done);
|
||||
|
|
@ -916,15 +969,12 @@ static void cmd_work_handler(struct work_struct *work)
|
|||
ent->ts1 = ktime_get_ns();
|
||||
cmd_mode = cmd->mode;
|
||||
|
||||
if (ent->callback)
|
||||
schedule_delayed_work(&ent->cb_timeout_work, cb_timeout);
|
||||
if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, cb_timeout))
|
||||
cmd_ent_get(ent);
|
||||
set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
|
||||
|
||||
/* Skip sending command to fw if internal error */
|
||||
if (pci_channel_offline(dev->pdev) ||
|
||||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
|
||||
cmd->state != MLX5_CMDIF_STATE_UP ||
|
||||
!opcode_allowed(&dev->cmd, ent->op)) {
|
||||
if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
|
||||
u8 status = 0;
|
||||
u32 drv_synd;
|
||||
|
||||
|
|
@ -933,13 +983,10 @@ static void cmd_work_handler(struct work_struct *work)
|
|||
MLX5_SET(mbox_out, ent->out, syndrome, drv_synd);
|
||||
|
||||
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
|
||||
/* no doorbell, no need to keep the entry */
|
||||
free_ent(cmd, ent->idx);
|
||||
if (ent->callback)
|
||||
free_cmd(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_ent_get(ent); /* for the _real_ FW event on completion */
|
||||
/* ring doorbell after the descriptor is valid */
|
||||
mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
|
||||
wmb();
|
||||
|
|
@ -983,6 +1030,35 @@ static const char *deliv_status_to_str(u8 status)
|
|||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
MLX5_CMD_TIMEOUT_RECOVER_MSEC = 5 * 1000,
|
||||
};
|
||||
|
||||
static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev,
|
||||
struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_RECOVER_MSEC);
|
||||
|
||||
mlx5_cmd_eq_recover(dev);
|
||||
|
||||
/* Re-wait on the ent->done after executing the recovery flow. If the
|
||||
* recovery flow (or any other recovery flow running simultaneously)
|
||||
* has recovered an EQE, it should cause the entry to be completed by
|
||||
* the command interface.
|
||||
*/
|
||||
if (wait_for_completion_timeout(&ent->done, timeout)) {
|
||||
mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) recovered after timeout\n", ent->idx,
|
||||
mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
|
||||
return;
|
||||
}
|
||||
|
||||
mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) No done completion\n", ent->idx,
|
||||
mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
|
||||
|
||||
ent->ret = -ETIMEDOUT;
|
||||
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
|
||||
}
|
||||
|
||||
static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
|
||||
|
|
@ -994,12 +1070,10 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
|
|||
ent->ret = -ECANCELED;
|
||||
goto out_err;
|
||||
}
|
||||
if (cmd->mode == CMD_MODE_POLLING || ent->polling) {
|
||||
if (cmd->mode == CMD_MODE_POLLING || ent->polling)
|
||||
wait_for_completion(&ent->done);
|
||||
} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
|
||||
ent->ret = -ETIMEDOUT;
|
||||
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
|
||||
}
|
||||
else if (!wait_for_completion_timeout(&ent->done, timeout))
|
||||
wait_func_handle_exec_timeout(dev, ent);
|
||||
|
||||
out_err:
|
||||
err = ent->ret;
|
||||
|
|
@ -1039,11 +1113,16 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
|
|||
if (callback && page_queue)
|
||||
return -EINVAL;
|
||||
|
||||
ent = alloc_cmd(cmd, in, out, uout, uout_size, callback, context,
|
||||
page_queue);
|
||||
ent = cmd_alloc_ent(cmd, in, out, uout, uout_size,
|
||||
callback, context, page_queue);
|
||||
if (IS_ERR(ent))
|
||||
return PTR_ERR(ent);
|
||||
|
||||
/* put for this ent is when consumed, depending on the use case
|
||||
* 1) (!callback) blocking flow: by caller after wait_func completes
|
||||
* 2) (callback) flow: by mlx5_cmd_comp_handler() when ent is handled
|
||||
*/
|
||||
|
||||
ent->token = token;
|
||||
ent->polling = force_polling;
|
||||
|
||||
|
|
@ -1062,12 +1141,10 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
|
|||
}
|
||||
|
||||
if (callback)
|
||||
goto out;
|
||||
goto out; /* mlx5_cmd_comp_handler() will put(ent) */
|
||||
|
||||
err = wait_func(dev, ent);
|
||||
if (err == -ETIMEDOUT)
|
||||
goto out;
|
||||
if (err == -ECANCELED)
|
||||
if (err == -ETIMEDOUT || err == -ECANCELED)
|
||||
goto out_free;
|
||||
|
||||
ds = ent->ts2 - ent->ts1;
|
||||
|
|
@ -1085,7 +1162,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
|
|||
*status = ent->status;
|
||||
|
||||
out_free:
|
||||
free_cmd(ent);
|
||||
cmd_ent_put(ent);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1516,14 +1593,19 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
if (!forced) {
|
||||
mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n",
|
||||
ent->idx);
|
||||
free_ent(cmd, ent->idx);
|
||||
free_cmd(ent);
|
||||
cmd_ent_put(ent);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ent->callback)
|
||||
cancel_delayed_work(&ent->cb_timeout_work);
|
||||
if (ent->callback && cancel_delayed_work(&ent->cb_timeout_work))
|
||||
cmd_ent_put(ent); /* timeout work was canceled */
|
||||
|
||||
if (!forced || /* Real FW completion */
|
||||
pci_channel_offline(dev->pdev) || /* FW is inaccessible */
|
||||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
|
||||
cmd_ent_put(ent);
|
||||
|
||||
if (ent->page_queue)
|
||||
sem = &cmd->pages_sem;
|
||||
else
|
||||
|
|
@ -1545,10 +1627,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
ent->ret, deliv_status_to_str(ent->status), ent->status);
|
||||
}
|
||||
|
||||
/* only real completion will free the entry slot */
|
||||
if (!forced)
|
||||
free_ent(cmd, ent->idx);
|
||||
|
||||
if (ent->callback) {
|
||||
ds = ent->ts2 - ent->ts1;
|
||||
if (ent->op < MLX5_CMD_OP_MAX) {
|
||||
|
|
@ -1576,10 +1654,13 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
free_msg(dev, ent->in);
|
||||
|
||||
err = err ? err : ent->status;
|
||||
if (!forced)
|
||||
free_cmd(ent);
|
||||
/* final consumer is done, release ent */
|
||||
cmd_ent_put(ent);
|
||||
callback(err, context);
|
||||
} else {
|
||||
/* release wait_func() so mlx5_cmd_invoke()
|
||||
* can make the final ent_put()
|
||||
*/
|
||||
complete(&ent->done);
|
||||
}
|
||||
up(sem);
|
||||
|
|
@ -1589,8 +1670,11 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
|
||||
void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_cmd *cmd = &dev->cmd;
|
||||
unsigned long bitmask;
|
||||
unsigned long flags;
|
||||
u64 vector;
|
||||
int i;
|
||||
|
||||
/* wait for pending handlers to complete */
|
||||
mlx5_eq_synchronize_cmd_irq(dev);
|
||||
|
|
@ -1599,11 +1683,20 @@ void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
|
|||
if (!vector)
|
||||
goto no_trig;
|
||||
|
||||
bitmask = vector;
|
||||
/* we must increment the allocated entries refcount before triggering the completions
|
||||
* to guarantee pending commands will not get freed in the meanwhile.
|
||||
* For that reason, it also has to be done inside the alloc_lock.
|
||||
*/
|
||||
for_each_set_bit(i, &bitmask, (1 << cmd->log_sz))
|
||||
cmd_ent_get(cmd->ent_arr[i]);
|
||||
vector |= MLX5_TRIGGERED_CMD_COMP;
|
||||
spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
|
||||
|
||||
mlx5_core_dbg(dev, "vector 0x%llx\n", vector);
|
||||
mlx5_cmd_comp_handler(dev, vector, true);
|
||||
for_each_set_bit(i, &bitmask, (1 << cmd->log_sz))
|
||||
cmd_ent_put(cmd->ent_arr[i]);
|
||||
return;
|
||||
|
||||
no_trig:
|
||||
|
|
@ -1711,10 +1804,7 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
|
|||
u8 token;
|
||||
|
||||
opcode = MLX5_GET(mbox_in, in, opcode);
|
||||
if (pci_channel_offline(dev->pdev) ||
|
||||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
|
||||
dev->cmd.state != MLX5_CMDIF_STATE_UP ||
|
||||
!opcode_allowed(&dev->cmd, opcode)) {
|
||||
if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, opcode)) {
|
||||
err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
|
||||
MLX5_SET(mbox_out, out, status, status);
|
||||
MLX5_SET(mbox_out, out, syndrome, drv_synd);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,12 @@ struct page_pool;
|
|||
#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
|
||||
|
||||
#define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2)
|
||||
#define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8))
|
||||
/* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between
|
||||
* WQEs, This page will absorb write overflow by the hardware, when
|
||||
* receiving packets larger than MTU. These oversize packets are
|
||||
* dropped by the driver at a later stage.
|
||||
*/
|
||||
#define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE + 1, 8))
|
||||
#define MLX5E_LOG_ALIGNED_MPWQE_PPW (ilog2(MLX5E_REQUIRED_WQE_MTTS))
|
||||
#define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS)
|
||||
#define MLX5E_MAX_RQ_NUM_MTTS \
|
||||
|
|
@ -617,6 +622,7 @@ struct mlx5e_rq {
|
|||
u32 rqn;
|
||||
struct mlx5_core_dev *mdev;
|
||||
struct mlx5_core_mkey umr_mkey;
|
||||
struct mlx5e_dma_info wqe_overflow;
|
||||
|
||||
/* XDP read-mostly */
|
||||
struct xdp_rxq_info xdp_rxq;
|
||||
|
|
|
|||
|
|
@ -569,6 +569,9 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
|
|||
if (fec_policy >= (1 << MLX5E_FEC_LLRS_272_257_1) && !fec_50g_per_lane)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (fec_policy && !mlx5e_fec_in_caps(dev, fec_policy))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
MLX5_SET(pplm_reg, in, local_port, 1);
|
||||
err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 0);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -110,11 +110,25 @@ static void mlx5e_rep_neigh_stats_work(struct work_struct *work)
|
|||
rtnl_unlock();
|
||||
}
|
||||
|
||||
struct neigh_update_work {
|
||||
struct work_struct work;
|
||||
struct neighbour *n;
|
||||
struct mlx5e_neigh_hash_entry *nhe;
|
||||
};
|
||||
|
||||
static void mlx5e_release_neigh_update_work(struct neigh_update_work *update_work)
|
||||
{
|
||||
neigh_release(update_work->n);
|
||||
mlx5e_rep_neigh_entry_release(update_work->nhe);
|
||||
kfree(update_work);
|
||||
}
|
||||
|
||||
static void mlx5e_rep_neigh_update(struct work_struct *work)
|
||||
{
|
||||
struct mlx5e_neigh_hash_entry *nhe =
|
||||
container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
|
||||
struct neighbour *n = nhe->n;
|
||||
struct neigh_update_work *update_work = container_of(work, struct neigh_update_work,
|
||||
work);
|
||||
struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
|
||||
struct neighbour *n = update_work->n;
|
||||
struct mlx5e_encap_entry *e;
|
||||
unsigned char ha[ETH_ALEN];
|
||||
struct mlx5e_priv *priv;
|
||||
|
|
@ -146,30 +160,42 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
|
|||
mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
|
||||
mlx5e_encap_put(priv, e);
|
||||
}
|
||||
mlx5e_rep_neigh_entry_release(nhe);
|
||||
rtnl_unlock();
|
||||
neigh_release(n);
|
||||
mlx5e_release_neigh_update_work(update_work);
|
||||
}
|
||||
|
||||
static void mlx5e_rep_queue_neigh_update_work(struct mlx5e_priv *priv,
|
||||
struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct neighbour *n)
|
||||
static struct neigh_update_work *mlx5e_alloc_neigh_update_work(struct mlx5e_priv *priv,
|
||||
struct neighbour *n)
|
||||
{
|
||||
/* Take a reference to ensure the neighbour and mlx5 encap
|
||||
* entry won't be destructed until we drop the reference in
|
||||
* delayed work.
|
||||
*/
|
||||
neigh_hold(n);
|
||||
struct neigh_update_work *update_work;
|
||||
struct mlx5e_neigh_hash_entry *nhe;
|
||||
struct mlx5e_neigh m_neigh = {};
|
||||
|
||||
/* This assignment is valid as long as the the neigh reference
|
||||
* is taken
|
||||
*/
|
||||
nhe->n = n;
|
||||
update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC);
|
||||
if (WARN_ON(!update_work))
|
||||
return NULL;
|
||||
|
||||
if (!queue_work(priv->wq, &nhe->neigh_update_work)) {
|
||||
mlx5e_rep_neigh_entry_release(nhe);
|
||||
neigh_release(n);
|
||||
m_neigh.dev = n->dev;
|
||||
m_neigh.family = n->ops->family;
|
||||
memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
|
||||
|
||||
/* Obtain reference to nhe as last step in order not to release it in
|
||||
* atomic context.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
|
||||
rcu_read_unlock();
|
||||
if (!nhe) {
|
||||
kfree(update_work);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_WORK(&update_work->work, mlx5e_rep_neigh_update);
|
||||
neigh_hold(n);
|
||||
update_work->n = n;
|
||||
update_work->nhe = nhe;
|
||||
|
||||
return update_work;
|
||||
}
|
||||
|
||||
static int mlx5e_rep_netevent_event(struct notifier_block *nb,
|
||||
|
|
@ -181,7 +207,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
|
|||
struct net_device *netdev = rpriv->netdev;
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
struct mlx5e_neigh_hash_entry *nhe = NULL;
|
||||
struct mlx5e_neigh m_neigh = {};
|
||||
struct neigh_update_work *update_work;
|
||||
struct neigh_parms *p;
|
||||
struct neighbour *n;
|
||||
bool found = false;
|
||||
|
|
@ -196,17 +222,11 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
|
|||
#endif
|
||||
return NOTIFY_DONE;
|
||||
|
||||
m_neigh.dev = n->dev;
|
||||
m_neigh.family = n->ops->family;
|
||||
memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
|
||||
|
||||
rcu_read_lock();
|
||||
nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
|
||||
rcu_read_unlock();
|
||||
if (!nhe)
|
||||
update_work = mlx5e_alloc_neigh_update_work(priv, n);
|
||||
if (!update_work)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
mlx5e_rep_queue_neigh_update_work(priv, nhe, n);
|
||||
queue_work(priv->wq, &update_work->work);
|
||||
break;
|
||||
|
||||
case NETEVENT_DELAY_PROBE_TIME_UPDATE:
|
||||
|
|
@ -352,7 +372,6 @@ int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv,
|
|||
|
||||
(*nhe)->priv = priv;
|
||||
memcpy(&(*nhe)->m_neigh, &e->m_neigh, sizeof(e->m_neigh));
|
||||
INIT_WORK(&(*nhe)->neigh_update_work, mlx5e_rep_neigh_update);
|
||||
spin_lock_init(&(*nhe)->encap_list_lock);
|
||||
INIT_LIST_HEAD(&(*nhe)->encap_list);
|
||||
refcount_set(&(*nhe)->refcnt, 1);
|
||||
|
|
|
|||
|
|
@ -246,8 +246,10 @@ mlx5_tc_ct_rule_to_tuple_nat(struct mlx5_ct_tuple *tuple,
|
|||
case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
|
||||
ip6_offset = (offset - offsetof(struct ipv6hdr, saddr));
|
||||
ip6_offset /= 4;
|
||||
if (ip6_offset < 8)
|
||||
if (ip6_offset < 4)
|
||||
tuple->ip.src_v6.s6_addr32[ip6_offset] = cpu_to_be32(val);
|
||||
else if (ip6_offset < 8)
|
||||
tuple->ip.dst_v6.s6_addr32[ip6_offset - 4] = cpu_to_be32(val);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
|
|||
break;
|
||||
}
|
||||
|
||||
if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type))
|
||||
return 0;
|
||||
|
||||
*rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
|
||||
|
||||
if (IS_ERR(*rule_p)) {
|
||||
|
|
@ -397,8 +400,7 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
|
|||
for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID)
|
||||
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
|
||||
|
||||
if (priv->fs.vlan.cvlan_filter_disabled &&
|
||||
!(priv->netdev->flags & IFF_PROMISC))
|
||||
if (priv->fs.vlan.cvlan_filter_disabled)
|
||||
mlx5e_add_any_vid_rules(priv);
|
||||
}
|
||||
|
||||
|
|
@ -415,8 +417,12 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
|
|||
for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID)
|
||||
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
|
||||
|
||||
if (priv->fs.vlan.cvlan_filter_disabled &&
|
||||
!(priv->netdev->flags & IFF_PROMISC))
|
||||
WARN_ON_ONCE(!(test_bit(MLX5E_STATE_DESTROYING, &priv->state)));
|
||||
|
||||
/* must be called after DESTROY bit is set and
|
||||
* set_rx_mode is called and flushed
|
||||
*/
|
||||
if (priv->fs.vlan.cvlan_filter_disabled)
|
||||
mlx5e_del_any_vid_rules(priv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,12 +246,17 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
|
|||
|
||||
static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
|
||||
u64 npages, u8 page_shift,
|
||||
struct mlx5_core_mkey *umr_mkey)
|
||||
struct mlx5_core_mkey *umr_mkey,
|
||||
dma_addr_t filler_addr)
|
||||
{
|
||||
int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
|
||||
struct mlx5_mtt *mtt;
|
||||
int inlen;
|
||||
void *mkc;
|
||||
u32 *in;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
inlen = MLX5_ST_SZ_BYTES(create_mkey_in) + sizeof(*mtt) * npages;
|
||||
|
||||
in = kvzalloc(inlen, GFP_KERNEL);
|
||||
if (!in)
|
||||
|
|
@ -271,6 +276,18 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
|
|||
MLX5_SET(mkc, mkc, translations_octword_size,
|
||||
MLX5_MTT_OCTW(npages));
|
||||
MLX5_SET(mkc, mkc, log_page_size, page_shift);
|
||||
MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
|
||||
MLX5_MTT_OCTW(npages));
|
||||
|
||||
/* Initialize the mkey with all MTTs pointing to a default
|
||||
* page (filler_addr). When the channels are activated, UMR
|
||||
* WQEs will redirect the RX WQEs to the actual memory from
|
||||
* the RQ's pool, while the gaps (wqe_overflow) remain mapped
|
||||
* to the default page.
|
||||
*/
|
||||
mtt = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
|
||||
for (i = 0 ; i < npages ; i++)
|
||||
mtt[i].ptag = cpu_to_be64(filler_addr);
|
||||
|
||||
err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen);
|
||||
|
||||
|
|
@ -282,7 +299,8 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq
|
|||
{
|
||||
u64 num_mtts = MLX5E_REQUIRED_MTTS(mlx5_wq_ll_get_size(&rq->mpwqe.wq));
|
||||
|
||||
return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey);
|
||||
return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey,
|
||||
rq->wqe_overflow.addr);
|
||||
}
|
||||
|
||||
static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix)
|
||||
|
|
@ -350,6 +368,28 @@ static void mlx5e_rq_err_cqe_work(struct work_struct *recover_work)
|
|||
mlx5e_reporter_rq_cqe_err(rq);
|
||||
}
|
||||
|
||||
static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
|
||||
{
|
||||
rq->wqe_overflow.page = alloc_page(GFP_KERNEL);
|
||||
if (!rq->wqe_overflow.page)
|
||||
return -ENOMEM;
|
||||
|
||||
rq->wqe_overflow.addr = dma_map_page(rq->pdev, rq->wqe_overflow.page, 0,
|
||||
PAGE_SIZE, rq->buff.map_dir);
|
||||
if (dma_mapping_error(rq->pdev, rq->wqe_overflow.addr)) {
|
||||
__free_page(rq->wqe_overflow.page);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5e_free_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
|
||||
{
|
||||
dma_unmap_page(rq->pdev, rq->wqe_overflow.addr, PAGE_SIZE,
|
||||
rq->buff.map_dir);
|
||||
__free_page(rq->wqe_overflow.page);
|
||||
}
|
||||
|
||||
static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
||||
struct mlx5e_params *params,
|
||||
struct mlx5e_xsk_param *xsk,
|
||||
|
|
@ -396,7 +436,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
rq_xdp_ix += params->num_channels * MLX5E_RQ_GROUP_XSK;
|
||||
err = xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq_xdp_ix);
|
||||
if (err < 0)
|
||||
goto err_rq_wq_destroy;
|
||||
goto err_rq_xdp_prog;
|
||||
|
||||
rq->buff.map_dir = params->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
|
||||
rq->buff.headroom = mlx5e_get_rq_headroom(mdev, params, xsk);
|
||||
|
|
@ -406,6 +446,10 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->mpwqe.wq,
|
||||
&rq->wq_ctrl);
|
||||
if (err)
|
||||
goto err_rq_xdp;
|
||||
|
||||
err = mlx5e_alloc_mpwqe_rq_drop_page(rq);
|
||||
if (err)
|
||||
goto err_rq_wq_destroy;
|
||||
|
||||
|
|
@ -424,18 +468,18 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
|
||||
err = mlx5e_create_rq_umr_mkey(mdev, rq);
|
||||
if (err)
|
||||
goto err_rq_wq_destroy;
|
||||
goto err_rq_drop_page;
|
||||
rq->mkey_be = cpu_to_be32(rq->umr_mkey.key);
|
||||
|
||||
err = mlx5e_rq_alloc_mpwqe_info(rq, c);
|
||||
if (err)
|
||||
goto err_free;
|
||||
goto err_rq_mkey;
|
||||
break;
|
||||
default: /* MLX5_WQ_TYPE_CYCLIC */
|
||||
err = mlx5_wq_cyc_create(mdev, &rqp->wq, rqc_wq, &rq->wqe.wq,
|
||||
&rq->wq_ctrl);
|
||||
if (err)
|
||||
goto err_rq_wq_destroy;
|
||||
goto err_rq_xdp;
|
||||
|
||||
rq->wqe.wq.db = &rq->wqe.wq.db[MLX5_RCV_DBR];
|
||||
|
||||
|
|
@ -450,19 +494,19 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
GFP_KERNEL, cpu_to_node(c->cpu));
|
||||
if (!rq->wqe.frags) {
|
||||
err = -ENOMEM;
|
||||
goto err_free;
|
||||
goto err_rq_wq_destroy;
|
||||
}
|
||||
|
||||
err = mlx5e_init_di_list(rq, wq_sz, c->cpu);
|
||||
if (err)
|
||||
goto err_free;
|
||||
goto err_rq_frags;
|
||||
|
||||
rq->mkey_be = c->mkey_be;
|
||||
}
|
||||
|
||||
err = mlx5e_rq_set_handlers(rq, params, xsk);
|
||||
if (err)
|
||||
goto err_free;
|
||||
goto err_free_by_rq_type;
|
||||
|
||||
if (xsk) {
|
||||
err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
|
||||
|
|
@ -486,13 +530,13 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
if (IS_ERR(rq->page_pool)) {
|
||||
err = PTR_ERR(rq->page_pool);
|
||||
rq->page_pool = NULL;
|
||||
goto err_free;
|
||||
goto err_free_by_rq_type;
|
||||
}
|
||||
err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
|
||||
MEM_TYPE_PAGE_POOL, rq->page_pool);
|
||||
}
|
||||
if (err)
|
||||
goto err_free;
|
||||
goto err_free_by_rq_type;
|
||||
|
||||
for (i = 0; i < wq_sz; i++) {
|
||||
if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
|
||||
|
|
@ -542,23 +586,27 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
|||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
err_free_by_rq_type:
|
||||
switch (rq->wq_type) {
|
||||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
kvfree(rq->mpwqe.info);
|
||||
err_rq_mkey:
|
||||
mlx5_core_destroy_mkey(mdev, &rq->umr_mkey);
|
||||
err_rq_drop_page:
|
||||
mlx5e_free_mpwqe_rq_drop_page(rq);
|
||||
break;
|
||||
default: /* MLX5_WQ_TYPE_CYCLIC */
|
||||
kvfree(rq->wqe.frags);
|
||||
mlx5e_free_di_list(rq);
|
||||
err_rq_frags:
|
||||
kvfree(rq->wqe.frags);
|
||||
}
|
||||
|
||||
err_rq_wq_destroy:
|
||||
mlx5_wq_destroy(&rq->wq_ctrl);
|
||||
err_rq_xdp:
|
||||
xdp_rxq_info_unreg(&rq->xdp_rxq);
|
||||
err_rq_xdp_prog:
|
||||
if (params->xdp_prog)
|
||||
bpf_prog_put(params->xdp_prog);
|
||||
xdp_rxq_info_unreg(&rq->xdp_rxq);
|
||||
page_pool_destroy(rq->page_pool);
|
||||
mlx5_wq_destroy(&rq->wq_ctrl);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -580,6 +628,7 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
|
|||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
kvfree(rq->mpwqe.info);
|
||||
mlx5_core_destroy_mkey(rq->mdev, &rq->umr_mkey);
|
||||
mlx5e_free_mpwqe_rq_drop_page(rq);
|
||||
break;
|
||||
default: /* MLX5_WQ_TYPE_CYCLIC */
|
||||
kvfree(rq->wqe.frags);
|
||||
|
|
@ -4177,6 +4226,21 @@ int mlx5e_get_vf_stats(struct net_device *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool mlx5e_gre_tunnel_inner_proto_offload_supported(struct mlx5_core_dev *mdev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
switch (skb->inner_protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
case htons(ETH_P_IPV6):
|
||||
case htons(ETH_P_TEB):
|
||||
return true;
|
||||
case htons(ETH_P_MPLS_UC):
|
||||
case htons(ETH_P_MPLS_MC):
|
||||
return MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_gre);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
|
||||
struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
|
|
@ -4199,7 +4263,9 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
|
|||
|
||||
switch (proto) {
|
||||
case IPPROTO_GRE:
|
||||
return features;
|
||||
if (mlx5e_gre_tunnel_inner_proto_offload_supported(priv->mdev, skb))
|
||||
return features;
|
||||
break;
|
||||
case IPPROTO_IPIP:
|
||||
case IPPROTO_IPV6:
|
||||
if (mlx5e_tunnel_proto_supported(priv->mdev, IPPROTO_IPIP))
|
||||
|
|
|
|||
|
|
@ -135,12 +135,6 @@ struct mlx5e_neigh_hash_entry {
|
|||
/* encap list sharing the same neigh */
|
||||
struct list_head encap_list;
|
||||
|
||||
/* valid only when the neigh reference is taken during
|
||||
* neigh_update_work workqueue callback.
|
||||
*/
|
||||
struct neighbour *n;
|
||||
struct work_struct neigh_update_work;
|
||||
|
||||
/* neigh hash entry can be deleted only when the refcount is zero.
|
||||
* refcount is needed to avoid neigh hash entry removal by TC, while
|
||||
* it's used by the neigh notification call.
|
||||
|
|
|
|||
|
|
@ -189,6 +189,29 @@ u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq)
|
|||
return count_eqe;
|
||||
}
|
||||
|
||||
static void mlx5_eq_async_int_lock(struct mlx5_eq_async *eq, unsigned long *flags)
|
||||
__acquires(&eq->lock)
|
||||
{
|
||||
if (in_irq())
|
||||
spin_lock(&eq->lock);
|
||||
else
|
||||
spin_lock_irqsave(&eq->lock, *flags);
|
||||
}
|
||||
|
||||
static void mlx5_eq_async_int_unlock(struct mlx5_eq_async *eq, unsigned long *flags)
|
||||
__releases(&eq->lock)
|
||||
{
|
||||
if (in_irq())
|
||||
spin_unlock(&eq->lock);
|
||||
else
|
||||
spin_unlock_irqrestore(&eq->lock, *flags);
|
||||
}
|
||||
|
||||
enum async_eq_nb_action {
|
||||
ASYNC_EQ_IRQ_HANDLER = 0,
|
||||
ASYNC_EQ_RECOVER = 1,
|
||||
};
|
||||
|
||||
static int mlx5_eq_async_int(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
|
|
@ -198,11 +221,14 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
|
|||
struct mlx5_eq_table *eqt;
|
||||
struct mlx5_core_dev *dev;
|
||||
struct mlx5_eqe *eqe;
|
||||
unsigned long flags;
|
||||
int num_eqes = 0;
|
||||
|
||||
dev = eq->dev;
|
||||
eqt = dev->priv.eq_table;
|
||||
|
||||
mlx5_eq_async_int_lock(eq_async, &flags);
|
||||
|
||||
eqe = next_eqe_sw(eq);
|
||||
if (!eqe)
|
||||
goto out;
|
||||
|
|
@ -223,8 +249,19 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
|
|||
|
||||
out:
|
||||
eq_update_ci(eq, 1);
|
||||
mlx5_eq_async_int_unlock(eq_async, &flags);
|
||||
|
||||
return 0;
|
||||
return unlikely(action == ASYNC_EQ_RECOVER) ? num_eqes : 0;
|
||||
}
|
||||
|
||||
void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_eq_async *eq = &dev->priv.eq_table->cmd_eq;
|
||||
int eqes;
|
||||
|
||||
eqes = mlx5_eq_async_int(&eq->irq_nb, ASYNC_EQ_RECOVER, NULL);
|
||||
if (eqes)
|
||||
mlx5_core_warn(dev, "Recovered %d EQEs on cmd_eq\n", eqes);
|
||||
}
|
||||
|
||||
static void init_eq_buf(struct mlx5_eq *eq)
|
||||
|
|
@ -569,6 +606,7 @@ setup_async_eq(struct mlx5_core_dev *dev, struct mlx5_eq_async *eq,
|
|||
int err;
|
||||
|
||||
eq->irq_nb.notifier_call = mlx5_eq_async_int;
|
||||
spin_lock_init(&eq->lock);
|
||||
|
||||
err = create_async_eq(dev, &eq->core, param);
|
||||
if (err) {
|
||||
|
|
@ -656,8 +694,10 @@ static void destroy_async_eqs(struct mlx5_core_dev *dev)
|
|||
|
||||
cleanup_async_eq(dev, &table->pages_eq, "pages");
|
||||
cleanup_async_eq(dev, &table->async_eq, "async");
|
||||
mlx5_cmd_allowed_opcode(dev, MLX5_CMD_OP_DESTROY_EQ);
|
||||
mlx5_cmd_use_polling(dev);
|
||||
cleanup_async_eq(dev, &table->cmd_eq, "cmd");
|
||||
mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL);
|
||||
mlx5_eq_notifier_unregister(dev, &table->cq_err_nb);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct mlx5_eq {
|
|||
struct mlx5_eq_async {
|
||||
struct mlx5_eq core;
|
||||
struct notifier_block irq_nb;
|
||||
spinlock_t lock; /* To avoid irq EQ handle races with resiliency flows */
|
||||
};
|
||||
|
||||
struct mlx5_eq_comp {
|
||||
|
|
@ -81,6 +82,7 @@ void mlx5_cq_tasklet_cb(unsigned long data);
|
|||
struct cpumask *mlx5_eq_comp_cpumask(struct mlx5_core_dev *dev, int ix);
|
||||
|
||||
u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq);
|
||||
void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev);
|
||||
void mlx5_eq_synchronize_async_irq(struct mlx5_core_dev *dev);
|
||||
void mlx5_eq_synchronize_cmd_irq(struct mlx5_core_dev *dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
|
|||
u32 npages;
|
||||
u32 i = 0;
|
||||
|
||||
if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR)
|
||||
if (!mlx5_cmd_is_down(dev))
|
||||
return mlx5_cmd_exec(dev, in, in_size, out, out_size);
|
||||
|
||||
/* No hard feelings, we want our pages back! */
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static int request_irqs(struct mlx5_core_dev *dev, int nvec)
|
|||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
for (; i >= 0; i--) {
|
||||
while (i--) {
|
||||
struct mlx5_irq *irq = mlx5_irq_get(dev, i);
|
||||
int irqn = pci_irq_vector(dev->pdev, i);
|
||||
|
||||
|
|
|
|||
|
|
@ -3690,13 +3690,13 @@ bool mlxsw_sp_port_dev_check(const struct net_device *dev)
|
|||
return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev, void *data)
|
||||
static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct mlxsw_sp_port **p_mlxsw_sp_port = data;
|
||||
int ret = 0;
|
||||
|
||||
if (mlxsw_sp_port_dev_check(lower_dev)) {
|
||||
*p_mlxsw_sp_port = netdev_priv(lower_dev);
|
||||
priv->data = (void *)netdev_priv(lower_dev);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
|
|
@ -3705,15 +3705,16 @@ static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev, void *data)
|
|||
|
||||
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = NULL,
|
||||
};
|
||||
|
||||
if (mlxsw_sp_port_dev_check(dev))
|
||||
return netdev_priv(dev);
|
||||
|
||||
mlxsw_sp_port = NULL;
|
||||
netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &mlxsw_sp_port);
|
||||
netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &priv);
|
||||
|
||||
return mlxsw_sp_port;
|
||||
return (struct mlxsw_sp_port *)priv.data;
|
||||
}
|
||||
|
||||
struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
|
||||
|
|
@ -3726,16 +3727,17 @@ struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
|
|||
|
||||
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = NULL,
|
||||
};
|
||||
|
||||
if (mlxsw_sp_port_dev_check(dev))
|
||||
return netdev_priv(dev);
|
||||
|
||||
mlxsw_sp_port = NULL;
|
||||
netdev_walk_all_lower_dev_rcu(dev, mlxsw_sp_lower_dev_walk,
|
||||
&mlxsw_sp_port);
|
||||
&priv);
|
||||
|
||||
return mlxsw_sp_port;
|
||||
return (struct mlxsw_sp_port *)priv.data;
|
||||
}
|
||||
|
||||
struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
|
||||
|
|
|
|||
|
|
@ -292,13 +292,14 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp_acl_tcam *tcam,
|
|||
int err;
|
||||
|
||||
group->tcam = tcam;
|
||||
mutex_init(&group->lock);
|
||||
INIT_LIST_HEAD(&group->region_list);
|
||||
|
||||
err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mutex_init(&group->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7351,9 +7351,10 @@ int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data)
|
||||
static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct mlxsw_sp_rif *rif = data;
|
||||
struct mlxsw_sp_rif *rif = (struct mlxsw_sp_rif *)priv->data;
|
||||
|
||||
if (!netif_is_macvlan(dev))
|
||||
return 0;
|
||||
|
|
@ -7364,12 +7365,16 @@ static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data)
|
|||
|
||||
static int mlxsw_sp_rif_macvlan_flush(struct mlxsw_sp_rif *rif)
|
||||
{
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)rif,
|
||||
};
|
||||
|
||||
if (!netif_is_macvlan_port(rif->dev))
|
||||
return 0;
|
||||
|
||||
netdev_warn(rif->dev, "Router interface is deleted. Upper macvlans will not work\n");
|
||||
return netdev_walk_all_upper_dev_rcu(rif->dev,
|
||||
__mlxsw_sp_rif_macvlan_flush, rif);
|
||||
__mlxsw_sp_rif_macvlan_flush, &priv);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_rif_subport_setup(struct mlxsw_sp_rif *rif,
|
||||
|
|
|
|||
|
|
@ -136,9 +136,9 @@ bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
|
|||
}
|
||||
|
||||
static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
|
||||
void *data)
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = data;
|
||||
struct mlxsw_sp *mlxsw_sp = priv->data;
|
||||
|
||||
mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
|
||||
return 0;
|
||||
|
|
@ -147,10 +147,14 @@ static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
|
|||
static void mlxsw_sp_bridge_device_rifs_destroy(struct mlxsw_sp *mlxsw_sp,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct netdev_nested_priv priv = {
|
||||
.data = (void *)mlxsw_sp,
|
||||
};
|
||||
|
||||
mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
|
||||
netdev_walk_all_upper_dev_rcu(dev,
|
||||
mlxsw_sp_bridge_device_upper_rif_destroy,
|
||||
mlxsw_sp);
|
||||
&priv);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_bridge_device_vxlan_init(struct mlxsw_sp_bridge *bridge,
|
||||
|
|
|
|||
|
|
@ -1253,7 +1253,7 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
|
|||
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
||||
int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
|
||||
int pause_start, pause_stop;
|
||||
int atop_wm;
|
||||
int atop, atop_tot;
|
||||
|
||||
if (port == ocelot->npi) {
|
||||
maxlen += OCELOT_TAG_LEN;
|
||||
|
|
@ -1274,12 +1274,12 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
|
|||
ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_STOP,
|
||||
pause_stop);
|
||||
|
||||
/* Tail dropping watermark */
|
||||
atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
|
||||
/* Tail dropping watermarks */
|
||||
atop_tot = (ocelot->shared_queue_sz - 9 * maxlen) /
|
||||
OCELOT_BUFFER_CELL_SZ;
|
||||
ocelot_write_rix(ocelot, ocelot->ops->wm_enc(9 * maxlen),
|
||||
SYS_ATOP, port);
|
||||
ocelot_write(ocelot, ocelot->ops->wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
|
||||
atop = (9 * maxlen) / OCELOT_BUFFER_CELL_SZ;
|
||||
ocelot_write_rix(ocelot, ocelot->ops->wm_enc(atop), SYS_ATOP, port);
|
||||
ocelot_write(ocelot, ocelot->ops->wm_enc(atop_tot), SYS_ATOP_TOT_CFG);
|
||||
}
|
||||
EXPORT_SYMBOL(ocelot_port_set_maxlen);
|
||||
|
||||
|
|
|
|||
|
|
@ -745,6 +745,8 @@ static int ocelot_reset(struct ocelot *ocelot)
|
|||
*/
|
||||
static u16 ocelot_wm_enc(u16 value)
|
||||
{
|
||||
WARN_ON(value >= 16 * BIT(8));
|
||||
|
||||
if (value >= BIT(8))
|
||||
return BIT(8) | (value / 16);
|
||||
|
||||
|
|
|
|||
|
|
@ -2058,11 +2058,18 @@ static void rtl_release_firmware(struct rtl8169_private *tp)
|
|||
|
||||
void r8169_apply_firmware(struct rtl8169_private *tp)
|
||||
{
|
||||
int val;
|
||||
|
||||
/* TODO: release firmware if rtl_fw_write_firmware signals failure. */
|
||||
if (tp->rtl_fw) {
|
||||
rtl_fw_write_firmware(tp, tp->rtl_fw);
|
||||
/* At least one firmware doesn't reset tp->ocp_base. */
|
||||
tp->ocp_base = OCP_STD_PHY_BASE;
|
||||
|
||||
/* PHY soft reset may still be in progress */
|
||||
phy_read_poll_timeout(tp->phydev, MII_BMCR, val,
|
||||
!(val & BMCR_RESET),
|
||||
50000, 600000, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2239,14 +2246,10 @@ static void rtl_pll_power_down(struct rtl8169_private *tp)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(tp->clk);
|
||||
}
|
||||
|
||||
static void rtl_pll_power_up(struct rtl8169_private *tp)
|
||||
{
|
||||
clk_prepare_enable(tp->clk);
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33:
|
||||
case RTL_GIGA_MAC_VER_37:
|
||||
|
|
@ -2904,7 +2907,7 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
|
|||
{ 0x08, 0x0001, 0x0002 },
|
||||
{ 0x09, 0x0000, 0x0080 },
|
||||
{ 0x19, 0x0000, 0x0224 },
|
||||
{ 0x00, 0x0000, 0x0004 },
|
||||
{ 0x00, 0x0000, 0x0008 },
|
||||
{ 0x0c, 0x3df0, 0x0200 },
|
||||
};
|
||||
|
||||
|
|
@ -2921,7 +2924,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
|
|||
{ 0x06, 0x00c0, 0x0020 },
|
||||
{ 0x0f, 0xffff, 0x5200 },
|
||||
{ 0x19, 0x0000, 0x0224 },
|
||||
{ 0x00, 0x0000, 0x0004 },
|
||||
{ 0x00, 0x0000, 0x0008 },
|
||||
{ 0x0c, 0x3df0, 0x0200 },
|
||||
};
|
||||
|
||||
|
|
@ -4826,21 +4829,8 @@ static void rtl8169_net_suspend(struct rtl8169_private *tp)
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int __maybe_unused rtl8169_suspend(struct device *device)
|
||||
static int rtl8169_net_resume(struct rtl8169_private *tp)
|
||||
{
|
||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||
|
||||
rtnl_lock();
|
||||
rtl8169_net_suspend(tp);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8169_resume(struct device *device)
|
||||
{
|
||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||
|
||||
rtl_rar_set(tp, tp->dev->dev_addr);
|
||||
|
||||
if (tp->TxDescArray)
|
||||
|
|
@ -4851,6 +4841,33 @@ static int rtl8169_resume(struct device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rtl8169_suspend(struct device *device)
|
||||
{
|
||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||
|
||||
rtnl_lock();
|
||||
rtl8169_net_suspend(tp);
|
||||
if (!device_may_wakeup(tp_to_dev(tp)))
|
||||
clk_disable_unprepare(tp->clk);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rtl8169_resume(struct device *device)
|
||||
{
|
||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||
|
||||
if (!device_may_wakeup(tp_to_dev(tp)))
|
||||
clk_prepare_enable(tp->clk);
|
||||
|
||||
/* Reportedly at least Asus X453MA truncates packets otherwise */
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_37)
|
||||
rtl_init_rxcfg(tp);
|
||||
|
||||
return rtl8169_net_resume(tp);
|
||||
}
|
||||
|
||||
static int rtl8169_runtime_suspend(struct device *device)
|
||||
{
|
||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||
|
|
@ -4874,7 +4891,7 @@ static int rtl8169_runtime_resume(struct device *device)
|
|||
|
||||
__rtl8169_set_wol(tp, tp->saved_wolopts);
|
||||
|
||||
return rtl8169_resume(device);
|
||||
return rtl8169_net_resume(tp);
|
||||
}
|
||||
|
||||
static int rtl8169_runtime_idle(struct device *device)
|
||||
|
|
|
|||
|
|
@ -1342,51 +1342,6 @@ static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler,
|
|||
return error;
|
||||
}
|
||||
|
||||
/* MDIO bus init function */
|
||||
static int ravb_mdio_init(struct ravb_private *priv)
|
||||
{
|
||||
struct platform_device *pdev = priv->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
int error;
|
||||
|
||||
/* Bitbang init */
|
||||
priv->mdiobb.ops = &bb_ops;
|
||||
|
||||
/* MII controller setting */
|
||||
priv->mii_bus = alloc_mdio_bitbang(&priv->mdiobb);
|
||||
if (!priv->mii_bus)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Hook up MII support for ethtool */
|
||||
priv->mii_bus->name = "ravb_mii";
|
||||
priv->mii_bus->parent = dev;
|
||||
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, pdev->id);
|
||||
|
||||
/* Register MDIO bus */
|
||||
error = of_mdiobus_register(priv->mii_bus, dev->of_node);
|
||||
if (error)
|
||||
goto out_free_bus;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_bus:
|
||||
free_mdio_bitbang(priv->mii_bus);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* MDIO bus release function */
|
||||
static int ravb_mdio_release(struct ravb_private *priv)
|
||||
{
|
||||
/* Unregister mdio bus */
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
|
||||
/* Free bitbang info */
|
||||
free_mdio_bitbang(priv->mii_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Network device open function for Ethernet AVB */
|
||||
static int ravb_open(struct net_device *ndev)
|
||||
{
|
||||
|
|
@ -1395,13 +1350,6 @@ static int ravb_open(struct net_device *ndev)
|
|||
struct device *dev = &pdev->dev;
|
||||
int error;
|
||||
|
||||
/* MDIO bus init */
|
||||
error = ravb_mdio_init(priv);
|
||||
if (error) {
|
||||
netdev_err(ndev, "failed to initialize MDIO\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
napi_enable(&priv->napi[RAVB_BE]);
|
||||
napi_enable(&priv->napi[RAVB_NC]);
|
||||
|
||||
|
|
@ -1479,7 +1427,6 @@ static int ravb_open(struct net_device *ndev)
|
|||
out_napi_off:
|
||||
napi_disable(&priv->napi[RAVB_NC]);
|
||||
napi_disable(&priv->napi[RAVB_BE]);
|
||||
ravb_mdio_release(priv);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -1789,8 +1736,6 @@ static int ravb_close(struct net_device *ndev)
|
|||
ravb_ring_free(ndev, RAVB_BE);
|
||||
ravb_ring_free(ndev, RAVB_NC);
|
||||
|
||||
ravb_mdio_release(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1942,6 +1887,51 @@ static const struct net_device_ops ravb_netdev_ops = {
|
|||
.ndo_set_features = ravb_set_features,
|
||||
};
|
||||
|
||||
/* MDIO bus init function */
|
||||
static int ravb_mdio_init(struct ravb_private *priv)
|
||||
{
|
||||
struct platform_device *pdev = priv->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
int error;
|
||||
|
||||
/* Bitbang init */
|
||||
priv->mdiobb.ops = &bb_ops;
|
||||
|
||||
/* MII controller setting */
|
||||
priv->mii_bus = alloc_mdio_bitbang(&priv->mdiobb);
|
||||
if (!priv->mii_bus)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Hook up MII support for ethtool */
|
||||
priv->mii_bus->name = "ravb_mii";
|
||||
priv->mii_bus->parent = dev;
|
||||
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
pdev->name, pdev->id);
|
||||
|
||||
/* Register MDIO bus */
|
||||
error = of_mdiobus_register(priv->mii_bus, dev->of_node);
|
||||
if (error)
|
||||
goto out_free_bus;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_bus:
|
||||
free_mdio_bitbang(priv->mii_bus);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* MDIO bus release function */
|
||||
static int ravb_mdio_release(struct ravb_private *priv)
|
||||
{
|
||||
/* Unregister mdio bus */
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
|
||||
/* Free bitbang info */
|
||||
free_mdio_bitbang(priv->mii_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ravb_match_table[] = {
|
||||
{ .compatible = "renesas,etheravb-r8a7790", .data = (void *)RCAR_GEN2 },
|
||||
{ .compatible = "renesas,etheravb-r8a7794", .data = (void *)RCAR_GEN2 },
|
||||
|
|
@ -2184,6 +2174,13 @@ static int ravb_probe(struct platform_device *pdev)
|
|||
eth_hw_addr_random(ndev);
|
||||
}
|
||||
|
||||
/* MDIO bus init */
|
||||
error = ravb_mdio_init(priv);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to initialize MDIO\n");
|
||||
goto out_dma_free;
|
||||
}
|
||||
|
||||
netif_napi_add(ndev, &priv->napi[RAVB_BE], ravb_poll, 64);
|
||||
netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64);
|
||||
|
||||
|
|
@ -2205,6 +2202,8 @@ static int ravb_probe(struct platform_device *pdev)
|
|||
out_napi_del:
|
||||
netif_napi_del(&priv->napi[RAVB_NC]);
|
||||
netif_napi_del(&priv->napi[RAVB_BE]);
|
||||
ravb_mdio_release(priv);
|
||||
out_dma_free:
|
||||
dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat,
|
||||
priv->desc_bat_dma);
|
||||
|
||||
|
|
@ -2236,6 +2235,7 @@ static int ravb_remove(struct platform_device *pdev)
|
|||
unregister_netdev(ndev);
|
||||
netif_napi_del(&priv->napi[RAVB_NC]);
|
||||
netif_napi_del(&priv->napi[RAVB_BE]);
|
||||
ravb_mdio_release(priv);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
free_netdev(ndev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
|
|
|||
|
|
@ -3099,9 +3099,10 @@ struct rocker_walk_data {
|
|||
struct rocker_port *port;
|
||||
};
|
||||
|
||||
static int rocker_lower_dev_walk(struct net_device *lower_dev, void *_data)
|
||||
static int rocker_lower_dev_walk(struct net_device *lower_dev,
|
||||
struct netdev_nested_priv *priv)
|
||||
{
|
||||
struct rocker_walk_data *data = _data;
|
||||
struct rocker_walk_data *data = (struct rocker_walk_data *)priv->data;
|
||||
int ret = 0;
|
||||
|
||||
if (rocker_port_dev_check_under(lower_dev, data->rocker)) {
|
||||
|
|
@ -3115,6 +3116,7 @@ static int rocker_lower_dev_walk(struct net_device *lower_dev, void *_data)
|
|||
struct rocker_port *rocker_port_dev_lower_find(struct net_device *dev,
|
||||
struct rocker *rocker)
|
||||
{
|
||||
struct netdev_nested_priv priv;
|
||||
struct rocker_walk_data data;
|
||||
|
||||
if (rocker_port_dev_check_under(dev, rocker))
|
||||
|
|
@ -3122,7 +3124,8 @@ struct rocker_port *rocker_port_dev_lower_find(struct net_device *dev,
|
|||
|
||||
data.rocker = rocker;
|
||||
data.port = NULL;
|
||||
netdev_walk_all_lower_dev(dev, rocker_lower_dev_walk, &data);
|
||||
priv.data = (void *)&data;
|
||||
netdev_walk_all_lower_dev(dev, rocker_lower_dev_walk, &priv);
|
||||
|
||||
return data.port;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -653,7 +653,6 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
|
|||
|
||||
pci_free_irq_vectors(pdev);
|
||||
|
||||
clk_disable_unprepare(priv->plat->stmmac_clk);
|
||||
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
|
||||
|
||||
pcim_iounmap_regions(pdev, BIT(0));
|
||||
|
|
|
|||
|
|
@ -203,6 +203,8 @@ struct stmmac_priv {
|
|||
int eee_enabled;
|
||||
int eee_active;
|
||||
int tx_lpi_timer;
|
||||
int tx_lpi_enabled;
|
||||
int eee_tw_timer;
|
||||
unsigned int mode;
|
||||
unsigned int chain_mode;
|
||||
int extend_desc;
|
||||
|
|
|
|||
|
|
@ -665,6 +665,7 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
|
|||
edata->eee_enabled = priv->eee_enabled;
|
||||
edata->eee_active = priv->eee_active;
|
||||
edata->tx_lpi_timer = priv->tx_lpi_timer;
|
||||
edata->tx_lpi_enabled = priv->tx_lpi_enabled;
|
||||
|
||||
return phylink_ethtool_get_eee(priv->phylink, edata);
|
||||
}
|
||||
|
|
@ -675,24 +676,26 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
|
|||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (!edata->eee_enabled) {
|
||||
if (!priv->dma_cap.eee)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)
|
||||
netdev_warn(priv->dev,
|
||||
"Setting EEE tx-lpi is not supported\n");
|
||||
|
||||
if (!edata->eee_enabled)
|
||||
stmmac_disable_eee_mode(priv);
|
||||
} else {
|
||||
/* We are asking for enabling the EEE but it is safe
|
||||
* to verify all by invoking the eee_init function.
|
||||
* In case of failure it will return an error.
|
||||
*/
|
||||
edata->eee_enabled = stmmac_eee_init(priv);
|
||||
if (!edata->eee_enabled)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = phylink_ethtool_set_eee(priv->phylink, edata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->eee_enabled = edata->eee_enabled;
|
||||
priv->tx_lpi_timer = edata->tx_lpi_timer;
|
||||
if (edata->eee_enabled &&
|
||||
priv->tx_lpi_timer != edata->tx_lpi_timer) {
|
||||
priv->tx_lpi_timer = edata->tx_lpi_timer;
|
||||
stmmac_eee_init(priv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
|
|||
static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
|
||||
module_param(eee_timer, int, 0644);
|
||||
MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
|
||||
#define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x))
|
||||
#define STMMAC_LPI_T(x) (jiffies + usecs_to_jiffies(x))
|
||||
|
||||
/* By default the driver will use the ring mode to manage tx and rx descriptors,
|
||||
* but allow user to force to use the chain instead of the ring
|
||||
|
|
@ -370,7 +370,7 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t)
|
|||
struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer);
|
||||
|
||||
stmmac_enable_eee_mode(priv);
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -383,7 +383,7 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t)
|
|||
*/
|
||||
bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||
{
|
||||
int tx_lpi_timer = priv->tx_lpi_timer;
|
||||
int eee_tw_timer = priv->eee_tw_timer;
|
||||
|
||||
/* Using PCS we cannot dial with the phy registers at this stage
|
||||
* so we do not support extra feature like EEE.
|
||||
|
|
@ -403,7 +403,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
|||
if (priv->eee_enabled) {
|
||||
netdev_dbg(priv->dev, "disable EEE\n");
|
||||
del_timer_sync(&priv->eee_ctrl_timer);
|
||||
stmmac_set_eee_timer(priv, priv->hw, 0, tx_lpi_timer);
|
||||
stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer);
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
return false;
|
||||
|
|
@ -411,11 +411,12 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
|||
|
||||
if (priv->eee_active && !priv->eee_enabled) {
|
||||
timer_setup(&priv->eee_ctrl_timer, stmmac_eee_ctrl_timer, 0);
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
|
||||
stmmac_set_eee_timer(priv, priv->hw, STMMAC_DEFAULT_LIT_LS,
|
||||
tx_lpi_timer);
|
||||
eee_tw_timer);
|
||||
}
|
||||
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
|
||||
return true;
|
||||
|
|
@ -930,6 +931,7 @@ static void stmmac_mac_link_down(struct phylink_config *config,
|
|||
|
||||
stmmac_mac_set(priv, priv->ioaddr, false);
|
||||
priv->eee_active = false;
|
||||
priv->tx_lpi_enabled = false;
|
||||
stmmac_eee_init(priv);
|
||||
stmmac_set_eee_pls(priv, priv->hw, false);
|
||||
}
|
||||
|
|
@ -1027,6 +1029,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
|
|||
if (phy && priv->dma_cap.eee) {
|
||||
priv->eee_active = phy_init_eee(phy, 1) >= 0;
|
||||
priv->eee_enabled = stmmac_eee_init(priv);
|
||||
priv->tx_lpi_enabled = priv->eee_enabled;
|
||||
stmmac_set_eee_pls(priv, priv->hw, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -2061,7 +2064,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
|
|||
|
||||
if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
|
||||
stmmac_enable_eee_mode(priv);
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
|
||||
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
|
||||
}
|
||||
|
||||
/* We still have pending packets, let's call for a new scheduling */
|
||||
|
|
@ -2694,7 +2697,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
|
|||
netdev_warn(priv->dev, "PTP init failed\n");
|
||||
}
|
||||
|
||||
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
|
||||
priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
|
||||
|
||||
/* Convert the timer from msec to usec */
|
||||
if (!priv->tx_lpi_timer)
|
||||
priv->tx_lpi_timer = eee_timer * 1000;
|
||||
|
||||
if (priv->use_riwt) {
|
||||
if (!priv->rx_riwt)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
Written 1998-2001 by Donald Becker.
|
||||
|
||||
Current Maintainer: Roger Luethi <rl@hellgate.ch>
|
||||
Current Maintainer: Kevin Brace <kevinbrace@bracecomputerlab.com>
|
||||
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU General Public License (GPL), incorporated herein by reference.
|
||||
|
|
@ -32,8 +32,6 @@
|
|||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#define DRV_NAME "via-rhine"
|
||||
#define DRV_VERSION "1.5.1"
|
||||
#define DRV_RELDATE "2010-10-09"
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
|
|
@ -117,10 +115,6 @@ static const int multicast_filter_limit = 32;
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
/* These identify the driver base version and may not be removed. */
|
||||
static const char version[] =
|
||||
"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
|
||||
|
||||
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
|
||||
MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -243,7 +237,7 @@ enum rhine_revs {
|
|||
VT8233 = 0x60, /* Integrated MAC */
|
||||
VT8235 = 0x74, /* Integrated MAC */
|
||||
VT8237 = 0x78, /* Integrated MAC */
|
||||
VTunknown1 = 0x7C,
|
||||
VT8251 = 0x7C, /* Integrated MAC */
|
||||
VT6105 = 0x80,
|
||||
VT6105_B0 = 0x83,
|
||||
VT6105L = 0x8A,
|
||||
|
|
@ -1051,11 +1045,6 @@ static int rhine_init_one_pci(struct pci_dev *pdev,
|
|||
u32 quirks = 0;
|
||||
#endif
|
||||
|
||||
/* when built into the kernel, we only print version if device is found */
|
||||
#ifndef MODULE
|
||||
pr_info_once("%s\n", version);
|
||||
#endif
|
||||
|
||||
rc = pci_enable_device(pdev);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
|
@ -1706,6 +1695,8 @@ static int rhine_open(struct net_device *dev)
|
|||
goto out_free_ring;
|
||||
|
||||
alloc_tbufs(dev);
|
||||
enable_mmio(rp->pioaddr, rp->quirks);
|
||||
rhine_power_init(dev);
|
||||
rhine_chip_reset(dev);
|
||||
rhine_task_enable(rp);
|
||||
init_registers(dev);
|
||||
|
|
@ -2294,7 +2285,6 @@ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
|
|||
struct device *hwdev = dev->dev.parent;
|
||||
|
||||
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
|
||||
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
|
||||
strlcpy(info->bus_info, dev_name(hwdev), sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
|
|
@ -2616,9 +2606,6 @@ static int __init rhine_init(void)
|
|||
int ret_pci, ret_platform;
|
||||
|
||||
/* when a module, this is printed whether or not devices are found in probe */
|
||||
#ifdef MODULE
|
||||
pr_info("%s\n", version);
|
||||
#endif
|
||||
if (dmi_check_system(rhine_dmi_table)) {
|
||||
/* these BIOSes fail at PXE boot if chip is in D3 */
|
||||
avoid_D3 = true;
|
||||
|
|
|
|||
|
|
@ -1077,6 +1077,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
|
|||
struct macsec_rx_sa *rx_sa;
|
||||
struct macsec_rxh_data *rxd;
|
||||
struct macsec_dev *macsec;
|
||||
unsigned int len;
|
||||
sci_t sci;
|
||||
u32 hdr_pn;
|
||||
bool cbit;
|
||||
|
|
@ -1232,9 +1233,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
|
|||
macsec_rxsc_put(rx_sc);
|
||||
|
||||
skb_orphan(skb);
|
||||
len = skb->len;
|
||||
ret = gro_cells_receive(&macsec->gro_cells, skb);
|
||||
if (ret == NET_RX_SUCCESS)
|
||||
count_rx(dev, skb->len);
|
||||
count_rx(dev, len);
|
||||
else
|
||||
macsec->secy.netdev->stats.rx_dropped++;
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ config MDIO_THUNDER
|
|||
depends on 64BIT
|
||||
depends on PCI
|
||||
select MDIO_CAVIUM
|
||||
select MDIO_DEVRES
|
||||
help
|
||||
This driver supports the MDIO interfaces found on Cavium
|
||||
ThunderX SoCs when the MDIO bus device appears as a PCI
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* drivers/net/phy/realtek.c
|
||||
/* drivers/net/phy/realtek.c
|
||||
*
|
||||
* Driver for Realtek PHYs
|
||||
*
|
||||
|
|
@ -32,9 +31,9 @@
|
|||
#define RTL8211F_TX_DELAY BIT(8)
|
||||
#define RTL8211F_RX_DELAY BIT(3)
|
||||
|
||||
#define RTL8211E_TX_DELAY BIT(1)
|
||||
#define RTL8211E_RX_DELAY BIT(2)
|
||||
#define RTL8211E_MODE_MII_GMII BIT(3)
|
||||
#define RTL8211E_CTRL_DELAY BIT(13)
|
||||
#define RTL8211E_TX_DELAY BIT(12)
|
||||
#define RTL8211E_RX_DELAY BIT(11)
|
||||
|
||||
#define RTL8201F_ISR 0x1e
|
||||
#define RTL8201F_IER 0x13
|
||||
|
|
@ -246,16 +245,16 @@ static int rtl8211e_config_init(struct phy_device *phydev)
|
|||
/* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
|
||||
switch (phydev->interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
val = 0;
|
||||
val = RTL8211E_CTRL_DELAY | 0;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
|
||||
val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
val = RTL8211E_RX_DELAY;
|
||||
val = RTL8211E_CTRL_DELAY | RTL8211E_RX_DELAY;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
val = RTL8211E_TX_DELAY;
|
||||
val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY;
|
||||
break;
|
||||
default: /* the rest of the modes imply leaving delays as is. */
|
||||
return 0;
|
||||
|
|
@ -263,11 +262,12 @@ static int rtl8211e_config_init(struct phy_device *phydev)
|
|||
|
||||
/* According to a sample driver there is a 0x1c config register on the
|
||||
* 0xa4 extension page (0x7) layout. It can be used to disable/enable
|
||||
* the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
|
||||
* also be used to customize the whole configuration register:
|
||||
* 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
|
||||
* 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
|
||||
* for details).
|
||||
* the RX/TX delays otherwise controlled by RXDLY/TXDLY pins.
|
||||
* The configuration register definition:
|
||||
* 14 = reserved
|
||||
* 13 = Force Tx RX Delay controlled by bit12 bit11,
|
||||
* 12 = RX Delay, 11 = TX Delay
|
||||
* 10:0 = Test && debug settings reserved by realtek
|
||||
*/
|
||||
oldpage = phy_select_page(phydev, 0x7);
|
||||
if (oldpage < 0)
|
||||
|
|
@ -277,7 +277,8 @@ static int rtl8211e_config_init(struct phy_device *phydev)
|
|||
if (ret)
|
||||
goto err_restore_page;
|
||||
|
||||
ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
|
||||
ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
|
||||
| RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
|
||||
val);
|
||||
|
||||
err_restore_page:
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ static int __team_options_register(struct team *team,
|
|||
for (i--; i >= 0; i--)
|
||||
__team_option_inst_del_option(team, dst_opts[i]);
|
||||
|
||||
i = option_count - 1;
|
||||
i = option_count;
|
||||
alloc_rollback:
|
||||
for (i--; i >= 0; i--)
|
||||
kfree(dst_opts[i]);
|
||||
|
|
@ -2112,6 +2112,7 @@ static void team_setup_by_port(struct net_device *dev,
|
|||
dev->header_ops = port_dev->header_ops;
|
||||
dev->type = port_dev->type;
|
||||
dev->hard_header_len = port_dev->hard_header_len;
|
||||
dev->needed_headroom = port_dev->needed_headroom;
|
||||
dev->addr_len = port_dev->addr_len;
|
||||
dev->mtu = port_dev->mtu;
|
||||
memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
|
||||
|
|
|
|||
|
|
@ -1823,6 +1823,33 @@ static const struct driver_info belkin_info = {
|
|||
.status = ax88179_status,
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
|
||||
static const struct driver_info toshiba_info = {
|
||||
.description = "Toshiba USB Ethernet Adapter",
|
||||
.bind = ax88179_bind,
|
||||
.unbind = ax88179_unbind,
|
||||
.status = ax88179_status,
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
|
||||
static const struct driver_info mct_info = {
|
||||
.description = "MCT USB 3.0 Gigabit Ethernet Adapter",
|
||||
.bind = ax88179_bind,
|
||||
.unbind = ax88179_unbind,
|
||||
.status = ax88179_status,
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
|
|
@ -1861,6 +1888,14 @@ static const struct usb_device_id products[] = {
|
|||
/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
|
||||
USB_DEVICE(0x050d, 0x0128),
|
||||
.driver_info = (unsigned long)&belkin_info,
|
||||
}, {
|
||||
/* Toshiba USB 3.0 GBit Ethernet Adapter */
|
||||
USB_DEVICE(0x0930, 0x0a13),
|
||||
.driver_info = (unsigned long)&toshiba_info,
|
||||
}, {
|
||||
/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
|
||||
USB_DEVICE(0x0711, 0x0179),
|
||||
.driver_info = (unsigned long)&mct_info,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -360,28 +360,47 @@ static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
|
|||
}
|
||||
#endif /* PEGASUS_WRITE_EEPROM */
|
||||
|
||||
static inline void get_node_id(pegasus_t *pegasus, __u8 *id)
|
||||
static inline int get_node_id(pegasus_t *pegasus, u8 *id)
|
||||
{
|
||||
int i;
|
||||
__u16 w16;
|
||||
int i, ret;
|
||||
u16 w16;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
read_eprom_word(pegasus, i, &w16);
|
||||
ret = read_eprom_word(pegasus, i, &w16);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
((__le16 *) id)[i] = cpu_to_le16(w16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_ethernet_addr(pegasus_t *pegasus)
|
||||
{
|
||||
__u8 node_id[6];
|
||||
int ret;
|
||||
u8 node_id[6];
|
||||
|
||||
if (pegasus->features & PEGASUS_II) {
|
||||
get_registers(pegasus, 0x10, sizeof(node_id), node_id);
|
||||
ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
} else {
|
||||
get_node_id(pegasus, node_id);
|
||||
set_registers(pegasus, EthID, sizeof(node_id), node_id);
|
||||
ret = get_node_id(pegasus, node_id);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = set_registers(pegasus, EthID, sizeof(node_id), node_id);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
|
||||
|
||||
return;
|
||||
err:
|
||||
eth_hw_addr_random(pegasus->net);
|
||||
dev_info(&pegasus->intf->dev, "software assigned MAC address.\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int reset_mac(pegasus_t *pegasus)
|
||||
|
|
|
|||
|
|
@ -1375,6 +1375,7 @@ static const struct usb_device_id products[] = {
|
|||
{QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
|
||||
{QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
|
||||
|
||||
/* 4. Gobi 1000 devices */
|
||||
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
|
|
|
|||
|
|
@ -274,12 +274,20 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline void set_ethernet_addr(rtl8150_t * dev)
|
||||
static void set_ethernet_addr(rtl8150_t *dev)
|
||||
{
|
||||
u8 node_id[6];
|
||||
u8 node_id[ETH_ALEN];
|
||||
int ret;
|
||||
|
||||
get_registers(dev, IDR, sizeof(node_id), node_id);
|
||||
memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id));
|
||||
ret = get_registers(dev, IDR, sizeof(node_id), node_id);
|
||||
|
||||
if (ret == sizeof(node_id)) {
|
||||
ether_addr_copy(dev->netdev->dev_addr, node_id);
|
||||
} else {
|
||||
eth_hw_addr_random(dev->netdev);
|
||||
netdev_notice(dev->netdev, "Assigned a random MAC address: %pM\n",
|
||||
dev->netdev->dev_addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@ static const unsigned long guest_offloads[] = {
|
|||
VIRTIO_NET_F_GUEST_CSUM
|
||||
};
|
||||
|
||||
#define GUEST_OFFLOAD_LRO_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
|
||||
(1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
|
||||
(1ULL << VIRTIO_NET_F_GUEST_ECN) | \
|
||||
(1ULL << VIRTIO_NET_F_GUEST_UFO))
|
||||
|
||||
struct virtnet_stat_desc {
|
||||
char desc[ETH_GSTRING_LEN];
|
||||
size_t offset;
|
||||
|
|
@ -2534,7 +2539,8 @@ static int virtnet_set_features(struct net_device *dev,
|
|||
if (features & NETIF_F_LRO)
|
||||
offloads = vi->guest_offloads_capable;
|
||||
else
|
||||
offloads = 0;
|
||||
offloads = vi->guest_offloads_capable &
|
||||
~GUEST_OFFLOAD_LRO_MASK;
|
||||
|
||||
err = virtnet_set_guest_offloads(vi, offloads);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -1032,7 +1032,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
|
|||
/* Use temporary descriptor to avoid touching bits multiple times */
|
||||
union Vmxnet3_GenericDesc tempTxDesc;
|
||||
#endif
|
||||
struct udphdr *udph;
|
||||
|
||||
count = txd_estimate(skb);
|
||||
|
||||
|
|
@ -1135,8 +1134,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
|
|||
gdesc->txd.om = VMXNET3_OM_ENCAP;
|
||||
gdesc->txd.msscof = ctx.mss;
|
||||
|
||||
udph = udp_hdr(skb);
|
||||
if (udph->check)
|
||||
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
|
||||
gdesc->txd.oco = 1;
|
||||
} else {
|
||||
gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
|
||||
|
|
@ -3371,6 +3369,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
|
|||
.ndo_change_mtu = vmxnet3_change_mtu,
|
||||
.ndo_fix_features = vmxnet3_fix_features,
|
||||
.ndo_set_features = vmxnet3_set_features,
|
||||
.ndo_features_check = vmxnet3_features_check,
|
||||
.ndo_get_stats64 = vmxnet3_get_stats64,
|
||||
.ndo_tx_timeout = vmxnet3_tx_timeout,
|
||||
.ndo_set_rx_mode = vmxnet3_set_mc,
|
||||
|
|
|
|||
|
|
@ -267,6 +267,34 @@ netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
|
|||
return features;
|
||||
}
|
||||
|
||||
netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
|
||||
struct net_device *netdev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
/* Validate if the tunneled packet is being offloaded by the device */
|
||||
if (VMXNET3_VERSION_GE_4(adapter) &&
|
||||
skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
u8 l4_proto = 0;
|
||||
|
||||
switch (vlan_get_protocol(skb)) {
|
||||
case htons(ETH_P_IP):
|
||||
l4_proto = ip_hdr(skb)->protocol;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
l4_proto = ipv6_hdr(skb)->nexthdr;
|
||||
break;
|
||||
default:
|
||||
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
|
||||
}
|
||||
|
||||
if (l4_proto != IPPROTO_UDP)
|
||||
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
static void vmxnet3_enable_encap_offloads(struct net_device *netdev)
|
||||
{
|
||||
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
|
||||
|
|
|
|||
|
|
@ -470,6 +470,10 @@ vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
|
|||
netdev_features_t
|
||||
vmxnet3_fix_features(struct net_device *netdev, netdev_features_t features);
|
||||
|
||||
netdev_features_t
|
||||
vmxnet3_features_check(struct sk_buff *skb,
|
||||
struct net_device *netdev, netdev_features_t features);
|
||||
|
||||
int
|
||||
vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user