@@ -427,8 +427,9 @@ struct crng_state primary_crng = {
* its value (from 0->1->2).
*/
static int crng_init = 0;
#define crng_ready() (likely(crng_init > 0))
#define crng_ready() (likely(crng_init > 1))
static int crng_init_cnt = 0;
static unsigned long crng_global_init_time = 0;
#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
static void _extract_crng(struct crng_state *crng,
__u32 out[CHACHA20_BLOCK_WORDS]);
@@ -787,14 +788,44 @@ static void crng_initialize(struct crng_state *crng)
crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
}

#ifdef CONFIG_NUMA
static void numa_crng_init(void)
{
int i;
struct crng_state *crng;
struct crng_state **pool;

pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
for_each_online_node(i) {
crng = kmalloc_node(sizeof(struct crng_state),
GFP_KERNEL | __GFP_NOFAIL, i);
spin_lock_init(&crng->lock);
crng_initialize(crng);
pool[i] = crng;
}
mb();
if (cmpxchg(&crng_node_pool, NULL, pool)) {
for_each_node(i)
kfree(pool[i]);
kfree(pool);
}
}
#else
static void numa_crng_init(void) {}
#endif

/*
* crng_fast_load() can be called by code in the interrupt service
* path. So we can't afford to dilly-dally.
*/
static int crng_fast_load(const char *cp, size_t len)
{
unsigned long flags;
char *p;

if (!spin_trylock_irqsave(&primary_crng.lock, flags))
return 0;
if (crng_ready()) {
if (crng_init != 0) {
spin_unlock_irqrestore(&primary_crng.lock, flags);
return 0;
}
@@ -813,6 +844,51 @@ static int crng_fast_load(const char *cp, size_t len)
return 1;
}

/*
* crng_slow_load() is called by add_device_randomness, which has two
* attributes. (1) We can't trust the buffer passed to it is
* guaranteed to be unpredictable (so it might not have any entropy at
* all), and (2) it doesn't have the performance constraints of
* crng_fast_load().
*
* So we do something more comprehensive which is guaranteed to touch
* all of the primary_crng's state, and which uses a LFSR with a
* period of 255 as part of the mixing algorithm. Finally, we do
* *not* advance crng_init_cnt since buffer we may get may be something
* like a fixed DMI table (for example), which might very well be
* unique to the machine, but is otherwise unvarying.
*/
static int crng_slow_load(const char *cp, size_t len)
{
unsigned long flags;
static unsigned char lfsr = 1;
unsigned char tmp;
unsigned i, max = CHACHA20_KEY_SIZE;
const char * src_buf = cp;
char * dest_buf = (char *) &primary_crng.state[4];

if (!spin_trylock_irqsave(&primary_crng.lock, flags))
return 0;
if (crng_init != 0) {
spin_unlock_irqrestore(&primary_crng.lock, flags);
return 0;
}
if (len > max)
max = len;

for (i = 0; i < max ; i++) {
tmp = lfsr;
lfsr >>= 1;
if (tmp & 1)
lfsr ^= 0xE1;
tmp = dest_buf[i % CHACHA20_KEY_SIZE];
dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
lfsr += (tmp << 3) | (tmp >> 5);
}
spin_unlock_irqrestore(&primary_crng.lock, flags);
return 1;
}

static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
{
unsigned long flags;
@@ -831,7 +907,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
_crng_backtrack_protect(&primary_crng, buf.block,
CHACHA20_KEY_SIZE);
}
spin_lock_irqsave(&primary_crng.lock, flags);
spin_lock_irqsave(&crng->lock, flags);
for (i = 0; i < 8; i++) {
unsigned long rv;
if (!arch_get_random_seed_long(&rv) &&
@@ -841,9 +917,10 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
}
memzero_explicit(&buf, sizeof(buf));
crng->init_time = jiffies;
spin_unlock_irqrestore(&primary_crng.lock, flags);
spin_unlock_irqrestore(&crng->lock, flags);
if (crng == &primary_crng && crng_init < 2) {
invalidate_batched_entropy();
numa_crng_init();
crng_init = 2;
process_random_ready_list();
wake_up_interruptible(&crng_init_wait);
@@ -856,8 +933,9 @@ static void _extract_crng(struct crng_state *crng,
{
unsigned long v, flags;

if (crng_init > 1 &&
time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
if (crng_ready() &&
(time_after(crng_global_init_time, crng->init_time) ||
time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
spin_lock_irqsave(&crng->lock, flags);
if (arch_get_random_long(&v))
@@ -981,10 +1059,8 @@ void add_device_randomness(const void *buf, unsigned int size)
unsigned long time = random_get_entropy() ^ jiffies;
unsigned long flags;

if (!crng_ready()) {
crng_fast_load(buf, size);
return;
}
if (!crng_ready() && size)
crng_slow_load(buf, size);

trace_add_device_randomness(size, _RET_IP_);
spin_lock_irqsave(&input_pool.lock, flags);
@@ -1139,7 +1215,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
fast_mix(fast_pool);
add_interrupt_bench(cycles);

if (!crng_ready()) {
if (unlikely(crng_init == 0)) {
if ((fast_pool->count >= 64) &&
crng_fast_load((char *) fast_pool->pool,
sizeof(fast_pool->pool))) {
@@ -1680,28 +1756,10 @@ static void init_std_data(struct entropy_store *r)
*/
static int rand_initialize(void)
{
#ifdef CONFIG_NUMA
int i;
struct crng_state *crng;
struct crng_state **pool;
#endif

init_std_data(&input_pool);
init_std_data(&blocking_pool);
crng_initialize(&primary_crng);

#ifdef CONFIG_NUMA
pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
for_each_online_node(i) {
crng = kmalloc_node(sizeof(struct crng_state),
GFP_KERNEL | __GFP_NOFAIL, i);
spin_lock_init(&crng->lock);
crng_initialize(crng);
pool[i] = crng;
}
mb();
crng_node_pool = pool;
#endif
crng_global_init_time = jiffies;
return 0;
}
early_initcall(rand_initialize);
@@ -1875,6 +1933,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
input_pool.entropy_count = 0;
blocking_pool.entropy_count = 0;
return 0;
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (crng_init < 2)
return -ENODATA;
crng_reseed(&primary_crng, NULL);
crng_global_init_time = jiffies - 1;
return 0;
default:
return -EINVAL;
}
@@ -2212,7 +2278,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
{
struct entropy_store *poolp = &input_pool;

if (!crng_ready()) {
if (unlikely(crng_init == 0)) {
crng_fast_load(buffer, count);
return;
}
@@ -133,6 +133,14 @@ config VT8500_TIMER
help
Enables support for the VT8500 driver.

config NPCM7XX_TIMER
bool "NPCM7xx timer driver" if COMPILE_TEST
depends on HAS_IOMEM
select CLKSRC_MMIO
help
Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture,
While TIMER0 serves as clockevent and TIMER1 serves as clocksource.

config CADENCE_TTC_TIMER
bool "Cadence TTC timer driver" if COMPILE_TEST
depends on COMMON_CLK
@@ -56,6 +56,7 @@ obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
obj-$(CONFIG_OWL_TIMER) += owl-timer.o
obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o
obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o

obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
@@ -17,9 +17,14 @@
#include <linux/of_irq.h>
#include <linux/sched_clock.h>

#define TPM_PARAM 0x4
#define TPM_PARAM_WIDTH_SHIFT 16
#define TPM_PARAM_WIDTH_MASK (0xff << 16)
#define TPM_SC 0x10
#define TPM_SC_CMOD_INC_PER_CNT (0x1 << 3)
#define TPM_SC_CMOD_DIV_DEFAULT 0x3
#define TPM_SC_CMOD_DIV_MAX 0x7
#define TPM_SC_TOF_MASK (0x1 << 7)
#define TPM_CNT 0x14
#define TPM_MOD 0x18
#define TPM_STATUS 0x1c
@@ -29,8 +34,11 @@
#define TPM_C0SC_MODE_SHIFT 2
#define TPM_C0SC_MODE_MASK 0x3c
#define TPM_C0SC_MODE_SW_COMPARE 0x4
#define TPM_C0SC_CHF_MASK (0x1 << 7)
#define TPM_C0V 0x24

static int counter_width;
static int rating;
static void __iomem *timer_base;
static struct clock_event_device clockevent_tpm;

@@ -83,10 +91,11 @@ static int __init tpm_clocksource_init(unsigned long rate)
tpm_delay_timer.freq = rate;
register_current_timer_delay(&tpm_delay_timer);

sched_clock_register(tpm_read_sched_clock, 32, rate);
sched_clock_register(tpm_read_sched_clock, counter_width, rate);

return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm",
rate, 200, 32, clocksource_mmio_readl_up);
rate, rating, counter_width,
clocksource_mmio_readl_up);
}

static int tpm_set_next_event(unsigned long delta,
@@ -105,7 +114,7 @@ static int tpm_set_next_event(unsigned long delta,
* of writing CNT registers which may cause the min_delta event got
* missed, so we need add a ETIME check here in case it happened.
*/
return (int)((next - now) <= 0) ? -ETIME : 0;
return (int)(next - now) <= 0 ? -ETIME : 0;
}

static int tpm_set_state_oneshot(struct clock_event_device *evt)
@@ -139,7 +148,6 @@ static struct clock_event_device clockevent_tpm = {
.set_state_oneshot = tpm_set_state_oneshot,
.set_next_event = tpm_set_next_event,
.set_state_shutdown = tpm_set_state_shutdown,
.rating = 200,
};

static int __init tpm_clockevent_init(unsigned long rate, int irq)
@@ -149,10 +157,11 @@ static int __init tpm_clockevent_init(unsigned long rate, int irq)
ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
"i.MX7ULP TPM Timer", &clockevent_tpm);

clockevent_tpm.rating = rating;
clockevent_tpm.cpumask = cpumask_of(0);
clockevent_tpm.irq = irq;
clockevents_config_and_register(&clockevent_tpm,
rate, 300, 0xfffffffe);
clockevents_config_and_register(&clockevent_tpm, rate, 300,
GENMASK(counter_width - 1, 1));

return ret;
}
@@ -179,7 +188,7 @@ static int __init tpm_timer_init(struct device_node *np)
ipg = of_clk_get_by_name(np, "ipg");
per = of_clk_get_by_name(np, "per");
if (IS_ERR(ipg) || IS_ERR(per)) {
pr_err("tpm: failed to get igp or per clk\n");
pr_err("tpm: failed to get ipg or per clk\n");
ret = -ENODEV;
goto err_clk_get;
}
@@ -197,6 +206,11 @@ static int __init tpm_timer_init(struct device_node *np)
goto err_per_clk_enable;
}

counter_width = (readl(timer_base + TPM_PARAM) & TPM_PARAM_WIDTH_MASK)
>> TPM_PARAM_WIDTH_SHIFT;
/* use rating 200 for 32-bit counter and 150 for 16-bit counter */
rating = counter_width == 0x20 ? 200 : 150;

/*
* Initialize tpm module to a known state
* 1) Counter disabled
@@ -205,16 +219,25 @@ static int __init tpm_timer_init(struct device_node *np)
* 4) Channel0 disabled
* 5) DMA transfers disabled
*/
/* make sure counter is disabled */
writel(0, timer_base + TPM_SC);
/* TOF is W1C */
writel(TPM_SC_TOF_MASK, timer_base + TPM_SC);
writel(0, timer_base + TPM_CNT);
writel(0, timer_base + TPM_C0SC);
/* CHF is W1C */
writel(TPM_C0SC_CHF_MASK, timer_base + TPM_C0SC);

/* increase per cnt, div 8 by default */
writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT,
/*
* increase per cnt,
* div 8 for 32-bit counter and div 128 for 16-bit counter
*/
writel(TPM_SC_CMOD_INC_PER_CNT |
(counter_width == 0x20 ?
TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX),
timer_base + TPM_SC);

/* set MOD register to maximum for free running mode */
writel(0xffffffff, timer_base + TPM_MOD);
writel(GENMASK(counter_width - 1, 0), timer_base + TPM_MOD);

rate = clk_get_rate(per) >> 3;
ret = tpm_clocksource_init(rate);
@@ -0,0 +1,215 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014-2018 Nuvoton Technologies tomer.maimon@nuvoton.com
* All rights reserved.
*
* Copyright 2017 Google, Inc.
*/

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clockchips.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include "timer-of.h"

/* Timers registers */
#define NPCM7XX_REG_TCSR0 0x0 /* Timer 0 Control and Status Register */
#define NPCM7XX_REG_TICR0 0x8 /* Timer 0 Initial Count Register */
#define NPCM7XX_REG_TCSR1 0x4 /* Timer 1 Control and Status Register */
#define NPCM7XX_REG_TICR1 0xc /* Timer 1 Initial Count Register */
#define NPCM7XX_REG_TDR1 0x14 /* Timer 1 Data Register */
#define NPCM7XX_REG_TISR 0x18 /* Timer Interrupt Status Register */

/* Timers control */
#define NPCM7XX_Tx_RESETINT 0x1f
#define NPCM7XX_Tx_PERIOD BIT(27)
#define NPCM7XX_Tx_INTEN BIT(29)
#define NPCM7XX_Tx_COUNTEN BIT(30)
#define NPCM7XX_Tx_ONESHOT 0x0
#define NPCM7XX_Tx_OPER GENMASK(3, 27)
#define NPCM7XX_Tx_MIN_PRESCALE 0x1
#define NPCM7XX_Tx_TDR_MASK_BITS 24
#define NPCM7XX_Tx_MAX_CNT 0xFFFFFF
#define NPCM7XX_T0_CLR_INT 0x1
#define NPCM7XX_Tx_CLR_CSR 0x0

/* Timers operating mode */
#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
NPCM7XX_Tx_INTEN | \
NPCM7XX_Tx_MIN_PRESCALE)

#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
NPCM7XX_Tx_INTEN | \
NPCM7XX_Tx_MIN_PRESCALE)

#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
NPCM7XX_Tx_MIN_PRESCALE)

#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)

static int npcm7xx_timer_resume(struct clock_event_device *evt)
{
struct timer_of *to = to_timer_of(evt);
u32 val;

val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val |= NPCM7XX_Tx_COUNTEN;
writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);

return 0;
}

static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
{
struct timer_of *to = to_timer_of(evt);
u32 val;

val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val &= ~NPCM7XX_Tx_COUNTEN;
writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);

return 0;
}

static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
{
struct timer_of *to = to_timer_of(evt);
u32 val;

val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val &= ~NPCM7XX_Tx_OPER;

val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val |= NPCM7XX_START_ONESHOT_Tx;
writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);

return 0;
}

static int npcm7xx_timer_periodic(struct clock_event_device *evt)
{
struct timer_of *to = to_timer_of(evt);
u32 val;

val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val &= ~NPCM7XX_Tx_OPER;

writel(timer_of_period(to), timer_of_base(to) + NPCM7XX_REG_TICR0);
val |= NPCM7XX_START_PERIODIC_Tx;

writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);

return 0;
}

