Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Cross-merge networking fixes after downstream PR.

Conflicts:

net/mac80211/rx.c
  91535613b6 ("wifi: mac80211: don't drop all unprotected public action frames")
  6c02fab724 ("wifi: mac80211: split ieee80211_drop_unencrypted_mgmt() return value")

Adjacent changes:

drivers/net/ethernet/apm/xgene/xgene_enet_main.c
  61471264c0 ("net: ethernet: apm: Convert to platform remove callback returning void")
  d2ca43f306 ("net: xgene: Fix unused xgene_enet_of_match warning for !CONFIG_OF")

net/vmw_vsock/virtio_transport.c
  64c99d2d6a ("vsock/virtio: support to send non-linear skb")
  53b08c4985 ("vsock/virtio: initialize the_virtio_vsock before using VQs")

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2023-10-26 13:42:19 -07:00
commit ec4c20ca09
205 changed files with 1936 additions and 762 deletions

View File

@ -87,6 +87,7 @@ Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com>
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com> Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com>
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com> Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com> Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com>
Ben Dooks <ben-linux@fluff.org> <ben.dooks@simtec.co.uk> Ben Dooks <ben-linux@fluff.org> <ben.dooks@simtec.co.uk>
Ben Dooks <ben-linux@fluff.org> <ben.dooks@sifive.com> Ben Dooks <ben-linux@fluff.org> <ben.dooks@sifive.com>
Ben Gardner <bgardner@wabtec.com> Ben Gardner <bgardner@wabtec.com>
@ -450,9 +451,10 @@ Oleksandr Natalenko <oleksandr@natalenko.name> <oleksandr@redhat.com>
Oleksij Rempel <linux@rempel-privat.de> <bug-track@fisher-privat.net> Oleksij Rempel <linux@rempel-privat.de> <bug-track@fisher-privat.net>
Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com> Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com>
Oleksij Rempel <linux@rempel-privat.de> <fixed-term.Oleksij.Rempel@de.bosch.com> Oleksij Rempel <linux@rempel-privat.de> <fixed-term.Oleksij.Rempel@de.bosch.com>
Oleksij Rempel <linux@rempel-privat.de> <o.rempel@pengutronix.de> Oleksij Rempel <o.rempel@pengutronix.de>
Oleksij Rempel <linux@rempel-privat.de> <ore@pengutronix.de> Oleksij Rempel <o.rempel@pengutronix.de> <ore@pengutronix.de>
Oliver Upton <oliver.upton@linux.dev> <oupton@google.com> Oliver Upton <oliver.upton@linux.dev> <oupton@google.com>
Ondřej Jirman <megi@xff.cz> <megous@megous.com>
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org> Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com> Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com>
Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

View File

@ -69,7 +69,7 @@ properties:
maxItems: 4 maxItems: 4
clocks: clocks:
minItems: 3 minItems: 2
items: items:
- description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock - description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock
- description: SDC MMC clock, MCLK - description: SDC MMC clock, MCLK

View File

@ -70,7 +70,7 @@ examples:
phy@84000 { phy@84000 {
compatible = "qcom,ipq6018-qmp-pcie-phy"; compatible = "qcom,ipq6018-qmp-pcie-phy";
reg = <0x0 0x00084000 0x0 0x1000>; reg = <0x00084000 0x1000>;
clocks = <&gcc GCC_PCIE0_AUX_CLK>, clocks = <&gcc GCC_PCIE0_AUX_CLK>,
<&gcc GCC_PCIE0_AHB_CLK>, <&gcc GCC_PCIE0_AHB_CLK>,

View File

@ -82,7 +82,7 @@ properties:
description: description:
Current at which the headset micbias sense clamp will engage, 0 to Current at which the headset micbias sense clamp will engage, 0 to
disable. disable.
enum: [ 0, 14, 23, 41, 50, 60, 68, 86, 95 ] enum: [ 0, 14, 24, 43, 52, 61, 71, 90, 99 ]
default: 0 default: 0
cirrus,bias-ramp-ms: cirrus,bias-ramp-ms:

View File

@ -29,7 +29,7 @@ target with the same invocation used for compilation, e.g.::
To read the docs locally in your web browser, run e.g.:: To read the docs locally in your web browser, run e.g.::
xdg-open rust/doc/kernel/index.html xdg-open Documentation/output/rust/rustdoc/kernel/index.html
To learn about how to write the documentation, please see coding-guidelines.rst. To learn about how to write the documentation, please see coding-guidelines.rst.

View File

@ -378,8 +378,9 @@ F: drivers/acpi/viot.c
F: include/linux/acpi_viot.h F: include/linux/acpi_viot.h
ACPI WMI DRIVER ACPI WMI DRIVER
M: Armin Wolf <W_Armin@gmx.de>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Orphan S: Maintained
F: Documentation/driver-api/wmi.rst F: Documentation/driver-api/wmi.rst
F: Documentation/wmi/ F: Documentation/wmi/
F: drivers/platform/x86/wmi.c F: drivers/platform/x86/wmi.c
@ -6769,7 +6770,7 @@ F: drivers/gpu/drm/panel/panel-sitronix-st7701.c
DRM DRIVER FOR SITRONIX ST7703 PANELS DRM DRIVER FOR SITRONIX ST7703 PANELS
M: Guido Günther <agx@sigxcpu.org> M: Guido Günther <agx@sigxcpu.org>
R: Purism Kernel Team <kernel@puri.sm> R: Purism Kernel Team <kernel@puri.sm>
R: Ondrej Jirman <megous@megous.com> R: Ondrej Jirman <megi@xff.cz>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml F: Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
F: drivers/gpu/drm/panel/panel-sitronix-st7703.c F: drivers/gpu/drm/panel/panel-sitronix-st7703.c
@ -15137,7 +15138,7 @@ NOLIBC HEADER FILE
M: Willy Tarreau <w@1wt.eu> M: Willy Tarreau <w@1wt.eu>
M: Thomas Weißschuh <linux@weissschuh.net> M: Thomas Weißschuh <linux@weissschuh.net>
S: Maintained S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc.git
F: tools/include/nolibc/ F: tools/include/nolibc/
F: tools/testing/selftests/nolibc/ F: tools/testing/selftests/nolibc/

View File

@ -2,7 +2,7 @@
VERSION = 6 VERSION = 6
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc6 EXTRAVERSION = -rc7
NAME = Hurr durr I'ma ninja sloth NAME = Hurr durr I'ma ninja sloth
# *DOCUMENTATION* # *DOCUMENTATION*
@ -1474,7 +1474,7 @@ endif # CONFIG_MODULES
# Directories & files removed with 'make clean' # Directories & files removed with 'make clean'
CLEAN_FILES += vmlinux.symvers modules-only.symvers \ CLEAN_FILES += vmlinux.symvers modules-only.symvers \
modules.builtin modules.builtin.modinfo modules.nsdeps \ modules.builtin modules.builtin.modinfo modules.nsdeps \
compile_commands.json .thinlto-cache rust/test rust/doc \ compile_commands.json .thinlto-cache rust/test \
rust-project.json .vmlinux.objs .vmlinux.export.c rust-project.json .vmlinux.objs .vmlinux.export.c
# Directories & files removed with 'make mrproper' # Directories & files removed with 'make mrproper'

View File

@ -910,7 +910,7 @@ config ARCH_FORCE_MAX_ORDER
default "6" if PPC32 && PPC_64K_PAGES default "6" if PPC32 && PPC_64K_PAGES
range 4 10 if PPC32 && PPC_256K_PAGES range 4 10 if PPC32 && PPC_256K_PAGES
default "4" if PPC32 && PPC_256K_PAGES default "4" if PPC32 && PPC_256K_PAGES
range 10 10 range 10 12
default "10" default "10"
help help
The kernel page allocator limits the size of maximal physically The kernel page allocator limits the size of maximal physically

View File

@ -406,6 +406,9 @@ static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode *
if ((yield_count & 1) == 0) if ((yield_count & 1) == 0)
goto yield_prev; /* owner vcpu is running */ goto yield_prev; /* owner vcpu is running */
if (get_owner_cpu(READ_ONCE(lock->val)) != yield_cpu)
goto yield_prev; /* re-sample lock owner */
spin_end(); spin_end();
preempted = true; preempted = true;

View File

@ -1212,14 +1212,7 @@ void radix__tlb_flush(struct mmu_gather *tlb)
smp_mb(); /* see radix__flush_tlb_mm */ smp_mb(); /* see radix__flush_tlb_mm */
exit_flush_lazy_tlbs(mm); exit_flush_lazy_tlbs(mm);
_tlbiel_pid(mm->context.id, RIC_FLUSH_ALL); __flush_all_mm(mm, true);
/*
* It should not be possible to have coprocessors still
* attached here.
*/
if (WARN_ON_ONCE(atomic_read(&mm->context.copros) > 0))
__flush_all_mm(mm, true);
preempt_enable(); preempt_enable();
} else { } else {

View File

@ -72,7 +72,7 @@ static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_f
} }
pagefault_out_of_memory(); pagefault_out_of_memory();
return; return;
} else if (fault & VM_FAULT_SIGBUS) { } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) {
/* Kernel mode? Handle exceptions or die */ /* Kernel mode? Handle exceptions or die */
if (!user_mode(regs)) { if (!user_mode(regs)) {
no_context(regs, addr); no_context(regs, addr);

View File

@ -183,15 +183,22 @@ void set_huge_pte_at(struct mm_struct *mm,
pte_t pte, pte_t pte,
unsigned long sz) unsigned long sz)
{ {
unsigned long hugepage_shift;
int i, pte_num; int i, pte_num;
if (!pte_napot(pte)) { if (sz >= PGDIR_SIZE)
set_pte_at(mm, addr, ptep, pte); hugepage_shift = PGDIR_SHIFT;
return; else if (sz >= P4D_SIZE)
} hugepage_shift = P4D_SHIFT;
else if (sz >= PUD_SIZE)
hugepage_shift = PUD_SHIFT;
else if (sz >= PMD_SIZE)
hugepage_shift = PMD_SHIFT;
else
hugepage_shift = PAGE_SHIFT;
pte_num = napot_pte_num(napot_cont_order(pte)); pte_num = sz >> hugepage_shift;
for (i = 0; i < pte_num; i++, ptep++, addr += PAGE_SIZE) for (i = 0; i < pte_num; i++, ptep++, addr += (1 << hugepage_shift))
set_pte_at(mm, addr, ptep, pte); set_pte_at(mm, addr, ptep, pte);
} }

View File

@ -57,6 +57,7 @@ static void kasan_populate_shadow(void)
pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY); pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY);
pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY); pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY);
p4d_t p4d_z = __p4d(__pa(kasan_early_shadow_pud) | _REGION2_ENTRY); p4d_t p4d_z = __p4d(__pa(kasan_early_shadow_pud) | _REGION2_ENTRY);
unsigned long memgap_start = 0;
unsigned long untracked_end; unsigned long untracked_end;
unsigned long start, end; unsigned long start, end;
int i; int i;
@ -101,8 +102,12 @@ static void kasan_populate_shadow(void)
* +- shadow end ----+---------+- shadow end ---+ * +- shadow end ----+---------+- shadow end ---+
*/ */
for_each_physmem_usable_range(i, &start, &end) for_each_physmem_usable_range(i, &start, &end) {
kasan_populate(start, end, POPULATE_KASAN_MAP_SHADOW); kasan_populate(start, end, POPULATE_KASAN_MAP_SHADOW);
if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260)
kasan_populate(memgap_start, start, POPULATE_KASAN_ZERO_SHADOW);
memgap_start = end;
}
if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
untracked_end = VMALLOC_START; untracked_end = VMALLOC_START;
/* shallowly populate kasan shadow for vmalloc and modules */ /* shallowly populate kasan shadow for vmalloc and modules */

View File

