Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b1513c3531
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 11
|
PATCHLEVEL = 11
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc7
|
EXTRAVERSION = -rc8
|
||||||
NAME = Fearless Coyote
|
NAME = Fearless Coyote
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|
|
@ -406,6 +406,14 @@ config ARC_HAS_DIV_REM
|
||||||
bool "Insn: div, divu, rem, remu"
|
bool "Insn: div, divu, rem, remu"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config ARC_HAS_ACCL_REGS
|
||||||
|
bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Depending on the configuration, CPU can contain accumulator reg-pair
|
||||||
|
(also referred to as r58:r59). These can also be used by gcc as GPR so
|
||||||
|
kernel needs to save/restore per process
|
||||||
|
|
||||||
endif # ISA_ARCV2
|
endif # ISA_ARCV2
|
||||||
|
|
||||||
endmenu # "ARC CPU Configuration"
|
endmenu # "ARC CPU Configuration"
|
||||||
|
|
|
@ -17,10 +17,11 @@
|
||||||
#include <asm/barrier.h>
|
#include <asm/barrier.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
|
||||||
|
#define ATOMIC_INIT(i) { (i) }
|
||||||
|
|
||||||
#ifndef CONFIG_ARC_PLAT_EZNPS
|
#ifndef CONFIG_ARC_PLAT_EZNPS
|
||||||
|
|
||||||
#define atomic_read(v) READ_ONCE((v)->counter)
|
#define atomic_read(v) READ_ONCE((v)->counter)
|
||||||
#define ATOMIC_INIT(i) { (i) }
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_HAS_LLSC
|
#ifdef CONFIG_ARC_HAS_LLSC
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
;
|
;
|
||||||
; Now manually save: r12, sp, fp, gp, r25
|
; Now manually save: r12, sp, fp, gp, r25
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_ACCL_REGS
|
||||||
|
PUSH r59
|
||||||
|
PUSH r58
|
||||||
|
#endif
|
||||||
|
|
||||||
PUSH r30
|
PUSH r30
|
||||||
PUSH r12
|
PUSH r12
|
||||||
|
|
||||||
|
@ -75,6 +80,11 @@
|
||||||
POP r12
|
POP r12
|
||||||
POP r30
|
POP r30
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_ACCL_REGS
|
||||||
|
POP r58
|
||||||
|
POP r59
|
||||||
|
#endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -86,6 +86,10 @@ struct pt_regs {
|
||||||
|
|
||||||
unsigned long r12, r30;
|
unsigned long r12, r30;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_ACCL_REGS
|
||||||
|
unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*------- Below list auto saved by h/w -----------*/
|
/*------- Below list auto saved by h/w -----------*/
|
||||||
unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
|
unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
|
||||||
static void arc_chk_core_config(void)
|
static void arc_chk_core_config(void)
|
||||||
{
|
{
|
||||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||||
int fpu_enabled;
|
int saved = 0, present = 0;
|
||||||
|
char *opt_nm = NULL;;
|
||||||
|
|
||||||
if (!cpu->extn.timer0)
|
if (!cpu->extn.timer0)
|
||||||
panic("Timer0 is not present!\n");
|
panic("Timer0 is not present!\n");
|
||||||
|
@ -346,17 +347,28 @@ static void arc_chk_core_config(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FP hardware/software config sanity
|
* FP hardware/software config sanity
|
||||||
* -If hardware contains DPFP, kernel needs to save/restore FPU state
|
* -If hardware present, kernel needs to save/restore FPU state
|
||||||
* -If not, it will crash trying to save/restore the non-existant regs
|
* -If not, it will crash trying to save/restore the non-existant regs
|
||||||
*
|
|
||||||
* (only DPDP checked since SP has no arch visible regs)
|
|
||||||
*/
|
*/
|
||||||
fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
|
|
||||||
|
|
||||||
if (cpu->extn.fpu_dp && !fpu_enabled)
|
if (is_isa_arcompact()) {
|
||||||
pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
|
opt_nm = "CONFIG_ARC_FPU_SAVE_RESTORE";
|
||||||
else if (!cpu->extn.fpu_dp && fpu_enabled)
|
saved = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
|
||||||
panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
|
|
||||||
|
/* only DPDP checked since SP has no arch visible regs */
|
||||||
|
present = cpu->extn.fpu_dp;
|
||||||
|
} else {
|
||||||
|
opt_nm = "CONFIG_ARC_HAS_ACCL_REGS";
|
||||||
|
saved = IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS);
|
||||||
|
|
||||||
|
/* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */
|
||||||
|
present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (present && !saved)
|
||||||
|
pr_warn("Enable %s for working apps\n", opt_nm);
|
||||||
|
else if (!present && saved)
|
||||||
|
panic("Disable %s, hardware NOT present\n", opt_nm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -489,7 +489,7 @@ $(generic_defconfigs):
|
||||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
|
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
|
||||||
-m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \
|
-m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \
|
||||||
$(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config)
|
$(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config)
|
||||||
$(Q)$(MAKE) olddefconfig
|
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
|
||||||
|
|
||||||
#
|
#
|
||||||
# Prevent generic merge_config rules attempting to merge single fragments
|
# Prevent generic merge_config rules attempting to merge single fragments
|
||||||
|
@ -503,8 +503,8 @@ $(generic_config_dir)/%.config: ;
|
||||||
#
|
#
|
||||||
.PHONY: sead3_defconfig
|
.PHONY: sead3_defconfig
|
||||||
sead3_defconfig:
|
sead3_defconfig:
|
||||||
$(Q)$(MAKE) 32r2el_defconfig BOARDS=sead-3
|
$(Q)$(MAKE) -f $(srctree)/Makefile 32r2el_defconfig BOARDS=sead-3
|
||||||
|
|
||||||
.PHONY: sead3micro_defconfig
|
.PHONY: sead3micro_defconfig
|
||||||
sead3micro_defconfig:
|
sead3micro_defconfig:
|
||||||
$(Q)$(MAKE) micro32r2el_defconfig BOARDS=sead-3
|
$(Q)$(MAKE) -f $(srctree)/Makefile micro32r2el_defconfig BOARDS=sead-3
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
#include <asm/fpu.h>
|
#include <asm/fpu.h>
|
||||||
#include <asm-generic/asm-prototypes.h>
|
#include <asm-generic/asm-prototypes.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/ftrace.h>
|
||||||
|
|
|
@ -80,7 +80,7 @@ static unsigned int calculate_min_delta(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sorted insert of 75th percentile into buf2 */
|
/* Sorted insert of 75th percentile into buf2 */
|
||||||
for (k = 0; k < i; ++k) {
|
for (k = 0; k < i && k < ARRAY_SIZE(buf2); ++k) {
|
||||||
if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) {
|
if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) {
|
||||||
l = min_t(unsigned int,
|
l = min_t(unsigned int,
|
||||||
i, ARRAY_SIZE(buf2) - 1);
|
i, ARRAY_SIZE(buf2) - 1);
|
||||||
|
|
|
@ -257,7 +257,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
|
||||||
else if ((prog_req.fr1 && prog_req.frdefault) ||
|
else if ((prog_req.fr1 && prog_req.frdefault) ||
|
||||||
(prog_req.single && !prog_req.frdefault))
|
(prog_req.single && !prog_req.frdefault))
|
||||||
/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
|
/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
|
||||||
state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
|
state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
|
||||||
cpu_has_mips_r2_r6) ?
|
cpu_has_mips_r2_r6) ?
|
||||||
FP_FR1 : FP_FR0;
|
FP_FR1 : FP_FR0;
|
||||||
else if (prog_req.fr1)
|
else if (prog_req.fr1)
|
||||||
|
|
|
@ -244,9 +244,6 @@ static int compute_signal(int tt)
|
||||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||||
{
|
{
|
||||||
int reg;
|
int reg;
|
||||||
struct thread_info *ti = task_thread_info(p);
|
|
||||||
unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
|
|
||||||
struct pt_regs *regs = (struct pt_regs *)ksp - 1;
|
|
||||||
#if (KGDB_GDB_REG_SIZE == 32)
|
#if (KGDB_GDB_REG_SIZE == 32)
|
||||||
u32 *ptr = (u32 *)gdb_regs;
|
u32 *ptr = (u32 *)gdb_regs;
|
||||||
#else
|
#else
|
||||||
|
@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (reg = 0; reg < 16; reg++)
|
for (reg = 0; reg < 16; reg++)
|
||||||
*(ptr++) = regs->regs[reg];
|
*(ptr++) = 0;
|
||||||
|
|
||||||
/* S0 - S7 */
|
/* S0 - S7 */
|
||||||
for (reg = 16; reg < 24; reg++)
|
*(ptr++) = p->thread.reg16;
|
||||||
*(ptr++) = regs->regs[reg];
|
*(ptr++) = p->thread.reg17;
|
||||||
|
*(ptr++) = p->thread.reg18;
|
||||||
|
*(ptr++) = p->thread.reg19;
|
||||||
|
*(ptr++) = p->thread.reg20;
|
||||||
|
*(ptr++) = p->thread.reg21;
|
||||||
|
*(ptr++) = p->thread.reg22;
|
||||||
|
*(ptr++) = p->thread.reg23;
|
||||||
|
|
||||||
for (reg = 24; reg < 28; reg++)
|
for (reg = 24; reg < 28; reg++)
|
||||||
*(ptr++) = 0;
|
*(ptr++) = 0;
|
||||||
|
|
||||||
/* GP, SP, FP, RA */
|
/* GP, SP, FP, RA */
|
||||||
for (reg = 28; reg < 32; reg++)
|
*(ptr++) = (long)p;
|
||||||
*(ptr++) = regs->regs[reg];
|
*(ptr++) = p->thread.reg29;
|
||||||
|
*(ptr++) = p->thread.reg30;
|
||||||
|
*(ptr++) = p->thread.reg31;
|
||||||
|
|
||||||
*(ptr++) = regs->cp0_status;
|
*(ptr++) = p->thread.cp0_status;
|
||||||
*(ptr++) = regs->lo;
|
|
||||||
*(ptr++) = regs->hi;
|
/* lo, hi */
|
||||||
*(ptr++) = regs->cp0_badvaddr;
|
*(ptr++) = 0;
|
||||||
*(ptr++) = regs->cp0_cause;
|
*(ptr++) = 0;
|
||||||
*(ptr++) = regs->cp0_epc;
|
|
||||||
|
/*
|
||||||
|
* BadVAddr, Cause
|
||||||
|
* Ideally these would come from the last exception frame up the stack
|
||||||
|
* but that requires unwinding, otherwise we can't know much for sure.
|
||||||
|
*/
|
||||||
|
*(ptr++) = 0;
|
||||||
|
*(ptr++) = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PC
|
||||||
|
* use return address (RA), i.e. the moment after return from resume()
|
||||||
|
*/
|
||||||
|
*(ptr++) = p->thread.reg31;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
||||||
|
|
|
@ -1446,6 +1446,11 @@ static int mipsxx_pmu_handle_shared_irq(void)
|
||||||
HANDLE_COUNTER(0)
|
HANDLE_COUNTER(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
|
||||||
|
read_unlock(&pmuint_rwlock);
|
||||||
|
#endif
|
||||||
|
resume_local_counters();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do all the work for the pending perf events. We can do this
|
* Do all the work for the pending perf events. We can do this
|
||||||
* in here because the performance counter interrupt is a regular
|
* in here because the performance counter interrupt is a regular
|
||||||
|
@ -1454,10 +1459,6 @@ static int mipsxx_pmu_handle_shared_irq(void)
|
||||||
if (handled == IRQ_HANDLED)
|
if (handled == IRQ_HANDLED)
|
||||||
irq_work_run();
|
irq_work_run();
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
|
|
||||||
read_unlock(&pmuint_rwlock);
|
|
||||||
#endif
|
|
||||||
resume_local_counters();
|
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/libfdt.h>
|
#include <linux/libfdt.h>
|
||||||
#include <linux/of_fdt.h>
|
#include <linux/of_fdt.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched/task.h>
|
||||||
#include <linux/start_kernel.h>
|
#include <linux/start_kernel.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
|
|
|
@ -422,13 +422,12 @@ void play_dead(void)
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
idle_task_exit();
|
idle_task_exit();
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
|
core = cpu_data[cpu].core;
|
||||||
cpu_death = CPU_DEATH_POWER;
|
cpu_death = CPU_DEATH_POWER;
|
||||||
|
|
||||||
pr_debug("CPU%d going offline\n", cpu);
|
pr_debug("CPU%d going offline\n", cpu);
|
||||||
|
|
||||||
if (cpu_has_mipsmt || cpu_has_vp) {
|
if (cpu_has_mipsmt || cpu_has_vp) {
|
||||||
core = cpu_data[cpu].core;
|
|
||||||
|
|
||||||
/* Look for another online VPE within the core */
|
/* Look for another online VPE within the core */
|
||||||
for_each_online_cpu(cpu_death_sibling) {
|
for_each_online_cpu(cpu_death_sibling) {
|
||||||
if (cpu_data[cpu_death_sibling].core != core)
|
if (cpu_data[cpu_death_sibling].core != core)
|
||||||
|
|
|
@ -232,6 +232,17 @@ void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
int corehi_irq;
|
int corehi_irq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preallocate the i8259's expected virq's here. Since irqchip_init()
|
||||||
|
* will probe the irqchips in hierarchial order, i8259 is probed last.
|
||||||
|
* If anything allocates a virq before the i8259 is probed, it will
|
||||||
|
* be given one of the i8259's expected range and consequently setup
|
||||||
|
* of the i8259 will fail.
|
||||||
|
*/
|
||||||
|
WARN(irq_alloc_descs(I8259A_IRQ_BASE, I8259A_IRQ_BASE,
|
||||||
|
16, numa_node_id()) < 0,
|
||||||
|
"Cannot reserve i8259 virqs at IRQ%d\n", I8259A_IRQ_BASE);
|
||||||
|
|
||||||
i8259_set_poll(mips_pcibios_iack);
|
i8259_set_poll(mips_pcibios_iack);
|
||||||
irqchip_init();
|
irqchip_init();
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ void register_pci_controller(struct pci_controller *hose)
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&hose->list);
|
INIT_LIST_HEAD(&hose->list);
|
||||||
list_add(&hose->list, &controllers);
|
list_add_tail(&hose->list, &controllers);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not panic here but later - this might happen before console init.
|
* Do not panic here but later - this might happen before console init.
|
||||||
|
|
|
@ -83,6 +83,7 @@ config SPARC64
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||||
select HAVE_NMI
|
select HAVE_NMI
|
||||||
|
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||||
|
|
||||||
config ARCH_DEFCONFIG
|
config ARCH_DEFCONFIG
|
||||||
string
|
string
|
||||||
|
|
|
@ -83,7 +83,8 @@ unsigned long profile_pc(struct pt_regs *);
|
||||||
|
|
||||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, magic))
|
#define MAX_REG_OFFSET (offsetof(struct pt_regs, magic))
|
||||||
|
|
||||||
extern int regs_query_register_offset(const char *name);
|
int regs_query_register_offset(const char *name);
|
||||||
|
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regs_get_register() - get register value from its offset
|
* regs_get_register() - get register value from its offset
|
||||||
|
|
|
@ -425,8 +425,9 @@
|
||||||
#define __NR_copy_file_range 357
|
#define __NR_copy_file_range 357
|
||||||
#define __NR_preadv2 358
|
#define __NR_preadv2 358
|
||||||
#define __NR_pwritev2 359
|
#define __NR_pwritev2 359
|
||||||
|
#define __NR_statx 360
|
||||||
|
|
||||||
#define NR_syscalls 360
|
#define NR_syscalls 361
|
||||||
|
|
||||||
/* Bitmask values returned from kern_features system call. */
|
/* Bitmask values returned from kern_features system call. */
|
||||||
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
|
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
|
||||||
|
@ -442,4 +443,9 @@
|
||||||
#define __IGNORE_getresgid
|
#define __IGNORE_getresgid
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Sparc doesn't have protection keys. */
|
||||||
|
#define __IGNORE_pkey_mprotect
|
||||||
|
#define __IGNORE_pkey_alloc
|
||||||
|
#define __IGNORE_pkey_free
|
||||||
|
|
||||||
#endif /* _UAPI_SPARC_UNISTD_H */
|
#endif /* _UAPI_SPARC_UNISTD_H */
|
||||||
|
|
|
@ -1162,3 +1162,39 @@ int regs_query_register_offset(const char *name)
|
||||||
return roff->offset;
|
return roff->offset;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regs_within_kernel_stack() - check the address in the stack
|
||||||
|
* @regs: pt_regs which contains kernel stack pointer.
|
||||||
|
* @addr: address which is checked.
|
||||||
|
*
|
||||||
|
* regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
|
||||||
|
* If @addr is within the kernel stack, it returns true. If not, returns false.
|
||||||
|
*/
|
||||||
|
static inline int regs_within_kernel_stack(struct pt_regs *regs,
|
||||||
|
unsigned long addr)
|
||||||
|
{
|
||||||
|
unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
|
||||||
|
return ((addr & ~(THREAD_SIZE - 1)) ==
|
||||||
|
(ksp & ~(THREAD_SIZE - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regs_get_kernel_stack_nth() - get Nth entry of the stack
|
||||||
|
* @regs: pt_regs which contains kernel stack pointer.
|
||||||
|
* @n: stack entry number.
|
||||||
|
*
|
||||||
|
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
|
||||||
|
* is specified by @regs. If the @n th entry is NOT in the kernel stack,
|
||||||
|
* this returns 0.
|
||||||
|
*/
|
||||||
|
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
|
||||||
|
unsigned long *addr = (unsigned long *)ksp;
|
||||||
|
addr += n;
|
||||||
|
if (regs_within_kernel_stack(regs, (unsigned long)addr))
|
||||||
|
return *addr;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -89,3 +89,4 @@ sys_call_table:
|
||||||
/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
||||||
/*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
/*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
||||||
/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2
|
/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2
|
||||||
|
/*360*/ .long sys_statx
|
||||||
|
|
|
@ -90,6 +90,7 @@ sys_call_table32:
|
||||||
.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
||||||
/*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
/*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
||||||
.word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2
|
.word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2
|
||||||
|
/*360*/ .word sys_statx
|
||||||
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
|
|
||||||
|
@ -171,3 +172,4 @@ sys_call_table:
|
||||||
.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
|
||||||
/*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
/*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
|
||||||
.word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2
|
.word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2
|
||||||
|
/*360*/ .word sys_statx
|
||||||
|
|
|
@ -85,7 +85,7 @@ void mce_gen_pool_process(struct work_struct *__unused)
|
||||||
head = llist_reverse_order(head);
|
head = llist_reverse_order(head);
|
||||||
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
||||||
mce = &node->mce;
|
mce = &node->mce;
|
||||||
atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
||||||
gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
|
gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum severity_level {
|
||||||
MCE_PANIC_SEVERITY,
|
MCE_PANIC_SEVERITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct atomic_notifier_head x86_mce_decoder_chain;
|
extern struct blocking_notifier_head x86_mce_decoder_chain;
|
||||||
|
|
||||||
#define ATTR_LEN 16
|
#define ATTR_LEN 16
|
||||||
#define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */
|
#define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */
|
||||||
|
|
|
@ -123,7 +123,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
|
||||||
* CPU/chipset specific EDAC code can register a notifier call here to print
|
* CPU/chipset specific EDAC code can register a notifier call here to print
|
||||||
* MCE errors in a human-readable form.
|
* MCE errors in a human-readable form.
|
||||||
*/
|
*/
|
||||||
ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
||||||
|
|
||||||
/* Do initial initialization of a struct mce */
|
/* Do initial initialization of a struct mce */
|
||||||
void mce_setup(struct mce *m)
|
void mce_setup(struct mce *m)
|
||||||
|
@ -220,7 +220,7 @@ void mce_register_decode_chain(struct notifier_block *nb)
|
||||||
|
|
||||||
WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC);
|
WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC);
|
||||||
|
|
||||||
atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
|
blocking_notifier_chain_register(&x86_mce_decoder_chain, nb);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mce_register_decode_chain);
|
EXPORT_SYMBOL_GPL(mce_register_decode_chain);
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ void mce_unregister_decode_chain(struct notifier_block *nb)
|
||||||
{
|
{
|
||||||
atomic_dec(&num_notifiers);
|
atomic_dec(&num_notifiers);
|
||||||
|
|
||||||
atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
|
blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
|
EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
|
||||||
|
|
||||||
|
@ -321,18 +321,7 @@ static void __print_mce(struct mce *m)
|
||||||
|
|
||||||
static void print_mce(struct mce *m)
|
static void print_mce(struct mce *m)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
__print_mce(m);
|
__print_mce(m);
|
||||||
|
|
||||||
/*
|
|
||||||
* Print out human-readable details about the MCE error,
|
|
||||||
* (if the CPU has an implementation for that)
|
|
||||||
*/
|
|
||||||
ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
|
|
||||||
if (ret == NOTIFY_STOP)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n");
|
pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes == 0) {
|
|
||||||
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
|
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (bytes == 0) {
|
||||||
err = clear_update_marker(ubi, vol, 0);
|
err = clear_update_marker(ubi, vol, 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -72,6 +72,8 @@ config CAN_PEAK_USB
|
||||||
PCAN-USB Pro dual CAN 2.0b channels USB adapter
|
PCAN-USB Pro dual CAN 2.0b channels USB adapter
|
||||||
PCAN-USB FD single CAN-FD channel USB adapter
|
PCAN-USB FD single CAN-FD channel USB adapter
|
||||||
PCAN-USB Pro FD dual CAN-FD channels USB adapter
|
PCAN-USB Pro FD dual CAN-FD channels USB adapter
|
||||||
|
PCAN-Chip USB CAN-FD to USB stamp module
|
||||||
|
PCAN-USB X6 6 CAN-FD channels USB adapter
|
||||||
|
|
||||||
(see also http://www.peak-system.com).
|
(see also http://www.peak-system.com).
|
||||||
|
|
||||||
|
|
|
@ -739,13 +739,18 @@ static const struct net_device_ops gs_usb_netdev_ops = {
|
||||||
static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
||||||
{
|
{
|
||||||
struct gs_can *dev = netdev_priv(netdev);
|
struct gs_can *dev = netdev_priv(netdev);
|
||||||
struct gs_identify_mode imode;
|
struct gs_identify_mode *imode;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
imode = kmalloc(sizeof(*imode), GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!imode)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (do_identify)
|
if (do_identify)
|
||||||
imode.mode = GS_CAN_IDENTIFY_ON;
|
imode->mode = GS_CAN_IDENTIFY_ON;
|
||||||
else
|
else
|
||||||
imode.mode = GS_CAN_IDENTIFY_OFF;
|
imode->mode = GS_CAN_IDENTIFY_OFF;
|
||||||
|
|
||||||
rc = usb_control_msg(interface_to_usbdev(dev->iface),
|
rc = usb_control_msg(interface_to_usbdev(dev->iface),
|
||||||
usb_sndctrlpipe(interface_to_usbdev(dev->iface),
|
usb_sndctrlpipe(interface_to_usbdev(dev->iface),
|
||||||
|
@ -755,10 +760,12 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
||||||
USB_RECIP_INTERFACE,
|
USB_RECIP_INTERFACE,
|
||||||
dev->channel,
|
dev->channel,
|
||||||
0,
|
0,
|
||||||
&imode,
|
imode,
|
||||||
sizeof(imode),
|
sizeof(*imode),
|
||||||
100);
|
100);
|
||||||
|
|
||||||
|
kfree(imode);
|
||||||
|
|
||||||
return (rc > 0) ? 0 : rc;
|
return (rc > 0) ? 0 : rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ static struct usb_device_id peak_usb_table[] = {
|
||||||
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
|
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
|
||||||
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBFD_PRODUCT_ID)},
|
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBFD_PRODUCT_ID)},
|
||||||
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPROFD_PRODUCT_ID)},
|
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPROFD_PRODUCT_ID)},
|
||||||
|
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBCHIP_PRODUCT_ID)},
|
||||||
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBX6_PRODUCT_ID)},
|
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBX6_PRODUCT_ID)},
|
||||||
{} /* Terminating entry */
|
{} /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
@ -51,6 +52,7 @@ static const struct peak_usb_adapter *const peak_usb_adapters_list[] = {
|
||||||
&pcan_usb_pro,
|
&pcan_usb_pro,
|
||||||
&pcan_usb_fd,
|
&pcan_usb_fd,
|
||||||
&pcan_usb_pro_fd,
|
&pcan_usb_pro_fd,
|
||||||
|
&pcan_usb_chip,
|
||||||
&pcan_usb_x6,
|
&pcan_usb_x6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define PCAN_USBPRO_PRODUCT_ID 0x000d
|
#define PCAN_USBPRO_PRODUCT_ID 0x000d
|
||||||
#define PCAN_USBPROFD_PRODUCT_ID 0x0011
|
#define PCAN_USBPROFD_PRODUCT_ID 0x0011
|
||||||
#define PCAN_USBFD_PRODUCT_ID 0x0012
|
#define PCAN_USBFD_PRODUCT_ID 0x0012
|
||||||
|
#define PCAN_USBCHIP_PRODUCT_ID 0x0013
|
||||||
#define PCAN_USBX6_PRODUCT_ID 0x0014
|
#define PCAN_USBX6_PRODUCT_ID 0x0014
|
||||||
|
|
||||||
#define PCAN_USB_DRIVER_NAME "peak_usb"
|
#define PCAN_USB_DRIVER_NAME "peak_usb"
|
||||||
|
@ -90,6 +91,7 @@ struct peak_usb_adapter {
|
||||||
extern const struct peak_usb_adapter pcan_usb;
|
extern const struct peak_usb_adapter pcan_usb;
|
||||||
extern const struct peak_usb_adapter pcan_usb_pro;
|
extern const struct peak_usb_adapter pcan_usb_pro;
|
||||||
extern const struct peak_usb_adapter pcan_usb_fd;
|
extern const struct peak_usb_adapter pcan_usb_fd;
|
||||||
|
extern const struct peak_usb_adapter pcan_usb_chip;
|
||||||
extern const struct peak_usb_adapter pcan_usb_pro_fd;
|
extern const struct peak_usb_adapter pcan_usb_pro_fd;
|
||||||
extern const struct peak_usb_adapter pcan_usb_x6;
|
extern const struct peak_usb_adapter pcan_usb_x6;
|
||||||
|
|
||||||
|
|
|
@ -1062,6 +1062,78 @@ const struct peak_usb_adapter pcan_usb_fd = {
|
||||||
.do_get_berr_counter = pcan_usb_fd_get_berr_counter,
|
.do_get_berr_counter = pcan_usb_fd_get_berr_counter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* describes the PCAN-CHIP USB */
|
||||||
|
static const struct can_bittiming_const pcan_usb_chip_const = {
|
||||||
|
.name = "pcan_chip_usb",
|
||||||
|
.tseg1_min = 1,
|
||||||
|
.tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
|
||||||
|
.tseg2_min = 1,
|
||||||
|
.tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
|
||||||
|
.sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
|
||||||
|
.brp_min = 1,
|
||||||
|
.brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
|
||||||
|
.brp_inc = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct can_bittiming_const pcan_usb_chip_data_const = {
|
||||||
|
.name = "pcan_chip_usb",
|
||||||
|
.tseg1_min = 1,
|
||||||
|
.tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
|
||||||
|
.tseg2_min = 1,
|
||||||
|
.tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
|
||||||
|
.sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
|
||||||
|
.brp_min = 1,
|
||||||
|
.brp_max = (1 << PUCAN_TFAST_BRP_BITS),
|
||||||
|
.brp_inc = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct peak_usb_adapter pcan_usb_chip = {
|
||||||
|
.name = "PCAN-Chip USB",
|
||||||
|
.device_id = PCAN_USBCHIP_PRODUCT_ID,
|
||||||
|
.ctrl_count = PCAN_USBFD_CHANNEL_COUNT,
|
||||||
|
.ctrlmode_supported = CAN_CTRLMODE_FD |
|
||||||
|
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
|
||||||
|
.clock = {
|
||||||
|
.freq = PCAN_UFD_CRYSTAL_HZ,
|
||||||
|
},
|
||||||
|
.bittiming_const = &pcan_usb_chip_const,
|
||||||
|
.data_bittiming_const = &pcan_usb_chip_data_const,
|
||||||
|
|
||||||
|
/* size of device private data */
|
||||||
|
.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
|
||||||
|
|
||||||
|
/* timestamps usage */
|
||||||
|
.ts_used_bits = 32,
|
||||||
|
.ts_period = 1000000, /* calibration period in ts. */
|
||||||
|
.us_per_ts_scale = 1, /* us = (ts * scale) >> shift */
|
||||||
|
.us_per_ts_shift = 0,
|
||||||
|
|
||||||
|
/* give here messages in/out endpoints */
|
||||||
|
.ep_msg_in = PCAN_USBPRO_EP_MSGIN,
|
||||||
|
.ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0},
|
||||||
|
|
||||||
|
/* size of rx/tx usb buffers */
|
||||||
|
.rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE,
|
||||||
|
.tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
|
||||||
|
|
||||||
|
/* device callbacks */
|
||||||
|
.intf_probe = pcan_usb_pro_probe, /* same as PCAN-USB Pro */
|
||||||
|
.dev_init = pcan_usb_fd_init,
|
||||||
|
|
||||||
|
.dev_exit = pcan_usb_fd_exit,
|
||||||
|
.dev_free = pcan_usb_fd_free,
|
||||||
|
.dev_set_bus = pcan_usb_fd_set_bus,
|
||||||
|
.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
|
||||||
|
.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
|
||||||
|
.dev_decode_buf = pcan_usb_fd_decode_buf,
|
||||||
|
.dev_start = pcan_usb_fd_start,
|
||||||
|
.dev_stop = pcan_usb_fd_stop,
|
||||||
|
.dev_restart_async = pcan_usb_fd_restart_async,
|
||||||
|
.dev_encode_msg = pcan_usb_fd_encode_msg,
|
||||||
|
|
||||||
|
.do_get_berr_counter = pcan_usb_fd_get_berr_counter,
|
||||||
|
};
|
||||||
|
|
||||||
/* describes the PCAN-USB Pro FD adapter */
|
/* describes the PCAN-USB Pro FD adapter */
|
||||||
static const struct can_bittiming_const pcan_usb_pro_fd_const = {
|
static const struct can_bittiming_const pcan_usb_pro_fd_const = {
|
||||||
.name = "pcan_usb_pro_fd",
|
.name = "pcan_usb_pro_fd",
|
||||||
|
|
|
@ -326,6 +326,7 @@ static void b53_get_vlan_entry(struct b53_device *dev, u16 vid,
|
||||||
|
|
||||||
static void b53_set_forwarding(struct b53_device *dev, int enable)
|
static void b53_set_forwarding(struct b53_device *dev, int enable)
|
||||||
{
|
{
|
||||||
|
struct dsa_switch *ds = dev->ds;
|
||||||
u8 mgmt;
|
u8 mgmt;
|
||||||
|
|
||||||
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
|
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
|
||||||
|
@ -336,6 +337,15 @@ static void b53_set_forwarding(struct b53_device *dev, int enable)
|
||||||
mgmt &= ~SM_SW_FWD_EN;
|
mgmt &= ~SM_SW_FWD_EN;
|
||||||
|
|
||||||
b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
|
b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
|
||||||
|
|
||||||
|
/* Include IMP port in dumb forwarding mode when no tagging protocol is
|
||||||
|
* set
|
||||||
|
*/
|
||||||
|
if (ds->ops->get_tag_protocol(ds) == DSA_TAG_PROTO_NONE) {
|
||||||
|
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt);
|
||||||
|
mgmt |= B53_MII_DUMB_FWDG_EN;
|
||||||
|
b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void b53_enable_vlan(struct b53_device *dev, bool enable)
|
static void b53_enable_vlan(struct b53_device *dev, bool enable)
|
||||||
|
@ -598,7 +608,8 @@ static void b53_switch_reset_gpio(struct b53_device *dev)
|
||||||
|
|
||||||
static int b53_switch_reset(struct b53_device *dev)
|
static int b53_switch_reset(struct b53_device *dev)
|
||||||
{
|
{
|
||||||
u8 mgmt;
|
unsigned int timeout = 1000;
|
||||||
|
u8 mgmt, reg;
|
||||||
|
|
||||||
b53_switch_reset_gpio(dev);
|
b53_switch_reset_gpio(dev);
|
||||||
|
|
||||||
|
@ -607,6 +618,28 @@ static int b53_switch_reset(struct b53_device *dev)
|
||||||
b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00);
|
b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is specific to 58xx devices here, do not use is58xx() which
|
||||||
|
* covers the larger Starfigther 2 family, including 7445/7278 which
|
||||||
|
* still use this driver as a library and need to perform the reset
|
||||||
|
* earlier.
|
||||||
|
*/
|
||||||
|
if (dev->chip_id == BCM58XX_DEVICE_ID) {
|
||||||
|
b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®);
|
||||||
|
reg |= SW_RST | EN_SW_RST | EN_CH_RST;
|
||||||
|
b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, reg);
|
||||||
|
|
||||||
|
do {
|
||||||
|
b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®);
|
||||||
|
if (!(reg & SW_RST))
|
||||||
|
break;
|
||||||
|
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
} while (timeout-- > 0);
|
||||||
|
|
||||||
|
if (timeout == 0)
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
|
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
|
||||||
|
|
||||||
if (!(mgmt & SM_SW_FWD_EN)) {
|
if (!(mgmt & SM_SW_FWD_EN)) {
|
||||||
|
@ -1731,7 +1764,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
|
||||||
.vlans = 4096,
|
.vlans = 4096,
|
||||||
.enabled_ports = 0x1ff,
|
.enabled_ports = 0x1ff,
|
||||||
.arl_entries = 4,
|
.arl_entries = 4,
|
||||||
.cpu_port = B53_CPU_PORT_25,
|
.cpu_port = B53_CPU_PORT,
|
||||||
.vta_regs = B53_VTA_REGS,
|
.vta_regs = B53_VTA_REGS,
|
||||||
.duplex_reg = B53_DUPLEX_STAT_GE,
|
.duplex_reg = B53_DUPLEX_STAT_GE,
|
||||||
.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
|
.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
|
||||||
|
|
|
@ -104,6 +104,10 @@
|
||||||
#define B53_UC_FWD_EN BIT(6)
|
#define B53_UC_FWD_EN BIT(6)
|
||||||
#define B53_MC_FWD_EN BIT(7)
|
#define B53_MC_FWD_EN BIT(7)
|
||||||
|
|
||||||
|
/* Switch control (8 bit) */
|
||||||
|
#define B53_SWITCH_CTRL 0x22
|
||||||
|
#define B53_MII_DUMB_FWDG_EN BIT(6)
|
||||||
|
|
||||||
/* (16 bit) */
|
/* (16 bit) */
|
||||||
#define B53_UC_FLOOD_MASK 0x32
|
#define B53_UC_FLOOD_MASK 0x32
|
||||||
#define B53_MC_FLOOD_MASK 0x34
|
#define B53_MC_FLOOD_MASK 0x34
|
||||||
|
@ -139,6 +143,7 @@
|
||||||
/* Software reset register (8 bit) */
|
/* Software reset register (8 bit) */
|
||||||
#define B53_SOFTRESET 0x79
|
#define B53_SOFTRESET 0x79
|
||||||
#define SW_RST BIT(7)
|
#define SW_RST BIT(7)
|
||||||
|
#define EN_CH_RST BIT(6)
|
||||||
#define EN_SW_RST BIT(4)
|
#define EN_SW_RST BIT(4)
|
||||||
|
|
||||||
/* Fast Aging Control register (8 bit) */
|
/* Fast Aging Control register (8 bit) */
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
#define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) - 1 <= U16_MAX)
|
#define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) - 1 <= U16_MAX)
|
||||||
|
|
||||||
#define MLX5_UMR_ALIGN (2048)
|
#define MLX5_UMR_ALIGN (2048)
|
||||||
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
|
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (256)
|
||||||
|
|
||||||
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
|
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
|
||||||
#define MLX5E_DEFAULT_LRO_TIMEOUT 32
|
#define MLX5E_DEFAULT_LRO_TIMEOUT 32
|
||||||
|
|
|
@ -564,6 +564,7 @@ int mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv, struct ethtool_rxnfc *i
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
info->data = MAX_NUM_OF_ETHTOOL_RULES;
|
||||||
while ((!err || err == -ENOENT) && idx < info->rule_cnt) {
|
while ((!err || err == -ENOENT) && idx < info->rule_cnt) {
|
||||||
err = mlx5e_ethtool_get_flow(priv, info, location);
|
err = mlx5e_ethtool_get_flow(priv, info, location);
|
||||||
if (!err)
|
if (!err)
|
||||||
|
|
|
@ -167,7 +167,7 @@ unlock:
|
||||||
|
|
||||||
static void mlx5e_update_sw_counters(struct mlx5e_priv *priv)
|
static void mlx5e_update_sw_counters(struct mlx5e_priv *priv)
|
||||||
{
|
{
|
||||||
struct mlx5e_sw_stats *s = &priv->stats.sw;
|
struct mlx5e_sw_stats temp, *s = &temp;
|
||||||
struct mlx5e_rq_stats *rq_stats;
|
struct mlx5e_rq_stats *rq_stats;
|
||||||
struct mlx5e_sq_stats *sq_stats;
|
struct mlx5e_sq_stats *sq_stats;
|
||||||
u64 tx_offload_none = 0;
|
u64 tx_offload_none = 0;
|
||||||
|
@ -224,6 +224,7 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv)
|
||||||
s->link_down_events_phy = MLX5_GET(ppcnt_reg,
|
s->link_down_events_phy = MLX5_GET(ppcnt_reg,
|
||||||
priv->stats.pport.phy_counters,
|
priv->stats.pport.phy_counters,
|
||||||
counter_set.phys_layer_cntrs.link_down_events);
|
counter_set.phys_layer_cntrs.link_down_events);
|
||||||
|
memcpy(&priv->stats.sw, s, sizeof(*s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlx5e_update_vport_counters(struct mlx5e_priv *priv)
|
static void mlx5e_update_vport_counters(struct mlx5e_priv *priv)
|
||||||
|
@ -238,7 +239,6 @@ static void mlx5e_update_vport_counters(struct mlx5e_priv *priv)
|
||||||
MLX5_SET(query_vport_counter_in, in, op_mod, 0);
|
MLX5_SET(query_vport_counter_in, in, op_mod, 0);
|
||||||
MLX5_SET(query_vport_counter_in, in, other_vport, 0);
|
MLX5_SET(query_vport_counter_in, in, other_vport, 0);
|
||||||
|
|
||||||
memset(out, 0, outlen);
|
|
||||||
mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
|
mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -710,7 +710,8 @@ static int parse_cls_flower(struct mlx5e_priv *priv,
|
||||||
|
|
||||||
if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH) &&
|
if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH) &&
|
||||||
rep->vport != FDB_UPLINK_VPORT) {
|
rep->vport != FDB_UPLINK_VPORT) {
|
||||||
if (min_inline > esw->offloads.inline_mode) {
|
if (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE &&
|
||||||
|
esw->offloads.inline_mode < min_inline) {
|
||||||
netdev_warn(priv->netdev,
|
netdev_warn(priv->netdev,
|
||||||
"Flow is not offloaded due to min inline setting, required %d actual %d\n",
|
"Flow is not offloaded due to min inline setting, required %d actual %d\n",
|
||||||
min_inline, esw->offloads.inline_mode);
|
min_inline, esw->offloads.inline_mode);
|
||||||
|
@ -1140,8 +1141,8 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gen_vxlan_header_ipv4(struct net_device *out_dev,
|
static void gen_vxlan_header_ipv4(struct net_device *out_dev,
|
||||||
char buf[],
|
char buf[], int encap_size,
|
||||||
unsigned char h_dest[ETH_ALEN],
|
unsigned char h_dest[ETH_ALEN],
|
||||||
int ttl,
|
int ttl,
|
||||||
__be32 daddr,
|
__be32 daddr,
|
||||||
|
@ -1149,7 +1150,6 @@ static int gen_vxlan_header_ipv4(struct net_device *out_dev,
|
||||||
__be16 udp_dst_port,
|
__be16 udp_dst_port,
|
||||||
__be32 vx_vni)
|
__be32 vx_vni)
|
||||||
{
|
{
|
||||||
int encap_size = VXLAN_HLEN + sizeof(struct iphdr) + ETH_HLEN;
|
|
||||||
struct ethhdr *eth = (struct ethhdr *)buf;
|
struct ethhdr *eth = (struct ethhdr *)buf;
|
||||||
struct iphdr *ip = (struct iphdr *)((char *)eth + sizeof(struct ethhdr));
|
struct iphdr *ip = (struct iphdr *)((char *)eth + sizeof(struct ethhdr));
|
||||||
struct udphdr *udp = (struct udphdr *)((char *)ip + sizeof(struct iphdr));
|
struct udphdr *udp = (struct udphdr *)((char *)ip + sizeof(struct iphdr));
|
||||||
|
@ -1172,12 +1172,10 @@ static int gen_vxlan_header_ipv4(struct net_device *out_dev,
|
||||||
udp->dest = udp_dst_port;
|
udp->dest = udp_dst_port;
|
||||||
vxh->vx_flags = VXLAN_HF_VNI;
|
vxh->vx_flags = VXLAN_HF_VNI;
|
||||||
vxh->vx_vni = vxlan_vni_field(vx_vni);
|
vxh->vx_vni = vxlan_vni_field(vx_vni);
|
||||||
|
|
||||||
return encap_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gen_vxlan_header_ipv6(struct net_device *out_dev,
|
static void gen_vxlan_header_ipv6(struct net_device *out_dev,
|
||||||
char buf[],
|
char buf[], int encap_size,
|
||||||
unsigned char h_dest[ETH_ALEN],
|
unsigned char h_dest[ETH_ALEN],
|
||||||
int ttl,
|
int ttl,
|
||||||
struct in6_addr *daddr,
|
struct in6_addr *daddr,
|
||||||
|
@ -1185,7 +1183,6 @@ static int gen_vxlan_header_ipv6(struct net_device *out_dev,
|
||||||
__be16 udp_dst_port,
|
__be16 udp_dst_port,
|
||||||
__be32 vx_vni)
|
__be32 vx_vni)
|
||||||
{
|
{
|
||||||
int encap_size = VXLAN_HLEN + sizeof(struct ipv6hdr) + ETH_HLEN;
|
|
||||||
struct ethhdr *eth = (struct ethhdr *)buf;
|
struct ethhdr *eth = (struct ethhdr *)buf;
|
||||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)((char *)eth + sizeof(struct ethhdr));
|
struct ipv6hdr *ip6h = (struct ipv6hdr *)((char *)eth + sizeof(struct ethhdr));
|
||||||
struct udphdr *udp = (struct udphdr *)((char *)ip6h + sizeof(struct ipv6hdr));
|
struct udphdr *udp = (struct udphdr *)((char *)ip6h + sizeof(struct ipv6hdr));
|
||||||
|
@ -1207,8 +1204,6 @@ static int gen_vxlan_header_ipv6(struct net_device *out_dev,
|
||||||
udp->dest = udp_dst_port;
|
udp->dest = udp_dst_port;
|
||||||
vxh->vx_flags = VXLAN_HF_VNI;
|
vxh->vx_flags = VXLAN_HF_VNI;
|
||||||
vxh->vx_vni = vxlan_vni_field(vx_vni);
|
vxh->vx_vni = vxlan_vni_field(vx_vni);
|
||||||
|
|
||||||
return encap_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
|
static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
|
||||||
|
@ -1217,13 +1212,20 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
|
||||||
struct net_device **out_dev)
|
struct net_device **out_dev)
|
||||||
{
|
{
|
||||||
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
|
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
|
||||||
|
int ipv4_encap_size = ETH_HLEN + sizeof(struct iphdr) + VXLAN_HLEN;
|
||||||
struct ip_tunnel_key *tun_key = &e->tun_info.key;
|
struct ip_tunnel_key *tun_key = &e->tun_info.key;
|
||||||
int encap_size, ttl, err;
|
|
||||||
struct neighbour *n = NULL;
|
struct neighbour *n = NULL;
|
||||||
struct flowi4 fl4 = {};
|
struct flowi4 fl4 = {};
|
||||||
char *encap_header;
|
char *encap_header;
|
||||||
|
int ttl, err;
|
||||||
|
|
||||||
encap_header = kzalloc(max_encap_size, GFP_KERNEL);
|
if (max_encap_size < ipv4_encap_size) {
|
||||||
|
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
|
||||||
|
ipv4_encap_size, max_encap_size);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
encap_header = kzalloc(ipv4_encap_size, GFP_KERNEL);
|
||||||
if (!encap_header)
|
if (!encap_header)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1258,8 +1260,8 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
|
||||||
|
|
||||||
switch (e->tunnel_type) {
|
switch (e->tunnel_type) {
|
||||||
case MLX5_HEADER_TYPE_VXLAN:
|
case MLX5_HEADER_TYPE_VXLAN:
|
||||||
encap_size = gen_vxlan_header_ipv4(*out_dev, encap_header,
|
gen_vxlan_header_ipv4(*out_dev, encap_header,
|
||||||
e->h_dest, ttl,
|
ipv4_encap_size, e->h_dest, ttl,
|
||||||
fl4.daddr,
|
fl4.daddr,
|
||||||
fl4.saddr, tun_key->tp_dst,
|
fl4.saddr, tun_key->tp_dst,
|
||||||
tunnel_id_to_key32(tun_key->tun_id));
|
tunnel_id_to_key32(tun_key->tun_id));
|
||||||
|
@ -1270,7 +1272,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
|
err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
|
||||||
encap_size, encap_header, &e->encap_id);
|
ipv4_encap_size, encap_header, &e->encap_id);
|
||||||
out:
|
out:
|
||||||
if (err && n)
|
if (err && n)
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
|
@ -1285,13 +1287,20 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
|
||||||
|
|
||||||
{
|
{
|
||||||
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
|
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
|
||||||
|
int ipv6_encap_size = ETH_HLEN + sizeof(struct ipv6hdr) + VXLAN_HLEN;
|
||||||
struct ip_tunnel_key *tun_key = &e->tun_info.key;
|
struct ip_tunnel_key *tun_key = &e->tun_info.key;
|
||||||
int encap_size, err, ttl = 0;
|
|
||||||
struct neighbour *n = NULL;
|
struct neighbour *n = NULL;
|
||||||
struct flowi6 fl6 = {};
|
struct flowi6 fl6 = {};
|
||||||
char *encap_header;
|
char *encap_header;
|
||||||
|
int err, ttl = 0;
|
||||||
|
|
||||||
encap_header = kzalloc(max_encap_size, GFP_KERNEL);
|
if (max_encap_size < ipv6_encap_size) {
|
||||||
|
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
|
||||||
|
ipv6_encap_size, max_encap_size);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
encap_header = kzalloc(ipv6_encap_size, GFP_KERNEL);
|
||||||
if (!encap_header)
|
if (!encap_header)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1327,8 +1336,8 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
|
||||||
|
|
||||||
switch (e->tunnel_type) {
|
switch (e->tunnel_type) {
|
||||||
case MLX5_HEADER_TYPE_VXLAN:
|
case MLX5_HEADER_TYPE_VXLAN:
|
||||||
encap_size = gen_vxlan_header_ipv6(*out_dev, encap_header,
|
gen_vxlan_header_ipv6(*out_dev, encap_header,
|
||||||
e->h_dest, ttl,
|
ipv6_encap_size, e->h_dest, ttl,
|
||||||
&fl6.daddr,
|
&fl6.daddr,
|
||||||
&fl6.saddr, tun_key->tp_dst,
|
&fl6.saddr, tun_key->tp_dst,
|
||||||
tunnel_id_to_key32(tun_key->tun_id));
|
tunnel_id_to_key32(tun_key->tun_id));
|
||||||
|
@ -1339,7 +1348,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
|
err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
|
||||||
encap_size, encap_header, &e->encap_id);
|
ipv6_encap_size, encap_header, &e->encap_id);
|
||||||
out:
|
out:
|
||||||
if (err && n)
|
if (err && n)
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
|
|
|
@ -955,8 +955,7 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
|
||||||
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
||||||
struct mlx5_eswitch *esw = dev->priv.eswitch;
|
struct mlx5_eswitch *esw = dev->priv.eswitch;
|
||||||
int num_vports = esw->enabled_vports;
|
int num_vports = esw->enabled_vports;
|
||||||
int err;
|
int err, vport;
|
||||||
int vport;
|
|
||||||
u8 mlx5_mode;
|
u8 mlx5_mode;
|
||||||
|
|
||||||
if (!MLX5_CAP_GEN(dev, vport_group_manager))
|
if (!MLX5_CAP_GEN(dev, vport_group_manager))
|
||||||
|
@ -965,9 +964,17 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
|
||||||
if (esw->mode == SRIOV_NONE)
|
if (esw->mode == SRIOV_NONE)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (MLX5_CAP_ETH(dev, wqe_inline_mode) !=
|
switch (MLX5_CAP_ETH(dev, wqe_inline_mode)) {
|
||||||
MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
|
case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
|
||||||
|
if (mode == DEVLINK_ESWITCH_INLINE_MODE_NONE)
|
||||||
|
return 0;
|
||||||
|
/* fall through */
|
||||||
|
case MLX5_CAP_INLINE_MODE_L2:
|
||||||
|
esw_warn(dev, "Inline mode can't be set\n");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (esw->offloads.num_flows > 0) {
|
if (esw->offloads.num_flows > 0) {
|
||||||
esw_warn(dev, "Can't set inline mode when flows are configured\n");
|
esw_warn(dev, "Can't set inline mode when flows are configured\n");
|
||||||
|
@ -1010,18 +1017,14 @@ int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode)
|
||||||
if (esw->mode == SRIOV_NONE)
|
if (esw->mode == SRIOV_NONE)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (MLX5_CAP_ETH(dev, wqe_inline_mode) !=
|
|
||||||
MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
return esw_inline_mode_to_devlink(esw->offloads.inline_mode, mode);
|
return esw_inline_mode_to_devlink(esw->offloads.inline_mode, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode)
|
int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode)
|
||||||
{
|
{
|
||||||
|
u8 prev_mlx5_mode, mlx5_mode = MLX5_INLINE_MODE_L2;
|
||||||
struct mlx5_core_dev *dev = esw->dev;
|
struct mlx5_core_dev *dev = esw->dev;
|
||||||
int vport;
|
int vport;
|
||||||
u8 prev_mlx5_mode, mlx5_mode = MLX5_INLINE_MODE_L2;
|
|
||||||
|
|
||||||
if (!MLX5_CAP_GEN(dev, vport_group_manager))
|
if (!MLX5_CAP_GEN(dev, vport_group_manager))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
@ -1029,10 +1032,18 @@ int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode)
|
||||||
if (esw->mode == SRIOV_NONE)
|
if (esw->mode == SRIOV_NONE)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (MLX5_CAP_ETH(dev, wqe_inline_mode) !=
|
switch (MLX5_CAP_ETH(dev, wqe_inline_mode)) {
|
||||||
MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
|
case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
|
||||||
return -EOPNOTSUPP;
|
mlx5_mode = MLX5_INLINE_MODE_NONE;
|
||||||
|
goto out;
|
||||||
|
case MLX5_CAP_INLINE_MODE_L2:
|
||||||
|
mlx5_mode = MLX5_INLINE_MODE_L2;
|
||||||
|
goto out;
|
||||||
|
case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
|
||||||
|
goto query_vports;
|
||||||
|
}
|
||||||
|
|
||||||
|
query_vports:
|
||||||
for (vport = 1; vport <= nvfs; vport++) {
|
for (vport = 1; vport <= nvfs; vport++) {
|
||||||
mlx5_query_nic_vport_min_inline(dev, vport, &mlx5_mode);
|
mlx5_query_nic_vport_min_inline(dev, vport, &mlx5_mode);
|
||||||
if (vport > 1 && prev_mlx5_mode != mlx5_mode)
|
if (vport > 1 && prev_mlx5_mode != mlx5_mode)
|
||||||
|
@ -1040,6 +1051,7 @@ int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode)
|
||||||
prev_mlx5_mode = mlx5_mode;
|
prev_mlx5_mode = mlx5_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
*mode = mlx5_mode;
|
*mode = mlx5_mode;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1029,7 +1029,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n",
|
dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n",
|
||||||
FW_INIT_TIMEOUT_MILI);
|
FW_INIT_TIMEOUT_MILI);
|
||||||
goto out_err;
|
goto err_cmd_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx5_core_enable_hca(dev, 0);
|
err = mlx5_core_enable_hca(dev, 0);
|
||||||
|
|
|
@ -87,6 +87,7 @@ static void up_rel_func(struct kref *kref)
|
||||||
struct mlx5_uars_page *up = container_of(kref, struct mlx5_uars_page, ref_count);
|
struct mlx5_uars_page *up = container_of(kref, struct mlx5_uars_page, ref_count);
|
||||||
|
|
||||||
list_del(&up->list);
|
list_del(&up->list);
|
||||||
|
iounmap(up->map);
|
||||||
if (mlx5_cmd_free_uar(up->mdev, up->index))
|
if (mlx5_cmd_free_uar(up->mdev, up->index))
|
||||||
mlx5_core_warn(up->mdev, "failed to free uar index %d\n", up->index);
|
mlx5_core_warn(up->mdev, "failed to free uar index %d\n", up->index);
|
||||||
kfree(up->reg_bitmap);
|
kfree(up->reg_bitmap);
|
||||||
|
|
|
@ -64,11 +64,11 @@
|
||||||
((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
|
((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
|
||||||
|
|
||||||
static const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = {
|
static const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = {
|
||||||
{DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_DEFAULT},
|
{DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_ISCSI},
|
||||||
{DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_DEFAULT},
|
{DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_FCOE},
|
||||||
{DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_DEFAULT},
|
{DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_ETH_ROCE},
|
||||||
{DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_DEFAULT},
|
{DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_ETH_ROCE},
|
||||||
{DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH}
|
{DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool qed_dcbx_app_ethtype(u32 app_info_bitmap)
|
static bool qed_dcbx_app_ethtype(u32 app_info_bitmap)
|
||||||
|
|
|
@ -1516,11 +1516,12 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
entry = priv->cur_tx[q] % (priv->num_tx_ring[q] * NUM_TX_DESC);
|
|
||||||
priv->tx_skb[q][entry / NUM_TX_DESC] = skb;
|
|
||||||
|
|
||||||
if (skb_put_padto(skb, ETH_ZLEN))
|
if (skb_put_padto(skb, ETH_ZLEN))
|
||||||
goto drop;
|
goto exit;
|
||||||
|
|
||||||
|
entry = priv->cur_tx[q] % (priv->num_tx_ring[q] * NUM_TX_DESC);
|
||||||
|
priv->tx_skb[q][entry / NUM_TX_DESC] = skb;
|
||||||
|
|
||||||
buffer = PTR_ALIGN(priv->tx_align[q], DPTR_ALIGN) +
|
buffer = PTR_ALIGN(priv->tx_align[q], DPTR_ALIGN) +
|
||||||
entry / NUM_TX_DESC * DPTR_ALIGN;
|
entry / NUM_TX_DESC * DPTR_ALIGN;
|
||||||
|
|
|
@ -74,7 +74,10 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
|
||||||
#define EFX_RXQ_MIN_ENT 128U
|
#define EFX_RXQ_MIN_ENT 128U
|
||||||
#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))
|
#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))
|
||||||
|
|
||||||
#define EFX_TXQ_MAX_ENT(efx) (EFX_WORKAROUND_35388(efx) ? \
|
/* All EF10 architecture NICs steal one bit of the DMAQ size for various
|
||||||
|
* other purposes when counting TxQ entries, so we halve the queue size.
|
||||||
|
*/
|
||||||
|
#define EFX_TXQ_MAX_ENT(efx) (EFX_WORKAROUND_EF10(efx) ? \
|
||||||
EFX_MAX_DMAQ_SIZE / 2 : EFX_MAX_DMAQ_SIZE)
|
EFX_MAX_DMAQ_SIZE / 2 : EFX_MAX_DMAQ_SIZE)
|
||||||
|
|
||||||
static inline bool efx_rss_enabled(struct efx_nic *efx)
|
static inline bool efx_rss_enabled(struct efx_nic *efx)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0)
|
#define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0)
|
||||||
|
#define EFX_WORKAROUND_EF10(efx) (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
|
||||||
#define EFX_WORKAROUND_10G(efx) 1
|
#define EFX_WORKAROUND_10G(efx) 1
|
||||||
|
|
||||||
/* Bit-bashed I2C reads cause performance drop */
|
/* Bit-bashed I2C reads cause performance drop */
|
||||||
|
|
|
@ -1017,8 +1017,8 @@ tc35815_free_queues(struct net_device *dev)
|
||||||
BUG_ON(lp->tx_skbs[i].skb != skb);
|
BUG_ON(lp->tx_skbs[i].skb != skb);
|
||||||
#endif
|
#endif
|
||||||
if (skb) {
|
if (skb) {
|
||||||
dev_kfree_skb(skb);
|
|
||||||
pci_unmap_single(lp->pci_dev, lp->tx_skbs[i].skb_dma, skb->len, PCI_DMA_TODEVICE);
|
pci_unmap_single(lp->pci_dev, lp->tx_skbs[i].skb_dma, skb->len, PCI_DMA_TODEVICE);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
lp->tx_skbs[i].skb = NULL;
|
lp->tx_skbs[i].skb = NULL;
|
||||||
lp->tx_skbs[i].skb_dma = 0;
|
lp->tx_skbs[i].skb_dma = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,7 +751,6 @@ struct netvsc_device {
|
||||||
u32 send_section_cnt;
|
u32 send_section_cnt;
|
||||||
u32 send_section_size;
|
u32 send_section_size;
|
||||||
unsigned long *send_section_map;
|
unsigned long *send_section_map;
|
||||||
int map_words;
|
|
||||||
|
|
||||||
/* Used for NetVSP initialization protocol */
|
/* Used for NetVSP initialization protocol */
|
||||||
struct completion channel_init_wait;
|
struct completion channel_init_wait;
|
||||||
|
|
|
@ -249,6 +249,7 @@ static int netvsc_init_buf(struct hv_device *device)
|
||||||
struct netvsc_device *net_device;
|
struct netvsc_device *net_device;
|
||||||
struct nvsp_message *init_packet;
|
struct nvsp_message *init_packet;
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
|
size_t map_words;
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
net_device = get_outbound_net_device(device);
|
net_device = get_outbound_net_device(device);
|
||||||
|
@ -414,11 +415,9 @@ static int netvsc_init_buf(struct hv_device *device)
|
||||||
net_device->send_section_size, net_device->send_section_cnt);
|
net_device->send_section_size, net_device->send_section_cnt);
|
||||||
|
|
||||||
/* Setup state for managing the send buffer. */
|
/* Setup state for managing the send buffer. */
|
||||||
net_device->map_words = DIV_ROUND_UP(net_device->send_section_cnt,
|
map_words = DIV_ROUND_UP(net_device->send_section_cnt, BITS_PER_LONG);
|
||||||
BITS_PER_LONG);
|
|
||||||
|
|
||||||
net_device->send_section_map = kcalloc(net_device->map_words,
|
net_device->send_section_map = kcalloc(map_words, sizeof(ulong), GFP_KERNEL);
|
||||||
sizeof(ulong), GFP_KERNEL);
|
|
||||||
if (net_device->send_section_map == NULL) {
|
if (net_device->send_section_map == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -698,7 +697,7 @@ static u32 netvsc_get_next_send_section(struct netvsc_device *net_device)
|
||||||
unsigned long *map_addr = net_device->send_section_map;
|
unsigned long *map_addr = net_device->send_section_map;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for_each_clear_bit(i, map_addr, net_device->map_words) {
|
for_each_clear_bit(i, map_addr, net_device->send_section_cnt) {
|
||||||
if (sync_test_and_set_bit(i, map_addr) == 0)
|
if (sync_test_and_set_bit(i, map_addr) == 0)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,7 +617,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
|
||||||
|
|
||||||
static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
|
static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
|
||||||
unsigned char **iv,
|
unsigned char **iv,
|
||||||
struct scatterlist **sg)
|
struct scatterlist **sg,
|
||||||
|
int num_frags)
|
||||||
{
|
{
|
||||||
size_t size, iv_offset, sg_offset;
|
size_t size, iv_offset, sg_offset;
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
|
@ -629,7 +630,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
|
||||||
|
|
||||||
size = ALIGN(size, __alignof__(struct scatterlist));
|
size = ALIGN(size, __alignof__(struct scatterlist));
|
||||||
sg_offset = size;
|
sg_offset = size;
|
||||||
size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1);
|
size += sizeof(struct scatterlist) * num_frags;
|
||||||
|
|
||||||
tmp = kmalloc(size, GFP_ATOMIC);
|
tmp = kmalloc(size, GFP_ATOMIC);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
|
@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
struct sk_buff *trailer;
|
||||||
unsigned char *iv;
|
unsigned char *iv;
|
||||||
struct ethhdr *eth;
|
struct ethhdr *eth;
|
||||||
struct macsec_eth_header *hh;
|
struct macsec_eth_header *hh;
|
||||||
|
@ -723,7 +725,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg);
|
ret = skb_cow_data(skb, 0, &trailer);
|
||||||
|
if (unlikely(ret < 0)) {
|
||||||
|
macsec_txsa_put(tx_sa);
|
||||||
|
kfree_skb(skb);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg, ret);
|
||||||
if (!req) {
|
if (!req) {
|
||||||
macsec_txsa_put(tx_sa);
|
macsec_txsa_put(tx_sa);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
|
||||||
|
|
||||||
macsec_fill_iv(iv, secy->sci, pn);
|
macsec_fill_iv(iv, secy->sci, pn);
|
||||||
|
|
||||||
sg_init_table(sg, MAX_SKB_FRAGS + 1);
|
sg_init_table(sg, ret);
|
||||||
skb_to_sgvec(skb, sg, 0, skb->len);
|
skb_to_sgvec(skb, sg, 0, skb->len);
|
||||||
|
|
||||||
if (tx_sc->encrypt) {
|
if (tx_sc->encrypt) {
|
||||||
|
@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
struct sk_buff *trailer;
|
||||||
unsigned char *iv;
|
unsigned char *iv;
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
struct macsec_eth_header *hdr;
|
struct macsec_eth_header *hdr;
|
||||||
|
@ -927,7 +937,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg);
|
ret = skb_cow_data(skb, 0, &trailer);
|
||||||
|
if (unlikely(ret < 0)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg, ret);
|
||||||
if (!req) {
|
if (!req) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
@ -936,7 +951,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
|
||||||
hdr = (struct macsec_eth_header *)skb->data;
|
hdr = (struct macsec_eth_header *)skb->data;
|
||||||
macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
|
macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
|
||||||
|
|
||||||
sg_init_table(sg, MAX_SKB_FRAGS + 1);
|
sg_init_table(sg, ret);
|
||||||
skb_to_sgvec(skb, sg, 0, skb->len);
|
skb_to_sgvec(skb, sg, 0, skb->len);
|
||||||
|
|
||||||
if (hdr->tci_an & MACSEC_TCI_E) {
|
if (hdr->tci_an & MACSEC_TCI_E) {
|
||||||
|
|
|
@ -1139,6 +1139,7 @@ static int macvlan_port_create(struct net_device *dev)
|
||||||
static void macvlan_port_destroy(struct net_device *dev)
|
static void macvlan_port_destroy(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
|
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
dev->priv_flags &= ~IFF_MACVLAN_PORT;
|
dev->priv_flags &= ~IFF_MACVLAN_PORT;
|
||||||
netdev_rx_handler_unregister(dev);
|
netdev_rx_handler_unregister(dev);
|
||||||
|
@ -1147,7 +1148,15 @@ static void macvlan_port_destroy(struct net_device *dev)
|
||||||
* but we need to cancel it and purge left skbs if any.
|
* but we need to cancel it and purge left skbs if any.
|
||||||
*/
|
*/
|
||||||
cancel_work_sync(&port->bc_work);
|
cancel_work_sync(&port->bc_work);
|
||||||
__skb_queue_purge(&port->bc_queue);
|
|
||||||
|
while ((skb = __skb_dequeue(&port->bc_queue))) {
|
||||||
|
const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
|
||||||
|
|
||||||
|
if (src)
|
||||||
|
dev_put(src->dev);
|
||||||
|
|
||||||
|
kfree_skb(skb);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(port);
|
kfree(port);
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,17 +297,6 @@ static int kszphy_config_init(struct phy_device *phydev)
|
||||||
if (priv->led_mode >= 0)
|
if (priv->led_mode >= 0)
|
||||||
kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
|
kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
|
||||||
|
|
||||||
if (phy_interrupt_is_valid(phydev)) {
|
|
||||||
int ctl = phy_read(phydev, MII_BMCR);
|
|
||||||
|
|
||||||
if (ctl < 0)
|
|
||||||
return ctl;
|
|
||||||
|
|
||||||
ret = phy_write(phydev, MII_BMCR, ctl & ~BMCR_ANENABLE);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -622,16 +622,18 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
|
||||||
EXPORT_SYMBOL(phy_mii_ioctl);
|
EXPORT_SYMBOL(phy_mii_ioctl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_start_aneg - start auto-negotiation for this PHY device
|
* phy_start_aneg_priv - start auto-negotiation for this PHY device
|
||||||
* @phydev: the phy_device struct
|
* @phydev: the phy_device struct
|
||||||
|
* @sync: indicate whether we should wait for the workqueue cancelation
|
||||||
*
|
*
|
||||||
* Description: Sanitizes the settings (if we're not autonegotiating
|
* Description: Sanitizes the settings (if we're not autonegotiating
|
||||||
* them), and then calls the driver's config_aneg function.
|
* them), and then calls the driver's config_aneg function.
|
||||||
* If the PHYCONTROL Layer is operating, we change the state to
|
* If the PHYCONTROL Layer is operating, we change the state to
|
||||||
* reflect the beginning of Auto-negotiation or forcing.
|
* reflect the beginning of Auto-negotiation or forcing.
|
||||||
*/
|
*/
|
||||||
int phy_start_aneg(struct phy_device *phydev)
|
static int phy_start_aneg_priv(struct phy_device *phydev, bool sync)
|
||||||
{
|
{
|
||||||
|
bool trigger = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!phydev->drv)
|
if (!phydev->drv)
|
||||||
|
@ -659,10 +661,40 @@ int phy_start_aneg(struct phy_device *phydev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Re-schedule a PHY state machine to check PHY status because
|
||||||
|
* negotiation may already be done and aneg interrupt may not be
|
||||||
|
* generated.
|
||||||
|
*/
|
||||||
|
if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) {
|
||||||
|
err = phy_aneg_done(phydev);
|
||||||
|
if (err > 0) {
|
||||||
|
trigger = true;
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&phydev->lock);
|
mutex_unlock(&phydev->lock);
|
||||||
|
|
||||||
|
if (trigger)
|
||||||
|
phy_trigger_machine(phydev, sync);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_start_aneg - start auto-negotiation for this PHY device
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
*
|
||||||
|
* Description: Sanitizes the settings (if we're not autonegotiating
|
||||||
|
* them), and then calls the driver's config_aneg function.
|
||||||
|
* If the PHYCONTROL Layer is operating, we change the state to
|
||||||
|
* reflect the beginning of Auto-negotiation or forcing.
|
||||||
|
*/
|
||||||
|
int phy_start_aneg(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return phy_start_aneg_priv(phydev, true);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(phy_start_aneg);
|
EXPORT_SYMBOL(phy_start_aneg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -690,7 +722,7 @@ void phy_start_machine(struct phy_device *phydev)
|
||||||
* state machine runs.
|
* state machine runs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void phy_trigger_machine(struct phy_device *phydev, bool sync)
|
void phy_trigger_machine(struct phy_device *phydev, bool sync)
|
||||||
{
|
{
|
||||||
if (sync)
|
if (sync)
|
||||||
cancel_delayed_work_sync(&phydev->state_queue);
|
cancel_delayed_work_sync(&phydev->state_queue);
|
||||||
|
@ -1185,7 +1217,7 @@ void phy_state_machine(struct work_struct *work)
|
||||||
mutex_unlock(&phydev->lock);
|
mutex_unlock(&phydev->lock);
|
||||||
|
|
||||||
if (needs_aneg)
|
if (needs_aneg)
|
||||||
err = phy_start_aneg(phydev);
|
err = phy_start_aneg_priv(phydev, false);
|
||||||
else if (do_suspend)
|
else if (do_suspend)
|
||||||
phy_suspend(phydev);
|
phy_suspend(phydev);
|
||||||
|
|
||||||
|
|
|
@ -2361,8 +2361,10 @@ start_again:
|
||||||
|
|
||||||
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
|
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
|
||||||
TEAM_CMD_OPTIONS_GET);
|
TEAM_CMD_OPTIONS_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(skb);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
|
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
@ -2635,8 +2637,10 @@ start_again:
|
||||||
|
|
||||||
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
|
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
|
||||||
TEAM_CMD_PORT_LIST_GET);
|
TEAM_CMD_PORT_LIST_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(skb);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
|
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
|
@ -369,7 +369,7 @@ config USB_NET_NET1080
|
||||||
optionally with LEDs that indicate traffic
|
optionally with LEDs that indicate traffic
|
||||||
|
|
||||||
config USB_NET_PLUSB
|
config USB_NET_PLUSB
|
||||||
tristate "Prolific PL-2301/2302/25A1 based cables"
|
tristate "Prolific PL-2301/2302/25A1/27A1 based cables"
|
||||||
# if the handshake/init/reset problems, from original 'plusb',
|
# if the handshake/init/reset problems, from original 'plusb',
|
||||||
# are ever resolved ... then remove "experimental"
|
# are ever resolved ... then remove "experimental"
|
||||||
depends on USB_USBNET
|
depends on USB_USBNET
|
||||||
|
|
|
@ -3279,9 +3279,9 @@ static void __exit hso_exit(void)
|
||||||
pr_info("unloaded\n");
|
pr_info("unloaded\n");
|
||||||
|
|
||||||
tty_unregister_driver(tty_drv);
|
tty_unregister_driver(tty_drv);
|
||||||
put_tty_driver(tty_drv);
|
|
||||||
/* deregister the usb driver */
|
/* deregister the usb driver */
|
||||||
usb_deregister(&hso_driver);
|
usb_deregister(&hso_driver);
|
||||||
|
put_tty_driver(tty_drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Module definitions */
|
/* Module definitions */
|
||||||
|
|
|
@ -102,7 +102,7 @@ static int pl_reset(struct usbnet *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct driver_info prolific_info = {
|
static const struct driver_info prolific_info = {
|
||||||
.description = "Prolific PL-2301/PL-2302/PL-25A1",
|
.description = "Prolific PL-2301/PL-2302/PL-25A1/PL-27A1",
|
||||||
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
|
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
|
||||||
/* some PL-2302 versions seem to fail usb_set_interface() */
|
/* some PL-2302 versions seem to fail usb_set_interface() */
|
||||||
.reset = pl_reset,
|
.reset = pl_reset,
|
||||||
|
@ -139,6 +139,17 @@ static const struct usb_device_id products [] = {
|
||||||
* Host-to-Host Cable
|
* Host-to-Host Cable
|
||||||
*/
|
*/
|
||||||
.driver_info = (unsigned long) &prolific_info,
|
.driver_info = (unsigned long) &prolific_info,
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/* super speed cables */
|
||||||
|
{
|
||||||
|
USB_DEVICE(0x067b, 0x27a1), /* PL-27A1, no eeprom
|
||||||
|
* also: goobay Active USB 3.0
|
||||||
|
* Data Link,
|
||||||
|
* Unitek Y-3501
|
||||||
|
*/
|
||||||
|
.driver_info = (unsigned long) &prolific_info,
|
||||||
},
|
},
|
||||||
|
|
||||||
{ }, // END
|
{ }, // END
|
||||||
|
@ -158,5 +169,5 @@ static struct usb_driver plusb_driver = {
|
||||||
module_usb_driver(plusb_driver);
|
module_usb_driver(plusb_driver);
|
||||||
|
|
||||||
MODULE_AUTHOR("David Brownell");
|
MODULE_AUTHOR("David Brownell");
|
||||||
MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver");
|
MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1/27A1 USB Host to Host Link Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -1061,10 +1061,10 @@ int scsi_init_io(struct scsi_cmnd *cmd)
|
||||||
struct scsi_device *sdev = cmd->device;
|
struct scsi_device *sdev = cmd->device;
|
||||||
struct request *rq = cmd->request;
|
struct request *rq = cmd->request;
|
||||||
bool is_mq = (rq->mq_ctx != NULL);
|
bool is_mq = (rq->mq_ctx != NULL);
|
||||||
int error;
|
int error = BLKPREP_KILL;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(!blk_rq_nr_phys_segments(rq)))
|
if (WARN_ON_ONCE(!blk_rq_nr_phys_segments(rq)))
|
||||||
return -EINVAL;
|
goto err_exit;
|
||||||
|
|
||||||
error = scsi_init_sgtable(rq, &cmd->sdb);
|
error = scsi_init_sgtable(rq, &cmd->sdb);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
11
fs/stat.c
11
fs/stat.c
|
@ -547,13 +547,13 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
|
||||||
/**
|
/**
|
||||||
* sys_statx - System call to get enhanced stats
|
* sys_statx - System call to get enhanced stats
|
||||||
* @dfd: Base directory to pathwalk from *or* fd to stat.
|
* @dfd: Base directory to pathwalk from *or* fd to stat.
|
||||||
* @filename: File to stat *or* NULL.
|
* @filename: File to stat or "" with AT_EMPTY_PATH
|
||||||
* @flags: AT_* flags to control pathwalk.
|
* @flags: AT_* flags to control pathwalk.
|
||||||
* @mask: Parts of statx struct actually required.
|
* @mask: Parts of statx struct actually required.
|
||||||
* @buffer: Result buffer.
|
* @buffer: Result buffer.
|
||||||
*
|
*
|
||||||
* Note that if filename is NULL, then it does the equivalent of fstat() using
|
* Note that fstat() can be emulated by setting dfd to the fd of interest,
|
||||||
* dfd to indicate the file of interest.
|
* supplying "" as the filename and setting AT_EMPTY_PATH in the flags.
|
||||||
*/
|
*/
|
||||||
SYSCALL_DEFINE5(statx,
|
SYSCALL_DEFINE5(statx,
|
||||||
int, dfd, const char __user *, filename, unsigned, flags,
|
int, dfd, const char __user *, filename, unsigned, flags,
|
||||||
|
@ -567,11 +567,10 @@ SYSCALL_DEFINE5(statx,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
|
if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (!filename)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (filename)
|
|
||||||
error = vfs_statx(dfd, filename, flags, &stat, mask);
|
error = vfs_statx(dfd, filename, flags, &stat, mask);
|
||||||
else
|
|
||||||
error = vfs_statx_fd(dfd, &stat, mask, flags);
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
#include "ubifs.h"
|
#include "ubifs.h"
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(dbg_lock);
|
static DEFINE_SPINLOCK(dbg_lock);
|
||||||
|
@ -286,8 +287,10 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_err("\t%d: %s (%s)\n",
|
pr_err("\t%d: inode %llu, type %s, len %d\n",
|
||||||
count++, dent->name, get_dent_type(dent->type));
|
count++, (unsigned long long) le64_to_cpu(dent->inum),
|
||||||
|
get_dent_type(dent->type),
|
||||||
|
le16_to_cpu(dent->nlen));
|
||||||
|
|
||||||
fname_name(&nm) = dent->name;
|
fname_name(&nm) = dent->name;
|
||||||
fname_len(&nm) = le16_to_cpu(dent->nlen);
|
fname_len(&nm) = le16_to_cpu(dent->nlen);
|
||||||
|
@ -464,7 +467,8 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
|
||||||
pr_err("(bad name length, not printing, bad or corrupted node)");
|
pr_err("(bad name length, not printing, bad or corrupted node)");
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < nlen && dent->name[i]; i++)
|
for (i = 0; i < nlen && dent->name[i]; i++)
|
||||||
pr_cont("%c", dent->name[i]);
|
pr_cont("%c", isprint(dent->name[i]) ?
|
||||||
|
dent->name[i] : '?');
|
||||||
}
|
}
|
||||||
pr_cont("\n");
|
pr_cont("\n");
|
||||||
|
|
||||||
|
|
|
@ -606,8 +606,8 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
dbg_gen("feed '%s', ino %llu, new f_pos %#x",
|
dbg_gen("ino %llu, new f_pos %#x",
|
||||||
dent->name, (unsigned long long)le64_to_cpu(dent->inum),
|
(unsigned long long)le64_to_cpu(dent->inum),
|
||||||
key_hash_flash(c, &dent->key));
|
key_hash_flash(c, &dent->key));
|
||||||
ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
|
ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
|
||||||
ubifs_inode(dir)->creat_sqnum);
|
ubifs_inode(dir)->creat_sqnum);
|
||||||
|
@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
goto out_fname;
|
goto out_fname;
|
||||||
|
|
||||||
lock_2_inodes(dir, inode);
|
lock_2_inodes(dir, inode);
|
||||||
|
|
||||||
|
/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
|
||||||
|
if (inode->i_nlink == 0)
|
||||||
|
ubifs_delete_orphan(c, inode->i_ino);
|
||||||
|
|
||||||
inc_nlink(inode);
|
inc_nlink(inode);
|
||||||
ihold(inode);
|
ihold(inode);
|
||||||
inode->i_ctime = ubifs_current_time(inode);
|
inode->i_ctime = ubifs_current_time(inode);
|
||||||
|
@ -768,6 +773,8 @@ out_cancel:
|
||||||
dir->i_size -= sz_change;
|
dir->i_size -= sz_change;
|
||||||
dir_ui->ui_size = dir->i_size;
|
dir_ui->ui_size = dir->i_size;
|
||||||
drop_nlink(inode);
|
drop_nlink(inode);
|
||||||
|
if (inode->i_nlink == 0)
|
||||||
|
ubifs_add_orphan(c, inode->i_ino);
|
||||||
unlock_2_inodes(dir, inode);
|
unlock_2_inodes(dir, inode);
|
||||||
ubifs_release_budget(c, &req);
|
ubifs_release_budget(c, &req);
|
||||||
iput(inode);
|
iput(inode);
|
||||||
|
@ -1068,8 +1075,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
|
err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
|
||||||
if (err)
|
if (err) {
|
||||||
|
kfree(dev);
|
||||||
goto out_budg;
|
goto out_budg;
|
||||||
|
}
|
||||||
|
|
||||||
sz_change = CALC_DENT_SIZE(fname_len(&nm));
|
sz_change = CALC_DENT_SIZE(fname_len(&nm));
|
||||||
|
|
||||||
|
@ -1316,9 +1325,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||||
unsigned int uninitialized_var(saved_nlink);
|
unsigned int uninitialized_var(saved_nlink);
|
||||||
struct fscrypt_name old_nm, new_nm;
|
struct fscrypt_name old_nm, new_nm;
|
||||||
|
|
||||||
if (flags & ~RENAME_NOREPLACE)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Budget request settings: deletion direntry, new direntry, removing
|
* Budget request settings: deletion direntry, new direntry, removing
|
||||||
* the old inode, and changing old and new parent directory inodes.
|
* the old inode, and changing old and new parent directory inodes.
|
||||||
|
|
|
@ -841,6 +841,7 @@ void phy_change_work(struct work_struct *work);
|
||||||
void phy_mac_interrupt(struct phy_device *phydev, int new_link);
|
void phy_mac_interrupt(struct phy_device *phydev, int new_link);
|
||||||
void phy_start_machine(struct phy_device *phydev);
|
void phy_start_machine(struct phy_device *phydev);
|
||||||
void phy_stop_machine(struct phy_device *phydev);
|
void phy_stop_machine(struct phy_device *phydev);
|
||||||
|
void phy_trigger_machine(struct phy_device *phydev, bool sync);
|
||||||
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||||
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||||
int phy_ethtool_ksettings_get(struct phy_device *phydev,
|
int phy_ethtool_ksettings_get(struct phy_device *phydev,
|
||||||
|
|
|
@ -98,7 +98,7 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
|
||||||
int ncpus, v, vecs_to_assign, vecs_per_node;
|
int ncpus, v, vecs_to_assign, vecs_per_node;
|
||||||
|
|
||||||
/* Spread the vectors per node */
|
/* Spread the vectors per node */
|
||||||
vecs_per_node = (affv - curvec) / nodes;
|
vecs_per_node = (affv - (curvec - affd->pre_vectors)) / nodes;
|
||||||
|
|
||||||
/* Get the cpus on this node which are in the mask */
|
/* Get the cpus on this node which are in the mask */
|
||||||
cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n));
|
cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n));
|
||||||
|
|
|
@ -123,6 +123,7 @@ static void br_dev_uninit(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct net_bridge *br = netdev_priv(dev);
|
struct net_bridge *br = netdev_priv(dev);
|
||||||
|
|
||||||
|
br_multicast_dev_del(br);
|
||||||
br_multicast_uninit_stats(br);
|
br_multicast_uninit_stats(br);
|
||||||
br_vlan_flush(br);
|
br_vlan_flush(br);
|
||||||
free_percpu(br->stats);
|
free_percpu(br->stats);
|
||||||
|
|
|
@ -312,7 +312,6 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
|
||||||
|
|
||||||
br_fdb_delete_by_port(br, NULL, 0, 1);
|
br_fdb_delete_by_port(br, NULL, 0, 1);
|
||||||
|
|
||||||
br_multicast_dev_del(br);
|
|
||||||
cancel_delayed_work_sync(&br->gc_work);
|
cancel_delayed_work_sync(&br->gc_work);
|
||||||
|
|
||||||
br_sysfs_delbr(br->dev);
|
br_sysfs_delbr(br->dev);
|
||||||
|
|
|
@ -2451,6 +2451,9 @@ void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (unlikely(!skb))
|
||||||
|
return;
|
||||||
|
|
||||||
if (likely(atomic_read(&skb->users) == 1)) {
|
if (likely(atomic_read(&skb->users) == 1)) {
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
atomic_set(&skb->users, 0);
|
atomic_set(&skb->users, 0);
|
||||||
|
|
|
@ -2403,7 +2403,8 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* L3 master device is the loopback for that domain */
|
/* L3 master device is the loopback for that domain */
|
||||||
dev_out = l3mdev_master_dev_rcu(dev_out) ? : net->loopback_dev;
|
dev_out = l3mdev_master_dev_rcu(FIB_RES_DEV(res)) ? :
|
||||||
|
net->loopback_dev;
|
||||||
fl4->flowi4_oif = dev_out->ifindex;
|
fl4->flowi4_oif = dev_out->ifindex;
|
||||||
flags |= RTCF_LOCAL;
|
flags |= RTCF_LOCAL;
|
||||||
goto make_route;
|
goto make_route;
|
||||||
|
|
|
@ -168,12 +168,8 @@ void tcp_assign_congestion_control(struct sock *sk)
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
/* Clear out private data before diag gets it and
|
|
||||||
* the ca has not been initialized.
|
|
||||||
*/
|
|
||||||
if (ca->get_info)
|
|
||||||
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
||||||
|
|
||||||
if (ca->flags & TCP_CONG_NEEDS_ECN)
|
if (ca->flags & TCP_CONG_NEEDS_ECN)
|
||||||
INET_ECN_xmit(sk);
|
INET_ECN_xmit(sk);
|
||||||
else
|
else
|
||||||
|
@ -200,12 +196,11 @@ static void tcp_reinit_congestion_control(struct sock *sk,
|
||||||
tcp_cleanup_congestion_control(sk);
|
tcp_cleanup_congestion_control(sk);
|
||||||
icsk->icsk_ca_ops = ca;
|
icsk->icsk_ca_ops = ca;
|
||||||
icsk->icsk_ca_setsockopt = 1;
|
icsk->icsk_ca_setsockopt = 1;
|
||||||
|
|
||||||
if (sk->sk_state != TCP_CLOSE) {
|
|
||||||
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
||||||
|
|
||||||
|
if (sk->sk_state != TCP_CLOSE)
|
||||||
tcp_init_congestion_control(sk);
|
tcp_init_congestion_control(sk);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Manage refcounts on socket close. */
|
/* Manage refcounts on socket close. */
|
||||||
void tcp_cleanup_congestion_control(struct sock *sk)
|
void tcp_cleanup_congestion_control(struct sock *sk)
|
||||||
|
|
|
@ -29,6 +29,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
|
||||||
u16 mac_len = skb->mac_len;
|
u16 mac_len = skb->mac_len;
|
||||||
int udp_offset, outer_hlen;
|
int udp_offset, outer_hlen;
|
||||||
__wsum partial;
|
__wsum partial;
|
||||||
|
bool need_ipsec;
|
||||||
|
|
||||||
if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
|
if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -62,8 +63,10 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
|
||||||
|
|
||||||
ufo = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP);
|
ufo = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP);
|
||||||
|
|
||||||
|
need_ipsec = skb_dst(skb) && dst_xfrm(skb_dst(skb));
|
||||||
/* Try to offload checksum if possible */
|
/* Try to offload checksum if possible */
|
||||||
offload_csum = !!(need_csum &&
|
offload_csum = !!(need_csum &&
|
||||||
|
!need_ipsec &&
|
||||||
(skb->dev->features &
|
(skb->dev->features &
|
||||||
(is_ipv6 ? (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM) :
|
(is_ipv6 ? (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM) :
|
||||||
(NETIF_F_HW_CSUM | NETIF_F_IP_CSUM))));
|
(NETIF_F_HW_CSUM | NETIF_F_IP_CSUM))));
|
||||||
|
|
|
@ -3303,14 +3303,24 @@ static void addrconf_gre_config(struct net_device *dev)
|
||||||
static int fixup_permanent_addr(struct inet6_dev *idev,
|
static int fixup_permanent_addr(struct inet6_dev *idev,
|
||||||
struct inet6_ifaddr *ifp)
|
struct inet6_ifaddr *ifp)
|
||||||
{
|
{
|
||||||
if (!ifp->rt) {
|
/* rt6i_ref == 0 means the host route was removed from the
|
||||||
struct rt6_info *rt;
|
* FIB, for example, if 'lo' device is taken down. In that
|
||||||
|
* case regenerate the host route.
|
||||||
|
*/
|
||||||
|
if (!ifp->rt || !atomic_read(&ifp->rt->rt6i_ref)) {
|
||||||
|
struct rt6_info *rt, *prev;
|
||||||
|
|
||||||
rt = addrconf_dst_alloc(idev, &ifp->addr, false);
|
rt = addrconf_dst_alloc(idev, &ifp->addr, false);
|
||||||
if (unlikely(IS_ERR(rt)))
|
if (unlikely(IS_ERR(rt)))
|
||||||
return PTR_ERR(rt);
|
return PTR_ERR(rt);
|
||||||
|
|
||||||
|
/* ifp->rt can be accessed outside of rtnl */
|
||||||
|
spin_lock(&ifp->lock);
|
||||||
|
prev = ifp->rt;
|
||||||
ifp->rt = rt;
|
ifp->rt = rt;
|
||||||
|
spin_unlock(&ifp->lock);
|
||||||
|
|
||||||
|
ip6_rt_put(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) {
|
if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) {
|
||||||
|
|
|
@ -933,8 +933,6 @@ static int __init inet6_init(void)
|
||||||
if (err)
|
if (err)
|
||||||
goto igmp_fail;
|
goto igmp_fail;
|
||||||
|
|
||||||
ipv6_stub = &ipv6_stub_impl;
|
|
||||||
|
|
||||||
err = ipv6_netfilter_init();
|
err = ipv6_netfilter_init();
|
||||||
if (err)
|
if (err)
|
||||||
goto netfilter_fail;
|
goto netfilter_fail;
|
||||||
|
@ -1014,6 +1012,10 @@ static int __init inet6_init(void)
|
||||||
if (err)
|
if (err)
|
||||||
goto sysctl_fail;
|
goto sysctl_fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ensure that ipv6 stubs are visible only after ipv6 is ready */
|
||||||
|
wmb();
|
||||||
|
ipv6_stub = &ipv6_stub_impl;
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -909,6 +909,8 @@ static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
|
||||||
{
|
{
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case IPV6_SRCRT_TYPE_0:
|
case IPV6_SRCRT_TYPE_0:
|
||||||
|
case IPV6_SRCRT_STRICT:
|
||||||
|
case IPV6_SRCRT_TYPE_2:
|
||||||
ipv6_push_rthdr0(skb, proto, opt, addr_p, saddr);
|
ipv6_push_rthdr0(skb, proto, opt, addr_p, saddr);
|
||||||
break;
|
break;
|
||||||
case IPV6_SRCRT_TYPE_4:
|
case IPV6_SRCRT_TYPE_4:
|
||||||
|
@ -1163,6 +1165,8 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
|
||||||
|
|
||||||
switch (opt->srcrt->type) {
|
switch (opt->srcrt->type) {
|
||||||
case IPV6_SRCRT_TYPE_0:
|
case IPV6_SRCRT_TYPE_0:
|
||||||
|
case IPV6_SRCRT_STRICT:
|
||||||
|
case IPV6_SRCRT_TYPE_2:
|
||||||
fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
|
fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
|
||||||
break;
|
break;
|
||||||
case IPV6_SRCRT_TYPE_4:
|
case IPV6_SRCRT_TYPE_4:
|
||||||
|
|
|
@ -1037,7 +1037,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
||||||
struct ip6_tnl *t = netdev_priv(dev);
|
struct ip6_tnl *t = netdev_priv(dev);
|
||||||
struct net *net = t->net;
|
struct net *net = t->net;
|
||||||
struct net_device_stats *stats = &t->dev->stats;
|
struct net_device_stats *stats = &t->dev->stats;
|
||||||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
struct ipv6hdr *ipv6h;
|
||||||
struct ipv6_tel_txoption opt;
|
struct ipv6_tel_txoption opt;
|
||||||
struct dst_entry *dst = NULL, *ndst = NULL;
|
struct dst_entry *dst = NULL, *ndst = NULL;
|
||||||
struct net_device *tdev;
|
struct net_device *tdev;
|
||||||
|
@ -1057,6 +1057,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
||||||
|
|
||||||
/* NBMA tunnel */
|
/* NBMA tunnel */
|
||||||
if (ipv6_addr_any(&t->parms.raddr)) {
|
if (ipv6_addr_any(&t->parms.raddr)) {
|
||||||
|
if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||||
struct in6_addr *addr6;
|
struct in6_addr *addr6;
|
||||||
struct neighbour *neigh;
|
struct neighbour *neigh;
|
||||||
int addr_type;
|
int addr_type;
|
||||||
|
@ -1077,6 +1078,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
||||||
|
|
||||||
memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
|
memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
|
||||||
neigh_release(neigh);
|
neigh_release(neigh);
|
||||||
|
}
|
||||||
} else if (!(t->parms.flags &
|
} else if (!(t->parms.flags &
|
||||||
(IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) {
|
(IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) {
|
||||||
/* enable the cache only only if the routing decision does
|
/* enable the cache only only if the routing decision does
|
||||||
|
|
|
@ -1753,7 +1753,8 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
|
||||||
idev = in6_dev_get(dev);
|
idev = in6_dev_get(dev);
|
||||||
if (!idev)
|
if (!idev)
|
||||||
break;
|
break;
|
||||||
if (idev->cnf.ndisc_notify)
|
if (idev->cnf.ndisc_notify ||
|
||||||
|
net->ipv6.devconf_all->ndisc_notify)
|
||||||
ndisc_send_unsol_na(dev);
|
ndisc_send_unsol_na(dev);
|
||||||
in6_dev_put(idev);
|
in6_dev_put(idev);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1178,8 +1178,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
||||||
spin_lock_bh(&sk->sk_receive_queue.lock);
|
spin_lock_bh(&sk->sk_receive_queue.lock);
|
||||||
skb = skb_peek(&sk->sk_receive_queue);
|
skb = skb_peek(&sk->sk_receive_queue);
|
||||||
if (skb)
|
if (skb)
|
||||||
amount = skb_tail_pointer(skb) -
|
amount = skb->len;
|
||||||
skb_transport_header(skb);
|
|
||||||
spin_unlock_bh(&sk->sk_receive_queue.lock);
|
spin_unlock_bh(&sk->sk_receive_queue.lock);
|
||||||
return put_user(amount, (int __user *)arg);
|
return put_user(amount, (int __user *)arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3880,6 +3880,8 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
|
||||||
case PACKET_HDRLEN:
|
case PACKET_HDRLEN:
|
||||||
if (len > sizeof(int))
|
if (len > sizeof(int))
|
||||||
len = sizeof(int);
|
len = sizeof(int);
|
||||||
|
if (len < sizeof(int))
|
||||||
|
return -EINVAL;
|
||||||
if (copy_from_user(&val, optval, len))
|
if (copy_from_user(&val, optval, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
switch (val) {
|
switch (val) {
|
||||||
|
|
|
@ -1083,7 +1083,7 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen)
|
||||||
}
|
}
|
||||||
} while (sent < dlen && !rc);
|
} while (sent < dlen && !rc);
|
||||||
|
|
||||||
return rc ? rc : sent;
|
return sent ? sent : rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1484,7 +1484,7 @@ restart:
|
||||||
if (unlikely(flags & MSG_PEEK))
|
if (unlikely(flags & MSG_PEEK))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
tsk->rcv_unacked += tsk_inc(tsk, hlen + sz);
|
tsk->rcv_unacked += tsk_inc(tsk, hlen + msg_data_sz(msg));
|
||||||
if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4)))
|
if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4)))
|
||||||
tipc_sk_send_ack(tsk);
|
tipc_sk_send_ack(tsk);
|
||||||
tsk_advance_rx_queue(sk);
|
tsk_advance_rx_queue(sk);
|
||||||
|
|
|
@ -28,19 +28,16 @@
|
||||||
/* wait until all locks are released */
|
/* wait until all locks are released */
|
||||||
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
|
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
|
||||||
{
|
{
|
||||||
int max_count = 5 * HZ;
|
int warn_count = 5 * HZ;
|
||||||
|
|
||||||
if (atomic_read(lockp) < 0) {
|
if (atomic_read(lockp) < 0) {
|
||||||
pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
|
pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (atomic_read(lockp) > 0) {
|
while (atomic_read(lockp) > 0) {
|
||||||
if (max_count == 0) {
|
if (warn_count-- == 0)
|
||||||
pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
|
pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line);
|
||||||
break;
|
|
||||||
}
|
|
||||||
schedule_timeout_uninterruptible(1);
|
schedule_timeout_uninterruptible(1);
|
||||||
max_count--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct snd_fw_async_midi_port {
|
||||||
|
|
||||||
struct snd_rawmidi_substream *substream;
|
struct snd_rawmidi_substream *substream;
|
||||||
snd_fw_async_midi_port_fill fill;
|
snd_fw_async_midi_port_fill fill;
|
||||||
unsigned int consume_bytes;
|
int consume_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
|
int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
|
||||||
|
|
|
@ -227,11 +227,11 @@ static void do_registration(struct work_struct *work)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err = detect_quirks(oxfw);
|
err = snd_oxfw_stream_discover(oxfw);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err = snd_oxfw_stream_discover(oxfw);
|
err = detect_quirks(oxfw);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -621,7 +621,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
|
||||||
.codec_dai_name = "snd-soc-dummy-dai",
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
.codec_name = "snd-soc-dummy",
|
.codec_name = "snd-soc-dummy",
|
||||||
.platform_name = "sst-mfld-platform",
|
.platform_name = "sst-mfld-platform",
|
||||||
.ignore_suspend = 1,
|
.nonatomic = true,
|
||||||
.dynamic = 1,
|
.dynamic = 1,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
.dpcm_capture = 1,
|
.dpcm_capture = 1,
|
||||||
|
@ -634,7 +634,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
|
||||||
.codec_dai_name = "snd-soc-dummy-dai",
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
.codec_name = "snd-soc-dummy",
|
.codec_name = "snd-soc-dummy",
|
||||||
.platform_name = "sst-mfld-platform",
|
.platform_name = "sst-mfld-platform",
|
||||||
.ignore_suspend = 1,
|
|
||||||
.nonatomic = true,
|
.nonatomic = true,
|
||||||
.dynamic = 1,
|
.dynamic = 1,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
|
@ -661,6 +660,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
|
||||||
| SND_SOC_DAIFMT_CBS_CFS,
|
| SND_SOC_DAIFMT_CBS_CFS,
|
||||||
.be_hw_params_fixup = byt_rt5640_codec_fixup,
|
.be_hw_params_fixup = byt_rt5640_codec_fixup,
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
|
.nonatomic = true,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
.dpcm_capture = 1,
|
.dpcm_capture = 1,
|
||||||
.init = byt_rt5640_init,
|
.init = byt_rt5640_init,
|
||||||
|
|
|
@ -235,7 +235,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
|
||||||
.codec_dai_name = "snd-soc-dummy-dai",
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
.codec_name = "snd-soc-dummy",
|
.codec_name = "snd-soc-dummy",
|
||||||
.platform_name = "sst-mfld-platform",
|
.platform_name = "sst-mfld-platform",
|
||||||
.ignore_suspend = 1,
|
|
||||||
.nonatomic = true,
|
.nonatomic = true,
|
||||||
.dynamic = 1,
|
.dynamic = 1,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
|
@ -249,7 +248,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
|
||||||
.codec_dai_name = "snd-soc-dummy-dai",
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
.codec_name = "snd-soc-dummy",
|
.codec_name = "snd-soc-dummy",
|
||||||
.platform_name = "sst-mfld-platform",
|
.platform_name = "sst-mfld-platform",
|
||||||
.ignore_suspend = 1,
|
|
||||||
.nonatomic = true,
|
.nonatomic = true,
|
||||||
.dynamic = 1,
|
.dynamic = 1,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
|
|
|
@ -933,6 +933,7 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
se->texts = (const char * const *)se->dobj.control.dtexts;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
|
@ -1299,6 +1299,7 @@ struct uniperif {
|
||||||
int ver; /* IP version, used by register access macros */
|
int ver; /* IP version, used by register access macros */
|
||||||
struct regmap_field *clk_sel;
|
struct regmap_field *clk_sel;
|
||||||
struct regmap_field *valid_sel;
|
struct regmap_field *valid_sel;
|
||||||
|
spinlock_t irq_lock; /* use to prevent race condition with IRQ */
|
||||||
|
|
||||||
/* capabilities */
|
/* capabilities */
|
||||||
const struct snd_pcm_hardware *hw;
|
const struct snd_pcm_hardware *hw;
|
||||||
|
|
|
@ -65,10 +65,13 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
if (player->state == UNIPERIF_STATE_STOPPED) {
|
spin_lock(&player->irq_lock);
|
||||||
/* Unexpected IRQ: do nothing */
|
if (!player->substream)
|
||||||
return IRQ_NONE;
|
goto irq_spin_unlock;
|
||||||
}
|
|
||||||
|
snd_pcm_stream_lock(player->substream);
|
||||||
|
if (player->state == UNIPERIF_STATE_STOPPED)
|
||||||
|
goto stream_unlock;
|
||||||
|
|
||||||
/* Get interrupt status & clear them immediately */
|
/* Get interrupt status & clear them immediately */
|
||||||
status = GET_UNIPERIF_ITS(player);
|
status = GET_UNIPERIF_ITS(player);
|
||||||
|
@ -88,9 +91,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
|
||||||
SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
|
SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
|
||||||
|
|
||||||
/* Stop the player */
|
/* Stop the player */
|
||||||
snd_pcm_stream_lock(player->substream);
|
|
||||||
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
||||||
snd_pcm_stream_unlock(player->substream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
|
@ -104,9 +105,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
|
||||||
SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
|
SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
|
||||||
|
|
||||||
/* Stop the player */
|
/* Stop the player */
|
||||||
snd_pcm_stream_lock(player->substream);
|
|
||||||
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
||||||
snd_pcm_stream_unlock(player->substream);
|
|
||||||
|
|
||||||
ret = IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +115,8 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
|
||||||
if (!player->underflow_enabled) {
|
if (!player->underflow_enabled) {
|
||||||
dev_err(player->dev,
|
dev_err(player->dev,
|
||||||
"unexpected Underflow recovering\n");
|
"unexpected Underflow recovering\n");
|
||||||
return -EPERM;
|
ret = -EPERM;
|
||||||
|
goto stream_unlock;
|
||||||
}
|
}
|
||||||
/* Read the underflow recovery duration */
|
/* Read the underflow recovery duration */
|
||||||
tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
|
tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
|
||||||
|
@ -138,13 +138,16 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
|
||||||
dev_err(player->dev, "Underflow recovery failed\n");
|
dev_err(player->dev, "Underflow recovery failed\n");
|
||||||
|
|
||||||
/* Stop the player */
|
/* Stop the player */
|
||||||
snd_pcm_stream_lock(player->substream);
|
|
||||||
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
|
||||||
snd_pcm_stream_unlock(player->substream);
|
|
||||||
|
|
||||||
ret = IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream_unlock:
|
||||||
|
snd_pcm_stream_unlock(player->substream);
|
||||||
|
irq_spin_unlock:
|
||||||
|
spin_unlock(&player->irq_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,6 +591,7 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
|
||||||
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
||||||
struct uniperif *player = priv->dai_data.uni;
|
struct uniperif *player = priv->dai_data.uni;
|
||||||
struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
|
struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
mutex_lock(&player->ctrl_lock);
|
mutex_lock(&player->ctrl_lock);
|
||||||
iec958->status[0] = ucontrol->value.iec958.status[0];
|
iec958->status[0] = ucontrol->value.iec958.status[0];
|
||||||
|
@ -596,12 +600,14 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
|
||||||
iec958->status[3] = ucontrol->value.iec958.status[3];
|
iec958->status[3] = ucontrol->value.iec958.status[3];
|
||||||
mutex_unlock(&player->ctrl_lock);
|
mutex_unlock(&player->ctrl_lock);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&player->irq_lock, flags);
|
||||||
if (player->substream && player->substream->runtime)
|
if (player->substream && player->substream->runtime)
|
||||||
uni_player_set_channel_status(player,
|
uni_player_set_channel_status(player,
|
||||||
player->substream->runtime);
|
player->substream->runtime);
|
||||||
else
|
else
|
||||||
uni_player_set_channel_status(player, NULL);
|
uni_player_set_channel_status(player, NULL);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&player->irq_lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,9 +692,12 @@ static int uni_player_startup(struct snd_pcm_substream *substream,
|
||||||
{
|
{
|
||||||
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
||||||
struct uniperif *player = priv->dai_data.uni;
|
struct uniperif *player = priv->dai_data.uni;
|
||||||
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&player->irq_lock, flags);
|
||||||
player->substream = substream;
|
player->substream = substream;
|
||||||
|
spin_unlock_irqrestore(&player->irq_lock, flags);
|
||||||
|
|
||||||
player->clk_adj = 0;
|
player->clk_adj = 0;
|
||||||
|
|
||||||
|
@ -986,12 +995,15 @@ static void uni_player_shutdown(struct snd_pcm_substream *substream,
|
||||||
{
|
{
|
||||||
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
||||||
struct uniperif *player = priv->dai_data.uni;
|
struct uniperif *player = priv->dai_data.uni;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&player->irq_lock, flags);
|
||||||
if (player->state != UNIPERIF_STATE_STOPPED)
|
if (player->state != UNIPERIF_STATE_STOPPED)
|
||||||
/* Stop the player */
|
/* Stop the player */
|
||||||
uni_player_stop(player);
|
uni_player_stop(player);
|
||||||
|
|
||||||
player->substream = NULL;
|
player->substream = NULL;
|
||||||
|
spin_unlock_irqrestore(&player->irq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
|
static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
|
||||||
|
@ -1096,6 +1108,7 @@ int uni_player_init(struct platform_device *pdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&player->ctrl_lock);
|
mutex_init(&player->ctrl_lock);
|
||||||
|
spin_lock_init(&player->irq_lock);
|
||||||
|
|
||||||
/* Ensure that disabled by default */
|
/* Ensure that disabled by default */
|
||||||
SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
|
SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
|
||||||
|
|
|
@ -46,10 +46,15 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
|
||||||
struct uniperif *reader = dev_id;
|
struct uniperif *reader = dev_id;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
|
spin_lock(&reader->irq_lock);
|
||||||
|
if (!reader->substream)
|
||||||
|
goto irq_spin_unlock;
|
||||||
|
|
||||||
|
snd_pcm_stream_lock(reader->substream);
|
||||||
if (reader->state == UNIPERIF_STATE_STOPPED) {
|
if (reader->state == UNIPERIF_STATE_STOPPED) {
|
||||||
/* Unexpected IRQ: do nothing */
|
/* Unexpected IRQ: do nothing */
|
||||||
dev_warn(reader->dev, "unexpected IRQ\n");
|
dev_warn(reader->dev, "unexpected IRQ\n");
|
||||||
return IRQ_HANDLED;
|
goto stream_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get interrupt status & clear them immediately */
|
/* Get interrupt status & clear them immediately */
|
||||||
|
@ -60,13 +65,16 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
|
||||||
if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
|
if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
|
||||||
dev_err(reader->dev, "FIFO error detected\n");
|
dev_err(reader->dev, "FIFO error detected\n");
|
||||||
|
|
||||||
snd_pcm_stream_lock(reader->substream);
|
|
||||||
snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN);
|
snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN);
|
||||||
snd_pcm_stream_unlock(reader->substream);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream_unlock:
|
||||||
|
snd_pcm_stream_unlock(reader->substream);
|
||||||
|
irq_spin_unlock:
|
||||||
|
spin_unlock(&reader->irq_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,9 +355,12 @@ static int uni_reader_startup(struct snd_pcm_substream *substream,
|
||||||
{
|
{
|
||||||
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
||||||
struct uniperif *reader = priv->dai_data.uni;
|
struct uniperif *reader = priv->dai_data.uni;
|
||||||
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&reader->irq_lock, flags);
|
||||||
reader->substream = substream;
|
reader->substream = substream;
|
||||||
|
spin_unlock_irqrestore(&reader->irq_lock, flags);
|
||||||
|
|
||||||
if (!UNIPERIF_TYPE_IS_TDM(reader))
|
if (!UNIPERIF_TYPE_IS_TDM(reader))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -375,12 +386,15 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream,
|
||||||
{
|
{
|
||||||
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
|
||||||
struct uniperif *reader = priv->dai_data.uni;
|
struct uniperif *reader = priv->dai_data.uni;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&reader->irq_lock, flags);
|
||||||
if (reader->state != UNIPERIF_STATE_STOPPED) {
|
if (reader->state != UNIPERIF_STATE_STOPPED) {
|
||||||
/* Stop the reader */
|
/* Stop the reader */
|
||||||
uni_reader_stop(reader);
|
uni_reader_stop(reader);
|
||||||
}
|
}
|
||||||
reader->substream = NULL;
|
reader->substream = NULL;
|
||||||
|
spin_unlock_irqrestore(&reader->irq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct snd_soc_dai_ops uni_reader_dai_ops = {
|
static const struct snd_soc_dai_ops uni_reader_dai_ops = {
|
||||||
|
@ -415,6 +429,8 @@ int uni_reader_init(struct platform_device *pdev,
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_init(&reader->irq_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(uni_reader_init);
|
EXPORT_SYMBOL_GPL(uni_reader_init);
|
||||||
|
|
Loading…
Reference in New Issue