static int npcm7xx_clockevent_set_next_event(unsigned long evt,
struct clock_event_device *clk)
{
struct timer_of *to = to_timer_of(clk);
u32 val;

writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
val |= NPCM7XX_START_Tx;
writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);

return 0;
}

static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
struct timer_of *to = to_timer_of(evt);

writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);

evt->event_handler(evt);

return IRQ_HANDLED;
}

static struct timer_of npcm7xx_to = {
.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,

.clkevt = {
.name = "npcm7xx-timer0",
.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT,
.set_next_event = npcm7xx_clockevent_set_next_event,
.set_state_shutdown = npcm7xx_timer_shutdown,
.set_state_periodic = npcm7xx_timer_periodic,
.set_state_oneshot = npcm7xx_timer_oneshot,
.tick_resume = npcm7xx_timer_resume,
.rating = 300,
},

.of_irq = {
.handler = npcm7xx_timer0_interrupt,
.flags = IRQF_TIMER | IRQF_IRQPOLL,
},
};

static void __init npcm7xx_clockevents_init(void)
{
writel(NPCM7XX_DEFAULT_CSR,
timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR0);

writel(NPCM7XX_Tx_RESETINT,
timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TISR);

npcm7xx_to.clkevt.cpumask = cpumask_of(0);
clockevents_config_and_register(&npcm7xx_to.clkevt,
timer_of_rate(&npcm7xx_to),
0x1, NPCM7XX_Tx_MAX_CNT);
}

static void __init npcm7xx_clocksource_init(void)
{
u32 val;

writel(NPCM7XX_DEFAULT_CSR,
timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
writel(NPCM7XX_Tx_MAX_CNT,
timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TICR1);

val = readl(timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
val |= NPCM7XX_START_Tx;
writel(val, timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);

clocksource_mmio_init(timer_of_base(&npcm7xx_to) +
NPCM7XX_REG_TDR1,
"npcm7xx-timer1", timer_of_rate(&npcm7xx_to),
200, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
clocksource_mmio_readl_down);
}

static int __init npcm7xx_timer_init(struct device_node *np)
{
int ret;

ret = timer_of_init(np, &npcm7xx_to);
if (ret)
return ret;

/* Clock input is divided by PRESCALE + 1 before it is fed */
/* to the counter */
npcm7xx_to.of_clk.rate = npcm7xx_to.of_clk.rate /
(NPCM7XX_Tx_MIN_PRESCALE + 1);

npcm7xx_clocksource_init();
npcm7xx_clockevents_init();

pr_info("Enabling NPCM7xx clocksource timer base: %px, IRQ: %d ",
timer_of_base(&npcm7xx_to), timer_of_irq(&npcm7xx_to));

return 0;
}

TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);

@@ -19,6 +19,7 @@
#include <linux/dax.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include "dax-private.h"
#include "dax.h"

@@ -540,6 +541,7 @@ static const struct file_operations dax_fops = {
.release = dax_release,
.get_unmapped_area = dax_get_unmapped_area,
.mmap = dax_mmap,
.mmap_supported_flags = MAP_SYNC,
};

static void dev_dax_release(struct device *dev)
@@ -138,13 +138,6 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc)
lut = (struct drm_color_lut *)blob->data;
lut_size = blob->length / sizeof(struct drm_color_lut);

if (__is_lut_linear(lut, lut_size)) {
/* Set to bypass if lut is set to linear */
stream->out_transfer_func->type = TF_TYPE_BYPASS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
return 0;
}

gamma = dc_create_gamma();
if (!gamma)
return -ENOMEM;
@@ -4743,23 +4743,27 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)

for (i=0; i < dep_table->count; i++) {
if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
break;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
return;
}
}
if (i == dep_table->count)
if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
}

dep_table = table_info->vdd_dep_on_sclk;
odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
for (i=0; i < dep_table->count; i++) {
if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
break;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
return;
}
}
if (i == dep_table->count)
if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
}
}