@ -564,6 +564,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
s->dma_length = 0; s->dma_length = 0;
} }
} }
static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags)
{
size_t n = BITS_TO_LONGS(bits);
size_t bytes;
if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes)))
return NULL;
return vzalloc(bytes);
}
int zpci_dma_init_device(struct zpci_dev *zdev) int zpci_dma_init_device(struct zpci_dev *zdev)
{ {
@ -604,13 +615,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
zdev->end_dma - zdev->start_dma + 1); zdev->end_dma - zdev->start_dma + 1);
zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
if (!zdev->iommu_bitmap) { if (!zdev->iommu_bitmap) {
rc = -ENOMEM; rc = -ENOMEM;
goto free_dma_table; goto free_dma_table;
} }
if (!s390_iommu_strict) { if (!s390_iommu_strict) {
zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8); zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
if (!zdev->lazy_bitmap) { if (!zdev->lazy_bitmap) {
rc = -ENOMEM; rc = -ENOMEM;
goto free_bitmap; goto free_bitmap;

View File

@ -103,6 +103,16 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
return ES_OK; return ES_OK;
} }
static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
{
return ES_OK;
}
static bool fault_in_kernel_space(unsigned long address)
{
return false;
}
#undef __init #undef __init
#define __init #define __init

View File

@ -632,6 +632,23 @@ fail:
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
} }
static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt,
unsigned long address,
bool write)
{
if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) {
ctxt->fi.vector = X86_TRAP_PF;
ctxt->fi.error_code = X86_PF_USER;
ctxt->fi.cr2 = address;
if (write)
ctxt->fi.error_code |= X86_PF_WRITE;
return ES_EXCEPTION;
}
return ES_OK;
}
static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
void *src, char *buf, void *src, char *buf,
unsigned int data_size, unsigned int data_size,
@ -639,7 +656,12 @@ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
bool backwards) bool backwards)
{ {
int i, b = backwards ? -1 : 1; int i, b = backwards ? -1 : 1;
enum es_result ret = ES_OK; unsigned long address = (unsigned long)src;
enum es_result ret;
ret = vc_insn_string_check(ctxt, address, false);
if (ret != ES_OK)
return ret;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
void *s = src + (i * data_size * b); void *s = src + (i * data_size * b);
@ -660,7 +682,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
bool backwards) bool backwards)
{ {
int i, s = backwards ? -1 : 1; int i, s = backwards ? -1 : 1;
enum es_result ret = ES_OK; unsigned long address = (unsigned long)dst;
enum es_result ret;
ret = vc_insn_string_check(ctxt, address, true);
if (ret != ES_OK)
return ret;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
void *d = dst + (i * data_size * s); void *d = dst + (i * data_size * s);
@ -696,6 +723,9 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
{ {
struct insn *insn = &ctxt->insn; struct insn *insn = &ctxt->insn;
size_t size;
u64 port;
*exitinfo = 0; *exitinfo = 0;
switch (insn->opcode.bytes[0]) { switch (insn->opcode.bytes[0]) {
@ -704,7 +734,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
case 0x6d: case 0x6d:
*exitinfo |= IOIO_TYPE_INS; *exitinfo |= IOIO_TYPE_INS;
*exitinfo |= IOIO_SEG_ES; *exitinfo |= IOIO_SEG_ES;
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16; port = ctxt->regs->dx & 0xffff;
break; break;
/* OUTS opcodes */ /* OUTS opcodes */
@ -712,41 +742,43 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
case 0x6f: case 0x6f:
*exitinfo |= IOIO_TYPE_OUTS; *exitinfo |= IOIO_TYPE_OUTS;
*exitinfo |= IOIO_SEG_DS; *exitinfo |= IOIO_SEG_DS;
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16; port = ctxt->regs->dx & 0xffff;
break; break;
/* IN immediate opcodes */ /* IN immediate opcodes */
case 0xe4: case 0xe4:
case 0xe5: case 0xe5:
*exitinfo |= IOIO_TYPE_IN; *exitinfo |= IOIO_TYPE_IN;
*exitinfo |= (u8)insn->immediate.value << 16; port = (u8)insn->immediate.value & 0xffff;
break; break;
/* OUT immediate opcodes */ /* OUT immediate opcodes */
case 0xe6: case 0xe6:
case 0xe7: case 0xe7:
*exitinfo |= IOIO_TYPE_OUT; *exitinfo |= IOIO_TYPE_OUT;
*exitinfo |= (u8)insn->immediate.value << 16; port = (u8)insn->immediate.value & 0xffff;
break; break;
/* IN register opcodes */ /* IN register opcodes */
case 0xec: case 0xec:
case 0xed: case 0xed:
*exitinfo |= IOIO_TYPE_IN; *exitinfo |= IOIO_TYPE_IN;
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16; port = ctxt->regs->dx & 0xffff;
break; break;
/* OUT register opcodes */ /* OUT register opcodes */
case 0xee: case 0xee:
case 0xef: case 0xef:
*exitinfo |= IOIO_TYPE_OUT; *exitinfo |= IOIO_TYPE_OUT;
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16; port = ctxt->regs->dx & 0xffff;
break; break;
default: default:
return ES_DECODE_FAILED; return ES_DECODE_FAILED;
} }
*exitinfo |= port << 16;
switch (insn->opcode.bytes[0]) { switch (insn->opcode.bytes[0]) {
case 0x6c: case 0x6c:
case 0x6e: case 0x6e:
@ -756,12 +788,15 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
case 0xee: case 0xee:
/* Single byte opcodes */ /* Single byte opcodes */
*exitinfo |= IOIO_DATA_8; *exitinfo |= IOIO_DATA_8;
size = 1;
break; break;
default: default:
/* Length determined by instruction parsing */ /* Length determined by instruction parsing */
*exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16
: IOIO_DATA_32; : IOIO_DATA_32;
size = (insn->opnd_bytes == 2) ? 2 : 4;
} }
switch (insn->addr_bytes) { switch (insn->addr_bytes) {
case 2: case 2:
*exitinfo |= IOIO_ADDR_16; *exitinfo |= IOIO_ADDR_16;
@ -777,7 +812,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
if (insn_has_rep_prefix(insn)) if (insn_has_rep_prefix(insn))
*exitinfo |= IOIO_REP; *exitinfo |= IOIO_REP;
return ES_OK; return vc_ioio_check(ctxt, (u16)port, size);
} }
static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)

View File

@ -524,6 +524,33 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt
return ES_OK; return ES_OK;
} }
static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
{
BUG_ON(size > 4);
if (user_mode(ctxt->regs)) {
struct thread_struct *t = &current->thread;
struct io_bitmap *iobm = t->io_bitmap;
size_t idx;
if (!iobm)
goto fault;
for (idx = port; idx < port + size; ++idx) {
if (test_bit(idx, iobm->bitmap))
goto fault;
}
}
return ES_OK;
fault:
ctxt->fi.vector = X86_TRAP_GP;
ctxt->fi.error_code = 0;
return ES_EXCEPTION;
}
/* Include code shared with pre-decompression boot stage */ /* Include code shared with pre-decompression boot stage */
#include "sev-shared.c" #include "sev-shared.c"
@ -1508,6 +1535,9 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
return ES_DECODE_FAILED; return ES_DECODE_FAILED;
} }
if (user_mode(ctxt->regs))
return ES_UNSUPPORTED;
switch (mmio) { switch (mmio) {
case INSN_MMIO_WRITE: case INSN_MMIO_WRITE:
memcpy(ghcb->shared_buffer, reg_data, bytes); memcpy(ghcb->shared_buffer, reg_data, bytes);

View File

@ -2888,12 +2888,11 @@ static int opal_lock_unlock(struct opal_dev *dev,
if (lk_unlk->session.who > OPAL_USER9) if (lk_unlk->session.who > OPAL_USER9)
return -EINVAL; return -EINVAL;
ret = opal_get_key(dev, &lk_unlk->session.opal_key);
if (ret)
return ret;
mutex_lock(&dev->dev_lock); mutex_lock(&dev->dev_lock);
opal_lock_check_for_saved_key(dev, lk_unlk); opal_lock_check_for_saved_key(dev, lk_unlk);
ret = __opal_lock_unlock(dev, lk_unlk); ret = opal_get_key(dev, &lk_unlk->session.opal_key);
if (!ret)
ret = __opal_lock_unlock(dev, lk_unlk);
mutex_unlock(&dev->dev_lock); mutex_unlock(&dev->dev_lock);
return ret; return ret;

View File

@ -81,14 +81,13 @@ software_key_determine_akcipher(const struct public_key *pkey,
* RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2]. * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
*/ */
if (strcmp(encoding, "pkcs1") == 0) { if (strcmp(encoding, "pkcs1") == 0) {
*sig = op == kernel_pkey_sign ||
op == kernel_pkey_verify;
if (!hash_algo) { if (!hash_algo) {
*sig = false;
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
"pkcs1pad(%s)", "pkcs1pad(%s)",
pkey->pkey_algo); pkey->pkey_algo);
} else { } else {
*sig = op == kernel_pkey_sign ||
op == kernel_pkey_verify;
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
"pkcs1pad(%s,%s)", "pkcs1pad(%s,%s)",
pkey->pkey_algo, hash_algo); pkey->pkey_algo, hash_algo);

View File

@ -367,14 +367,19 @@ int ivpu_boot(struct ivpu_device *vdev)
return 0; return 0;
} }
int ivpu_shutdown(struct ivpu_device *vdev) void ivpu_prepare_for_reset(struct ivpu_device *vdev)
{ {
int ret;
ivpu_hw_irq_disable(vdev); ivpu_hw_irq_disable(vdev);
disable_irq(vdev->irq); disable_irq(vdev->irq);
ivpu_ipc_disable(vdev); ivpu_ipc_disable(vdev);
ivpu_mmu_disable(vdev); ivpu_mmu_disable(vdev);
}
int ivpu_shutdown(struct ivpu_device *vdev)
{
int ret;
ivpu_prepare_for_reset(vdev);
ret = ivpu_hw_power_down(vdev); ret = ivpu_hw_power_down(vdev);
if (ret) if (ret)

View File

@ -151,6 +151,7 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link);
int ivpu_boot(struct ivpu_device *vdev); int ivpu_boot(struct ivpu_device *vdev);
int ivpu_shutdown(struct ivpu_device *vdev); int ivpu_shutdown(struct ivpu_device *vdev);
void ivpu_prepare_for_reset(struct ivpu_device *vdev);
static inline u8 ivpu_revision(struct ivpu_device *vdev) static inline u8 ivpu_revision(struct ivpu_device *vdev)
{ {

View File

@ -220,8 +220,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
if (ret) if (ret)
return ret; return ret;
fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC);
DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP);
if (!fw->mem) { if (!fw->mem) {
ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); ivpu_err(vdev, "Failed to allocate firmware runtime memory\n");
return -ENOMEM; return -ENOMEM;
@ -331,7 +330,7 @@ int ivpu_fw_load(struct ivpu_device *vdev)
memset(start, 0, size); memset(start, 0, size);
} }
clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size); wmb(); /* Flush WC buffers after writing fw->mem */
return 0; return 0;
} }
@ -433,7 +432,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
if (!ivpu_fw_is_cold_boot(vdev)) { if (!ivpu_fw_is_cold_boot(vdev)) {
boot_params->save_restore_ret_address = 0; boot_params->save_restore_ret_address = 0;
vdev->pm->is_warmboot = true; vdev->pm->is_warmboot = true;
clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); wmb(); /* Flush WC buffers after writing save_restore_ret_address */
return; return;
} }
@ -495,7 +494,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); wmb(); /* Flush WC buffers after writing bootparams */
ivpu_fw_boot_params_print(vdev, boot_params); ivpu_fw_boot_params_print(vdev, boot_params);
} }

View File

@ -8,8 +8,6 @@
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include <drm/drm_mm.h> #include <drm/drm_mm.h>
#define DRM_IVPU_BO_NOSNOOP 0x10000000
struct dma_buf; struct dma_buf;
struct ivpu_bo_ops; struct ivpu_bo_ops;
struct ivpu_file_priv; struct ivpu_file_priv;
@ -85,9 +83,6 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
{ {
if (bo->flags & DRM_IVPU_BO_NOSNOOP)
return false;
return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
} }

View File

@ -13,6 +13,7 @@ struct ivpu_hw_ops {
int (*power_up)(struct ivpu_device *vdev); int (*power_up)(struct ivpu_device *vdev);
int (*boot_fw)(struct ivpu_device *vdev); int (*boot_fw)(struct ivpu_device *vdev);
int (*power_down)(struct ivpu_device *vdev); int (*power_down)(struct ivpu_device *vdev);
int (*reset)(struct ivpu_device *vdev);
bool (*is_idle)(struct ivpu_device *vdev); bool (*is_idle)(struct ivpu_device *vdev);
void (*wdt_disable)(struct ivpu_device *vdev); void (*wdt_disable)(struct ivpu_device *vdev);
void (*diagnose_failure)(struct ivpu_device *vdev); void (*diagnose_failure)(struct ivpu_device *vdev);
@ -91,6 +92,13 @@ static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
return vdev->hw->ops->power_down(vdev); return vdev->hw->ops->power_down(vdev);
}; };
static inline int ivpu_hw_reset(struct ivpu_device *vdev)
{
ivpu_dbg(vdev, PM, "HW reset\n");
return vdev->hw->ops->reset(vdev);
};
static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev) static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
{ {
vdev->hw->ops->wdt_disable(vdev); vdev->hw->ops->wdt_disable(vdev);

View File

@ -1029,6 +1029,7 @@ const struct ivpu_hw_ops ivpu_hw_37xx_ops = {
.power_up = ivpu_hw_37xx_power_up, .power_up = ivpu_hw_37xx_power_up,
.is_idle = ivpu_hw_37xx_is_idle, .is_idle = ivpu_hw_37xx_is_idle,
.power_down = ivpu_hw_37xx_power_down, .power_down = ivpu_hw_37xx_power_down,
.reset = ivpu_hw_37xx_reset,
.boot_fw = ivpu_hw_37xx_boot_fw, .boot_fw = ivpu_hw_37xx_boot_fw,
.wdt_disable = ivpu_hw_37xx_wdt_disable, .wdt_disable = ivpu_hw_37xx_wdt_disable,
.diagnose_failure = ivpu_hw_37xx_diagnose_failure, .diagnose_failure = ivpu_hw_37xx_diagnose_failure,

View File

@ -1179,6 +1179,7 @@ const struct ivpu_hw_ops ivpu_hw_40xx_ops = {
.power_up = ivpu_hw_40xx_power_up, .power_up = ivpu_hw_40xx_power_up,
.is_idle = ivpu_hw_40xx_is_idle, .is_idle = ivpu_hw_40xx_is_idle,
.power_down = ivpu_hw_40xx_power_down, .power_down = ivpu_hw_40xx_power_down,
.reset = ivpu_hw_40xx_reset,
.boot_fw = ivpu_hw_40xx_boot_fw, .boot_fw = ivpu_hw_40xx_boot_fw,
.wdt_disable = ivpu_hw_40xx_wdt_disable, .wdt_disable = ivpu_hw_40xx_wdt_disable,
.diagnose_failure = ivpu_hw_40xx_diagnose_failure, .diagnose_failure = ivpu_hw_40xx_diagnose_failure,

View File

@ -11,6 +11,7 @@
#include "ivpu_mmu.h" #include "ivpu_mmu.h"
#include "ivpu_mmu_context.h" #include "ivpu_mmu_context.h"
#define IVPU_MMU_VPU_ADDRESS_MASK GENMASK(47, 12)
#define IVPU_MMU_PGD_INDEX_MASK GENMASK(47, 39) #define IVPU_MMU_PGD_INDEX_MASK GENMASK(47, 39)
#define IVPU_MMU_PUD_INDEX_MASK GENMASK(38, 30) #define IVPU_MMU_PUD_INDEX_MASK GENMASK(38, 30)
#define IVPU_MMU_PMD_INDEX_MASK GENMASK(29, 21) #define IVPU_MMU_PMD_INDEX_MASK GENMASK(29, 21)
@ -328,12 +329,8 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
if (!IS_ALIGNED(vpu_addr, IVPU_MMU_PAGE_SIZE)) if (!IS_ALIGNED(vpu_addr, IVPU_MMU_PAGE_SIZE))
return -EINVAL; return -EINVAL;
/*
* VPU is only 32 bit, but DMA engine is 38 bit if (vpu_addr & ~IVPU_MMU_VPU_ADDRESS_MASK)
* Ranges < 2 GB are reserved for VPU internal registers
* Limit range to 8 GB
*/
if (vpu_addr < SZ_2G || vpu_addr > SZ_8G)
return -EINVAL; return -EINVAL;
prot = IVPU_MMU_ENTRY_MAPPED; prot = IVPU_MMU_ENTRY_MAPPED;

View File

@ -261,7 +261,8 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
ivpu_dbg(vdev, PM, "Pre-reset..\n"); ivpu_dbg(vdev, PM, "Pre-reset..\n");
atomic_inc(&vdev->pm->reset_counter); atomic_inc(&vdev->pm->reset_counter);
atomic_set(&vdev->pm->in_reset, 1); atomic_set(&vdev->pm->in_reset, 1);
ivpu_shutdown(vdev); ivpu_prepare_for_reset(vdev);
ivpu_hw_reset(vdev);
ivpu_pm_prepare_cold_boot(vdev); ivpu_pm_prepare_cold_boot(vdev);
ivpu_jobs_abort_all(vdev); ivpu_jobs_abort_all(vdev);
ivpu_dbg(vdev, PM, "Pre-reset done.\n"); ivpu_dbg(vdev, PM, "Pre-reset done.\n");

View File

@ -1410,10 +1410,10 @@ static int __init acpi_init(void)
acpi_init_ffh(); acpi_init_ffh();
pci_mmcfg_late_init(); pci_mmcfg_late_init();
acpi_arm_init();
acpi_viot_early_init(); acpi_viot_early_init();
acpi_hest_init(); acpi_hest_init();
acpi_ghes_init(); acpi_ghes_init();
acpi_arm_init();
acpi_scan_init(); acpi_scan_init();
acpi_ec_init(); acpi_ec_init();
acpi_debugfs_init(); acpi_debugfs_init();

View File

@ -57,6 +57,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
int polarity) int polarity)
{ {
struct irq_fwspec fwspec; struct irq_fwspec fwspec;
unsigned int irq;
fwspec.fwnode = acpi_get_gsi_domain_id(gsi); fwspec.fwnode = acpi_get_gsi_domain_id(gsi);
if (WARN_ON(!fwspec.fwnode)) { if (WARN_ON(!fwspec.fwnode)) {
@ -68,7 +69,11 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
fwspec.param_count = 2; fwspec.param_count = 2;
return irq_create_fwspec_mapping(&fwspec); irq = irq_create_fwspec_mapping(&fwspec);
if (!irq)
return -EINVAL;
return irq;
} }
EXPORT_SYMBOL_GPL(acpi_register_gsi); EXPORT_SYMBOL_GPL(acpi_register_gsi);

View File

@ -3339,6 +3339,16 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_size sz; acpi_size sz;
int rc = 0; int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
acpi_nfit_notify);
if (rc)
return rc;
rc = devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler,
adev);
if (rc)
return rc;
status = acpi_get_table(ACPI_SIG_NFIT, 0, &tbl); status = acpi_get_table(ACPI_SIG_NFIT, 0, &tbl);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* The NVDIMM root device allows OS to trigger enumeration of /* The NVDIMM root device allows OS to trigger enumeration of
@ -3386,17 +3396,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
if (rc) if (rc)
return rc; return rc;
rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc); return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
if (rc)
return rc;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
acpi_nfit_notify);
if (rc)
return rc;
return devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler,
adev);
} }
static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle) static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)

View File

@ -54,7 +54,7 @@ static int cn_filter(struct sock *dsk, struct sk_buff *skb, void *data)
enum proc_cn_mcast_op mc_op; enum proc_cn_mcast_op mc_op;
uintptr_t val; uintptr_t val;
if (!dsk || !data) if (!dsk || !dsk->sk_user_data || !data)
return 0; return 0;
ptr = (__u32 *)data; ptr = (__u32 *)data;

View File

@ -35,6 +35,9 @@ struct virtio_crypto {
struct virtqueue *ctrl_vq; struct virtqueue *ctrl_vq;
struct data_queue *data_vq; struct data_queue *data_vq;
/* Work struct for config space updates */
struct work_struct config_work;
/* To protect the vq operations for the controlq */ /* To protect the vq operations for the controlq */
spinlock_t ctrl_lock; spinlock_t ctrl_lock;

View File

@ -335,6 +335,14 @@ static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto)
virtcrypto_free_queues(vcrypto); virtcrypto_free_queues(vcrypto);
} }
static void vcrypto_config_changed_work(struct work_struct *work)
{
struct virtio_crypto *vcrypto =
container_of(work, struct virtio_crypto, config_work);
virtcrypto_update_status(vcrypto);
}
static int virtcrypto_probe(struct virtio_device *vdev) static int virtcrypto_probe(struct virtio_device *vdev)
{ {
int err = -EFAULT; int err = -EFAULT;
@ -454,6 +462,8 @@ static int virtcrypto_probe(struct virtio_device *vdev)
if (err) if (err)
goto free_engines; goto free_engines;
INIT_WORK(&vcrypto->config_work, vcrypto_config_changed_work);
return 0; return 0;
free_engines: free_engines:
@ -490,6 +500,7 @@ static void virtcrypto_remove(struct virtio_device *vdev)
dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); dev_info(&vdev->dev, "Start virtcrypto_remove.\n");
flush_work(&vcrypto->config_work);
if (virtcrypto_dev_started(vcrypto)) if (virtcrypto_dev_started(vcrypto))
virtcrypto_dev_stop(vcrypto); virtcrypto_dev_stop(vcrypto);
virtio_reset_device(vdev); virtio_reset_device(vdev);
@ -504,7 +515,7 @@ static void virtcrypto_config_changed(struct virtio_device *vdev)
{ {
struct virtio_crypto *vcrypto = vdev->priv; struct virtio_crypto *vcrypto = vdev->priv;
virtcrypto_update_status(vcrypto); schedule_work(&vcrypto->config_work);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
@ -512,6 +523,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev)
{ {
struct virtio_crypto *vcrypto = vdev->priv; struct virtio_crypto *vcrypto = vdev->priv;
flush_work(&vcrypto->config_work);
virtio_reset_device(vdev); virtio_reset_device(vdev);
virtcrypto_free_unused_reqs(vcrypto); virtcrypto_free_unused_reqs(vcrypto);
if (virtcrypto_dev_started(vcrypto)) if (virtcrypto_dev_started(vcrypto))

View File

@ -273,9 +273,13 @@ static __init int efivar_ssdt_load(void)
if (status == EFI_NOT_FOUND) { if (status == EFI_NOT_FOUND) {
break; break;
} else if (status == EFI_BUFFER_TOO_SMALL) { } else if (status == EFI_BUFFER_TOO_SMALL) {
name = krealloc(name, name_size, GFP_KERNEL); efi_char16_t *name_tmp =
if (!name) krealloc(name, name_size, GFP_KERNEL);
if (!name_tmp) {
kfree(name);
return -ENOMEM; return -ENOMEM;
}
name = name_tmp;
continue; continue;
} }

View File

@ -605,11 +605,8 @@ setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_s
break; break;
case EFI_UNACCEPTED_MEMORY: case EFI_UNACCEPTED_MEMORY:
if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY)) { if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))
efi_warn_once(
"The system has unaccepted memory, but kernel does not support it\nConsider enabling CONFIG_UNACCEPTED_MEMORY\n");
continue; continue;
}
e820_type = E820_TYPE_RAM; e820_type = E820_TYPE_RAM;
process_unaccepted_memory(d->phys_addr, process_unaccepted_memory(d->phys_addr,
d->phys_addr + PAGE_SIZE * d->num_pages); d->phys_addr + PAGE_SIZE * d->num_pages);
@ -852,6 +849,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
unsigned long kernel_entry; unsigned long kernel_entry;
efi_status_t status; efi_status_t status;
boot_params_pointer = boot_params;
efi_system_table = sys_table_arg; efi_system_table = sys_table_arg;
/* Check if we were booted by the EFI firmware */ /* Check if we were booted by the EFI firmware */
if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)