static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
@@ -412,8 +412,10 @@ typedef struct {
QuadraticInt_t ReservedEquation2;
QuadraticInt_t ReservedEquation3;

uint16_t MinVoltageUlvGfx;
uint16_t MinVoltageUlvSoc;

uint32_t Reserved[15];
uint32_t Reserved[14];



@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
{
uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
ssize_t ret;
int retry;

if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
return 0;

ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmds_oen, sizeof(tmds_oen));
if (ret) {
DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
enable ? "enable" : "disable");
return ret;
/*
* LSPCON adapters in low-power state may ignore the first write, so
* read back and verify the written value a few times.
*/
for (retry = 0; retry < 3; retry++) {
uint8_t tmp;

ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmds_oen, sizeof(tmds_oen));
if (ret) {
DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
enable ? "enable" : "disable",
retry + 1);
return ret;
}

ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmp, sizeof(tmp));
if (ret) {
DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
enable ? "enabling" : "disabling",
retry + 1);
return ret;
}

if (tmp == tmds_oen)
return 0;
}

return 0;
DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
enable ? "enabling" : "disabling");

return -EIO;
}
EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);

@@ -18,6 +18,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <uapi/drm/exynos_drm.h>

#include "exynos_drm_drv.h"
@@ -26,20 +27,6 @@
#include "exynos_drm_iommu.h"
#include "exynos_drm_crtc.h"

#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb)

/*
* exynos specific framebuffer structure.
*
* @fb: drm framebuffer obejct.
* @exynos_gem: array of exynos specific gem object containing a gem object.
*/
struct exynos_drm_fb {
struct drm_framebuffer fb;
struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
dma_addr_t dma_addr[MAX_FB_BUFFER];
};

static int check_fb_gem_memory_type(struct drm_device *drm_dev,
struct exynos_drm_gem *exynos_gem)
{
@@ -66,40 +53,9 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev,
return 0;
}

static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
unsigned int i;

drm_framebuffer_cleanup(fb);

for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
struct drm_gem_object *obj;

if (exynos_fb->exynos_gem[i] == NULL)
continue;

obj = &exynos_fb->exynos_gem[i]->base;
drm_gem_object_unreference_unlocked(obj);
}

kfree(exynos_fb);
exynos_fb = NULL;
}

static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);

return drm_gem_handle_create(file_priv,
&exynos_fb->exynos_gem[0]->base, handle);
}

static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
.destroy = exynos_drm_fb_destroy,
.create_handle = exynos_drm_fb_create_handle,
.destroy = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
};

struct drm_framebuffer *
@@ -108,36 +64,34 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
struct exynos_drm_gem **exynos_gem,
int count)
{
struct exynos_drm_fb *exynos_fb;
struct drm_framebuffer *fb;
int i;
int ret;

exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb)
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);

for (i = 0; i < count; i++) {
ret = check_fb_gem_memory_type(dev, exynos_gem[i]);
if (ret < 0)
goto err;

exynos_fb->exynos_gem[i] = exynos_gem[i];
exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr
+ mode_cmd->offsets[i];
fb->obj[i] = &exynos_gem[i]->base;
}

drm_helper_mode_fill_fb_struct(dev, &exynos_fb->fb, mode_cmd);
drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);

ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs);
if (ret < 0) {
DRM_ERROR("failed to initialize framebuffer\n");
goto err;
}

return &exynos_fb->fb;
return fb;

err:
kfree(exynos_fb);
kfree(fb);
return ERR_PTR(ret);
}

@@ -191,12 +145,13 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,

dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
struct exynos_drm_gem *exynos_gem;

if (WARN_ON_ONCE(index >= MAX_FB_BUFFER))
return 0;

return exynos_fb->dma_addr[index];
exynos_gem = to_exynos_gem(fb->obj[index]);
return exynos_gem->dma_addr + fb->offsets[index];
}

static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
{
set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
s->workload->pending_events);
patch_value(s, cmd_ptr(s, 0), MI_NOOP);
return 0;
}

@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
int pipe;

vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
SDE_PORTC_HOTPLUG_CPT |
SDE_PORTD_HOTPLUG_CPT);
@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
if (IS_BROADWELL(dev_priv))
vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;

/* Disable Primary/Sprite/Cursor plane */
for_each_pipe(dev_priv, pipe) {
vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
}

vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
}

@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
struct intel_vgpu_fb_info *fb_info)
{
gvt_dmabuf->drm_format = fb_info->drm_format;
gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
gvt_dmabuf->width = fb_info->width;
gvt_dmabuf->height = fb_info->height;
gvt_dmabuf->stride = fb_info->stride;
@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
plane->hw_format = fmt;

plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
alpha_plane, alpha_force);

plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
plane->drm_format = drm_format;

plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm,
false, 0, mm->vgpu);
}

static void ggtt_get_host_entry(struct intel_vgpu_mm *mm,
struct intel_gvt_gtt_entry *entry, unsigned long index)
{
struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;

GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);

pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu);
}

static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
struct intel_gvt_gtt_entry *entry, unsigned long index)
{
@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off,
return ret;
}

static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,
struct intel_gvt_gtt_entry *entry)
{
struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
unsigned long pfn;

pfn = pte_ops->get_pfn(entry);
if (pfn != vgpu->gvt->gtt.scratch_mfn)
intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
pfn << PAGE_SHIFT);
}

static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
void *p_data, unsigned int bytes)
{
@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,

memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
bytes);
m = e;

if (ops->test_present(&e)) {
gfn = ops->get_pfn(&e);
m = e;

/* one PTE update may be issued in multiple writes and the
* first write may not construct a valid gfn
@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
ops->set_pfn(&m, gvt->gtt.scratch_mfn);
} else
ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
} else
} else {
ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
ggtt_invalidate_pte(vgpu, &m);
ops->set_pfn(&m, gvt->gtt.scratch_mfn);
ops->clear_present(&m);
}

out:
ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
return PTR_ERR(gtt->ggtt_mm);
}

intel_vgpu_reset_ggtt(vgpu);
intel_vgpu_reset_ggtt(vgpu, false);

return create_scratch_page_tree(vgpu);
}
@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu)
/**
* intel_vgpu_reset_ggtt - reset the GGTT entry
* @vgpu: a vGPU
* @invalidate_old: invalidate old entries
*
* This function is called at the vGPU create stage
* to reset all the GGTT entries.
*
*/
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
{
struct intel_gvt *gvt = vgpu->gvt;
struct drm_i915_private *dev_priv = gvt->dev_priv;
struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
struct intel_gvt_gtt_entry old_entry;
u32 index;
u32 num_entries;

@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)

index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
while (num_entries--)
while (num_entries--) {
if (invalidate_old) {
ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
ggtt_invalidate_pte(vgpu, &old_entry);
}
ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
}

index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
while (num_entries--)
while (num_entries--) {
if (invalidate_old) {
ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
ggtt_invalidate_pte(vgpu, &old_entry);
}
ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
}

ggtt_invalidate(dev_priv);
}
@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
* removing the shadow pages.
*/
intel_vgpu_destroy_all_ppgtt_mm(vgpu);
intel_vgpu_reset_ggtt(vgpu);
intel_vgpu_reset_ggtt(vgpu, true);
}
@@ -193,7 +193,7 @@ struct intel_vgpu_gtt {

extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);

extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
@@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)
switch (notification) {
case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE:
root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY;
/* fall through */
case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE:
mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps);
return PTR_ERR_OR_ZERO(mm);
@@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,

}

return 0;
return -ENOTTY;
}

static ssize_t
@@ -1105,30 +1105,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)

ret = i915_ggtt_probe_hw(dev_priv);
if (ret)
return ret;
goto err_perf;

/* WARNING: Apparently we must kick fbdev drivers before vgacon,
* otherwise the vga fbdev driver falls over. */
/*
* WARNING: Apparently we must kick fbdev drivers before vgacon,
* otherwise the vga fbdev driver falls over.
*/
ret = i915_kick_out_firmware_fb(dev_priv);
if (ret) {
DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
goto out_ggtt;
goto err_ggtt;
}

ret = i915_kick_out_vgacon(dev_priv);
if (ret) {
DRM_ERROR("failed to remove conflicting VGA console\n");
goto out_ggtt;
goto err_ggtt;
}

ret = i915_ggtt_init_hw(dev_priv);
if (ret)
return ret;
goto err_ggtt;

ret = i915_ggtt_enable_hw(dev_priv);
if (ret) {
DRM_ERROR("failed to enable GGTT\n");
goto out_ggtt;
goto err_ggtt;
}

pci_set_master(pdev);
@@ -1139,7 +1141,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
if (ret) {
DRM_ERROR("failed to set DMA mask\n");

goto out_ggtt;
goto err_ggtt;
}
}

@@ -1157,7 +1159,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
if (ret) {
DRM_ERROR("failed to set DMA mask\n");

goto out_ggtt;
goto err_ggtt;
}
}

@@ -1190,13 +1192,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)

ret = intel_gvt_init(dev_priv);
if (ret)
goto out_ggtt;
goto err_ggtt;

return 0;

out_ggtt:
err_ggtt:
i915_ggtt_cleanup_hw(dev_priv);

err_perf:
i915_perf_fini(dev_priv);
return ret;
}

@@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)

err = radix_tree_insert(handles_vma, handle, vma);
if (unlikely(err)) {
kfree(lut);
kmem_cache_free(eb->i915->luts, lut);
goto err_obj;
}

@@ -473,20 +473,37 @@ static u64 get_rc6(struct drm_i915_private *i915)
spin_lock_irqsave(&i915->pmu.lock, flags);
spin_lock(&kdev->power.lock);

if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
i915->pmu.suspended_jiffies_last =
kdev->power.suspended_jiffies;
/*
* After the above branch intel_runtime_pm_get_if_in_use failed
* to get the runtime PM reference we cannot assume we are in
* runtime suspend since we can either: a) race with coming out
* of it before we took the power.lock, or b) there are other
* states than suspended which can bring us here.
*
* We need to double-check that we are indeed currently runtime
* suspended and if not we cannot do better than report the last
* known RC6 value.
*/
if (kdev->power.runtime_status == RPM_SUSPENDED) {
if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
i915->pmu.suspended_jiffies_last =
kdev->power.suspended_jiffies;

val = kdev->power.suspended_jiffies -
i915->pmu.suspended_jiffies_last;
val += jiffies - kdev->power.accounting_timestamp;
val = kdev->power.suspended_jiffies -
i915->pmu.suspended_jiffies_last;
val += jiffies - kdev->power.accounting_timestamp;

spin_unlock(&kdev->power.lock);
val = jiffies_to_nsecs(val);
val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;

val = jiffies_to_nsecs(val);
val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
} else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
} else {
val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
}

spin_unlock(&kdev->power.lock);
spin_unlock_irqrestore(&i915->pmu.lock, flags);
}

@@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
u32 tmp;

if (!IS_GEN9_BC(dev_priv))
if (!IS_GEN9(dev_priv))
return;

i915_audio_component_get_power(kdev);
@@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
return;

aux_channel = child->aux_channel;
ddc_pin = child->ddc_pin;

is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
@@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));

if (is_dvi) {
info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin);

sanitize_ddc_pin(dev_priv, port);
ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin);
if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) {
info->alternate_ddc_pin = ddc_pin;
sanitize_ddc_pin(dev_priv, port);
} else {
DRM_DEBUG_KMS("Port %c has invalid DDC pin %d, "
"sticking to defaults\n",
port_name(port), ddc_pin);
}
}

if (is_dp) {
@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* know the next preemption status we see corresponds
* to this ELSP update.
*/
GEM_BUG_ON(!execlists_is_active(execlists,
EXECLISTS_ACTIVE_USER));
GEM_BUG_ON(!port_count(&port[0]));
if (port_count(&port[0]) > 1)
goto unlock;
@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
memset(port, 0, sizeof(*port));
port++;
}

execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
}

static void execlists_cancel_requests(struct intel_engine_cs *engine)
@@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data)

if (fw)
intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);

/* If the engine is now idle, so should be the flag; and vice versa. */
GEM_BUG_ON(execlists_is_active(&engine->execlists,
EXECLISTS_ACTIVE_USER) ==
!port_isset(engine->execlists.port));
}

static void queue_request(struct intel_engine_cs *engine,
@@ -195,6 +195,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
vc4_bo_set_label(obj, -1);

if (bo->validated_shader) {
kfree(bo->validated_shader->uniform_addr_offsets);
kfree(bo->validated_shader->texture_samples);
kfree(bo->validated_shader);
bo->validated_shader = NULL;
@@ -591,6 +592,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
}

if (bo->validated_shader) {
kfree(bo->validated_shader->uniform_addr_offsets);
kfree(bo->validated_shader->texture_samples);
kfree(bo->validated_shader);
bo->validated_shader = NULL;
@@ -942,6 +942,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
fail:
kfree(validation_state.branch_targets);
if (validated_shader) {
kfree(validated_shader->uniform_addr_offsets);
kfree(validated_shader->texture_samples);
kfree(validated_shader);
}
@@ -525,6 +525,9 @@
#define I2C_VENDOR_ID_HANTICK 0x0911
#define I2C_PRODUCT_ID_HANTICK_5288 0x5288

#define I2C_VENDOR_ID_RAYD 0x2386
#define I2C_PRODUCT_ID_RAYD_3118 0x3118

#define USB_VENDOR_ID_HANWANG 0x0b57
#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
@@ -387,7 +387,8 @@ static int hidinput_get_battery_property(struct power_supply *psy,
break;

case POWER_SUPPLY_PROP_CAPACITY:
if (dev->battery_report_type == HID_FEATURE_REPORT) {
if (dev->battery_status != HID_BATTERY_REPORTED &&
!dev->battery_avoid_query) {
value = hidinput_query_battery_capacity(dev);
if (value < 0)
return value;
@@ -403,17 +404,17 @@ static int hidinput_get_battery_property(struct power_supply *psy,
break;

case POWER_SUPPLY_PROP_STATUS:
if (!dev->battery_reported &&
dev->battery_report_type == HID_FEATURE_REPORT) {
if (dev->battery_status != HID_BATTERY_REPORTED &&
!dev->battery_avoid_query) {
value = hidinput_query_battery_capacity(dev);
if (value < 0)
return value;

dev->battery_capacity = value;
dev->battery_reported = true;
dev->battery_status = HID_BATTERY_QUERIED;
}

if (!dev->battery_reported)
if (dev->battery_status == HID_BATTERY_UNKNOWN)
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
else if (dev->battery_capacity == 100)
val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
dev->battery_report_type = report_type;
dev->battery_report_id = field->report->id;

/*
* Stylus is normally not connected to the device and thus we
* can't query the device and get meaningful battery strength.
* We have to wait for the device to report it on its own.
*/
dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
field->physical == HID_DG_STYLUS;

dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
if (IS_ERR(dev->battery)) {
error = PTR_ERR(dev->battery);
@@ -530,9 +539,10 @@ static void hidinput_update_battery(struct hid_device *dev, int value)

capacity = hidinput_scale_battery_capacity(dev, value);

if (!dev->battery_reported || capacity != dev->battery_capacity) {
if (dev->battery_status != HID_BATTERY_REPORTED ||
capacity != dev->battery_capacity) {
dev->battery_capacity = capacity;
dev->battery_reported = true;
dev->battery_status = HID_BATTERY_REPORTED;
power_supply_changed(dev->battery);
}
}
@@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
int ret = 0, len;
unsigned char report_number;

if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
ret = -ENODEV;
goto out;
}

dev = hidraw_table[minor]->hid;

if (!dev->ll_driver->raw_request) {
@@ -47,6 +47,7 @@
/* quirks to control the device */
#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
#define I2C_HID_QUIRK_RESEND_REPORT_DESCR BIT(2)

/* flags */
#define I2C_HID_STARTED 0
@@ -171,6 +172,8 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ 0, 0 }
};

@@ -1220,6 +1223,16 @@ static int i2c_hid_resume(struct device *dev)
if (ret)
return ret;

/* RAYDIUM device (2386:3118) need to re-send report descr cmd
* after resume, after this it will be back normal.
* otherwise it issues too many incomplete reports.
*/
if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) {
ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0);
if (ret)
return ret;
}

if (hid->driver && hid->driver->reset_resume) {
ret = hid->driver->reset_resume(hid);
return ret;
@@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(int tool_id)
return tool_type;
}

static void wacom_exit_report(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->pen_input;
struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data;
int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;

/*
* Reset all states otherwise we lose the initial states
* when in-prox next time
*/
input_report_abs(input, ABS_X, 0);
input_report_abs(input, ABS_Y, 0);
input_report_abs(input, ABS_DISTANCE, 0);
input_report_abs(input, ABS_TILT_X, 0);
input_report_abs(input, ABS_TILT_Y, 0);
if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
input_report_key(input, BTN_LEFT, 0);
input_report_key(input, BTN_MIDDLE, 0);
input_report_key(input, BTN_RIGHT, 0);
input_report_key(input, BTN_SIDE, 0);
input_report_key(input, BTN_EXTRA, 0);
input_report_abs(input, ABS_THROTTLE, 0);
input_report_abs(input, ABS_RZ, 0);
} else {
input_report_abs(input, ABS_PRESSURE, 0);
input_report_key(input, BTN_STYLUS, 0);
input_report_key(input, BTN_STYLUS2, 0);
input_report_key(input, BTN_TOUCH, 0);
input_report_abs(input, ABS_WHEEL, 0);
if (features->type >= INTUOS3S)
input_report_abs(input, ABS_Z, 0);
}
input_report_key(input, wacom->tool[idx], 0);
input_report_abs(input, ABS_MISC, 0); /* reset tool id */
input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
wacom->id[idx] = 0;
}

static int wacom_intuos_inout(struct wacom_wac *wacom)
{
struct wacom_features *features = &wacom->features;
@@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
if (!wacom->id[idx])
return 1;

/*
* Reset all states otherwise we lose the initial states
* when in-prox next time
*/
input_report_abs(input, ABS_X, 0);
input_report_abs(input, ABS_Y, 0);
input_report_abs(input, ABS_DISTANCE, 0);
input_report_abs(input, ABS_TILT_X, 0);
input_report_abs(input, ABS_TILT_Y, 0);
if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
input_report_key(input, BTN_LEFT, 0);
input_report_key(input, BTN_MIDDLE, 0);
input_report_key(input, BTN_RIGHT, 0);
input_report_key(input, BTN_SIDE, 0);
input_report_key(input, BTN_EXTRA, 0);
input_report_abs(input, ABS_THROTTLE, 0);
input_report_abs(input, ABS_RZ, 0);
} else {
input_report_abs(input, ABS_PRESSURE, 0);
input_report_key(input, BTN_STYLUS, 0);
input_report_key(input, BTN_STYLUS2, 0);
input_report_key(input, BTN_TOUCH, 0);
input_report_abs(input, ABS_WHEEL, 0);
if (features->type >= INTUOS3S)
input_report_abs(input, ABS_Z, 0);
}
input_report_key(input, wacom->tool[idx], 0);
input_report_abs(input, ABS_MISC, 0); /* reset tool id */
input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
wacom->id[idx] = 0;
wacom_exit_report(wacom);
return 2;
}

@@ -1235,6 +1245,12 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
if (!valid)
continue;

if (!prox) {
wacom->shared->stylus_in_proximity = false;
wacom_exit_report(wacom);
input_sync(pen_input);
return;
}
if (range) {
input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
@@ -68,12 +68,12 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
goto _do;

{
char _dup[len + 1];
char *dup, *tok, *name, *val;
int tmp;

strcpy(_dup, arg);
dup = _dup;
dup = kstrdup(arg, GFP_ATOMIC);
if (!dup)
return;

while ((tok = strsep(&dup, ","))) {
if (!strlen(tok))
@@ -89,6 +89,8 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
deftaps = tmp;
}
}

kfree(dup);
}

_do:
@@ -279,7 +279,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
u16 timebase, u8 *buf, int len)
{
u8 *p;
u8 frame[len + 32];
u8 frame[MAX_DFRAME_LEN_L1 + 32];
struct socket *socket = NULL;

if (debug & DEBUG_L1OIP_MSG)
@@ -902,7 +902,11 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
p = skb->data;
l = skb->len;
while (l) {
ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
/*
* This is technically bounded by L1OIP_MAX_PERFRAME but
* MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
*/
ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
l1oip_socket_send(hc, 0, dch->slot, 0,
hc->chan[dch->slot].tx_counter++, p, ll);
p += ll;
@@ -1140,7 +1144,11 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
p = skb->data;
l = skb->len;
while (l) {
ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
/*
* This is technically bounded by L1OIP_MAX_PERFRAME but
* MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
*/
ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
l1oip_socket_send(hc, hc->codec, bch->slot, 0,
hc->chan[bch->slot].tx_counter, p, ll);
hc->chan[bch->slot].tx_counter += ll;
@@ -9256,8 +9256,10 @@ void md_reload_sb(struct mddev *mddev, int nr)
check_sb_changes(mddev, rdev);

/* Read all rdev's to update recovery_offset */
rdev_for_each_rcu(rdev, mddev)
read_rdev(mddev, rdev);
rdev_for_each_rcu(rdev, mddev) {
if (!test_bit(Faulty, &rdev->flags))
read_rdev(mddev, rdev);
}
}
EXPORT_SYMBOL(md_reload_sb);

@@ -854,7 +854,7 @@ static void flush_pending_writes(struct r1conf *conf)
* there is no normal IO happeing. It must arrange to call
* lower_barrier when the particular background IO completes.
*/
static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr)
{
int idx = sector_to_idx(sector_nr);

@@ -885,13 +885,23 @@ static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
* max resync count which allowed on current I/O barrier bucket.
*/
wait_event_lock_irq(conf->wait_barrier,
!conf->array_frozen &&
(!conf->array_frozen &&
!atomic_read(&conf->nr_pending[idx]) &&
atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH,
atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) ||
test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery),
conf->resync_lock);

if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
atomic_dec(&conf->barrier[idx]);
spin_unlock_irq(&conf->resync_lock);
wake_up(&conf->wait_barrier);
return -EINTR;
}

atomic_inc(&conf->nr_sync_pending);
spin_unlock_irq(&conf->resync_lock);

return 0;
}