View File

@ -2,6 +2,8 @@
#include <linux/efi.h> #include <linux/efi.h>
extern struct boot_params *boot_params_pointer asm("boot_params");
extern void trampoline_32bit_src(void *, bool); extern void trampoline_32bit_src(void *, bool);
extern const u16 trampoline_ljmp_imm_offset; extern const u16 trampoline_ljmp_imm_offset;

View File

@ -5,9 +5,17 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <asm/unaccepted_memory.h> #include <asm/unaccepted_memory.h>
/* Protects unaccepted memory bitmap */ /* Protects unaccepted memory bitmap and accepting_list */
static DEFINE_SPINLOCK(unaccepted_memory_lock); static DEFINE_SPINLOCK(unaccepted_memory_lock);
struct accept_range {
struct list_head list;
unsigned long start;
unsigned long end;
};
static LIST_HEAD(accepting_list);
/* /*
* accept_memory() -- Consult bitmap and accept the memory if needed. * accept_memory() -- Consult bitmap and accept the memory if needed.
* *
@ -24,6 +32,7 @@ void accept_memory(phys_addr_t start, phys_addr_t end)
{ {
struct efi_unaccepted_memory *unaccepted; struct efi_unaccepted_memory *unaccepted;
unsigned long range_start, range_end; unsigned long range_start, range_end;
struct accept_range range, *entry;
unsigned long flags; unsigned long flags;
u64 unit_size; u64 unit_size;
@ -78,20 +87,67 @@ void accept_memory(phys_addr_t start, phys_addr_t end)
if (end > unaccepted->size * unit_size * BITS_PER_BYTE) if (end > unaccepted->size * unit_size * BITS_PER_BYTE)
end = unaccepted->size * unit_size * BITS_PER_BYTE; end = unaccepted->size * unit_size * BITS_PER_BYTE;
range_start = start / unit_size; range.start = start / unit_size;
range.end = DIV_ROUND_UP(end, unit_size);
retry:
spin_lock_irqsave(&unaccepted_memory_lock, flags); spin_lock_irqsave(&unaccepted_memory_lock, flags);
/*
* Check if anybody works on accepting the same range of the memory.
*
* The check is done with unit_size granularity. It is crucial to catch
* all accept requests to the same unit_size block, even if they don't
* overlap on physical address level.
*/
list_for_each_entry(entry, &accepting_list, list) {
if (entry->end < range.start)
continue;
if (entry->start >= range.end)
continue;
/*
* Somebody else accepting the range. Or at least part of it.
*
* Drop the lock and retry until it is complete.
*/
spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
goto retry;
}
/*
* Register that the range is about to be accepted.
* Make sure nobody else will accept it.
*/
list_add(&range.list, &accepting_list);
range_start = range.start;
for_each_set_bitrange_from(range_start, range_end, unaccepted->bitmap, for_each_set_bitrange_from(range_start, range_end, unaccepted->bitmap,
DIV_ROUND_UP(end, unit_size)) { range.end) {
unsigned long phys_start, phys_end; unsigned long phys_start, phys_end;
unsigned long len = range_end - range_start; unsigned long len = range_end - range_start;
phys_start = range_start * unit_size + unaccepted->phys_base; phys_start = range_start * unit_size + unaccepted->phys_base;
phys_end = range_end * unit_size + unaccepted->phys_base; phys_end = range_end * unit_size + unaccepted->phys_base;
/*
* Keep interrupts disabled until the accept operation is
* complete in order to prevent deadlocks.
*
* Enabling interrupts before calling arch_accept_memory()
* creates an opportunity for an interrupt handler to request
* acceptance for the same memory. The handler will continuously
* spin with interrupts disabled, preventing other task from
* making progress with the acceptance process.
*/
spin_unlock(&unaccepted_memory_lock);
arch_accept_memory(phys_start, phys_end); arch_accept_memory(phys_start, phys_end);
spin_lock(&unaccepted_memory_lock);
bitmap_clear(unaccepted->bitmap, range_start, len); bitmap_clear(unaccepted->bitmap, range_start, len);
} }
list_del(&range.list);
spin_unlock_irqrestore(&unaccepted_memory_lock, flags); spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
} }

View File

@ -126,14 +126,14 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
unsigned long mask = BIT(gpio); unsigned long mask = BIT(gpio);
u32 val; u32 val;
vf610_gpio_set(chip, gpio, value);
if (port->sdata && port->sdata->have_paddr) { if (port->sdata && port->sdata->have_paddr) {
val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR); val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
val |= mask; val |= mask;
vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR); vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR);
} }
vf610_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio); return pinctrl_gpio_direction_output(chip->base + gpio);
} }
@ -246,7 +246,8 @@ static const struct irq_chip vf610_irqchip = {
.irq_unmask = vf610_gpio_irq_unmask, .irq_unmask = vf610_gpio_irq_unmask,
.irq_set_type = vf610_gpio_irq_set_type, .irq_set_type = vf610_gpio_irq_set_type,
.irq_set_wake = vf610_gpio_irq_set_wake, .irq_set_wake = vf610_gpio_irq_set_wake,
.flags = IRQCHIP_IMMUTABLE, .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND
| IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND,
GPIOCHIP_IRQ_RESOURCE_HELPERS, GPIOCHIP_IRQ_RESOURCE_HELPERS,
}; };

View File

@ -951,6 +951,7 @@ static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode,
if (!propname) if (!propname)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
memset(&lookup, 0, sizeof(lookup));
lookup.index = index; lookup.index = index;
ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);

View File

@ -47,7 +47,6 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio) bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
{ {
switch (ctx_prio) { switch (ctx_prio) {
case AMDGPU_CTX_PRIORITY_UNSET:
case AMDGPU_CTX_PRIORITY_VERY_LOW: case AMDGPU_CTX_PRIORITY_VERY_LOW:
case AMDGPU_CTX_PRIORITY_LOW: case AMDGPU_CTX_PRIORITY_LOW:
case AMDGPU_CTX_PRIORITY_NORMAL: case AMDGPU_CTX_PRIORITY_NORMAL:
@ -55,6 +54,7 @@ bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
case AMDGPU_CTX_PRIORITY_VERY_HIGH: case AMDGPU_CTX_PRIORITY_VERY_HIGH:
return true; return true;
default: default:
case AMDGPU_CTX_PRIORITY_UNSET:
return false; return false;
} }
} }
@ -64,7 +64,8 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)
{ {
switch (ctx_prio) { switch (ctx_prio) {
case AMDGPU_CTX_PRIORITY_UNSET: case AMDGPU_CTX_PRIORITY_UNSET:
return DRM_SCHED_PRIORITY_UNSET; pr_warn_once("AMD-->DRM context priority value UNSET-->NORMAL");
return DRM_SCHED_PRIORITY_NORMAL;
case AMDGPU_CTX_PRIORITY_VERY_LOW: case AMDGPU_CTX_PRIORITY_VERY_LOW:
return DRM_SCHED_PRIORITY_MIN; return DRM_SCHED_PRIORITY_MIN;

View File

@ -403,7 +403,10 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
continue; continue;
} }
r = amdgpu_vm_clear_freed(adev, vm, NULL); /* Reserve fences for two SDMA page table updates */
r = dma_resv_reserve_fences(resv, 2);
if (!r)
r = amdgpu_vm_clear_freed(adev, vm, NULL);
if (!r) if (!r)
r = amdgpu_vm_handle_moved(adev, vm); r = amdgpu_vm_handle_moved(adev, vm);

View File

@ -1090,7 +1090,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
struct drm_gem_object *gobj = dma_buf->priv; struct drm_gem_object *gobj = dma_buf->priv;
struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
if (abo->tbo.resource->mem_type == TTM_PL_VRAM) if (abo->tbo.resource &&
abo->tbo.resource->mem_type == TTM_PL_VRAM)
bo = gem_to_amdgpu_bo(gobj); bo = gem_to_amdgpu_bo(gobj);
} }
mem = bo->tbo.resource; mem = bo->tbo.resource;

View File

@ -692,7 +692,7 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge)
return container_of(bridge, struct ti_sn65dsi86, bridge); return container_of(bridge, struct ti_sn65dsi86, bridge);
} }
static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) static int ti_sn_attach_host(struct auxiliary_device *adev, struct ti_sn65dsi86 *pdata)
{ {
int val; int val;
struct mipi_dsi_host *host; struct mipi_dsi_host *host;
@ -707,7 +707,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata)
if (!host) if (!host)
return -EPROBE_DEFER; return -EPROBE_DEFER;
dsi = devm_mipi_dsi_device_register_full(dev, host, &info); dsi = devm_mipi_dsi_device_register_full(&adev->dev, host, &info);
if (IS_ERR(dsi)) if (IS_ERR(dsi))
return PTR_ERR(dsi); return PTR_ERR(dsi);
@ -725,7 +725,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata)
pdata->dsi = dsi; pdata->dsi = dsi;
return devm_mipi_dsi_attach(dev, dsi); return devm_mipi_dsi_attach(&adev->dev, dsi);
} }
static int ti_sn_bridge_attach(struct drm_bridge *bridge, static int ti_sn_bridge_attach(struct drm_bridge *bridge,
@ -1298,9 +1298,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
struct device_node *np = pdata->dev->of_node; struct device_node *np = pdata->dev->of_node;
int ret; int ret;
pdata->next_bridge = devm_drm_of_get_bridge(pdata->dev, np, 1, 0); pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0);
if (IS_ERR(pdata->next_bridge)) if (IS_ERR(pdata->next_bridge))
return dev_err_probe(pdata->dev, PTR_ERR(pdata->next_bridge), return dev_err_probe(&adev->dev, PTR_ERR(pdata->next_bridge),
"failed to create panel bridge\n"); "failed to create panel bridge\n");
ti_sn_bridge_parse_lanes(pdata, np); ti_sn_bridge_parse_lanes(pdata, np);
@ -1319,9 +1319,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
drm_bridge_add(&pdata->bridge); drm_bridge_add(&pdata->bridge);
ret = ti_sn_attach_host(pdata); ret = ti_sn_attach_host(adev, pdata);
if (ret) { if (ret) {
dev_err_probe(pdata->dev, ret, "failed to attach dsi host\n"); dev_err_probe(&adev->dev, ret, "failed to attach dsi host\n");
goto err_remove_bridge; goto err_remove_bridge;
} }

View File

@ -123,6 +123,9 @@ static const struct edid_quirk {
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC), EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC),
/* BenQ GW2765 */
EDID_QUIRK('B', 'N', 'Q', 0x78d6, EDID_QUIRK_FORCE_8BPC),
/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */ /* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */
EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC), EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC),

View File

@ -2553,8 +2553,7 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915,
drm_warn(&i915->drm, "PHY %c failed to bring out of SOC reset after %dus.\n", drm_warn(&i915->drm, "PHY %c failed to bring out of SOC reset after %dus.\n",
phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US); phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US);
intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), lane_pipe_reset,
XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1),
lane_pipe_reset); lane_pipe_reset);
if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port), if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port),

View File

@ -235,6 +235,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
case 0: case 0:
case -EAGAIN: case -EAGAIN:
case -ENOSPC: /* transient failure to evict? */ case -ENOSPC: /* transient failure to evict? */
case -ENOBUFS: /* temporarily out of fences? */
case -ERESTARTSYS: case -ERESTARTSYS:
case -EINTR: case -EINTR:
case -EBUSY: case -EBUSY:

View File

@ -239,6 +239,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
npages = obj->size >> PAGE_SHIFT; npages = obj->size >> PAGE_SHIFT;
mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL);
if (!mtk_gem->pages) { if (!mtk_gem->pages) {
sg_free_table(sgt);
kfree(sgt); kfree(sgt);
return -ENOMEM; return -ENOMEM;
} }
@ -248,12 +249,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
pgprot_writecombine(PAGE_KERNEL)); pgprot_writecombine(PAGE_KERNEL));
if (!mtk_gem->kvaddr) { if (!mtk_gem->kvaddr) {
sg_free_table(sgt);
kfree(sgt); kfree(sgt);
kfree(mtk_gem->pages); kfree(mtk_gem->pages);
return -ENOMEM; return -ENOMEM;
} }
out: sg_free_table(sgt);
kfree(sgt); kfree(sgt);
out:
iosys_map_set_vaddr(map, mtk_gem->kvaddr); iosys_map_set_vaddr(map, mtk_gem->kvaddr);
return 0; return 0;

View File

@ -62,6 +62,18 @@ nvkm_uconn_uevent_gpio(struct nvkm_object *object, u64 token, u32 bits)
return object->client->event(token, &args, sizeof(args.v0)); return object->client->event(token, &args, sizeof(args.v0));
} }
static bool
nvkm_connector_is_dp_dms(u8 type)
{
switch (type) {
case DCB_CONNECTOR_DMS59_DP0:
case DCB_CONNECTOR_DMS59_DP1:
return true;
default:
return false;
}
}
static int static int
nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent) nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
{ {
@ -101,7 +113,7 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO; if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO;
if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) { if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) {
/* TODO: support DP IRQ on ANX9805 and remove this hack. */ /* TODO: support DP IRQ on ANX9805 and remove this hack. */
if (!outp->info.location) if (!outp->info.location && !nvkm_connector_is_dp_dms(conn->info.type))
return -EINVAL; return -EINVAL;
} }

View File

@ -976,32 +976,6 @@ static const struct panel_desc auo_b116xak01 = {
}, },
}; };
static const struct drm_display_mode auo_b116xw03_mode = {
.clock = 70589,
.hdisplay = 1366,
.hsync_start = 1366 + 40,
.hsync_end = 1366 + 40 + 40,
.htotal = 1366 + 40 + 40 + 32,
.vdisplay = 768,
.vsync_start = 768 + 10,
.vsync_end = 768 + 10 + 12,
.vtotal = 768 + 10 + 12 + 6,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct panel_desc auo_b116xw03 = {
.modes = &auo_b116xw03_mode,
.num_modes = 1,
.bpc = 6,
.size = {
.width = 256,
.height = 144,
},
.delay = {
.enable = 400,
},
};
static const struct drm_display_mode auo_b133han05_mode = { static const struct drm_display_mode auo_b133han05_mode = {
.clock = 142600, .clock = 142600,
.hdisplay = 1920, .hdisplay = 1920,
@ -1725,9 +1699,6 @@ static const struct of_device_id platform_of_match[] = {
}, { }, {
.compatible = "auo,b116xa01", .compatible = "auo,b116xa01",
.data = &auo_b116xak01, .data = &auo_b116xak01,
}, {
.compatible = "auo,b116xw03",
.data = &auo_b116xw03,
}, { }, {
.compatible = "auo,b133han05", .compatible = "auo,b133han05",
.data = &auo_b133han05, .data = &auo_b133han05,

View File

@ -919,6 +919,38 @@ static const struct panel_desc auo_b101xtn01 = {
}, },
}; };
static const struct drm_display_mode auo_b116xw03_mode = {
.clock = 70589,
.hdisplay = 1366,
.hsync_start = 1366 + 40,
.hsync_end = 1366 + 40 + 40,
.htotal = 1366 + 40 + 40 + 32,
.vdisplay = 768,
.vsync_start = 768 + 10,
.vsync_end = 768 + 10 + 12,
.vtotal = 768 + 10 + 12 + 6,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct panel_desc auo_b116xw03 = {
.modes = &auo_b116xw03_mode,
.num_modes = 1,
.bpc = 6,
.size = {
.width = 256,
.height = 144,
},
.delay = {
.prepare = 1,
.enable = 200,
.disable = 200,
.unprepare = 500,
},
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
.bus_flags = DRM_BUS_FLAG_DE_HIGH,
.connector_type = DRM_MODE_CONNECTOR_LVDS,
};
static const struct display_timing auo_g070vvn01_timings = { static const struct display_timing auo_g070vvn01_timings = {
.pixelclock = { 33300000, 34209000, 45000000 }, .pixelclock = { 33300000, 34209000, 45000000 },
.hactive = { 800, 800, 800 }, .hactive = { 800, 800, 800 },
@ -4102,6 +4134,9 @@ static const struct of_device_id platform_of_match[] = {
}, { }, {
.compatible = "auo,b101xtn01", .compatible = "auo,b101xtn01",
.data = &auo_b101xtn01, .data = &auo_b101xtn01,
}, {
.compatible = "auo,b116xw03",
.data = &auo_b116xw03,
}, { }, {
.compatible = "auo,g070vvn01", .compatible = "auo,g070vvn01",
.data = &auo_g070vvn01, .data = &auo_g070vvn01,

View File

@ -232,10 +232,6 @@ void ttm_device_fini(struct ttm_device *bdev)
struct ttm_resource_manager *man; struct ttm_resource_manager *man;
unsigned i; unsigned i;
man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
ttm_resource_manager_set_used(man, false);
ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
mutex_lock(&ttm_global_mutex); mutex_lock(&ttm_global_mutex);
list_del(&bdev->device_list); list_del(&bdev->device_list);
mutex_unlock(&ttm_global_mutex); mutex_unlock(&ttm_global_mutex);
@ -243,6 +239,10 @@ void ttm_device_fini(struct ttm_device *bdev)
drain_workqueue(bdev->wq); drain_workqueue(bdev->wq);
destroy_workqueue(bdev->wq); destroy_workqueue(bdev->wq);
man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
ttm_resource_manager_set_used(man, false);
ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
spin_lock(&bdev->lru_lock); spin_lock(&bdev->lru_lock);
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
if (list_empty(&man->lru[0])) if (list_empty(&man->lru[0]))

View File

@ -678,7 +678,7 @@ ph_state(struct dchannel *dch)
} }
/* /*
* disable/enable BChannel for desired protocoll * disable/enable BChannel for desired protocol
*/ */
static int static int
hfcsusb_setup_bch(struct bchannel *bch, int protocol) hfcsusb_setup_bch(struct bchannel *bch, int protocol)

View File

@ -179,6 +179,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_queue *mq); struct mmc_queue *mq);
static void mmc_blk_hsq_req_done(struct mmc_request *mrq); static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
static int mmc_spi_err_check(struct mmc_card *card); static int mmc_spi_err_check(struct mmc_card *card);
static int mmc_blk_busy_cb(void *cb_data, bool *busy);
static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
{ {
@ -470,7 +471,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
struct mmc_data data = {}; struct mmc_data data = {};
struct mmc_request mrq = {}; struct mmc_request mrq = {};
struct scatterlist sg; struct scatterlist sg;
bool r1b_resp, use_r1b_resp = false; bool r1b_resp;
unsigned int busy_timeout_ms; unsigned int busy_timeout_ms;
int err; int err;
unsigned int target_part; unsigned int target_part;
@ -551,8 +552,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS; busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS;
r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B; r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B;
if (r1b_resp) if (r1b_resp)
use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd, mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout_ms);
busy_timeout_ms);
mmc_wait_for_req(card->host, &mrq); mmc_wait_for_req(card->host, &mrq);
memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
@ -605,19 +605,28 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
if (idata->ic.postsleep_min_us) if (idata->ic.postsleep_min_us)
usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);
/* No need to poll when using HW busy detection. */
if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
return 0;
if (mmc_host_is_spi(card->host)) { if (mmc_host_is_spi(card->host)) {
if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY) if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY)
return mmc_spi_err_check(card); return mmc_spi_err_check(card);
return err; return err;
} }
/* Ensure RPMB/R1B command has completed by polling with CMD13. */
if (idata->rpmb || r1b_resp) /*
err = mmc_poll_for_busy(card, busy_timeout_ms, false, * Ensure RPMB, writes and R1B responses are completed by polling with
MMC_BUSY_IO); * CMD13. Note that, usually we don't need to poll when using HW busy
* detection, but here it's needed since some commands may indicate the
* error through the R1 status bits.
*/
if (idata->rpmb || idata->ic.write_flag || r1b_resp) {
struct mmc_blk_busy_data cb_data = {
.card = card,
};
err = __mmc_poll_for_busy(card->host, 0, busy_timeout_ms,
&mmc_blk_busy_cb, &cb_data);
idata->ic.response[0] = cb_data.status;
}
return err; return err;
} }

View File

@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card)
case 3: /* MMC v3.1 - v3.3 */ case 3: /* MMC v3.1 - v3.3 */
case 4: /* MMC v4 */ case 4: /* MMC v4 */
card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); card->cid.oemid = UNSTUFF_BITS(resp, 104, 8);
card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);

View File

@ -1089,8 +1089,14 @@ static int mmc_sdio_resume(struct mmc_host *host)
} }
err = mmc_sdio_reinit_card(host); err = mmc_sdio_reinit_card(host);
} else if (mmc_card_wake_sdio_irq(host)) { } else if (mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */ /*
* We may have switched to 1-bit mode during suspend,
* need to hold retuning, because tuning only supprt
* 4-bit mode or 8 bit mode.
*/
mmc_retune_hold_now(host);
err = sdio_enable_4bit_bus(host->card); err = sdio_enable_4bit_bus(host->card);
mmc_retune_release(host);
} }
if (err) if (err)

View File

@ -669,11 +669,11 @@ static void msdc_reset_hw(struct msdc_host *host)
u32 val; u32 val;
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
readl_poll_timeout(host->base + MSDC_FIFOCS, val, readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val,
!(val & MSDC_FIFOCS_CLR), 0, 0); !(val & MSDC_FIFOCS_CLR), 0, 0);
val = readl(host->base + MSDC_INT); val = readl(host->base + MSDC_INT);
writel(val, host->base + MSDC_INT); writel(val, host->base + MSDC_INT);

View File

@ -1144,42 +1144,6 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg)
return value; return value;
} }
#ifdef CONFIG_PM_SLEEP
static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
pci_free_irq_vectors(slot->chip->pdev);
gli_pcie_enable_msi(slot);
return sdhci_pci_resume_host(chip);
}
static int sdhci_cqhci_gli_resume(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
int ret;
ret = sdhci_pci_gli_resume(chip);
if (ret)
return ret;
return cqhci_resume(slot->host->mmc);
}
static int sdhci_cqhci_gli_suspend(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
int ret;
ret = cqhci_suspend(slot->host->mmc);
if (ret)
return ret;
return sdhci_suspend_host(slot->host);
}
#endif
static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc,
struct mmc_ios *ios) struct mmc_ios *ios)
{ {
@ -1420,6 +1384,70 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip)
} }
#endif #endif
#ifdef CONFIG_PM_SLEEP
static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
pci_free_irq_vectors(slot->chip->pdev);
gli_pcie_enable_msi(slot);
return sdhci_pci_resume_host(chip);
}
static int gl9763e_resume(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
int ret;
ret = sdhci_pci_gli_resume(chip);
if (ret)
return ret;
ret = cqhci_resume(slot->host->mmc);
if (ret)
return ret;
/*
* Disable LPM negotiation to bring device back in sync
* with its runtime_pm state.
*/
gl9763e_set_low_power_negotiation(slot, false);
return 0;
}
static int gl9763e_suspend(struct sdhci_pci_chip *chip)
{
struct sdhci_pci_slot *slot = chip->slots[0];
int ret;
/*
* Certain SoCs can suspend only with the bus in low-
* power state, notably x86 SoCs when using S0ix.
* Re-enable LPM negotiation to allow entering L1 state
* and entering system suspend.
*/
gl9763e_set_low_power_negotiation(slot, true);
ret = cqhci_suspend(slot->host->mmc);
if (ret)
goto err_suspend;
ret = sdhci_suspend_host(slot->host);
if (ret)
goto err_suspend_host;
return 0;
err_suspend_host:
cqhci_resume(slot->host->mmc);
err_suspend:
gl9763e_set_low_power_negotiation(slot, false);
return ret;
}
#endif
static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
{ {
struct pci_dev *pdev = slot->chip->pdev; struct pci_dev *pdev = slot->chip->pdev;
@ -1527,8 +1555,8 @@ const struct sdhci_pci_fixes sdhci_gl9763e = {
.probe_slot = gli_probe_slot_gl9763e, .probe_slot = gli_probe_slot_gl9763e,
.ops = &sdhci_gl9763e_ops, .ops = &sdhci_gl9763e_ops,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.resume = sdhci_cqhci_gli_resume, .resume = gl9763e_resume,
.suspend = sdhci_cqhci_gli_suspend, .suspend = gl9763e_suspend,
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
.runtime_suspend = gl9763e_runtime_suspend, .runtime_suspend = gl9763e_runtime_suspend,

View File

@ -644,6 +644,7 @@ static int sdhci_sprd_tuning(struct mmc_host *mmc, struct mmc_card *card,
best_clk_sample = sdhci_sprd_get_best_clk_sample(mmc, value); best_clk_sample = sdhci_sprd_get_best_clk_sample(mmc, value);
if (best_clk_sample < 0) { if (best_clk_sample < 0) {
dev_err(mmc_dev(host->mmc), "all tuning phase fail!\n"); dev_err(mmc_dev(host->mmc), "all tuning phase fail!\n");
err = best_clk_sample;
goto out; goto out;
} }

View File

@ -551,6 +551,17 @@ static int physmap_flash_probe(struct platform_device *dev)
if (info->probe_type) { if (info->probe_type) {
info->mtds[i] = do_map_probe(info->probe_type, info->mtds[i] = do_map_probe(info->probe_type,
&info->maps[i]); &info->maps[i]);
/* Fall back to mapping region as ROM */
if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) &&
strcmp(info->probe_type, "map_rom")) {
dev_warn(&dev->dev,
"map_probe() failed for type %s\n",
info->probe_type);
info->mtds[i] = do_map_probe("map_rom",
&info->maps[i]);
}
} else { } else {
int j; int j;

View File

@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
struct mtd_info *mtd = nand_to_mtd(chip); struct mtd_info *mtd = nand_to_mtd(chip);
unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
dma_addr_t dma_addr; dma_addr_t dma_addr;
u8 status;
int ret; int ret;
struct anfc_op nfc_op = { struct anfc_op nfc_op = {
.pkt_reg = .pkt_reg =
@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
} }
/* Spare data is not protected */ /* Spare data is not protected */
if (oob_required) if (oob_required) {
ret = nand_write_oob_std(chip, page); ret = nand_write_oob_std(chip, page);
if (ret)
return ret;
}
return ret; /* Check write status on the chip side */
ret = nand_status_op(chip, &status);
if (ret)
return ret;
if (status & NAND_STATUS_FAIL)
return -EIO;
return 0;
} }
static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,

View File

@ -1165,6 +1165,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
.ndcb[2] = NDCB2_ADDR5_PAGE(page), .ndcb[2] = NDCB2_ADDR5_PAGE(page),
}; };
unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0); unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
u8 status;
int ret; int ret;
/* NFCv2 needs more information about the operation being executed */ /* NFCv2 needs more information about the operation being executed */
@ -1198,7 +1199,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
ret = marvell_nfc_wait_op(chip, ret = marvell_nfc_wait_op(chip,
PSEC_TO_MSEC(sdr->tPROG_max)); PSEC_TO_MSEC(sdr->tPROG_max));
return ret; if (ret)
return ret;
/* Check write status on the chip side */
ret = nand_status_op(chip, &status);
if (ret)
return ret;
if (status & NAND_STATUS_FAIL)
return -EIO;
return 0;
} }
static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip, static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
@ -1627,6 +1639,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
int data_len = lt->data_bytes; int data_len = lt->data_bytes;
int spare_len = lt->spare_bytes; int spare_len = lt->spare_bytes;
int chunk, ret; int chunk, ret;
u8 status;
marvell_nfc_select_target(chip, chip->cur_cs); marvell_nfc_select_target(chip, chip->cur_cs);
@ -1663,6 +1676,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
if (ret) if (ret)
return ret; return ret;
/* Check write status on the chip side */
ret = nand_status_op(chip, &status);
if (ret)
return ret;
if (status & NAND_STATUS_FAIL)
return -EIO;
return 0; return 0;
} }