static void lower_barrier(struct r1conf *conf, sector_t sector_nr)
@@ -1092,6 +1102,8 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio,
goto skip_copy;
}

behind_bio->bi_write_hint = bio->bi_write_hint;

while (i < vcnt && size) {
struct page *page;
int len = min_t(int, PAGE_SIZE, size);
@@ -2662,9 +2674,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,

bitmap_cond_end_sync(mddev->bitmap, sector_nr,
mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
r1_bio = raid1_alloc_init_r1buf(conf);

raise_barrier(conf, sector_nr);

if (raise_barrier(conf, sector_nr))
return 0;

r1_bio = raid1_alloc_init_r1buf(conf);

rcu_read_lock();
/*
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/

#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/io-64-nonatomic-hi-lo.h>
@@ -62,6 +63,17 @@
* need a custom accessor.
*/

static unsigned long global_flags;
/*
* Workaround for avoiding to use RX DMAC by multiple channels.
* On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use
* RX DMAC simultaneously, sometimes hundreds of bytes data are not
* stored into the system memory even if the DMAC interrupt happened.
* So, this driver then uses one RX DMAC channel only.
*/
#define SDHI_INTERNAL_DMAC_ONE_RX_ONLY 0
#define SDHI_INTERNAL_DMAC_RX_IN_USE 1

/* Definitions for sampling clocks */
static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
{
@@ -126,6 +138,9 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
RST_RESERVED_BITS | val);

if (host->data && host->data->flags & MMC_DATA_READ)
clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);

renesas_sdhi_internal_dmac_enable_dma(host, true);
}

@@ -155,6 +170,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
if (data->flags & MMC_DATA_READ) {
dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
dir = DMA_FROM_DEVICE;
if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) &&
test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags))
goto force_pio;
} else {
dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
dir = DMA_TO_DEVICE;
@@ -208,6 +226,9 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
renesas_sdhi_internal_dmac_enable_dma(host, false);
dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir);

if (dir == DMA_FROM_DEVICE)
clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);

tmio_mmc_do_data_irq(host);
out:
spin_unlock_irq(&host->lock);
@@ -251,18 +272,24 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
* implementation as others may use a different implementation.
*/
static const struct soc_device_attribute gen3_soc_whitelist[] = {
{ .soc_id = "r8a7795", .revision = "ES1.*" },
{ .soc_id = "r8a7795", .revision = "ES2.0" },
{ .soc_id = "r8a7796", .revision = "ES1.0" },
{ .soc_id = "r8a77995", .revision = "ES1.0" },
{ /* sentinel */ }
{ .soc_id = "r8a7795", .revision = "ES1.*",
.data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
{ .soc_id = "r8a7795", .revision = "ES2.0" },
{ .soc_id = "r8a7796", .revision = "ES1.0",
.data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
{ .soc_id = "r8a77995", .revision = "ES1.0" },
{ /* sentinel */ }
};

static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
{
if (!soc_device_match(gen3_soc_whitelist))
const struct soc_device_attribute *soc = soc_device_match(gen3_soc_whitelist);

if (!soc)
return -ENODEV;

global_flags |= (unsigned long)soc->data;

return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
}

@@ -1312,7 +1312,7 @@ static void amd_enable_manual_tuning(struct pci_dev *pdev)
pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val);
}

static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
static int amd_execute_tuning_hs200(struct sdhci_host *host, u32 opcode)
{
struct sdhci_pci_slot *slot = sdhci_priv(host);
struct pci_dev *pdev = slot->chip->pdev;
@@ -1351,6 +1351,27 @@ static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
return 0;
}

static int amd_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host = mmc_priv(mmc);

/* AMD requires custom HS200 tuning */
if (host->timing == MMC_TIMING_MMC_HS200)
return amd_execute_tuning_hs200(host, opcode);

/* Otherwise perform standard SDHCI tuning */
return sdhci_execute_tuning(mmc, opcode);
}

static int amd_probe_slot(struct sdhci_pci_slot *slot)
{
struct mmc_host_ops *ops = &slot->host->mmc_host_ops;

ops->execute_tuning = amd_execute_tuning;

return 0;
}

static int amd_probe(struct sdhci_pci_chip *chip)
{
struct pci_dev *smbus_dev;
@@ -1385,12 +1406,12 @@ static const struct sdhci_ops amd_sdhci_pci_ops = {
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
.platform_execute_tuning = amd_execute_tuning,
};

static const struct sdhci_pci_fixes sdhci_amd = {
.probe = amd_probe,
.ops = &amd_sdhci_pci_ops,
.probe_slot = amd_probe_slot,
};

static const struct pci_device_id pci_ids[] = {
@@ -285,10 +285,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
struct sk_buff_head *rxq)
{
u16 buf[4] = { 0 }, status, seq_id;
u64 ns, timelo, timehi;
struct skb_shared_hwtstamps *shwt;
struct sk_buff_head received;
u64 ns, timelo, timehi;
unsigned long flags;
int err;

/* The latched timestamp belongs to one of the received frames. */
__skb_queue_head_init(&received);
spin_lock_irqsave(&rxq->lock, flags);
skb_queue_splice_tail_init(rxq, &received);
spin_unlock_irqrestore(&rxq->lock, flags);

mutex_lock(&chip->reg_lock);
err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
reg, buf, ARRAY_SIZE(buf));
@@ -311,7 +319,7 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
/* Since the device can only handle one time stamp at a time,
* we purge any extra frames from the queue.
*/
for ( ; skb; skb = skb_dequeue(rxq)) {
for ( ; skb; skb = __skb_dequeue(&received)) {
if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) {
ns = timehi << 16 | timelo;

@@ -1927,22 +1927,39 @@ static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen)
return retval;
}

static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen)
static void bnxt_get_pkgver(struct net_device *dev)
{
struct bnxt *bp = netdev_priv(dev);
u16 index = 0;
u32 datalen;
char *pkgver;
u32 pkglen;
u8 *pkgbuf;
int len;

if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG,
BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
&index, NULL, &datalen) != 0)
return NULL;
&index, NULL, &pkglen) != 0)
return;

memset(buf, 0, buflen);
if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0)
return NULL;
pkgbuf = kzalloc(pkglen, GFP_KERNEL);
if (!pkgbuf) {
dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n",
pkglen);
return;
}

if (bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf))
goto err;

return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf,
datalen);
pkgver = bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, pkgbuf,
pkglen);
if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
len = strlen(bp->fw_ver_str);
snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
"/pkg %s", pkgver);
}
err:
kfree(pkgbuf);
}

static int bnxt_get_eeprom(struct net_device *dev,
@@ -2615,22 +2632,10 @@ void bnxt_ethtool_init(struct bnxt *bp)
struct hwrm_selftest_qlist_input req = {0};
struct bnxt_test_info *test_info;
struct net_device *dev = bp->dev;
char *pkglog;
int i, rc;

pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL);
if (pkglog) {
char *pkgver;
int len;
bnxt_get_pkgver(dev);

pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH);
if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
len = strlen(bp->fw_ver_str);
snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
"/pkg %s", pkgver);
}
kfree(pkglog);
}
if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp))
return;

@@ -59,8 +59,6 @@ enum bnxt_nvm_directory_type {
#define BNX_DIR_ATTR_NO_CHKSUM (1 << 0)
#define BNX_DIR_ATTR_PROP_STREAM (1 << 1)

#define BNX_PKG_LOG_MAX_LENGTH 4096

enum bnxnvm_pkglog_field_index {
BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0,
BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1,
@@ -87,7 +87,7 @@ do { \

#define HNAE_AE_REGISTER 0x1

#define RCB_RING_NAME_LEN 16
#define RCB_RING_NAME_LEN (IFNAMSIZ + 4)

#define HNAE_LOWEST_LATENCY_COAL_PARAM 30
#define HNAE_LOW_LATENCY_COAL_PARAM 80
@@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev)
{
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(30000);
struct device *dev = &adapter->vdev->dev;
int retry_count = 0;
int rc;

do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
if (retry_count > IBMVNIC_MAX_QUEUES) {
netdev_warn(netdev, "Login attempts exceeded\n");
return -1;
}

adapter->init_done_rc = 0;
reinit_completion(&adapter->init_done);
rc = send_login(adapter);
if (rc) {
netdev_warn(netdev, "Unable to login\n");
return rc;
}

if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) {
netdev_warn(netdev, "Login timed out\n");
return -1;
}

if (adapter->init_done_rc == PARTIALSUCCESS) {
retry_count++;
release_sub_crqs(adapter, 1);

adapter->init_done_rc = 0;
reinit_completion(&adapter->init_done);
send_cap_queries(adapter);
if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) {
dev_err(dev, "Capabilities query timeout\n");
netdev_warn(netdev,
"Capabilities query timed out\n");
return -1;
}

rc = init_sub_crqs(adapter);
if (rc) {
dev_err(dev,
"Initialization of SCRQ's failed\n");
netdev_warn(netdev,
"SCRQ initialization failed\n");
return -1;
}

rc = init_sub_crq_irqs(adapter);
if (rc) {
dev_err(dev,
"Initialization of SCRQ's irqs failed\n");
netdev_warn(netdev,
"SCRQ irq initialization failed\n");
return -1;
}
}

reinit_completion(&adapter->init_done);
rc = send_login(adapter);
if (rc) {
dev_err(dev, "Unable to attempt device login\n");
return rc;
} else if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) {
dev_err(dev, "Login timeout\n");
} else if (adapter->init_done_rc) {
netdev_warn(netdev, "Adapter login failed\n");
return -1;
}
} while (adapter->renegotiate);
} while (adapter->init_done_rc == PARTIALSUCCESS);

/* handle pending MAC address changes after successful login */
if (adapter->mac_change_pending) {
@@ -1034,16 +1049,14 @@ static int __ibmvnic_open(struct net_device *netdev)
netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i);
if (prev_state == VNIC_CLOSED)
enable_irq(adapter->rx_scrq[i]->irq);
else
enable_scrq_irq(adapter, adapter->rx_scrq[i]);
enable_scrq_irq(adapter, adapter->rx_scrq[i]);
}

for (i = 0; i < adapter->req_tx_queues; i++) {
netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i);
if (prev_state == VNIC_CLOSED)
enable_irq(adapter->tx_scrq[i]->irq);
else
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
}

rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
@@ -1184,6 +1197,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
if (adapter->tx_scrq[i]->irq) {
netdev_dbg(netdev,
"Disabling tx_scrq[%d] irq\n", i);
disable_scrq_irq(adapter, adapter->tx_scrq[i]);
disable_irq(adapter->tx_scrq[i]->irq);
}
}
@@ -1193,6 +1207,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
if (adapter->rx_scrq[i]->irq) {
netdev_dbg(netdev,
"Disabling rx_scrq[%d] irq\n", i);
disable_scrq_irq(adapter, adapter->rx_scrq[i]);
disable_irq(adapter->rx_scrq[i]->irq);
}
}
@@ -1828,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
for (i = 0; i < adapter->req_rx_queues; i++)
napi_schedule(&adapter->napi[i]);

if (adapter->reset_reason != VNIC_RESET_FAILOVER)
if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
netdev_notify_peers(netdev);

netif_carrier_on(netdev);
@@ -2601,12 +2617,19 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
{
struct device *dev = &adapter->vdev->dev;
unsigned long rc;
u64 val;

if (scrq->hw_irq > 0x100000000ULL) {
dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
return 1;
}

val = (0xff000000) | scrq->hw_irq;
rc = plpar_hcall_norets(H_EOI, val);
if (rc)
dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
val, rc);

rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
if (rc)
@@ -3170,7 +3193,7 @@ static int send_version_xchg(struct ibmvnic_adapter *adapter)
struct vnic_login_client_data {
u8 type;
__be16 len;
char name;
char name[];
} __packed;

static int vnic_client_data_len(struct ibmvnic_adapter *adapter)
@@ -3199,21 +3222,21 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
vlcd->type = 1;
len = strlen(os_name) + 1;
vlcd->len = cpu_to_be16(len);
strncpy(&vlcd->name, os_name, len);
vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
strncpy(vlcd->name, os_name, len);
vlcd = (struct vnic_login_client_data *)(vlcd->name + len);

/* Type 2 - LPAR name */
vlcd->type = 2;
len = strlen(utsname()->nodename) + 1;
vlcd->len = cpu_to_be16(len);
strncpy(&vlcd->name, utsname()->nodename, len);
vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
strncpy(vlcd->name, utsname()->nodename, len);
vlcd = (struct vnic_login_client_data *)(vlcd->name + len);

/* Type 3 - device name */
vlcd->type = 3;
len = strlen(adapter->netdev->name) + 1;
vlcd->len = cpu_to_be16(len);
strncpy(&vlcd->name, adapter->netdev->name, len);
strncpy(vlcd->name, adapter->netdev->name, len);
}

static int send_login(struct ibmvnic_adapter *adapter)
@@ -3942,7 +3965,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
* to resend the login buffer with fewer queues requested.
*/
if (login_rsp_crq->generic.rc.code) {
adapter->renegotiate = true;
adapter->init_done_rc = login_rsp_crq->generic.rc.code;
complete(&adapter->init_done);
return 0;
}
@@ -1035,7 +1035,6 @@ struct ibmvnic_adapter {

struct ibmvnic_sub_crq_queue **tx_scrq;
struct ibmvnic_sub_crq_queue **rx_scrq;
bool renegotiate;

/* rx structs */
struct napi_struct *napi;
@@ -663,7 +663,7 @@ enum mvpp2_tag_type {
#define MVPP2_PE_VID_FILT_RANGE_END (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
#define MVPP2_PE_VID_FILT_RANGE_START (MVPP2_PE_VID_FILT_RANGE_END - \
MVPP2_PRS_VLAN_FILT_RANGE_SIZE + 1)
#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_VID_FILT_RANGE_START - 1)
#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_MAC_RANGE_START - 1)
#define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
@@ -916,6 +916,8 @@ static struct {

#define MVPP2_MIB_COUNTERS_STATS_DELAY (1 * HZ)

#define MVPP2_DESC_DMA_MASK DMA_BIT_MASK(40)

/* Definitions */

/* Shared Packet Processor resources */
@@ -1429,7 +1431,7 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
if (port->priv->hw_version == MVPP21)
return tx_desc->pp21.buf_dma_addr;
else
return tx_desc->pp22.buf_dma_addr_ptp & GENMASK_ULL(40, 0);
return tx_desc->pp22.buf_dma_addr_ptp & MVPP2_DESC_DMA_MASK;
}

static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
@@ -1447,7 +1449,7 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
} else {
u64 val = (u64)addr;

tx_desc->pp22.buf_dma_addr_ptp &= ~GENMASK_ULL(40, 0);
tx_desc->pp22.buf_dma_addr_ptp &= ~MVPP2_DESC_DMA_MASK;
tx_desc->pp22.buf_dma_addr_ptp |= val;
tx_desc->pp22.packet_offset = offset;
}
@@ -1507,7 +1509,7 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.buf_dma_addr;
else
return rx_desc->pp22.buf_dma_addr_key_hash & GENMASK_ULL(40, 0);
return rx_desc->pp22.buf_dma_addr_key_hash & MVPP2_DESC_DMA_MASK;
}

static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
@@ -1516,7 +1518,7 @@ static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.buf_cookie;
else
return rx_desc->pp22.buf_cookie_misc & GENMASK_ULL(40, 0);
return rx_desc->pp22.buf_cookie_misc & MVPP2_DESC_DMA_MASK;
}

static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
@@ -8789,7 +8791,7 @@ static int mvpp2_probe(struct platform_device *pdev)
}

if (priv->hw_version == MVPP22) {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40));
err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK);
if (err)
goto err_mg_clk;
/* Sadly, the BM pools all share the same register to
@@ -258,9 +258,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
nfp_tunnel_keep_alive(app, skb);
break;
case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH:
/* Acks from the NFP that the route is added - ignore. */
break;
default:
nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
type);
@@ -275,18 +272,49 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)