View File

@ -5110,6 +5110,9 @@ static void rawnand_check_cont_read_support(struct nand_chip *chip)
{ {
struct mtd_info *mtd = nand_to_mtd(chip); struct mtd_info *mtd = nand_to_mtd(chip);
if (!chip->parameters.supports_read_cache)
return;
if (chip->read_retries) if (chip->read_retries)
return; return;

View File

@ -94,6 +94,9 @@ int nand_jedec_detect(struct nand_chip *chip)
goto free_jedec_param_page; goto free_jedec_param_page;
} }
if (p->opt_cmd[0] & JEDEC_OPT_CMD_READ_CACHE)
chip->parameters.supports_read_cache = true;
memorg->pagesize = le32_to_cpu(p->byte_per_page); memorg->pagesize = le32_to_cpu(p->byte_per_page);
mtd->writesize = memorg->pagesize; mtd->writesize = memorg->pagesize;

View File

@ -303,6 +303,9 @@ int nand_onfi_detect(struct nand_chip *chip)
ONFI_FEATURE_ADDR_TIMING_MODE, 1); ONFI_FEATURE_ADDR_TIMING_MODE, 1);
} }
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_READ_CACHE)
chip->parameters.supports_read_cache = true;
onfi = kzalloc(sizeof(*onfi), GFP_KERNEL); onfi = kzalloc(sizeof(*onfi), GFP_KERNEL);
if (!onfi) { if (!onfi) {
ret = -ENOMEM; ret = -ENOMEM;

View File

@ -511,6 +511,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
u32 addr1 = 0, addr2 = 0, row; u32 addr1 = 0, addr2 = 0, row;
u32 cmd_addr; u32 cmd_addr;
int i, ret; int i, ret;
u8 status;
ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB); ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB);
if (ret) if (ret)
@ -563,6 +564,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
if (ret) if (ret)
goto disable_ecc_engine; goto disable_ecc_engine;
/* Check write status on the chip side */
ret = nand_status_op(chip, &status);
if (ret)
goto disable_ecc_engine;
if (status & NAND_STATUS_FAIL)
ret = -EIO;
disable_ecc_engine: disable_ecc_engine:
pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS); pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS);

View File

@ -3444,7 +3444,7 @@ err_nandc_alloc:
err_aon_clk: err_aon_clk:
clk_disable_unprepare(nandc->core_clk); clk_disable_unprepare(nandc->core_clk);
err_core_clk: err_core_clk:
dma_unmap_resource(dev, res->start, resource_size(res), dma_unmap_resource(dev, nandc->base_dma, resource_size(res),
DMA_BIDIRECTIONAL, 0); DMA_BIDIRECTIONAL, 0);
return ret; return ret;
} }

View File

@ -12,7 +12,7 @@
#define SPINAND_MFR_MICRON 0x2c #define SPINAND_MFR_MICRON 0x2c
#define MICRON_STATUS_ECC_MASK GENMASK(7, 4) #define MICRON_STATUS_ECC_MASK GENMASK(6, 4)
#define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4) #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4)
#define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4) #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
#define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)

View File

@ -294,7 +294,7 @@ static int adin1110_read_fifo(struct adin1110_port_priv *port_priv)
{ {
struct adin1110_priv *priv = port_priv->priv; struct adin1110_priv *priv = port_priv->priv;
u32 header_len = ADIN1110_RD_HEADER_LEN; u32 header_len = ADIN1110_RD_HEADER_LEN;
struct spi_transfer t; struct spi_transfer t = {0};
u32 frame_size_no_fcs; u32 frame_size_no_fcs;
struct sk_buff *rxb; struct sk_buff *rxb;
u32 frame_size; u32 frame_size;

View File

@ -2155,7 +2155,7 @@ static void xgene_enet_shutdown(struct platform_device *pdev)
static struct platform_driver xgene_enet_driver = { static struct platform_driver xgene_enet_driver = {
.driver = { .driver = {
.name = "xgene-enet", .name = "xgene-enet",
.of_match_table = of_match_ptr(xgene_enet_of_match), .of_match_table = xgene_enet_of_match,
.acpi_match_table = ACPI_PTR(xgene_enet_acpi_match), .acpi_match_table = ACPI_PTR(xgene_enet_acpi_match),
}, },
.probe = xgene_enet_probe, .probe = xgene_enet_probe,

View File

@ -3816,6 +3816,8 @@ int t4_load_phy_fw(struct adapter *adap, int win,
FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD)); FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD));
ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1, ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1,
&param, &val, 30000); &param, &val, 30000);
if (ret)
return ret;
/* If we have version number support, then check to see that the new /* If we have version number support, then check to see that the new
* firmware got loaded properly. * firmware got loaded properly.

View File

@ -528,7 +528,6 @@ struct i40e_pf {
#define I40E_FLAG_DISABLE_FW_LLDP BIT(24) #define I40E_FLAG_DISABLE_FW_LLDP BIT(24)
#define I40E_FLAG_RS_FEC BIT(25) #define I40E_FLAG_RS_FEC BIT(25)
#define I40E_FLAG_BASE_R_FEC BIT(26) #define I40E_FLAG_BASE_R_FEC BIT(26)
#define I40E_FLAG_VF_VLAN_PRUNING BIT(27)
/* TOTAL_PORT_SHUTDOWN /* TOTAL_PORT_SHUTDOWN
* Allows to physically disable the link on the NIC's port. * Allows to physically disable the link on the NIC's port.
* If enabled, (after link down request from the OS) * If enabled, (after link down request from the OS)
@ -551,6 +550,7 @@ struct i40e_pf {
* in abilities field of i40e_aq_set_phy_config structure * in abilities field of i40e_aq_set_phy_config structure
*/ */
#define I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED BIT(27) #define I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED BIT(27)
#define I40E_FLAG_VF_VLAN_PRUNING BIT(28)
struct i40e_client_instance *cinst; struct i40e_client_instance *cinst;
bool stat_offsets_loaded; bool stat_offsets_loaded;

View File

@ -2543,7 +2543,14 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
rx_buffer = i40e_rx_bi(rx_ring, ntp); rx_buffer = i40e_rx_bi(rx_ring, ntp);
i40e_inc_ntp(rx_ring); i40e_inc_ntp(rx_ring);
i40e_reuse_rx_page(rx_ring, rx_buffer); i40e_reuse_rx_page(rx_ring, rx_buffer);
cleaned_count++; /* Update ntc and bump cleaned count if not in the
* middle of mb packet.
*/
if (rx_ring->next_to_clean == ntp) {
rx_ring->next_to_clean =
rx_ring->next_to_process;
cleaned_count++;
}
continue; continue;
} }
@ -2846,7 +2853,7 @@ tx_only:
return budget; return budget;
} }
if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR) if (q_vector->tx.ring[0].flags & I40E_TXR_FLAGS_WB_ON_ITR)
q_vector->arm_wb_state = false; q_vector->arm_wb_state = false;
/* Exit the polling mode, but don't re-enable interrupts if stack might /* Exit the polling mode, but don't re-enable interrupts if stack might

View File

@ -433,12 +433,12 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
unsigned int total_rx_bytes = 0, total_rx_packets = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0;
u16 next_to_process = rx_ring->next_to_process; u16 next_to_process = rx_ring->next_to_process;
u16 next_to_clean = rx_ring->next_to_clean; u16 next_to_clean = rx_ring->next_to_clean;
u16 count_mask = rx_ring->count - 1;
unsigned int xdp_res, xdp_xmit = 0; unsigned int xdp_res, xdp_xmit = 0;
struct xdp_buff *first = NULL; struct xdp_buff *first = NULL;
u32 count = rx_ring->count;
struct bpf_prog *xdp_prog; struct bpf_prog *xdp_prog;
u32 entries_to_alloc;
bool failure = false; bool failure = false;
u16 cleaned_count;
if (next_to_process != next_to_clean) if (next_to_process != next_to_clean)
first = *i40e_rx_bi(rx_ring, next_to_clean); first = *i40e_rx_bi(rx_ring, next_to_clean);
@ -471,7 +471,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
qword); qword);
bi = *i40e_rx_bi(rx_ring, next_to_process); bi = *i40e_rx_bi(rx_ring, next_to_process);
xsk_buff_free(bi); xsk_buff_free(bi);
next_to_process = (next_to_process + 1) & count_mask; if (++next_to_process == count)
next_to_process = 0;
continue; continue;
} }
@ -489,7 +490,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
else if (i40e_add_xsk_frag(rx_ring, first, bi, size)) else if (i40e_add_xsk_frag(rx_ring, first, bi, size))
break; break;
next_to_process = (next_to_process + 1) & count_mask; if (++next_to_process == count)
next_to_process = 0;
if (i40e_is_non_eop(rx_ring, rx_desc)) if (i40e_is_non_eop(rx_ring, rx_desc))
continue; continue;
@ -509,10 +511,10 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
rx_ring->next_to_clean = next_to_clean; rx_ring->next_to_clean = next_to_clean;
rx_ring->next_to_process = next_to_process; rx_ring->next_to_process = next_to_process;
cleaned_count = (next_to_clean - rx_ring->next_to_use - 1) & count_mask;
if (cleaned_count >= I40E_RX_BUFFER_WRITE) entries_to_alloc = I40E_DESC_UNUSED(rx_ring);
failure |= !i40e_alloc_rx_buffers_zc(rx_ring, cleaned_count); if (entries_to_alloc >= I40E_RX_BUFFER_WRITE)
failure |= !i40e_alloc_rx_buffers_zc(rx_ring, entries_to_alloc);
i40e_finalize_xdp_rx(rx_ring, xdp_xmit); i40e_finalize_xdp_rx(rx_ring, xdp_xmit);
i40e_update_rx_stats(rx_ring, total_rx_bytes, total_rx_packets); i40e_update_rx_stats(rx_ring, total_rx_bytes, total_rx_packets);
@ -748,14 +750,16 @@ int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring) void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring)
{ {
u16 count_mask = rx_ring->count - 1;
u16 ntc = rx_ring->next_to_clean; u16 ntc = rx_ring->next_to_clean;
u16 ntu = rx_ring->next_to_use; u16 ntu = rx_ring->next_to_use;
for ( ; ntc != ntu; ntc = (ntc + 1) & count_mask) { while (ntc != ntu) {
struct xdp_buff *rx_bi = *i40e_rx_bi(rx_ring, ntc); struct xdp_buff *rx_bi = *i40e_rx_bi(rx_ring, ntc);
xsk_buff_free(rx_bi); xsk_buff_free(rx_bi);
ntc++;
if (ntc >= rx_ring->count)
ntc = 0;
} }
} }

View File

@ -1438,9 +1438,9 @@ void iavf_down(struct iavf_adapter *adapter)
adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
if (!list_empty(&adapter->adv_rss_list_head)) if (!list_empty(&adapter->adv_rss_list_head))
adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG; adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
} }
adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
} }
@ -5025,8 +5025,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
INIT_WORK(&adapter->finish_config, iavf_finish_config); INIT_WORK(&adapter->finish_config, iavf_finish_config);
INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task); INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task);
INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task);
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
msecs_to_jiffies(5 * (pdev->devfn & 0x07)));
/* Setup the wait queue for indicating transition to down status */ /* Setup the wait queue for indicating transition to down status */
init_waitqueue_head(&adapter->down_waitqueue); init_waitqueue_head(&adapter->down_waitqueue);
@ -5037,6 +5035,9 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Setup the wait queue for indicating virtchannel events */ /* Setup the wait queue for indicating virtchannel events */
init_waitqueue_head(&adapter->vc_waitqueue); init_waitqueue_head(&adapter->vc_waitqueue);
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
msecs_to_jiffies(5 * (pdev->devfn & 0x07)));
/* Initialization goes on in the work. Do not add more of it below. */
return 0; return 0;
err_ioremap: err_ioremap:

View File

@ -2978,11 +2978,15 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter,
if (err) if (err)
goto err_out_w_lock; goto err_out_w_lock;
igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx); err = igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx);
if (err)
goto err_out_input_filter;
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_lock);
return 0; return 0;
err_out_input_filter:
igb_erase_filter(adapter, input);
err_out_w_lock: err_out_w_lock:
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_lock);
err_out: err_out:

View File

@ -1818,7 +1818,7 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev,
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
u32 advertising; u16 advertised = 0;
/* When adapter in resetting mode, autoneg/speed/duplex /* When adapter in resetting mode, autoneg/speed/duplex
* cannot be changed * cannot be changed
@ -1843,18 +1843,33 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev,
while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) while (test_and_set_bit(__IGC_RESETTING, &adapter->state))
usleep_range(1000, 2000); usleep_range(1000, 2000);
ethtool_convert_link_mode_to_legacy_u32(&advertising, if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
cmd->link_modes.advertising); 2500baseT_Full))
/* Converting to legacy u32 drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT. advertised |= ADVERTISE_2500_FULL;
* We have to check this and convert it to ADVERTISE_2500_FULL
* (aka ETHTOOL_LINK_MODE_2500baseX_Full_BIT) explicitly. if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
*/ 1000baseT_Full))
if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 2500baseT_Full)) advertised |= ADVERTISE_1000_FULL;
advertising |= ADVERTISE_2500_FULL;
if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
100baseT_Full))
advertised |= ADVERTISE_100_FULL;
if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
100baseT_Half))
advertised |= ADVERTISE_100_HALF;
if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
10baseT_Full))
advertised |= ADVERTISE_10_FULL;
if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
10baseT_Half))
advertised |= ADVERTISE_10_HALF;
if (cmd->base.autoneg == AUTONEG_ENABLE) { if (cmd->base.autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1; hw->mac.autoneg = 1;
hw->phy.autoneg_advertised = advertising; hw->phy.autoneg_advertised = advertised;
if (adapter->fc_autoneg) if (adapter->fc_autoneg)
hw->fc.requested_mode = igc_fc_default; hw->fc.requested_mode = igc_fc_default;
} else { } else {

View File

@ -4364,7 +4364,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
unsigned int entry = dirty_tx % NUM_TX_DESC; unsigned int entry = dirty_tx % NUM_TX_DESC;
u32 status; u32 status;
status = le32_to_cpu(tp->TxDescArray[entry].opts1); status = le32_to_cpu(READ_ONCE(tp->TxDescArray[entry].opts1));
if (status & DescOwn) if (status & DescOwn)
break; break;
@ -4394,7 +4394,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
* If skb is NULL then we come here again once a tx irq is * If skb is NULL then we come here again once a tx irq is
* triggered after the last fragment is marked transmitted. * triggered after the last fragment is marked transmitted.
*/ */
if (tp->cur_tx != dirty_tx && skb) if (READ_ONCE(tp->cur_tx) != dirty_tx && skb)
rtl8169_doorbell(tp); rtl8169_doorbell(tp);
} }
} }
@ -4427,7 +4427,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
dma_addr_t addr; dma_addr_t addr;
u32 status; u32 status;
status = le32_to_cpu(desc->opts1); status = le32_to_cpu(READ_ONCE(desc->opts1));
if (status & DescOwn) if (status & DescOwn)
break; break;

View File

@ -629,14 +629,14 @@ static int efx_tc_flower_record_encap_match(struct efx_nic *efx,
} }
if (child_ip_tos_mask != old->child_ip_tos_mask) { if (child_ip_tos_mask != old->child_ip_tos_mask) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Pseudo encap match for TOS mask %#04x conflicts with existing pseudo(MASK) entry for TOS mask %#04x", "Pseudo encap match for TOS mask %#04x conflicts with existing mask %#04x",
child_ip_tos_mask, child_ip_tos_mask,
old->child_ip_tos_mask); old->child_ip_tos_mask);
return -EEXIST; return -EEXIST;
} }
if (child_udp_sport_mask != old->child_udp_sport_mask) { if (child_udp_sport_mask != old->child_udp_sport_mask) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Pseudo encap match for UDP src port mask %#x conflicts with existing pseudo(MASK) entry for mask %#x", "Pseudo encap match for UDP src port mask %#x conflicts with existing mask %#x",
child_udp_sport_mask, child_udp_sport_mask,
old->child_udp_sport_mask); old->child_udp_sport_mask);
return -EEXIST; return -EEXIST;
@ -1180,7 +1180,7 @@ static int efx_tc_pedit_add(struct efx_nic *efx, struct efx_tc_action_set *act,
/* check that we do not decrement ttl twice */ /* check that we do not decrement ttl twice */
if (!efx_tc_flower_action_order_ok(act, if (!efx_tc_flower_action_order_ok(act,
EFX_TC_AO_DEC_TTL)) { EFX_TC_AO_DEC_TTL)) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported: multiple dec ttl"); NL_SET_ERR_MSG_MOD(extack, "multiple dec ttl are not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
act->do_ttl_dec = 1; act->do_ttl_dec = 1;
@ -1205,7 +1205,7 @@ static int efx_tc_pedit_add(struct efx_nic *efx, struct efx_tc_action_set *act,
/* check that we do not decrement hoplimit twice */ /* check that we do not decrement hoplimit twice */
if (!efx_tc_flower_action_order_ok(act, if (!efx_tc_flower_action_order_ok(act,
EFX_TC_AO_DEC_TTL)) { EFX_TC_AO_DEC_TTL)) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported: multiple dec ttl"); NL_SET_ERR_MSG_MOD(extack, "multiple dec ttl are not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
act->do_ttl_dec = 1; act->do_ttl_dec = 1;
@ -1219,7 +1219,7 @@ static int efx_tc_pedit_add(struct efx_nic *efx, struct efx_tc_action_set *act,
} }
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: ttl add action type %x %x %x/%x", "ttl add action type %x %x %x/%x is not supported",
fa->mangle.htype, fa->mangle.offset, fa->mangle.htype, fa->mangle.offset,
fa->mangle.val, fa->mangle.mask); fa->mangle.val, fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -1263,7 +1263,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
case 0: case 0:
if (fa->mangle.mask) { if (fa->mangle.mask) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: mask (%#x) of eth.dst32 mangle", "mask (%#x) of eth.dst32 mangle is not supported",
fa->mangle.mask); fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1283,7 +1283,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
mung->dst_mac_16 = 1; mung->dst_mac_16 = 1;
} else { } else {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: mask (%#x) of eth+4 mangle is not high or low 16b", "mask (%#x) of eth+4 mangle is not high or low 16b",
fa->mangle.mask); fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1291,7 +1291,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
case 8: case 8:
if (fa->mangle.mask) { if (fa->mangle.mask) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: mask (%#x) of eth.src32 mangle", "mask (%#x) of eth.src32 mangle is not supported",
fa->mangle.mask); fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1300,7 +1300,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
mung->src_mac_32 = 1; mung->src_mac_32 = 1;
return efx_tc_complete_mac_mangle(efx, act, mung, extack); return efx_tc_complete_mac_mangle(efx, act, mung, extack);
default: default:
NL_SET_ERR_MSG_FMT_MOD(extack, "Unsupported: mangle eth+%u %x/%x", NL_SET_ERR_MSG_FMT_MOD(extack, "mangle eth+%u %x/%x is not supported",
fa->mangle.offset, fa->mangle.val, fa->mangle.mask); fa->mangle.offset, fa->mangle.val, fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1316,7 +1316,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
/* check that pedit applies to ttl only */ /* check that pedit applies to ttl only */
if (fa->mangle.mask != ~EFX_TC_HDR_TYPE_TTL_MASK) { if (fa->mangle.mask != ~EFX_TC_HDR_TYPE_TTL_MASK) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: mask (%#x) out of range, only support mangle action on ipv4.ttl", "mask (%#x) out of range, only support mangle action on ipv4.ttl",
fa->mangle.mask); fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1326,7 +1326,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
*/ */
if (match->mask.ip_ttl != U8_MAX) { if (match->mask.ip_ttl != U8_MAX) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: only support mangle ipv4.ttl when we have an exact match on ttl, mask used for match (%#x)", "only support mangle ttl when we have an exact match, current mask (%#x)",
match->mask.ip_ttl); match->mask.ip_ttl);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1336,7 +1336,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
*/ */
if (match->value.ip_ttl == 0) { if (match->value.ip_ttl == 0) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Unsupported: we cannot decrement ttl past 0"); "decrement ttl past 0 is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1344,7 +1344,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
if (!efx_tc_flower_action_order_ok(act, if (!efx_tc_flower_action_order_ok(act,
EFX_TC_AO_DEC_TTL)) { EFX_TC_AO_DEC_TTL)) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Unsupported: multiple dec ttl"); "multiple dec ttl is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1358,7 +1358,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
fallthrough; fallthrough;
default: default:
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: only support mangle on the ttl field (offset is %u)", "only support mangle on the ttl field (offset is %u)",
fa->mangle.offset); fa->mangle.offset);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1374,7 +1374,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
/* check that pedit applies to ttl only */ /* check that pedit applies to ttl only */
if (fa->mangle.mask != EFX_TC_HDR_TYPE_HLIMIT_MASK) { if (fa->mangle.mask != EFX_TC_HDR_TYPE_HLIMIT_MASK) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: mask (%#x) out of range, only support mangle action on ipv6.hop_limit", "mask (%#x) out of range, only support mangle action on ipv6.hop_limit",
fa->mangle.mask); fa->mangle.mask);
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -1385,7 +1385,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
*/ */
if (match->mask.ip_ttl != U8_MAX) { if (match->mask.ip_ttl != U8_MAX) {
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: only support mangle ipv6.hop_limit when we have an exact match on ttl, mask used for match (%#x)", "only support hop_limit when we have an exact match, current mask (%#x)",
match->mask.ip_ttl); match->mask.ip_ttl);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1395,7 +1395,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
*/ */
if (match->value.ip_ttl == 0) { if (match->value.ip_ttl == 0) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Unsupported: we cannot decrement hop_limit past 0"); "decrementing hop_limit past 0 is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1403,7 +1403,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
if (!efx_tc_flower_action_order_ok(act, if (!efx_tc_flower_action_order_ok(act,
EFX_TC_AO_DEC_TTL)) { EFX_TC_AO_DEC_TTL)) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Unsupported: multiple dec ttl"); "multiple dec ttl is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -1417,7 +1417,7 @@ static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
fallthrough; fallthrough;
default: default:
NL_SET_ERR_MSG_FMT_MOD(extack, NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported: only support mangle on the hop_limit field"); "only support mangle on the hop_limit field");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
default: default:

View File

@ -1197,6 +1197,17 @@ static int stmmac_init_phy(struct net_device *dev)
return ret; return ret;
} }
static void stmmac_set_half_duplex(struct stmmac_priv *priv)
{
/* Half-Duplex can only work with single tx queue */
if (priv->plat->tx_queues_to_use > 1)
priv->phylink_config.mac_capabilities &=
~(MAC_10HD | MAC_100HD | MAC_1000HD);
else
priv->phylink_config.mac_capabilities |=
(MAC_10HD | MAC_100HD | MAC_1000HD);
}
static int stmmac_phy_setup(struct stmmac_priv *priv) static int stmmac_phy_setup(struct stmmac_priv *priv)
{ {
struct stmmac_mdio_bus_data *mdio_bus_data; struct stmmac_mdio_bus_data *mdio_bus_data;
@ -1228,10 +1239,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
MAC_10FD | MAC_100FD | MAC_10FD | MAC_100FD |
MAC_1000FD; MAC_1000FD;
/* Half-Duplex can only work with single queue */ stmmac_set_half_duplex(priv);
if (priv->plat->tx_queues_to_use <= 1)
priv->phylink_config.mac_capabilities |= MAC_10HD | MAC_100HD |
MAC_1000HD;
/* Get the MAC specific capabilities */ /* Get the MAC specific capabilities */
stmmac_mac_phylink_get_caps(priv); stmmac_mac_phylink_get_caps(priv);
@ -7208,6 +7216,7 @@ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt)
priv->rss.table[i] = ethtool_rxfh_indir_default(i, priv->rss.table[i] = ethtool_rxfh_indir_default(i,
rx_cnt); rx_cnt);
stmmac_set_half_duplex(priv);
stmmac_napi_add(dev); stmmac_napi_add(dev);
if (netif_running(dev)) if (netif_running(dev))

View File

@ -1217,7 +1217,7 @@ static int gelic_wl_set_encodeext(struct net_device *netdev,
key_index = wl->current_key; key_index = wl->current_key;
if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
/* reques to change default key index */ /* request to change default key index */
pr_debug("%s: request to change default key to %d\n", pr_debug("%s: request to change default key to %d\n",
__func__, key_index); __func__, key_index);
wl->current_key = key_index; wl->current_key = key_index;

View File

@ -872,8 +872,9 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
skb_dst_update_pmtu_no_confirm(skb, mtu); skb_dst_update_pmtu_no_confirm(skb, mtu);
if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && if (iph->frag_off & htons(IP_DF) &&
mtu < ntohs(iph->tot_len)) { ((!skb_is_gso(skb) && skb->len > mtu) ||
(skb_is_gso(skb) && !skb_gso_validate_network_len(skb, mtu)))) {
netdev_dbg(dev, "packet too big, fragmentation needed\n"); netdev_dbg(dev, "packet too big, fragmentation needed\n");
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu)); htonl(mtu));

View File

@ -1162,9 +1162,10 @@ static int adf7242_stats_show(struct seq_file *file, void *offset)
static void adf7242_debugfs_init(struct adf7242_local *lp) static void adf7242_debugfs_init(struct adf7242_local *lp)
{ {
char debugfs_dir_name[DNAME_INLINE_LEN + 1] = "adf7242-"; char debugfs_dir_name[DNAME_INLINE_LEN + 1];
strncat(debugfs_dir_name, dev_name(&lp->spi->dev), DNAME_INLINE_LEN); snprintf(debugfs_dir_name, sizeof(debugfs_dir_name),
"adf7242-%s", dev_name(&lp->spi->dev));
lp->debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL); lp->debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL);

View File

@ -764,7 +764,7 @@ enum rtl_register_content {
/* rtl8152 flags */ /* rtl8152 flags */
enum rtl8152_flags { enum rtl8152_flags {
RTL8152_UNPLUG = 0, RTL8152_INACCESSIBLE = 0,
RTL8152_SET_RX_MODE, RTL8152_SET_RX_MODE,
WORK_ENABLE, WORK_ENABLE,
RTL8152_LINK_CHG, RTL8152_LINK_CHG,
@ -773,6 +773,9 @@ enum rtl8152_flags {
SCHEDULE_TASKLET, SCHEDULE_TASKLET,
GREEN_ETHERNET, GREEN_ETHERNET,
RX_EPROTO, RX_EPROTO,
IN_PRE_RESET,
PROBED_WITH_NO_ERRORS,
PROBE_SHOULD_RETRY,
}; };
#define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e #define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e
@ -953,6 +956,8 @@ struct r8152 {
u8 version; u8 version;
u8 duplex; u8 duplex;
u8 autoneg; u8 autoneg;
unsigned int reg_access_reset_count;
}; };
/** /**
@ -1200,6 +1205,96 @@ static unsigned int agg_buf_sz = 16384;
#define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc))
/* If register access fails then we block access and issue a reset. If this
* happens too many times in a row without a successful access then we stop
* trying to reset and just leave access blocked.
*/
#define REGISTER_ACCESS_MAX_RESETS 3
static void rtl_set_inaccessible(struct r8152 *tp)
{
set_bit(RTL8152_INACCESSIBLE, &tp->flags);
smp_mb__after_atomic();
}
static void rtl_set_accessible(struct r8152 *tp)
{
clear_bit(RTL8152_INACCESSIBLE, &tp->flags);
smp_mb__after_atomic();
}
static
int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, const char *msg_tag)
{
struct usb_device *udev = tp->udev;
int ret;
if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV;
ret = usb_control_msg(udev, pipe, request, requesttype,
value, index, data, size,
USB_CTRL_GET_TIMEOUT);
/* No need to issue a reset to report an error if the USB device got
* unplugged; just return immediately.
*/
if (ret == -ENODEV)
return ret;
/* If the write was successful then we're done */
if (ret >= 0) {
tp->reg_access_reset_count = 0;
return ret;
}
dev_err(&udev->dev,
"Failed to %s %d bytes at %#06x/%#06x (%d)\n",
msg_tag, size, value, index, ret);
/* Block all future register access until we reset. Much of the code
* in the driver doesn't check for errors. Notably, many parts of the
* driver do a read/modify/write of a register value without
* confirming that the read succeeded. Writing back modified garbage
* like this can fully wedge the adapter, requiring a power cycle.
*/
rtl_set_inaccessible(tp);
/* If probe hasn't yet finished, then we'll request a retry of the
* whole probe routine if we get any control transfer errors. We
* never have to clear this bit since we free/reallocate the whole "tp"
* structure if we retry probe.
*/
if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) {
set_bit(PROBE_SHOULD_RETRY, &tp->flags);
return ret;
}
/* Failing to access registers in pre-reset is not surprising since we
* wouldn't be resetting if things were behaving normally. The register
* access we do in pre-reset isn't truly mandatory--we're just reusing
* the disable() function and trying to be nice by powering the
* adapter down before resetting it. Thus, if we're in pre-reset,
* we'll return right away and not try to queue up yet another reset.
* We know the post-reset is already coming.
*/
if (test_bit(IN_PRE_RESET, &tp->flags))
return ret;
if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) {
usb_queue_reset_device(tp->intf);
tp->reg_access_reset_count++;
} else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) {
dev_err(&udev->dev,
"Tried to reset %d times; giving up.\n",
REGISTER_ACCESS_MAX_RESETS);
}
return ret;
}
static static
int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
{ {
@ -1210,9 +1305,10 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;
ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in, ret = r8152_control_msg(tp, tp->pipe_ctrl_in,
RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
value, index, tmp, size, 500); value, index, tmp, size, "read");
if (ret < 0) if (ret < 0)
memset(data, 0xff, size); memset(data, 0xff, size);
else else
@ -1233,9 +1329,9 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;
ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out, ret = r8152_control_msg(tp, tp->pipe_ctrl_out,
RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
value, index, tmp, size, 500); value, index, tmp, size, "write");
kfree(tmp); kfree(tmp);
@ -1244,10 +1340,8 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
static void rtl_set_unplug(struct r8152 *tp) static void rtl_set_unplug(struct r8152 *tp)
{ {
if (tp->udev->state == USB_STATE_NOTATTACHED) { if (tp->udev->state == USB_STATE_NOTATTACHED)
set_bit(RTL8152_UNPLUG, &tp->flags); rtl_set_inaccessible(tp);
smp_mb__after_atomic();
}
} }
static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
@ -1256,7 +1350,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
u16 limit = 64; u16 limit = 64;
int ret = 0; int ret = 0;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
/* both size and indix must be 4 bytes align */ /* both size and indix must be 4 bytes align */
@ -1300,7 +1394,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen,
u16 byteen_start, byteen_end, byen; u16 byteen_start, byteen_end, byen;
u16 limit = 512; u16 limit = 512;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
/* both size and indix must be 4 bytes align */ /* both size and indix must be 4 bytes align */
@ -1537,7 +1631,7 @@ static int read_mii_word(struct net_device *netdev, int phy_id, int reg)
struct r8152 *tp = netdev_priv(netdev); struct r8152 *tp = netdev_priv(netdev);
int ret; int ret;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
if (phy_id != R8152_PHY_ID) if (phy_id != R8152_PHY_ID)
@ -1553,7 +1647,7 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val)
{ {
struct r8152 *tp = netdev_priv(netdev); struct r8152 *tp = netdev_priv(netdev);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (phy_id != R8152_PHY_ID) if (phy_id != R8152_PHY_ID)
@ -1758,7 +1852,7 @@ static void read_bulk_callback(struct urb *urb)
if (!tp) if (!tp)
return; return;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (!test_bit(WORK_ENABLE, &tp->flags)) if (!test_bit(WORK_ENABLE, &tp->flags))
@ -1850,7 +1944,7 @@ static void write_bulk_callback(struct urb *urb)
if (!test_bit(WORK_ENABLE, &tp->flags)) if (!test_bit(WORK_ENABLE, &tp->flags))
return; return;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (!skb_queue_empty(&tp->tx_queue)) if (!skb_queue_empty(&tp->tx_queue))
@ -1871,7 +1965,7 @@ static void intr_callback(struct urb *urb)
if (!test_bit(WORK_ENABLE, &tp->flags)) if (!test_bit(WORK_ENABLE, &tp->flags))
return; return;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
switch (status) { switch (status) {
@ -2656,7 +2750,7 @@ static void bottom_half(struct tasklet_struct *t)
{ {
struct r8152 *tp = from_tasklet(tp, t, tx_tl); struct r8152 *tp = from_tasklet(tp, t, tx_tl);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (!test_bit(WORK_ENABLE, &tp->flags)) if (!test_bit(WORK_ENABLE, &tp->flags))
@ -2699,7 +2793,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags)
int ret; int ret;
/* The rx would be stopped, so skip submitting */ /* The rx would be stopped, so skip submitting */
if (test_bit(RTL8152_UNPLUG, &tp->flags) || if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) ||
!test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev)) !test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev))
return 0; return 0;
@ -3099,7 +3193,7 @@ static int rtl_enable(struct r8152 *tp)
static int rtl8152_enable(struct r8152 *tp) static int rtl8152_enable(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
set_tx_qlen(tp); set_tx_qlen(tp);
@ -3186,7 +3280,7 @@ static int rtl8153_enable(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
set_tx_qlen(tp); set_tx_qlen(tp);
@ -3218,7 +3312,7 @@ static void rtl_disable(struct r8152 *tp)
u32 ocp_data; u32 ocp_data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
return; return;
} }
@ -3672,7 +3766,7 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired)
} }
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
break; break;
} }
@ -3704,6 +3798,8 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable)
int i; int i;
for (i = 0; i < 500; i++) { for (i = 0; i < 500; i++) {
if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return;
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
AUTOLOAD_DONE) AUTOLOAD_DONE)
break; break;
@ -3744,6 +3840,8 @@ static void r8153c_ups_en(struct r8152 *tp, bool enable)
int i; int i;
for (i = 0; i < 500; i++) { for (i = 0; i < 500; i++) {
if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return;
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
AUTOLOAD_DONE) AUTOLOAD_DONE)
break; break;
@ -4087,6 +4185,9 @@ static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait)
for (i = 0; wait && i < 5000; i++) { for (i = 0; wait && i < 5000; i++) {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV;
usleep_range(1000, 2000); usleep_range(1000, 2000);
ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT);
if ((ocp_data & PATCH_READY) ^ check) if ((ocp_data & PATCH_READY) ^ check)
@ -6043,7 +6144,7 @@ static int rtl8156_enable(struct r8152 *tp)
u32 ocp_data; u32 ocp_data;
u16 speed; u16 speed;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
r8156_fc_parameter(tp); r8156_fc_parameter(tp);
@ -6101,7 +6202,7 @@ static int rtl8156b_enable(struct r8152 *tp)
u32 ocp_data; u32 ocp_data;
u16 speed; u16 speed;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
set_tx_qlen(tp); set_tx_qlen(tp);
@ -6287,7 +6388,7 @@ out:
static void rtl8152_up(struct r8152 *tp) static void rtl8152_up(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8152_aldps_en(tp, false); r8152_aldps_en(tp, false);
@ -6297,7 +6398,7 @@ static void rtl8152_up(struct r8152 *tp)
static void rtl8152_down(struct r8152 *tp) static void rtl8152_down(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
return; return;
} }
@ -6312,7 +6413,7 @@ static void rtl8153_up(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153_u1u2en(tp, false); r8153_u1u2en(tp, false);
@ -6352,7 +6453,7 @@ static void rtl8153_down(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
return; return;
} }
@ -6373,7 +6474,7 @@ static void rtl8153b_up(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_u1u2en(tp, false); r8153b_u1u2en(tp, false);
@ -6397,7 +6498,7 @@ static void rtl8153b_down(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
return; return;
} }
@ -6434,7 +6535,7 @@ static void rtl8153c_up(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_u1u2en(tp, false); r8153b_u1u2en(tp, false);
@ -6515,7 +6616,7 @@ static void rtl8156_up(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_u1u2en(tp, false); r8153b_u1u2en(tp, false);
@ -6588,7 +6689,7 @@ static void rtl8156_down(struct r8152 *tp)
{ {
u32 ocp_data; u32 ocp_data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
return; return;
} }
@ -6726,7 +6827,7 @@ static void rtl_work_func_t(struct work_struct *work)
/* If the device is unplugged or !netif_running(), the workqueue /* If the device is unplugged or !netif_running(), the workqueue
* doesn't need to wake the device, and could return directly. * doesn't need to wake the device, and could return directly.
*/ */
if (test_bit(RTL8152_UNPLUG, &tp->flags) || !netif_running(tp->netdev)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) || !netif_running(tp->netdev))
return; return;
if (usb_autopm_get_interface(tp->intf) < 0) if (usb_autopm_get_interface(tp->intf) < 0)
@ -6765,7 +6866,7 @@ static void rtl_hw_phy_work_func_t(struct work_struct *work)
{ {
struct r8152 *tp = container_of(work, struct r8152, hw_phy_work.work); struct r8152 *tp = container_of(work, struct r8152, hw_phy_work.work);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (usb_autopm_get_interface(tp->intf) < 0) if (usb_autopm_get_interface(tp->intf) < 0)
@ -6892,7 +6993,7 @@ static int rtl8152_close(struct net_device *netdev)
netif_stop_queue(netdev); netif_stop_queue(netdev);
res = usb_autopm_get_interface(tp->intf); res = usb_autopm_get_interface(tp->intf);
if (res < 0 || test_bit(RTL8152_UNPLUG, &tp->flags)) { if (res < 0 || test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp); rtl_drop_queued_tx(tp);
rtl_stop_rx(tp); rtl_stop_rx(tp);
} else { } else {
@ -6925,7 +7026,7 @@ static void r8152b_init(struct r8152 *tp)
u32 ocp_data; u32 ocp_data;
u16 data; u16 data;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
data = r8152_mdio_read(tp, MII_BMCR); data = r8152_mdio_read(tp, MII_BMCR);
@ -6969,7 +7070,7 @@ static void r8153_init(struct r8152 *tp)
u16 data; u16 data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153_u1u2en(tp, false); r8153_u1u2en(tp, false);
@ -6980,7 +7081,7 @@ static void r8153_init(struct r8152 *tp)
break; break;
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
break; break;
} }
@ -7109,7 +7210,7 @@ static void r8153b_init(struct r8152 *tp)
u16 data; u16 data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_u1u2en(tp, false); r8153b_u1u2en(tp, false);
@ -7120,7 +7221,7 @@ static void r8153b_init(struct r8152 *tp)
break; break;
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
break; break;
} }
@ -7191,7 +7292,7 @@ static void r8153c_init(struct r8152 *tp)
u16 data; u16 data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_u1u2en(tp, false); r8153b_u1u2en(tp, false);
@ -7211,7 +7312,7 @@ static void r8153c_init(struct r8152 *tp)
break; break;
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
} }
@ -8040,7 +8141,7 @@ static void r8156_init(struct r8152 *tp)
u16 data; u16 data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP);
@ -8061,7 +8162,7 @@ static void r8156_init(struct r8152 *tp)
break; break;
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
} }
@ -8136,7 +8237,7 @@ static void r8156b_init(struct r8152 *tp)
u16 data; u16 data;
int i; int i;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP);
@ -8170,7 +8271,7 @@ static void r8156b_init(struct r8152 *tp)
break; break;
msleep(20); msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
} }
@ -8296,7 +8397,7 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
struct r8152 *tp = usb_get_intfdata(intf); struct r8152 *tp = usb_get_intfdata(intf);
struct net_device *netdev; struct net_device *netdev;
if (!tp) if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
return 0; return 0;
netdev = tp->netdev; netdev = tp->netdev;
@ -8311,7 +8412,9 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
napi_disable(&tp->napi); napi_disable(&tp->napi);
if (netif_carrier_ok(netdev)) { if (netif_carrier_ok(netdev)) {
mutex_lock(&tp->control); mutex_lock(&tp->control);
set_bit(IN_PRE_RESET, &tp->flags);
tp->rtl_ops.disable(tp); tp->rtl_ops.disable(tp);
clear_bit(IN_PRE_RESET, &tp->flags);
mutex_unlock(&tp->control); mutex_unlock(&tp->control);
} }
@ -8324,9 +8427,11 @@ static int rtl8152_post_reset(struct usb_interface *intf)
struct net_device *netdev; struct net_device *netdev;
struct sockaddr sa; struct sockaddr sa;
if (!tp) if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
return 0; return 0;
rtl_set_accessible(tp);
/* reset the MAC address in case of policy change */ /* reset the MAC address in case of policy change */
if (determine_ethernet_addr(tp, &sa) >= 0) { if (determine_ethernet_addr(tp, &sa) >= 0) {
rtnl_lock(); rtnl_lock();
@ -9199,7 +9304,7 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
struct mii_ioctl_data *data = if_mii(rq); struct mii_ioctl_data *data = if_mii(rq);
int res; int res;
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV; return -ENODEV;
res = usb_autopm_get_interface(tp->intf); res = usb_autopm_get_interface(tp->intf);
@ -9301,7 +9406,7 @@ static const struct net_device_ops rtl8152_netdev_ops = {
static void rtl8152_unload(struct r8152 *tp) static void rtl8152_unload(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
if (tp->version != RTL_VER_01) if (tp->version != RTL_VER_01)
@ -9310,7 +9415,7 @@ static void rtl8152_unload(struct r8152 *tp)
static void rtl8153_unload(struct r8152 *tp) static void rtl8153_unload(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153_power_cut_en(tp, false); r8153_power_cut_en(tp, false);
@ -9318,7 +9423,7 @@ static void rtl8153_unload(struct r8152 *tp)
static void rtl8153b_unload(struct r8152 *tp) static void rtl8153b_unload(struct r8152 *tp)
{ {
if (test_bit(RTL8152_UNPLUG, &tp->flags)) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return; return;
r8153b_power_cut_en(tp, false); r8153b_power_cut_en(tp, false);
@ -9528,16 +9633,29 @@ static u8 __rtl_get_hw_ver(struct usb_device *udev)
__le32 *tmp; __le32 *tmp;
u8 version; u8 version;
int ret; int ret;
int i;
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp) if (!tmp)
return 0; return 0;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), /* Retry up to 3 times in case there is a transitory error. We do this
RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, * since retrying a read of the version is always safe and this
PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); * function doesn't take advantage of r8152_control_msg().
if (ret > 0) */
ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; for (i = 0; i < 3; i++) {
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
USB_CTRL_GET_TIMEOUT);
if (ret > 0) {
ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
break;
}
}
if (i != 0 && ret > 0)
dev_warn(&udev->dev, "Needed %d retries to read version\n", i);
kfree(tmp); kfree(tmp);
@ -9636,25 +9754,14 @@ static bool rtl8152_supports_lenovo_macpassthru(struct usb_device *udev)
return 0; return 0;
} }
static int rtl8152_probe(struct usb_interface *intf, static int rtl8152_probe_once(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id, u8 version)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
struct r8152 *tp; struct r8152 *tp;
struct net_device *netdev; struct net_device *netdev;
u8 version;
int ret; int ret;
if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
return -ENODEV;
if (!rtl_check_vendor_ok(intf))
return -ENODEV;
version = rtl8152_get_version(intf);
if (version == RTL_VER_UNKNOWN)
return -ENODEV;
usb_reset_device(udev); usb_reset_device(udev);
netdev = alloc_etherdev(sizeof(struct r8152)); netdev = alloc_etherdev(sizeof(struct r8152));
if (!netdev) { if (!netdev) {
@ -9817,18 +9924,68 @@ static int rtl8152_probe(struct usb_interface *intf,
else else
device_set_wakeup_enable(&udev->dev, false); device_set_wakeup_enable(&udev->dev, false);
/* If we saw a control transfer error while probing then we may
* want to try probe() again. Consider this an error.
*/
if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
goto out2;
set_bit(PROBED_WITH_NO_ERRORS, &tp->flags);
netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
return 0; return 0;
out2:
unregister_netdev(netdev);
out1: out1:
tasklet_kill(&tp->tx_tl); tasklet_kill(&tp->tx_tl);
cancel_delayed_work_sync(&tp->hw_phy_work);
if (tp->rtl_ops.unload)
tp->rtl_ops.unload(tp);
rtl8152_release_firmware(tp);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
out: out:
if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
ret = -EAGAIN;
free_netdev(netdev); free_netdev(netdev);
return ret; return ret;
} }
#define RTL8152_PROBE_TRIES 3
static int rtl8152_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
u8 version;
int ret;
int i;
if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
return -ENODEV;
if (!rtl_check_vendor_ok(intf))
return -ENODEV;
version = rtl8152_get_version(intf);
if (version == RTL_VER_UNKNOWN)
return -ENODEV;
for (i = 0; i < RTL8152_PROBE_TRIES; i++) {
ret = rtl8152_probe_once(intf, id, version);
if (ret != -EAGAIN)
break;
}
if (ret == -EAGAIN) {
dev_err(&intf->dev,
"r8152 failed probe after %d tries; giving up\n", i);
return -ENODEV;
}
return ret;
}
static void rtl8152_disconnect(struct usb_interface *intf) static void rtl8152_disconnect(struct usb_interface *intf)
{ {
struct r8152 *tp = usb_get_intfdata(intf); struct r8152 *tp = usb_get_intfdata(intf);

View File

@ -95,7 +95,9 @@ static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
| USB_TYPE_VENDOR | USB_RECIP_DEVICE, | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, &buf, 4); 0, index, &buf, 4);
if (ret < 0) { if (ret < 4) {
ret = ret < 0 ? ret : -ENODATA;
if (ret != -ENODEV) if (ret != -ENODEV)
netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
index, ret); index, ret);

View File

@ -341,7 +341,7 @@ static int nvme_auth_process_dhchap_success1(struct nvme_ctrl *ctrl,
struct nvmf_auth_dhchap_success1_data *data = chap->buf; struct nvmf_auth_dhchap_success1_data *data = chap->buf;
size_t size = sizeof(*data); size_t size = sizeof(*data);
if (chap->ctrl_key) if (chap->s2)
size += chap->hash_len; size += chap->hash_len;
if (size > CHAP_BUF_SIZE) { if (size > CHAP_BUF_SIZE) {
@ -825,7 +825,7 @@ static void nvme_queue_auth_work(struct work_struct *work)
goto fail2; goto fail2;
} }
if (chap->ctrl_key) { if (chap->s2) {
/* DH-HMAC-CHAP Step 5: send success2 */ /* DH-HMAC-CHAP Step 5: send success2 */
dev_dbg(ctrl->device, "%s: qid %d send success2\n", dev_dbg(ctrl->device, "%s: qid %d send success2\n",
__func__, chap->qid); __func__, chap->qid);

View File

@ -108,9 +108,13 @@ static void *nvme_add_user_metadata(struct request *req, void __user *ubuf,
if (!buf) if (!buf)
goto out; goto out;
ret = -EFAULT; if (req_op(req) == REQ_OP_DRV_OUT) {
if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) ret = -EFAULT;
goto out_free_meta; if (copy_from_user(buf, ubuf, len))
goto out_free_meta;
} else {
memset(buf, 0, len);
}
bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
if (IS_ERR(bip)) { if (IS_ERR(bip)) {

View File

@ -3329,7 +3329,8 @@ static const struct pci_device_id nvme_id_table[] = {
{ PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */
.driver_data = NVME_QUIRK_STRIPE_SIZE | .driver_data = NVME_QUIRK_STRIPE_SIZE |
NVME_QUIRK_DEALLOCATE_ZEROES | NVME_QUIRK_DEALLOCATE_ZEROES |
NVME_QUIRK_IGNORE_DEV_SUBNQN, }, NVME_QUIRK_IGNORE_DEV_SUBNQN |
NVME_QUIRK_BOGUS_NID, },
{ PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */
.driver_data = NVME_QUIRK_STRIPE_SIZE | .driver_data = NVME_QUIRK_STRIPE_SIZE |
NVME_QUIRK_DEALLOCATE_ZEROES, }, NVME_QUIRK_DEALLOCATE_ZEROES, },

View File

@ -638,6 +638,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue)
static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue)
{ {
if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags))
return;
mutex_lock(&queue->queue_lock); mutex_lock(&queue->queue_lock);
if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags))
__nvme_rdma_stop_queue(queue); __nvme_rdma_stop_queue(queue);

View File

@ -333,19 +333,21 @@ done:
__func__, ctrl->cntlid, req->sq->qid, __func__, ctrl->cntlid, req->sq->qid,
status, req->error_loc); status, req->error_loc);
req->cqe->result.u64 = 0; req->cqe->result.u64 = 0;
nvmet_req_complete(req, status);
if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 && if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 &&
req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) { req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) {
unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120; unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120;
mod_delayed_work(system_wq, &req->sq->auth_expired_work, mod_delayed_work(system_wq, &req->sq->auth_expired_work,
auth_expire_secs * HZ); auth_expire_secs * HZ);
return; goto complete;
} }
/* Final states, clear up variables */ /* Final states, clear up variables */
nvmet_auth_sq_free(req->sq); nvmet_auth_sq_free(req->sq);
if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2)
nvmet_ctrl_fatal_error(ctrl); nvmet_ctrl_fatal_error(ctrl);
complete:
nvmet_req_complete(req, status);
} }
static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al)
@ -514,11 +516,12 @@ void nvmet_execute_auth_receive(struct nvmet_req *req)
kfree(d); kfree(d);
done: done:
req->cqe->result.u64 = 0; req->cqe->result.u64 = 0;
nvmet_req_complete(req, status);
if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2) if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2)
nvmet_auth_sq_free(req->sq); nvmet_auth_sq_free(req->sq);
else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) { else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) {
nvmet_auth_sq_free(req->sq); nvmet_auth_sq_free(req->sq);
nvmet_ctrl_fatal_error(ctrl); nvmet_ctrl_fatal_error(ctrl);
} }
nvmet_req_complete(req, status);
} }

View File

@ -372,6 +372,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
{ {
queue->rcv_state = NVMET_TCP_RECV_ERR;
if (status == -EPIPE || status == -ECONNRESET) if (status == -EPIPE || status == -ECONNRESET)
kernel_sock_shutdown(queue->sock, SHUT_RDWR); kernel_sock_shutdown(queue->sock, SHUT_RDWR);
else else
@ -910,15 +911,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
iov.iov_len = sizeof(*icresp); iov.iov_len = sizeof(*icresp);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
if (ret < 0) if (ret < 0)
goto free_crypto; return ret; /* queue removal will cleanup */
queue->state = NVMET_TCP_Q_LIVE; queue->state = NVMET_TCP_Q_LIVE;
nvmet_prepare_receive_pdu(queue); nvmet_prepare_receive_pdu(queue);
return 0; return 0;
free_crypto:
if (queue->hdr_digest || queue->data_digest)
nvmet_tcp_free_crypto(queue);
return ret;
} }
static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue,

View File

@ -122,16 +122,10 @@ static int phy_mdm6600_power_on(struct phy *x)
{ {
struct phy_mdm6600 *ddata = phy_get_drvdata(x); struct phy_mdm6600 *ddata = phy_get_drvdata(x);
struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE]; struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];
int error;
if (!ddata->enabled) if (!ddata->enabled)
return -ENODEV; return -ENODEV;
error = pinctrl_pm_select_default_state(ddata->dev);
if (error)
dev_warn(ddata->dev, "%s: error with default_state: %i\n",
__func__, error);
gpiod_set_value_cansleep(enable_gpio, 1); gpiod_set_value_cansleep(enable_gpio, 1);
/* Allow aggressive PM for USB, it's only needed for n_gsm port */ /* Allow aggressive PM for USB, it's only needed for n_gsm port */
@ -160,11 +154,6 @@ static int phy_mdm6600_power_off(struct phy *x)
gpiod_set_value_cansleep(enable_gpio, 0); gpiod_set_value_cansleep(enable_gpio, 0);
error = pinctrl_pm_select_sleep_state(ddata->dev);
if (error)
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
__func__, error);
return 0; return 0;
} }
@ -456,6 +445,7 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata)
{ {
struct gpio_desc *reset_gpio = struct gpio_desc *reset_gpio =
ddata->ctrl_gpios[PHY_MDM6600_RESET]; ddata->ctrl_gpios[PHY_MDM6600_RESET];
int error;
ddata->enabled = false; ddata->enabled = false;
phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ); phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ);
@ -471,6 +461,17 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata)
} else { } else {
dev_err(ddata->dev, "Timed out powering down\n"); dev_err(ddata->dev, "Timed out powering down\n");
} }
/*
* Keep reset gpio high with padconf internal pull-up resistor to
* prevent modem from waking up during deeper SoC idle states. The
* gpio bank lines can have glitches if not in the always-on wkup
* domain.
*/
error = pinctrl_pm_select_sleep_state(ddata->dev);
if (error)
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
__func__, error);
} }
static void phy_mdm6600_deferred_power_on(struct work_struct *work) static void phy_mdm6600_deferred_power_on(struct work_struct *work)
@ -571,12 +572,6 @@ static int phy_mdm6600_probe(struct platform_device *pdev)
ddata->dev = &pdev->dev; ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata); platform_set_drvdata(pdev, ddata);
/* Active state selected in phy_mdm6600_power_on() */
error = pinctrl_pm_select_sleep_state(ddata->dev);
if (error)
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
__func__, error);
error = phy_mdm6600_init_lines(ddata); error = phy_mdm6600_init_lines(ddata);
if (error) if (error)
return error; return error;
@ -627,10 +622,12 @@ idle:
pm_runtime_put_autosuspend(ddata->dev); pm_runtime_put_autosuspend(ddata->dev);
cleanup: cleanup:
if (error < 0) if (error < 0) {
phy_mdm6600_device_power_off(ddata); phy_mdm6600_device_power_off(ddata);
pm_runtime_disable(ddata->dev); pm_runtime_disable(ddata->dev);
pm_runtime_dont_use_autosuspend(ddata->dev); pm_runtime_dont_use_autosuspend(ddata->dev);
}
return error; return error;
} }
@ -639,6 +636,7 @@ static void phy_mdm6600_remove(struct platform_device *pdev)
struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); struct phy_mdm6600 *ddata = platform_get_drvdata(pdev);
struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET];
pm_runtime_get_noresume(ddata->dev);
pm_runtime_dont_use_autosuspend(ddata->dev); pm_runtime_dont_use_autosuspend(ddata->dev);
pm_runtime_put_sync(ddata->dev); pm_runtime_put_sync(ddata->dev);
pm_runtime_disable(ddata->dev); pm_runtime_disable(ddata->dev);