void nfp_flower_cmsg_process_rx(struct work_struct *work)
{
struct sk_buff_head cmsg_joined;
struct nfp_flower_priv *priv;
struct sk_buff *skb;

priv = container_of(work, struct nfp_flower_priv, cmsg_work);
skb_queue_head_init(&cmsg_joined);

spin_lock_bh(&priv->cmsg_skbs_high.lock);
skb_queue_splice_tail_init(&priv->cmsg_skbs_high, &cmsg_joined);
spin_unlock_bh(&priv->cmsg_skbs_high.lock);

while ((skb = skb_dequeue(&priv->cmsg_skbs)))
spin_lock_bh(&priv->cmsg_skbs_low.lock);
skb_queue_splice_tail_init(&priv->cmsg_skbs_low, &cmsg_joined);
spin_unlock_bh(&priv->cmsg_skbs_low.lock);

while ((skb = __skb_dequeue(&cmsg_joined)))
nfp_flower_cmsg_process_one_rx(priv->app, skb);
}

void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
static void
nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
{
struct nfp_flower_priv *priv = app->priv;
struct sk_buff_head *skb_head;

if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
skb_head = &priv->cmsg_skbs_high;
else
skb_head = &priv->cmsg_skbs_low;

if (skb_queue_len(skb_head) >= NFP_FLOWER_WORKQ_MAX_SKBS) {
nfp_flower_cmsg_warn(app, "Dropping queued control messages\n");
dev_kfree_skb_any(skb);
return;
}

skb_queue_tail(skb_head, skb);
schedule_work(&priv->cmsg_work);
}

void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
{
struct nfp_flower_cmsg_hdr *cmsg_hdr;

cmsg_hdr = nfp_flower_cmsg_get_hdr(skb);
@@ -306,8 +334,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
nfp_flower_process_mtu_ack(app, skb)) {
/* Handle MTU acks outside wq to prevent RTNL conflict. */
dev_consume_skb_any(skb);
} else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) {
/* Acks from the NFP that the route is added - ignore. */
dev_consume_skb_any(skb);
} else {
skb_queue_tail(&priv->cmsg_skbs, skb);
schedule_work(&priv->cmsg_work);
nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
}
}
@@ -108,6 +108,8 @@
#define NFP_FL_IPV4_TUNNEL_TYPE GENMASK(7, 4)
#define NFP_FL_IPV4_PRE_TUN_INDEX GENMASK(2, 0)

#define NFP_FLOWER_WORKQ_MAX_SKBS 30000

#define nfp_flower_cmsg_warn(app, fmt, args...) \
do { \
if (net_ratelimit()) \
@@ -519,7 +519,8 @@ static int nfp_flower_init(struct nfp_app *app)

app->priv = app_priv;
app_priv->app = app;
skb_queue_head_init(&app_priv->cmsg_skbs);
skb_queue_head_init(&app_priv->cmsg_skbs_high);
skb_queue_head_init(&app_priv->cmsg_skbs_low);
INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
init_waitqueue_head(&app_priv->reify_wait_queue);

@@ -549,7 +550,8 @@ static void nfp_flower_clean(struct nfp_app *app)
{
struct nfp_flower_priv *app_priv = app->priv;

skb_queue_purge(&app_priv->cmsg_skbs);
skb_queue_purge(&app_priv->cmsg_skbs_high);
skb_queue_purge(&app_priv->cmsg_skbs_low);
flush_work(&app_priv->cmsg_work);

nfp_flower_metadata_cleanup(app);
@@ -107,7 +107,10 @@ struct nfp_mtu_conf {
* @mask_table: Hash table used to store masks
* @flow_table: Hash table used to store flower rules
* @cmsg_work: Workqueue for control messages processing
* @cmsg_skbs: List of skbs for control message processing
* @cmsg_skbs_high: List of higher priority skbs for control message
* processing
* @cmsg_skbs_low: List of lower priority skbs for control message
* processing
* @nfp_mac_off_list: List of MAC addresses to offload
* @nfp_mac_index_list: List of unique 8-bit indexes for non NFP netdevs
* @nfp_ipv4_off_list: List of IPv4 addresses to offload
@@ -136,7 +139,8 @@ struct nfp_flower_priv {
DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
struct work_struct cmsg_work;
struct sk_buff_head cmsg_skbs;
struct sk_buff_head cmsg_skbs_high;
struct sk_buff_head cmsg_skbs_low;
struct list_head nfp_mac_off_list;
struct list_head nfp_mac_index_list;
struct list_head nfp_ipv4_off_list;
@@ -211,8 +211,11 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
break;

err = msleep_interruptible(timeout_ms);
if (err != 0)
if (err != 0) {
nfp_info(mutex->cpp,
"interrupted waiting for NFP mutex\n");
return -ERESTARTSYS;
}

if (time_is_before_eq_jiffies(warn_at)) {
warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
@@ -281,8 +281,7 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
if ((*reg & mask) == val)
return 0;

if (msleep_interruptible(25))
return -ERESTARTSYS;
msleep(25);

if (time_after(start_time, wait_until))
return -ETIMEDOUT;
@@ -350,15 +350,16 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)

real_dev = priv->real_dev;

if (!rmnet_is_real_dev_registered(real_dev))
return -ENODEV;

if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id))
goto nla_put_failure;

port = rmnet_get_port_rtnl(real_dev);
if (rmnet_is_real_dev_registered(real_dev)) {
port = rmnet_get_port_rtnl(real_dev);
f.flags = port->data_format;
} else {
f.flags = 0;
}

f.flags = port->data_format;
f.mask = ~0;

if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f))
@@ -4776,8 +4776,7 @@ static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
goto out_unlock;
}

if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id,
flow_id, filter_idx)) {
if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, flow_id, 0)) {
ret = false;
goto out_unlock;
}
@@ -5265,7 +5264,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
ids = vlan->uc;
}

filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;

/* Insert/renew filters */
for (i = 0; i < addr_count; i++) {
@@ -5334,7 +5333,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx,
int rc;
u16 *id;

filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;

efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);

@@ -2912,7 +2912,7 @@ bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
if (test_bit(index, table->used_bitmap) &&
table->spec[index].priority == EFX_FILTER_PRI_HINT &&
rps_may_expire_flow(efx->net_dev, table->spec[index].dmaq_id,
flow_id, index)) {
flow_id, 0)) {
efx_farch_filter_table_clear_entry(efx, table, index);
ret = true;
}
@@ -733,6 +733,27 @@ struct efx_rss_context {
u32 rx_indir_table[128];
};

#ifdef CONFIG_RFS_ACCEL
/**
* struct efx_async_filter_insertion - Request to asynchronously insert a filter
* @net_dev: Reference to the netdevice
* @spec: The filter to insert
* @work: Workitem for this request
* @rxq_index: Identifies the channel for which this request was made
* @flow_id: Identifies the kernel-side flow for which this request was made
*/
struct efx_async_filter_insertion {
struct net_device *net_dev;
struct efx_filter_spec spec;
struct work_struct work;
u16 rxq_index;
u32 flow_id;
};

/* Maximum number of ARFS workitems that may be in flight on an efx_nic */
#define EFX_RPS_MAX_IN_FLIGHT 8
#endif /* CONFIG_RFS_ACCEL */

/**
* struct efx_nic - an Efx NIC
* @name: Device name (net device name or bus id before net device registered)
@@ -850,6 +871,8 @@ struct efx_rss_context {
* @rps_expire_channel: Next channel to check for expiry
* @rps_expire_index: Next index to check for expiry in
* @rps_expire_channel's @rps_flow_id
* @rps_slot_map: bitmap of in-flight entries in @rps_slot
* @rps_slot: array of ARFS insertion requests for efx_filter_rfs_work()
* @active_queues: Count of RX and TX queues that haven't been flushed and drained.
* @rxq_flush_pending: Count of number of receive queues that need to be flushed.
* Decremented when the efx_flush_rx_queue() is called.
@@ -1004,6 +1027,8 @@ struct efx_nic {
struct mutex rps_mutex;
unsigned int rps_expire_channel;
unsigned int rps_expire_index;
unsigned long rps_slot_map;
struct efx_async_filter_insertion rps_slot[EFX_RPS_MAX_IN_FLIGHT];
#endif

atomic_t active_queues;
@@ -827,31 +827,16 @@ MODULE_PARM_DESC(rx_refill_threshold,

#ifdef CONFIG_RFS_ACCEL

/**
* struct efx_async_filter_insertion - Request to asynchronously insert a filter
* @net_dev: Reference to the netdevice
* @spec: The filter to insert
* @work: Workitem for this request
* @rxq_index: Identifies the channel for which this request was made
* @flow_id: Identifies the kernel-side flow for which this request was made
*/
struct efx_async_filter_insertion {
struct net_device *net_dev;
struct efx_filter_spec spec;
struct work_struct work;
u16 rxq_index;
u32 flow_id;
};

static void efx_filter_rfs_work(struct work_struct *data)
{
struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion,
work);
struct efx_nic *efx = netdev_priv(req->net_dev);
struct efx_channel *channel = efx_get_channel(efx, req->rxq_index);
int slot_idx = req - efx->rps_slot;
int rc;

rc = efx->type->filter_insert(efx, &req->spec, false);
rc = efx->type->filter_insert(efx, &req->spec, true);
if (rc >= 0) {
/* Remember this so we can check whether to expire the filter
* later.
@@ -878,8 +863,8 @@ static void efx_filter_rfs_work(struct work_struct *data)
}

/* Release references */
clear_bit(slot_idx, &efx->rps_slot_map);
dev_put(req->net_dev);
kfree(req);
}