View File

@ -152,7 +152,7 @@ static int qcom_apq8064_sata_phy_init(struct phy *generic_phy)
return ret; return ret;
} }
/* SATA phy calibrated succesfully, power up to functional mode */ /* SATA phy calibrated successfully, power up to functional mode */
writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1); writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1);
writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0); writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0);
writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0); writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0);

View File

@ -82,7 +82,7 @@ struct m31_priv_data {
unsigned int nregs; unsigned int nregs;
}; };
struct m31_phy_regs m31_ipq5332_regs[] = { static struct m31_phy_regs m31_ipq5332_regs[] = {
{ {
USB_PHY_CFG0, USB_PHY_CFG0,
UTMI_PHY_OVERRIDE_EN, UTMI_PHY_OVERRIDE_EN,
@ -172,8 +172,7 @@ static int m31usb_phy_init(struct phy *phy)
ret = clk_prepare_enable(qphy->clk); ret = clk_prepare_enable(qphy->clk);
if (ret) { if (ret) {
if (qphy->vreg) regulator_disable(qphy->vreg);
regulator_disable(qphy->vreg);
dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
return ret; return ret;
} }
@ -256,7 +255,7 @@ static int m31usb_phy_probe(struct platform_device *pdev)
qphy->vreg = devm_regulator_get(dev, "vdda-phy"); qphy->vreg = devm_regulator_get(dev, "vdda-phy");
if (IS_ERR(qphy->vreg)) if (IS_ERR(qphy->vreg))
return dev_err_probe(dev, PTR_ERR(qphy->phy), return dev_err_probe(dev, PTR_ERR(qphy->vreg),
"failed to get vreg\n"); "failed to get vreg\n");
phy_set_drvdata(qphy->phy, qphy); phy_set_drvdata(qphy->phy, qphy);

View File

@ -859,10 +859,10 @@ static const struct qmp_phy_init_tbl sm8550_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_PCS_TX_RX_CONFIG, 0x0c), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_PCS_TX_RX_CONFIG, 0x0c),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG1, 0x4b), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG1, 0x4b),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG5, 0x10), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG5, 0x10),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1, 0x68),
}; };
static const struct qmp_phy_init_tbl sm8550_usb3_pcs_usb_tbl[] = { static const struct qmp_phy_init_tbl sm8550_usb3_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1, 0x68),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40), QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
@ -2555,6 +2555,7 @@ static int qmp_combo_usb_power_on(struct phy *phy)
void __iomem *tx2 = qmp->tx2; void __iomem *tx2 = qmp->tx2;
void __iomem *rx2 = qmp->rx2; void __iomem *rx2 = qmp->rx2;
void __iomem *pcs = qmp->pcs; void __iomem *pcs = qmp->pcs;
void __iomem *pcs_usb = qmp->pcs_usb;
void __iomem *status; void __iomem *status;
unsigned int val; unsigned int val;
int ret; int ret;
@ -2576,6 +2577,9 @@ static int qmp_combo_usb_power_on(struct phy *phy)
qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
if (pcs_usb)
qmp_combo_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
if (cfg->has_pwrdn_delay) if (cfg->has_pwrdn_delay)
usleep_range(10, 20); usleep_range(10, 20);

View File

@ -12,7 +12,7 @@
#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG3 0xcc #define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG3 0xcc
#define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG6 0xd8 #define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG6 0xd8
#define QPHY_USB_V6_PCS_REFGEN_REQ_CONFIG1 0xdc #define QPHY_USB_V6_PCS_REFGEN_REQ_CONFIG1 0xdc
#define QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1 0x90 #define QPHY_USB_V6_PCS_POWER_STATE_CONFIG1 0x90
#define QPHY_USB_V6_PCS_RX_SIGDET_LVL 0x188 #define QPHY_USB_V6_PCS_RX_SIGDET_LVL 0x188
#define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 #define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
#define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 #define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
@ -23,6 +23,7 @@
#define QPHY_USB_V6_PCS_EQ_CONFIG1 0x1dc #define QPHY_USB_V6_PCS_EQ_CONFIG1 0x1dc
#define QPHY_USB_V6_PCS_EQ_CONFIG5 0x1ec #define QPHY_USB_V6_PCS_EQ_CONFIG5 0x1ec
#define QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1 0x00
#define QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18 #define QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18
#define QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c #define QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c
#define QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40 #define QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40

View File

@ -1112,8 +1112,6 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa), QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c), QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a), QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88), QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13), QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13),
@ -1122,6 +1120,11 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21),
}; };
static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
};
static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = { static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG1, 0xc4), QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG1, 0xc4),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG2, 0x89), QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG2, 0x89),
@ -1131,9 +1134,6 @@ static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa), QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c), QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_POWER_STATE_CONFIG1, 0x6f),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a), QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88), QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13), QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13),
@ -1142,6 +1142,12 @@ static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21),
}; };
static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_POWER_STATE_CONFIG1, 0x6f),
};
struct qmp_usb_offsets { struct qmp_usb_offsets {
u16 serdes; u16 serdes;
u16 pcs; u16 pcs;
@ -1383,6 +1389,8 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
.rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl), .rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl),
.pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl, .pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl), .pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl),
.pcs_usb_tbl = sa8775p_usb3_uniphy_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_usb_tbl),
.clk_list = qmp_v4_phy_clk_l, .clk_list = qmp_v4_phy_clk_l,
.num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
.reset_list = qcm2290_usb3phy_reset_l, .reset_list = qcm2290_usb3phy_reset_l,
@ -1405,6 +1413,8 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = {
.rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl), .rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl),
.pcs_tbl = sc8280xp_usb3_uniphy_pcs_tbl, .pcs_tbl = sc8280xp_usb3_uniphy_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_tbl), .pcs_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_tbl),
.pcs_usb_tbl = sc8280xp_usb3_uniphy_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_usb_tbl),
.clk_list = qmp_v4_phy_clk_l, .clk_list = qmp_v4_phy_clk_l,
.num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
.reset_list = qcm2290_usb3phy_reset_l, .reset_list = qcm2290_usb3phy_reset_l,
@ -1703,6 +1713,7 @@ static int qmp_usb_power_on(struct phy *phy)
void __iomem *tx = qmp->tx; void __iomem *tx = qmp->tx;
void __iomem *rx = qmp->rx; void __iomem *rx = qmp->rx;
void __iomem *pcs = qmp->pcs; void __iomem *pcs = qmp->pcs;
void __iomem *pcs_usb = qmp->pcs_usb;
void __iomem *status; void __iomem *status;
unsigned int val; unsigned int val;
int ret; int ret;
@ -1726,6 +1737,9 @@ static int qmp_usb_power_on(struct phy *phy)
qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
if (pcs_usb)
qmp_usb_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
if (cfg->has_pwrdn_delay) if (cfg->has_pwrdn_delay)
usleep_range(10, 20); usleep_range(10, 20);

View File

@ -2,6 +2,9 @@
# #
# Phy drivers for Realtek platforms # Phy drivers for Realtek platforms
# #
if ARCH_REALTEK || COMPILE_TEST
config PHY_RTK_RTD_USB2PHY config PHY_RTK_RTD_USB2PHY
tristate "Realtek RTD USB2 PHY Transceiver Driver" tristate "Realtek RTD USB2 PHY Transceiver Driver"
depends on USB_SUPPORT depends on USB_SUPPORT
@ -25,3 +28,5 @@ config PHY_RTK_RTD_USB3PHY
The DHC (digital home center) RTD series SoCs used the Synopsys The DHC (digital home center) RTD series SoCs used the Synopsys
DWC3 USB IP. This driver will do the PHY initialization DWC3 USB IP. This driver will do the PHY initialization
of the parameters. of the parameters.
endif # ARCH_REALTEK || COMPILE_TEST

View File

@ -853,17 +853,11 @@ static inline void create_debug_files(struct rtk_phy *rtk_phy)
rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev), rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev),
phy_debug_root); phy_debug_root);
if (!rtk_phy->debug_dir)
return;
if (!debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy, debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy,
&rtk_usb2_parameter_fops)) &rtk_usb2_parameter_fops);
goto file_error;
return; return;
file_error:
debugfs_remove_recursive(rtk_phy->debug_dir);
} }
static inline void remove_debug_files(struct rtk_phy *rtk_phy) static inline void remove_debug_files(struct rtk_phy *rtk_phy)

View File

@ -416,17 +416,11 @@ static inline void create_debug_files(struct rtk_phy *rtk_phy)
return; return;
rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev), phy_debug_root); rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev), phy_debug_root);
if (!rtk_phy->debug_dir)
return;
if (!debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy, debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy,
&rtk_usb3_parameter_fops)) &rtk_usb3_parameter_fops);
goto file_error;
return; return;
file_error:
debugfs_remove_recursive(rtk_phy->debug_dir);
} }
static inline void remove_debug_files(struct rtk_phy *rtk_phy) static inline void remove_debug_files(struct rtk_phy *rtk_phy)

Some files were not shown because too many files have changed in this diff Show More