int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
@@ -888,22 +873,36 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_async_filter_insertion *req;
struct flow_keys fk;
int slot_idx;
int rc;

if (flow_id == RPS_FLOW_ID_INVALID)
return -EINVAL;
/* find a free slot */
for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++)
if (!test_and_set_bit(slot_idx, &efx->rps_slot_map))
break;
if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT)
return -EBUSY;

if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
return -EPROTONOSUPPORT;
if (flow_id == RPS_FLOW_ID_INVALID) {
rc = -EINVAL;
goto out_clear;
}

if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6))
return -EPROTONOSUPPORT;
if (fk.control.flags & FLOW_DIS_IS_FRAGMENT)
return -EPROTONOSUPPORT;
if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) {
rc = -EPROTONOSUPPORT;
goto out_clear;
}

req = kmalloc(sizeof(*req), GFP_ATOMIC);
if (!req)
return -ENOMEM;
if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) {
rc = -EPROTONOSUPPORT;
goto out_clear;
}
if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) {
rc = -EPROTONOSUPPORT;
goto out_clear;
}

req = efx->rps_slot + slot_idx;
efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT,
efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
rxq_index);
@@ -933,6 +932,9 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
req->flow_id = flow_id;
schedule_work(&req->work);
return 0;
out_clear:
clear_bit(slot_idx, &efx->rps_slot_map);
return rc;
}

bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota)
@@ -347,7 +347,7 @@ enum power_event {
#define MTL_RX_OVERFLOW_INT BIT(16)

/* Default operating mode of the MAC */
#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | GMAC_CONFIG_ACS | \
#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | \
GMAC_CONFIG_BE | GMAC_CONFIG_DCRS)

/* To dump the core regs excluding the Address Registers */
@@ -31,13 +31,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,

value |= GMAC_CORE_INIT;

/* Clear ACS bit because Ethernet switch tagging formats such as
* Broadcom tags can look like invalid LLC/SNAP packets and cause the
* hardware to truncate packets on reception.
*/
if (netdev_uses_dsa(dev))
value &= ~GMAC_CONFIG_ACS;

if (mtu > 1500)
value |= GMAC_CONFIG_2K;
if (mtu > 2000)
@@ -3495,8 +3495,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)

/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
* Type frames (LLC/LLC-SNAP)
*
* llc_snap is never checked in GMAC >= 4, so this ACS
* feature is always disabled and packets need to be
* stripped manually.
*/
if (unlikely(status != llc_snap))
if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
unlikely(status != llc_snap))
frame_len -= ETH_FCS_LEN;

if (netif_msg_rx_status(priv)) {
@@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,

err = netdev_upper_dev_link(real_dev, dev, extack);
if (err < 0)
goto put_dev;
goto unregister;

/* need to be already registered so that ->init has run and
* the MAC addr is set
@@ -3316,8 +3316,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
macsec_del_dev(macsec);
unlink:
netdev_upper_dev_unlink(real_dev, dev);
put_dev:
dev_put(real_dev);
unregister:
unregister_netdevice(dev);
return err;
}
@@ -20,6 +20,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/microchipphy.h>
#include <linux/delay.h>

#define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>"
#define DRIVER_DESC "Microchip LAN88XX PHY driver"
@@ -30,6 +31,16 @@ struct lan88xx_priv {
__u32 wolopts;
};

static int lan88xx_read_page(struct phy_device *phydev)
{
return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS);
}

static int lan88xx_write_page(struct phy_device *phydev, int page)
{
return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
}

static int lan88xx_phy_config_intr(struct phy_device *phydev)
{
int rc;
@@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev)
return 0;
}

static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr,
u32 data)
{
int val, save_page, ret = 0;
u16 buf;

/* Save current page */
save_page = phy_save_page(phydev);
if (save_page < 0) {
pr_warn("Failed to get current page\n");
goto err;
}

/* Switch to TR page */
lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR);

ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA,
(data & 0xFFFF));
if (ret < 0) {
pr_warn("Failed to write TR low data\n");
goto err;
}

ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA,
(data & 0x00FF0000) >> 16);
if (ret < 0) {
pr_warn("Failed to write TR high data\n");
goto err;
}

/* Config control bits [15:13] of register */
buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */
buf |= 0x8000; /* Set [15] to Packet transmit */

ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf);
if (ret < 0) {
pr_warn("Failed to write data in reg\n");
goto err;
}

usleep_range(1000, 2000);/* Wait for Data to be written */
val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR);
if (!(val & 0x8000))
pr_warn("TR Register[0x%X] configuration failed\n", regaddr);
err:
return phy_restore_page(phydev, save_page, ret);
}

static void lan88xx_config_TR_regs(struct phy_device *phydev)
{
int err;

/* Get access to Channel 0x1, Node 0xF , Register 0x01.
* Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf,
* MrvlTrFix1000Kp, MasterEnableTR bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A);
if (err < 0)
pr_warn("Failed to Set Register[0x0F82]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x06.
* Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv,
* SSTrKp1000Mas bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F);
if (err < 0)
pr_warn("Failed to Set Register[0x168C]\n");

/* Get access to Channel b'10, Node b'1111, Register 0x11.
* Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh
* bits
*/
err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620);
if (err < 0)
pr_warn("Failed to Set Register[0x17A2]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x10.
* Write 24-bit value 0xEEFFDD to register. Setting
* eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000,
* eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD);
if (err < 0)
pr_warn("Failed to Set Register[0x16A0]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x13.
* Write 24-bit value 0x071448 to register. Setting
* slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448);
if (err < 0)
pr_warn("Failed to Set Register[0x16A6]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x12.
* Write 24-bit value 0x13132F to register. Setting
* slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F);
if (err < 0)
pr_warn("Failed to Set Register[0x16A4]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x14.
* Write 24-bit value 0x0 to register. Setting eee_3level_delay,
* eee_TrKf_freeze_delay bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0);
if (err < 0)
pr_warn("Failed to Set Register[0x16A8]\n");

/* Get access to Channel b'01, Node b'1111, Register 0x34.
* Write 24-bit value 0x91B06C to register. Setting
* FastMseSearchThreshLong1000, FastMseSearchThreshShort1000,
* FastMseSearchUpdGain1000 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C);
if (err < 0)
pr_warn("Failed to Set Register[0x0FE8]\n");

/* Get access to Channel b'01, Node b'1111, Register 0x3E.
* Write 24-bit value 0xC0A028 to register. Setting
* FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000,
* FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028);
if (err < 0)
pr_warn("Failed to Set Register[0x0FFC]\n");

/* Get access to Channel b'01, Node b'1111, Register 0x35.
* Write 24-bit value 0x041600 to register. Setting
* FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000,
* FastMsePhChangeDelay1000 bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600);
if (err < 0)
pr_warn("Failed to Set Register[0x0FEA]\n");

/* Get access to Channel b'10, Node b'1101, Register 0x03.
* Write 24-bit value 0x000004 to register. Setting TrFreeze bits.
*/
err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004);
if (err < 0)
pr_warn("Failed to Set Register[0x1686]\n");
}

static int lan88xx_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
@@ -132,6 +287,25 @@ static void lan88xx_set_mdix(struct phy_device *phydev)
phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0);
}

static int lan88xx_config_init(struct phy_device *phydev)
{
int val;

genphy_config_init(phydev);
/*Zerodetect delay enable */
val = phy_read_mmd(phydev, MDIO_MMD_PCS,
PHY_ARDENNES_MMD_DEV_3_PHY_CFG);
val |= PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_;

phy_write_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG,
val);

/* Config DSP registers */
lan88xx_config_TR_regs(phydev);

return 0;
}

static int lan88xx_config_aneg(struct phy_device *phydev)
{
lan88xx_set_mdix(phydev);
@@ -151,7 +325,7 @@ static struct phy_driver microchip_phy_driver[] = {
.probe = lan88xx_probe,
.remove = lan88xx_remove,

.config_init = genphy_config_init,
.config_init = lan88xx_config_init,
.config_aneg = lan88xx_config_aneg,

.ack_interrupt = lan88xx_phy_ack_interrupt,
@@ -160,6 +334,8 @@ static struct phy_driver microchip_phy_driver[] = {
.suspend = lan88xx_suspend,
.resume = genphy_resume,
.set_wol = lan88xx_set_wol,
.read_page = lan88xx_read_page,
.write_page = lan88xx_write_page,
} };

module_phy_driver(microchip_phy_driver);
@@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team,
}
}

static bool __team_option_inst_tmp_find(const struct list_head *opts,
const struct team_option_inst *needle)
{
struct team_option_inst *opt_inst;

list_for_each_entry(opt_inst, opts, tmp_list)
if (opt_inst == needle)
return true;
return false;
}

static int __team_options_register(struct team *team,
const struct team_option *option,
size_t option_count)
@@ -2568,6 +2579,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
if (err)
goto team_put;
opt_inst->changed = true;

/* dumb/evil user-space can send us duplicate opt,
* keep only the last one
*/
if (__team_option_inst_tmp_find(&opt_inst_list,
opt_inst))
continue;

list_add(&opt_inst->tmp_list, &opt_inst_list);
}
if (!opt_found) {
@@ -1102,12 +1102,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop;

len = run_ebpf_filter(tun, skb, len);

/* Trim extra bytes since we may insert vlan proto & TCI
* in tun_put_user().
*/
len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0;
if (len <= 0 || pskb_trim(skb, len))
if (len == 0 || pskb_trim(skb, len))
goto drop;

if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
@@ -1107,6 +1107,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */
{QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */
{QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */
{QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */
{QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
{QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */
{QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */