Merge 6.12.11 into android16-6.12
GKI (arm64) relevant 28 out of 122 changes, affecting 34 files +368/-94cccd51dd22bpf: Fix bpf_sk_select_reuseport() memory leak [1 file, +18/-12]1654578a3bcpuidle: teo: Update documentation after previous changes [1 file, +48/-43]7a4fd3df85net: make page_pool_ref_netmem work with net iovs [1 file, +1/-1]2b78cab481netdev: avoid CFI problems with sock priv helpers [2 files, +25/-5]e19f31169fi2c: core: fix reference leak in i2c_register_adapter() [1 file, +1/-0]b856d2c138mac802154: check local interfaces before deleting sdata list [1 file, +4/-0]7c37879b76fs: fix missing declaration of init_files [1 file, +1/-0]3d46037625netfs: Fix non-contiguous donation between completed reads [1 file, +5/-4]ac216ffa69scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers [1 file, +6/-3]402ce16421iomap: avoid avoid truncating 64-bit offset to 32 bits [1 file, +1/-1]621f95fa0bpoll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll() [1 file, +9/-1]e98394f7bcsched/fair: Fix update_cfs_group() vs DELAY_DEQUEUE [1 file, +5/-1]902ef8f16dzram: fix potential UAF of zram table [1 file, +1/-0]6771e1279dvsock/bpf: return early if transport is not assigned [1 file, +9/-0]677579b641vsock/virtio: discard packets if the transport changes [1 file, +5/-2]450aa12993vsock/virtio: cancel close work in the destructor [1 file, +21/-8]01c178d690vsock: reset socket state when de-assigning the transport [1 file, +9/-0]c23d1d4f8evsock: prevent null-ptr-deref in vsock_*[has_data|has_space] [1 file, +9/-0]280f1fb89afilemap: avoid truncating 64-bit offset to 32 bits [1 file, +1/-1]310ac886d6mm: clear uffd-wp PTE/PMD state on mremap() [4 files, +68/-2]c78b04977dmm: vmscan : pgdemote vmstat is not getting updated when MGLRU is enabled. [1 file, +3/-0]e96a2838d8tracing: gfp: Fix the GFP enum values shown for user space tracing tools [1 file, +63/-0]115719a953irqchip: Plug a OF node reference leak in platform_irqchip_probe() [1 file, +1/-3]44feb76129irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly [1 file, +1/-1]93955a7788irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity() [1 file, +1/-1]38492f6ee8hrtimers: Handle CPU state correctly on hotplug [3 files, +12/-2]12ead225b7timers/migration: Fix another race between hotplug and idle entry/exit [1 file, +28/-1]6e641d499btimers/migration: Enforce group initialization visibility to tree walkers [1 file, +12/-2] Changes in 6.12.11 efi/zboot: Limit compression options to GZIP and ZSTD net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field() bpf: Fix bpf_sk_select_reuseport() memory leak eth: bnxt: always recalculate features after XDP clearing, fix null-deref net: ravb: Fix max TX frame size for RZ/V2M openvswitch: fix lockup on tx to unregistering netdev with carrier pktgen: Avoid out-of-bounds access in get_imix_entries ice: Fix E825 initialization ice: Fix quad registers read on E825 ice: Fix ETH56G FC-FEC Rx offset value ice: Introduce ice_get_phy_model() wrapper ice: Add ice_get_ctrl_ptp() wrapper to simplify the code ice: Use ice_adapter for PTP shared data instead of auxdev ice: Add correct PHY lane assignment cpuidle: teo: Update documentation after previous changes btrfs: add the missing error handling inside get_canonical_dev_path gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp(). gtp: Destroy device along with udp socket's netns dismantle. pfcp: Destroy device along with udp socket's netns dismantle. cpufreq: Move endif to the end of Kconfig file nfp: bpf: prevent integer overflow in nfp_bpf_event_output() net: xilinx: axienet: Fix IRQ coalescing packet count overflow net: fec: handle page_pool_dev_alloc_pages error net: make page_pool_ref_netmem work with net iovs net/mlx5: Fix RDMA TX steering prio net/mlx5: Fix a lockdep warning as part of the write combining test net/mlx5: SF, Fix add port error handling net/mlx5: Clear port select structure when fail to create net/mlx5e: Fix inversion dependency warning while enabling IPsec tunnel net/mlx5e: Rely on reqid in IPsec tunnel mode net/mlx5e: Always start IPsec sequence number from 1 netdev: avoid CFI problems with sock priv helpers drm/tests: helpers: Fix compiler warning drm/vmwgfx: Unreserve BO on error drm/vmwgfx: Add new keep_resv BO param drm/v3d: Ensure job pointer is set to NULL after job completion reset: rzg2l-usbphy-ctrl: Assign proper of node to the allocated device soc: ti: pruss: Fix pruss APIs i2c: core: fix reference leak in i2c_register_adapter() platform/x86: dell-uart-backlight: fix serdev race platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: fix serdev race hwmon: (tmp513) Fix division of negative numbers Revert "mtd: spi-nor: core: replace dummy buswidth from addr to data" i2c: mux: demux-pinctrl: check initial mux selection, too i2c: rcar: fix NACK handling when being a target i2c: testunit: on errors, repeat NACK until STOP hwmon: (ltc2991) Fix mixed signed/unsigned in DIV_ROUND_CLOSEST smb: client: fix double free of TCP_Server_Info::hostname mac802154: check local interfaces before deleting sdata list hfs: Sanity check the root record fs/qnx6: Fix building with GCC 15 fs: fix missing declaration of init_files kheaders: Ignore silly-rename files netfs: Fix non-contiguous donation between completed reads cachefiles: Parse the "secctx" immediately scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers gpio: virtuser: lock up configfs that an instantiated device depends on gpio: sim: lock up configfs that an instantiated device depends on selftests: tc-testing: reduce rshift value platform/x86/intel: power-domains: Add Clearwater Forest support platform/x86: ISST: Add Clearwater Forest to support list ACPI: resource: acpi_dev_irq_override(): Check DMI match last sched_ext: keep running prev when prev->scx.slice != 0 iomap: avoid avoid truncating 64-bit offset to 32 bits afs: Fix merge preference rule failure condition poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll() selftests/sched_ext: fix build after renames in sched_ext API scx: Fix maximal BPF selftest prog RDMA/bnxt_re: Fix to export port num to ib_query_qp sched_ext: Fix dsq_local_on selftest nvmet: propagate npwg topology sched/fair: Fix update_cfs_group() vs DELAY_DEQUEUE x86/asm: Make serialize() always_inline ALSA: hda/realtek: Add support for Ayaneo System using CS35L41 HDA ALSA: hda/realtek: fixup ASUS GA605W ALSA: hda/realtek: fixup ASUS H7606W zram: fix potential UAF of zram table i2c: atr: Fix client detach mptcp: be sure to send ack when mptcp-level window re-opens mptcp: fix spurious wake-up on under memory pressure selftests: mptcp: avoid spurious errors on disconnect net: ethernet: xgbe: re-add aneg to supported features in PHY quirks vsock/bpf: return early if transport is not assigned vsock/virtio: discard packets if the transport changes vsock/virtio: cancel close work in the destructor vsock: reset socket state when de-assigning the transport vsock: prevent null-ptr-deref in vsock_*[has_data|has_space] nouveau/fence: handle cross device fences properly drm/nouveau/disp: Fix missing backlight control on Macbook 5,1 net/ncsi: fix locking in Get MAC Address handling filemap: avoid truncating 64-bit offset to 32 bits fs/proc: fix softlockup in __read_vmcore (part 2) gpio: xilinx: Convert gpio_lock to raw spinlock tools: fix atomic_set() definition to set the value correctly pmdomain: imx8mp-blk-ctrl: add missing loop break condition mm/kmemleak: fix percpu memory leak detection failure selftests/mm: set allocated memory to non-zero content in cow test drm/amd/display: Do not elevate mem_type change to full update mm: clear uffd-wp PTE/PMD state on mremap() mm: vmscan : pgdemote vmstat is not getting updated when MGLRU is enabled. tracing: gfp: Fix the GFP enum values shown for user space tracing tools irqchip: Plug a OF node reference leak in platform_irqchip_probe() irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity() hrtimers: Handle CPU state correctly on hotplug timers/migration: Fix another race between hotplug and idle entry/exit timers/migration: Enforce group initialization visibility to tree walkers x86/fred: Fix the FRED RSP0 MSR out of sync with its per-CPU cache drm/i915/fb: Relax clear color alignment to 64 bytes drm/xe: Mark ComputeCS read mode as UC on iGPU drm/xe/oa: Add missing VISACTL mux registers drm/amdgpu/smu13: update powersave optimizations drm/amdgpu: fix fw attestation for MP0_14_0_{2/3} drm/amdgpu: disable gfxoff with the compute workload on gfx12 drm/amdgpu: always sync the GFX pipe on ctx switch drm/amd/display: Fix PSR-SU not support but still call the amdgpu_dm_psr_enable drm/amd/display: Disable replay and psr while VRR is enabled drm/amd/display: Do not wait for PSR disable on vbl enable Revert "drm/amd/display: Enable urgent latency adjustments for DCN35" drm/amd/display: Validate mdoe under MST LCT=1 case as well apparmor: allocate xmatch for nullpdb inside aa_alloc_null Linux 6.12.11 Change-Id: I44fe9d80e5229632bb5dcbab4d39302fa03c099f Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 10
|
||||
SUBLEVEL = 11
|
||||
EXTRAVERSION =
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ fail:
|
||||
|
||||
#define nop() asm volatile ("nop")
|
||||
|
||||
static inline void serialize(void)
|
||||
static __always_inline void serialize(void)
|
||||
{
|
||||
/* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */
|
||||
asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory");
|
||||
|
||||
@@ -50,7 +50,13 @@ void cpu_init_fred_exceptions(void)
|
||||
FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user));
|
||||
|
||||
wrmsrl(MSR_IA32_FRED_STKLVLS, 0);
|
||||
wrmsrl(MSR_IA32_FRED_RSP0, 0);
|
||||
|
||||
/*
|
||||
* Ater a CPU offline/online cycle, the FRED RSP0 MSR should be
|
||||
* resynchronized with its per-CPU cache.
|
||||
*/
|
||||
wrmsrl(MSR_IA32_FRED_RSP0, __this_cpu_read(fred_rsp0));
|
||||
|
||||
wrmsrl(MSR_IA32_FRED_RSP1, 0);
|
||||
wrmsrl(MSR_IA32_FRED_RSP2, 0);
|
||||
wrmsrl(MSR_IA32_FRED_RSP3, 0);
|
||||
|
||||
@@ -689,11 +689,11 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
|
||||
for (i = 0; i < ARRAY_SIZE(override_table); i++) {
|
||||
const struct irq_override_cmp *entry = &override_table[i];
|
||||
|
||||
if (dmi_check_system(entry->system) &&
|
||||
entry->irq == gsi &&
|
||||
if (entry->irq == gsi &&
|
||||
entry->triggering == triggering &&
|
||||
entry->polarity == polarity &&
|
||||
entry->shareable == shareable)
|
||||
entry->shareable == shareable &&
|
||||
dmi_check_system(entry->system))
|
||||
return entry->override;
|
||||
}
|
||||
|
||||
|
||||
@@ -1349,6 +1349,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
|
||||
zram->mem_pool = zs_create_pool(zram->disk->disk_name);
|
||||
if (!zram->mem_pool) {
|
||||
vfree(zram->table);
|
||||
zram->table = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -341,8 +341,6 @@ config QORIQ_CPUFREQ
|
||||
This adds the CPUFreq driver support for Freescale QorIQ SoCs
|
||||
which are capable of changing the CPU's frequency dynamically.
|
||||
|
||||
endif
|
||||
|
||||
config ACPI_CPPC_CPUFREQ
|
||||
tristate "CPUFreq driver based on the ACPI CPPC spec"
|
||||
depends on ACPI_PROCESSOR
|
||||
@@ -371,4 +369,6 @@ config ACPI_CPPC_CPUFREQ_FIE
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -10,25 +10,27 @@
|
||||
* DOC: teo-description
|
||||
*
|
||||
* The idea of this governor is based on the observation that on many systems
|
||||
* timer events are two or more orders of magnitude more frequent than any
|
||||
* other interrupts, so they are likely to be the most significant cause of CPU
|
||||
* wakeups from idle states. Moreover, information about what happened in the
|
||||
* (relatively recent) past can be used to estimate whether or not the deepest
|
||||
* idle state with target residency within the (known) time till the closest
|
||||
* timer event, referred to as the sleep length, is likely to be suitable for
|
||||
* the upcoming CPU idle period and, if not, then which of the shallower idle
|
||||
* states to choose instead of it.
|
||||
* timer interrupts are two or more orders of magnitude more frequent than any
|
||||
* other interrupt types, so they are likely to dominate CPU wakeup patterns.
|
||||
* Moreover, in principle, the time when the next timer event is going to occur
|
||||
* can be determined at the idle state selection time, although doing that may
|
||||
* be costly, so it can be regarded as the most reliable source of information
|
||||
* for idle state selection.
|
||||
*
|
||||
* Of course, non-timer wakeup sources are more important in some use cases
|
||||
* which can be covered by taking a few most recent idle time intervals of the
|
||||
* CPU into account. However, even in that context it is not necessary to
|
||||
* consider idle duration values greater than the sleep length, because the
|
||||
* closest timer will ultimately wake up the CPU anyway unless it is woken up
|
||||
* earlier.
|
||||
* Of course, non-timer wakeup sources are more important in some use cases,
|
||||
* but even then it is generally unnecessary to consider idle duration values
|
||||
* greater than the time time till the next timer event, referred as the sleep
|
||||
* length in what follows, because the closest timer will ultimately wake up the
|
||||
* CPU anyway unless it is woken up earlier.
|
||||
*
|
||||
* Thus this governor estimates whether or not the prospective idle duration of
|
||||
* a CPU is likely to be significantly shorter than the sleep length and selects
|
||||
* an idle state for it accordingly.
|
||||
* However, since obtaining the sleep length may be costly, the governor first
|
||||
* checks if it can select a shallow idle state using wakeup pattern information
|
||||
* from recent times, in which case it can do without knowing the sleep length
|
||||
* at all. For this purpose, it counts CPU wakeup events and looks for an idle
|
||||
* state whose target residency has not exceeded the idle duration (measured
|
||||
* after wakeup) in the majority of relevant recent cases. If the target
|
||||
* residency of that state is small enough, it may be used right away and the
|
||||
* sleep length need not be determined.
|
||||
*
|
||||
* The computations carried out by this governor are based on using bins whose
|
||||
* boundaries are aligned with the target residency parameter values of the CPU
|
||||
@@ -39,7 +41,11 @@
|
||||
* idle state 2, the third bin spans from the target residency of idle state 2
|
||||
* up to, but not including, the target residency of idle state 3 and so on.
|
||||
* The last bin spans from the target residency of the deepest idle state
|
||||
* supplied by the driver to infinity.
|
||||
* supplied by the driver to the scheduler tick period length or to infinity if
|
||||
* the tick period length is less than the target residency of that state. In
|
||||
* the latter case, the governor also counts events with the measured idle
|
||||
* duration between the tick period length and the target residency of the
|
||||
* deepest idle state.
|
||||
*
|
||||
* Two metrics called "hits" and "intercepts" are associated with each bin.
|
||||
* They are updated every time before selecting an idle state for the given CPU
|
||||
@@ -49,47 +55,46 @@
|
||||
* sleep length and the idle duration measured after CPU wakeup fall into the
|
||||
* same bin (that is, the CPU appears to wake up "on time" relative to the sleep
|
||||
* length). In turn, the "intercepts" metric reflects the relative frequency of
|
||||
* situations in which the measured idle duration is so much shorter than the
|
||||
* sleep length that the bin it falls into corresponds to an idle state
|
||||
* shallower than the one whose bin is fallen into by the sleep length (these
|
||||
* situations are referred to as "intercepts" below).
|
||||
* non-timer wakeup events for which the measured idle duration falls into a bin
|
||||
* that corresponds to an idle state shallower than the one whose bin is fallen
|
||||
* into by the sleep length (these events are also referred to as "intercepts"
|
||||
* below).
|
||||
*
|
||||
* In order to select an idle state for a CPU, the governor takes the following
|
||||
* steps (modulo the possible latency constraint that must be taken into account
|
||||
* too):
|
||||
*
|
||||
* 1. Find the deepest CPU idle state whose target residency does not exceed
|
||||
* the current sleep length (the candidate idle state) and compute 2 sums as
|
||||
* follows:
|
||||
* 1. Find the deepest enabled CPU idle state (the candidate idle state) and
|
||||
* compute 2 sums as follows:
|
||||
*
|
||||
* - The sum of the "hits" and "intercepts" metrics for the candidate state
|
||||
* and all of the deeper idle states (it represents the cases in which the
|
||||
* CPU was idle long enough to avoid being intercepted if the sleep length
|
||||
* had been equal to the current one).
|
||||
* - The sum of the "hits" metric for all of the idle states shallower than
|
||||
* the candidate one (it represents the cases in which the CPU was likely
|
||||
* woken up by a timer).
|
||||
*
|
||||
* - The sum of the "intercepts" metrics for all of the idle states shallower
|
||||
* than the candidate one (it represents the cases in which the CPU was not
|
||||
* idle long enough to avoid being intercepted if the sleep length had been
|
||||
* equal to the current one).
|
||||
* - The sum of the "intercepts" metric for all of the idle states shallower
|
||||
* than the candidate one (it represents the cases in which the CPU was
|
||||
* likely woken up by a non-timer wakeup source).
|
||||
*
|
||||
* 2. If the second sum is greater than the first one the CPU is likely to wake
|
||||
* up early, so look for an alternative idle state to select.
|
||||
* 2. If the second sum computed in step 1 is greater than a half of the sum of
|
||||
* both metrics for the candidate state bin and all subsequent bins(if any),
|
||||
* a shallower idle state is likely to be more suitable, so look for it.
|
||||
*
|
||||
* - Traverse the idle states shallower than the candidate one in the
|
||||
* - Traverse the enabled idle states shallower than the candidate one in the
|
||||
* descending order.
|
||||
*
|
||||
* - For each of them compute the sum of the "intercepts" metrics over all
|
||||
* of the idle states between it and the candidate one (including the
|
||||
* former and excluding the latter).
|
||||
*
|
||||
* - If each of these sums that needs to be taken into account (because the
|
||||
* check related to it has indicated that the CPU is likely to wake up
|
||||
* early) is greater than a half of the corresponding sum computed in step
|
||||
* 1 (which means that the target residency of the state in question had
|
||||
* not exceeded the idle duration in over a half of the relevant cases),
|
||||
* select the given idle state instead of the candidate one.
|
||||
* - If this sum is greater than a half of the second sum computed in step 1,
|
||||
* use the given idle state as the new candidate one.
|
||||
*
|
||||
* 3. By default, select the candidate state.
|
||||
* 3. If the current candidate state is state 0 or its target residency is short
|
||||
* enough, return it and prevent the scheduler tick from being stopped.
|
||||
*
|
||||
* 4. Obtain the sleep length value and check if it is below the target
|
||||
* residency of the current candidate state, in which case a new shallower
|
||||
* candidate state needs to be found, so look for it.
|
||||
*/
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
|
||||
@@ -76,10 +76,6 @@ config EFI_ZBOOT
|
||||
bool "Enable the generic EFI decompressor"
|
||||
depends on EFI_GENERIC_STUB && !ARM
|
||||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_LZ4
|
||||
select HAVE_KERNEL_LZMA
|
||||
select HAVE_KERNEL_LZO
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_KERNEL_ZSTD
|
||||
help
|
||||
Create the bootable image as an EFI application that carries the
|
||||
|
||||
@@ -12,22 +12,16 @@ quiet_cmd_copy_and_pad = PAD $@
|
||||
$(obj)/vmlinux.bin: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
|
||||
$(call if_changed,copy_and_pad)
|
||||
|
||||
comp-type-$(CONFIG_KERNEL_GZIP) := gzip
|
||||
comp-type-$(CONFIG_KERNEL_LZ4) := lz4
|
||||
comp-type-$(CONFIG_KERNEL_LZMA) := lzma
|
||||
comp-type-$(CONFIG_KERNEL_LZO) := lzo
|
||||
comp-type-$(CONFIG_KERNEL_XZ) := xzkern
|
||||
comp-type-$(CONFIG_KERNEL_ZSTD) := zstd22
|
||||
|
||||
# in GZIP, the appended le32 carrying the uncompressed size is part of the
|
||||
# format, but in other cases, we just append it at the end for convenience,
|
||||
# causing the original tools to complain when checking image integrity.
|
||||
# So disregard it when calculating the payload size in the zimage header.
|
||||
zboot-method-y := $(comp-type-y)_with_size
|
||||
zboot-size-len-y := 4
|
||||
comp-type-y := gzip
|
||||
zboot-method-y := gzip
|
||||
zboot-size-len-y := 0
|
||||
|
||||
zboot-method-$(CONFIG_KERNEL_GZIP) := gzip
|
||||
zboot-size-len-$(CONFIG_KERNEL_GZIP) := 0
|
||||
comp-type-$(CONFIG_KERNEL_ZSTD) := zstd
|
||||
zboot-method-$(CONFIG_KERNEL_ZSTD) := zstd22_with_size
|
||||
zboot-size-len-$(CONFIG_KERNEL_ZSTD) := 4
|
||||
|
||||
$(obj)/vmlinuz: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,$(zboot-method-y))
|
||||
|
||||
+41
-7
@@ -1030,6 +1030,30 @@ static void gpio_sim_device_deactivate(struct gpio_sim_device *dev)
|
||||
dev->pdev = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock)
|
||||
{
|
||||
struct configfs_subsystem *subsys = dev->group.cg_subsys;
|
||||
struct gpio_sim_bank *bank;
|
||||
struct gpio_sim_line *line;
|
||||
|
||||
/*
|
||||
* The device only needs to depend on leaf line entries. This is
|
||||
* sufficient to lock up all the configfs entries that the
|
||||
* instantiated, alive device depends on.
|
||||
*/
|
||||
list_for_each_entry(bank, &dev->bank_list, siblings) {
|
||||
list_for_each_entry(line, &bank->line_list, siblings) {
|
||||
if (lock)
|
||||
WARN_ON(configfs_depend_item_unlocked(
|
||||
subsys, &line->group.cg_item));
|
||||
else
|
||||
configfs_undepend_item_unlocked(
|
||||
&line->group.cg_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
gpio_sim_device_config_live_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
@@ -1042,14 +1066,24 @@ gpio_sim_device_config_live_store(struct config_item *item,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(mutex)(&dev->lock);
|
||||
if (live)
|
||||
gpio_sim_device_lockup_configfs(dev, true);
|
||||
|
||||
if (live == gpio_sim_device_is_live(dev))
|
||||
ret = -EPERM;
|
||||
else if (live)
|
||||
ret = gpio_sim_device_activate(dev);
|
||||
else
|
||||
gpio_sim_device_deactivate(dev);
|
||||
scoped_guard(mutex, &dev->lock) {
|
||||
if (live == gpio_sim_device_is_live(dev))
|
||||
ret = -EPERM;
|
||||
else if (live)
|
||||
ret = gpio_sim_device_activate(dev);
|
||||
else
|
||||
gpio_sim_device_deactivate(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Undepend is required only if device disablement (live == 0)
|
||||
* succeeds or if device enablement (live == 1) fails.
|
||||
*/
|
||||
if (live == !!ret)
|
||||
gpio_sim_device_lockup_configfs(dev, false);
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
@@ -1546,6 +1546,30 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
|
||||
dev->pdev = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gpio_virtuser_device_lockup_configfs(struct gpio_virtuser_device *dev, bool lock)
|
||||
{
|
||||
struct configfs_subsystem *subsys = dev->group.cg_subsys;
|
||||
struct gpio_virtuser_lookup_entry *entry;
|
||||
struct gpio_virtuser_lookup *lookup;
|
||||
|
||||
/*
|
||||
* The device only needs to depend on leaf lookup entries. This is
|
||||
* sufficient to lock up all the configfs entries that the
|
||||
* instantiated, alive device depends on.
|
||||
*/
|
||||
list_for_each_entry(lookup, &dev->lookup_list, siblings) {
|
||||
list_for_each_entry(entry, &lookup->entry_list, siblings) {
|
||||
if (lock)
|
||||
WARN_ON(configfs_depend_item_unlocked(
|
||||
subsys, &entry->group.cg_item));
|
||||
else
|
||||
configfs_undepend_item_unlocked(
|
||||
&entry->group.cg_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
gpio_virtuser_device_config_live_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
@@ -1558,15 +1582,24 @@ gpio_virtuser_device_config_live_store(struct config_item *item,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
if (live == gpio_virtuser_device_is_live(dev))
|
||||
return -EPERM;
|
||||
|
||||
if (live)
|
||||
ret = gpio_virtuser_device_activate(dev);
|
||||
else
|
||||
gpio_virtuser_device_deactivate(dev);
|
||||
gpio_virtuser_device_lockup_configfs(dev, true);
|
||||
|
||||
scoped_guard(mutex, &dev->lock) {
|
||||
if (live == gpio_virtuser_device_is_live(dev))
|
||||
ret = -EPERM;
|
||||
else if (live)
|
||||
ret = gpio_virtuser_device_activate(dev);
|
||||
else
|
||||
gpio_virtuser_device_deactivate(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Undepend is required only if device disablement (live == 0)
|
||||
* succeeds or if device enablement (live == 1) fails.
|
||||
*/
|
||||
if (live == !!ret)
|
||||
gpio_virtuser_device_lockup_configfs(dev, false);
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
+16
-16
@@ -65,7 +65,7 @@ struct xgpio_instance {
|
||||
DECLARE_BITMAP(state, 64);
|
||||
DECLARE_BITMAP(last_irq_read, 64);
|
||||
DECLARE_BITMAP(dir, 64);
|
||||
spinlock_t gpio_lock; /* For serializing operations */
|
||||
raw_spinlock_t gpio_lock; /* For serializing operations */
|
||||
int irq;
|
||||
DECLARE_BITMAP(enable, 64);
|
||||
DECLARE_BITMAP(rising_edge, 64);
|
||||
@@ -179,14 +179,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int bit = xgpio_to_bit(chip, gpio);
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
/* Write to GPIO signal and set its direction to output */
|
||||
__assign_bit(bit, chip->state, val);
|
||||
|
||||
xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +210,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
|
||||
bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);
|
||||
|
||||
@@ -218,7 +218,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
|
||||
bitmap_copy(chip->state, state, 64);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,13 +236,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int bit = xgpio_to_bit(chip, gpio);
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
/* Set the GPIO bit in shadow register and set direction as input */
|
||||
__set_bit(bit, chip->dir);
|
||||
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int bit = xgpio_to_bit(chip, gpio);
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
/* Write state of GPIO signal */
|
||||
__assign_bit(bit, chip->state, val);
|
||||
@@ -275,7 +275,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
__clear_bit(bit, chip->dir);
|
||||
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -398,7 +398,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
|
||||
int bit = xgpio_to_bit(chip, irq_offset);
|
||||
u32 mask = BIT(bit / 32), temp;
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
__clear_bit(bit, chip->enable);
|
||||
|
||||
@@ -408,7 +408,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
|
||||
temp &= ~mask;
|
||||
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
|
||||
}
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
|
||||
gpiochip_disable_irq(&chip->gc, irq_offset);
|
||||
}
|
||||
@@ -428,7 +428,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
|
||||
|
||||
gpiochip_enable_irq(&chip->gc, irq_offset);
|
||||
|
||||
spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
|
||||
|
||||
__set_bit(bit, chip->enable);
|
||||
|
||||
@@ -447,7 +447,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
|
||||
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,7 +512,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
|
||||
|
||||
chained_irq_enter(irqchip, desc);
|
||||
|
||||
spin_lock(&chip->gpio_lock);
|
||||
raw_spin_lock(&chip->gpio_lock);
|
||||
|
||||
xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
|
||||
|
||||
@@ -529,7 +529,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
|
||||
bitmap_copy(chip->last_irq_read, all, 64);
|
||||
bitmap_or(all, rising, falling, 64);
|
||||
|
||||
spin_unlock(&chip->gpio_lock);
|
||||
raw_spin_unlock(&chip->gpio_lock);
|
||||
|
||||
dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
|
||||
|
||||
@@ -620,7 +620,7 @@ static int xgpio_probe(struct platform_device *pdev)
|
||||
bitmap_set(chip->hw_map, 0, width[0]);
|
||||
bitmap_set(chip->hw_map, 32, width[1]);
|
||||
|
||||
spin_lock_init(&chip->gpio_lock);
|
||||
raw_spin_lock_init(&chip->gpio_lock);
|
||||
|
||||
chip->gc.base = -1;
|
||||
chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
|
||||
|
||||
@@ -715,8 +715,9 @@ err:
|
||||
void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
|
||||
{
|
||||
enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE;
|
||||
if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
|
||||
((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) {
|
||||
if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
|
||||
((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) ||
|
||||
(IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 12)) {
|
||||
pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
|
||||
amdgpu_gfx_off_ctrl(adev, idle);
|
||||
} else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) &&
|
||||
|
||||
@@ -122,6 +122,10 @@ static int amdgpu_is_fw_attestation_supported(struct amdgpu_device *adev)
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return 0;
|
||||
|
||||
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(14, 0, 2) ||
|
||||
amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(14, 0, 3))
|
||||
return 0;
|
||||
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID)
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -193,8 +193,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
||||
need_ctx_switch = ring->current_ctx != fence_ctx;
|
||||
if (ring->funcs->emit_pipeline_sync && job &&
|
||||
((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) ||
|
||||
(amdgpu_sriov_vf(adev) && need_ctx_switch) ||
|
||||
amdgpu_vm_need_pipeline_sync(ring, job))) {
|
||||
need_ctx_switch || amdgpu_vm_need_pipeline_sync(ring, job))) {
|
||||
|
||||
need_pipe_sync = true;
|
||||
|
||||
if (tmp)
|
||||
|
||||
@@ -8889,6 +8889,7 @@ static void amdgpu_dm_enable_self_refresh(struct amdgpu_crtc *acrtc_attach,
|
||||
struct replay_settings *pr = &acrtc_state->stream->link->replay_settings;
|
||||
struct amdgpu_dm_connector *aconn =
|
||||
(struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
|
||||
bool vrr_active = amdgpu_dm_crtc_vrr_active(acrtc_state);
|
||||
|
||||
if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
|
||||
if (pr->config.replay_supported && !pr->replay_feature_enabled)
|
||||
@@ -8915,14 +8916,15 @@ static void amdgpu_dm_enable_self_refresh(struct amdgpu_crtc *acrtc_attach,
|
||||
* adequate number of fast atomic commits to notify KMD
|
||||
* of update events. See `vblank_control_worker()`.
|
||||
*/
|
||||
if (acrtc_attach->dm_irq_params.allow_sr_entry &&
|
||||
if (!vrr_active &&
|
||||
acrtc_attach->dm_irq_params.allow_sr_entry &&
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
!amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
|
||||
#endif
|
||||
(current_ts - psr->psr_dirty_rects_change_timestamp_ns) > 500000000) {
|
||||
if (pr->replay_feature_enabled && !pr->replay_allow_active)
|
||||
amdgpu_dm_replay_enable(acrtc_state->stream, true);
|
||||
if (psr->psr_version >= DC_PSR_VERSION_SU_1 &&
|
||||
if (psr->psr_version == DC_PSR_VERSION_SU_1 &&
|
||||
!psr->psr_allow_active && !aconn->disallow_edp_enter_psr)
|
||||
amdgpu_dm_psr_enable(acrtc_state->stream);
|
||||
}
|
||||
@@ -9093,7 +9095,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
acrtc_state->stream->link->psr_settings.psr_dirty_rects_change_timestamp_ns =
|
||||
timestamp_ns;
|
||||
if (acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream, true);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
}
|
||||
}
|
||||
@@ -9259,11 +9261,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
bundle->stream_update.abm_level = &acrtc_state->abm_level;
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
|
||||
if ((acrtc_state->update_type > UPDATE_TYPE_FAST) || vrr_active) {
|
||||
if (acrtc_state->stream->link->replay_settings.replay_allow_active)
|
||||
amdgpu_dm_replay_disable(acrtc_state->stream);
|
||||
if (acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream, true);
|
||||
}
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
@@ -11370,6 +11372,25 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *new_plane_state, *old_plane_state;
|
||||
|
||||
drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
|
||||
new_plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
old_plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
|
||||
if (old_plane_state->fb && new_plane_state->fb &&
|
||||
get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
|
||||
*
|
||||
@@ -11567,10 +11588,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
|
||||
/* Remove exiting planes if they are modified */
|
||||
for_each_oldnew_plane_in_descending_zpos(state, plane, old_plane_state, new_plane_state) {
|
||||
if (old_plane_state->fb && new_plane_state->fb &&
|
||||
get_mem_type(old_plane_state->fb) !=
|
||||
get_mem_type(new_plane_state->fb))
|
||||
lock_and_validation_needed = true;
|
||||
|
||||
ret = dm_update_plane_state(dc, state, plane,
|
||||
old_plane_state,
|
||||
@@ -11865,9 +11882,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
|
||||
/*
|
||||
* Only allow async flips for fast updates that don't change
|
||||
* the FB pitch, the DCC state, rotation, etc.
|
||||
* the FB pitch, the DCC state, rotation, mem_type, etc.
|
||||
*/
|
||||
if (new_crtc_state->async_flip && lock_and_validation_needed) {
|
||||
if (new_crtc_state->async_flip &&
|
||||
(lock_and_validation_needed ||
|
||||
amdgpu_dm_crtc_mem_type_changed(dev, state, new_crtc_state))) {
|
||||
drm_dbg_atomic(crtc->dev,
|
||||
"[CRTC:%d:%s] async flips are only supported for fast updates\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "amdgpu_dm.h"
|
||||
#include "dc.h"
|
||||
#include "amdgpu_securedisplay.h"
|
||||
#include "amdgpu_dm_psr.h"
|
||||
|
||||
static const char *const pipe_crc_sources[] = {
|
||||
"none",
|
||||
@@ -224,6 +225,10 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
|
||||
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
|
||||
/* For PSR1, check that the panel has exited PSR */
|
||||
if (stream_state->link->psr_settings.psr_version < DC_PSR_VERSION_SU_1)
|
||||
amdgpu_dm_psr_wait_disable(stream_state);
|
||||
|
||||
/* Enable or disable CRTC CRC generation */
|
||||
if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) {
|
||||
if (!dc_stream_configure_crc(stream_state->ctx->dc,
|
||||
@@ -357,6 +362,17 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading the CRC requires the vblank interrupt handler to be
|
||||
* enabled. Keep a reference until CRC capture stops.
|
||||
*/
|
||||
enabled = amdgpu_dm_is_valid_crc_source(cur_crc_src);
|
||||
if (!enabled && enable) {
|
||||
ret = drm_crtc_vblank_get(crtc);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/* Reset secure_display when we change crc source from debugfs */
|
||||
amdgpu_dm_set_crc_window_default(crtc, crtc_state->stream);
|
||||
@@ -367,16 +383,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading the CRC requires the vblank interrupt handler to be
|
||||
* enabled. Keep a reference until CRC capture stops.
|
||||
*/
|
||||
enabled = amdgpu_dm_is_valid_crc_source(cur_crc_src);
|
||||
if (!enabled && enable) {
|
||||
ret = drm_crtc_vblank_get(crtc);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
if (dm_is_crc_source_dprx(source)) {
|
||||
if (drm_dp_start_crc(aux, crtc)) {
|
||||
DRM_DEBUG_DRIVER("dp start crc failed\n");
|
||||
|
||||
@@ -93,7 +93,7 @@ int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state)
|
||||
bool amdgpu_dm_crtc_vrr_active(const struct dm_crtc_state *dm_state)
|
||||
{
|
||||
return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE ||
|
||||
dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
|
||||
@@ -142,7 +142,7 @@ static void amdgpu_dm_crtc_set_panel_sr_feature(
|
||||
amdgpu_dm_replay_enable(vblank_work->stream, true);
|
||||
} else if (vblank_enabled) {
|
||||
if (link->psr_settings.psr_version < DC_PSR_VERSION_SU_1 && is_sr_active)
|
||||
amdgpu_dm_psr_disable(vblank_work->stream);
|
||||
amdgpu_dm_psr_disable(vblank_work->stream, false);
|
||||
} else if (link->psr_settings.psr_feature_enabled &&
|
||||
allow_sr_entry && !is_sr_active && !is_crc_window_active) {
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable);
|
||||
|
||||
bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc);
|
||||
|
||||
bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state);
|
||||
bool amdgpu_dm_crtc_vrr_active(const struct dm_crtc_state *dm_state);
|
||||
|
||||
int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc);
|
||||
|
||||
|
||||
@@ -3638,7 +3638,7 @@ static int crc_win_update_set(void *data, u64 val)
|
||||
/* PSR may write to OTG CRC window control register,
|
||||
* so close it before starting secure_display.
|
||||
*/
|
||||
amdgpu_dm_psr_disable(acrtc->dm_irq_params.stream);
|
||||
amdgpu_dm_psr_disable(acrtc->dm_irq_params.stream, true);
|
||||
|
||||
spin_lock_irq(&adev_to_drm(adev)->event_lock);
|
||||
|
||||
|
||||
@@ -1831,11 +1831,15 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
if (immediate_upstream_port) {
|
||||
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
|
||||
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
|
||||
if (bw_range.min_kbps > virtual_channel_bw_in_kbps) {
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
|
||||
"Max dsc compression can't fit into MST available bw\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
} else {
|
||||
/* For topology LCT 1 case - only one mstb*/
|
||||
virtual_channel_bw_in_kbps = root_link_bw_in_kbps;
|
||||
}
|
||||
|
||||
if (bw_range.min_kbps > virtual_channel_bw_in_kbps) {
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
|
||||
"Max dsc compression can't fit into MST available bw\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,14 +201,13 @@ void amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
||||
*
|
||||
* Return: true if success
|
||||
*/
|
||||
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
|
||||
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream, bool wait)
|
||||
{
|
||||
unsigned int power_opt = 0;
|
||||
bool psr_enable = false;
|
||||
|
||||
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
||||
|
||||
return dc_link_set_psr_allow_active(stream->link, &psr_enable, true, false, &power_opt);
|
||||
return dc_link_set_psr_allow_active(stream->link, &psr_enable, wait, false, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -251,3 +250,33 @@ bool amdgpu_dm_psr_is_active_allowed(struct amdgpu_display_manager *dm)
|
||||
|
||||
return allow_active;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dm_psr_wait_disable() - Wait for eDP panel to exit PSR
|
||||
* @stream: stream state attached to the eDP link
|
||||
*
|
||||
* Waits for a max of 500ms for the eDP panel to exit PSR.
|
||||
*
|
||||
* Return: true if panel exited PSR, false otherwise.
|
||||
*/
|
||||
bool amdgpu_dm_psr_wait_disable(struct dc_stream_state *stream)
|
||||
{
|
||||
enum dc_psr_state psr_state = PSR_STATE0;
|
||||
struct dc_link *link = stream->link;
|
||||
int retry_count;
|
||||
|
||||
if (link == NULL)
|
||||
return false;
|
||||
|
||||
for (retry_count = 0; retry_count <= 1000; retry_count++) {
|
||||
dc_link_get_psr_state(link, &psr_state);
|
||||
if (psr_state == PSR_STATE0)
|
||||
break;
|
||||
udelay(500);
|
||||
}
|
||||
|
||||
if (retry_count == 1000)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,9 @@
|
||||
void amdgpu_dm_set_psr_caps(struct dc_link *link);
|
||||
void amdgpu_dm_psr_enable(struct dc_stream_state *stream);
|
||||
bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
|
||||
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
|
||||
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream, bool wait);
|
||||
bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
|
||||
bool amdgpu_dm_psr_is_active_allowed(struct amdgpu_display_manager *dm);
|
||||
bool amdgpu_dm_psr_wait_disable(struct dc_stream_state *stream);
|
||||
|
||||
#endif /* AMDGPU_DM_AMDGPU_DM_PSR_H_ */
|
||||
|
||||
@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.gpuvm_min_page_size_bytes = 4096,
|
||||
.hostvm_min_page_size_bytes = 4096,
|
||||
.do_urgent_latency_adjustment = 1,
|
||||
.do_urgent_latency_adjustment = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
|
||||
};
|
||||
|
||||
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
|
||||
|
||||
@@ -2549,11 +2549,12 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
|
||||
&backend_workload_mask);
|
||||
|
||||
/* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */
|
||||
if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
|
||||
((smu->adev->pm.fw_version == 0x004e6601) ||
|
||||
(smu->adev->pm.fw_version >= 0x004e7300))) ||
|
||||
(amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
|
||||
smu->adev->pm.fw_version >= 0x00504500)) {
|
||||
if ((workload_mask & (1 << PP_SMC_POWER_PROFILE_COMPUTE)) &&
|
||||
((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
|
||||
((smu->adev->pm.fw_version == 0x004e6601) ||
|
||||
(smu->adev->pm.fw_version >= 0x004e7300))) ||
|
||||
(amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
|
||||
smu->adev->pm.fw_version >= 0x00504500))) {
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
CMN2ASIC_MAPPING_WORKLOAD,
|
||||
PP_SMC_POWER_PROFILE_POWERSAVING);
|
||||
|
||||
@@ -1613,7 +1613,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
|
||||
* arithmetic related to alignment and offset calculation.
|
||||
*/
|
||||
if (is_gen12_ccs_cc_plane(&fb->base, i)) {
|
||||
if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE))
|
||||
if (IS_ALIGNED(fb->base.offsets[i], 64))
|
||||
continue;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
@@ -387,11 +387,13 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
|
||||
if (f) {
|
||||
struct nouveau_channel *prev;
|
||||
bool must_wait = true;
|
||||
bool local;
|
||||
|
||||
rcu_read_lock();
|
||||
prev = rcu_dereference(f->channel);
|
||||
if (prev && (prev == chan ||
|
||||
fctx->sync(f, prev, chan) == 0))
|
||||
local = prev && prev->cli->drm == chan->cli->drm;
|
||||
if (local && (prev == chan ||
|
||||
fctx->sync(f, prev, chan) == 0))
|
||||
must_wait = false;
|
||||
rcu_read_unlock();
|
||||
if (!must_wait)
|
||||
|
||||
@@ -31,6 +31,7 @@ mcp77_sor = {
|
||||
.state = g94_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = nv50_sor_clock,
|
||||
.bl = &nv50_sor_bl,
|
||||
.hdmi = &g84_sor_hdmi,
|
||||
.dp = &g94_sor_dp,
|
||||
};
|
||||
|
||||
@@ -320,8 +320,7 @@ static void kunit_action_drm_mode_destroy(void *ptr)
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC
|
||||
for a KUnit test
|
||||
* drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test
|
||||
* @test: The test context object
|
||||
* @dev: DRM device
|
||||
* @video_code: CEA VIC of the mode
|
||||
|
||||
@@ -108,6 +108,7 @@ v3d_irq(int irq, void *arg)
|
||||
v3d_job_update_stats(&v3d->bin_job->base, V3D_BIN);
|
||||
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
v3d->bin_job = NULL;
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -118,6 +119,7 @@ v3d_irq(int irq, void *arg)
|
||||
v3d_job_update_stats(&v3d->render_job->base, V3D_RENDER);
|
||||
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
v3d->render_job = NULL;
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -128,6 +130,7 @@ v3d_irq(int irq, void *arg)
|
||||
v3d_job_update_stats(&v3d->csd_job->base, V3D_CSD);
|
||||
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
v3d->csd_job = NULL;
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -165,6 +168,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
v3d_job_update_stats(&v3d->tfu_job->base, V3D_TFU);
|
||||
trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
v3d->tfu_job = NULL;
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -443,7 +443,8 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
|
||||
|
||||
if (params->pin)
|
||||
ttm_bo_pin(&vmw_bo->tbo);
|
||||
ttm_bo_unreserve(&vmw_bo->tbo);
|
||||
if (!params->keep_resv)
|
||||
ttm_bo_unreserve(&vmw_bo->tbo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,9 @@ struct vmw_bo_params {
|
||||
u32 domain;
|
||||
u32 busy_domain;
|
||||
enum ttm_bo_type bo_type;
|
||||
size_t size;
|
||||
bool pin;
|
||||
bool keep_resv;
|
||||
size_t size;
|
||||
struct dma_resv *resv;
|
||||
struct sg_table *sg;
|
||||
};
|
||||
|
||||
@@ -401,7 +401,8 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
|
||||
.busy_domain = VMW_BO_DOMAIN_SYS,
|
||||
.bo_type = ttm_bo_type_kernel,
|
||||
.size = PAGE_SIZE,
|
||||
.pin = true
|
||||
.pin = true,
|
||||
.keep_resv = true,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -413,10 +414,6 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
|
||||
BUG_ON(ret != 0);
|
||||
vmw_bo_pin_reserved(vbo, true);
|
||||
|
||||
ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map);
|
||||
if (likely(ret == 0)) {
|
||||
result = ttm_kmap_obj_virtual(&map, &dummy);
|
||||
|
||||
@@ -206,6 +206,7 @@ struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev,
|
||||
.bo_type = ttm_bo_type_sg,
|
||||
.size = attach->dmabuf->size,
|
||||
.pin = false,
|
||||
.keep_resv = true,
|
||||
.resv = attach->dmabuf->resv,
|
||||
.sg = table,
|
||||
|
||||
|
||||
@@ -750,6 +750,7 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
|
||||
struct vmw_bo *old_bo = NULL;
|
||||
struct vmw_bo *new_bo = NULL;
|
||||
struct ww_acquire_ctx ctx;
|
||||
s32 hotspot_x, hotspot_y;
|
||||
int ret;
|
||||
|
||||
@@ -769,9 +770,11 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
if (du->cursor_surface)
|
||||
du->cursor_age = du->cursor_surface->snooper.age;
|
||||
|
||||
ww_acquire_init(&ctx, &reservation_ww_class);
|
||||
|
||||
if (!vmw_user_object_is_null(&old_vps->uo)) {
|
||||
old_bo = vmw_user_object_buffer(&old_vps->uo);
|
||||
ret = ttm_bo_reserve(&old_bo->tbo, false, false, NULL);
|
||||
ret = ttm_bo_reserve(&old_bo->tbo, false, false, &ctx);
|
||||
if (ret != 0)
|
||||
return;
|
||||
}
|
||||
@@ -779,9 +782,14 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
if (!vmw_user_object_is_null(&vps->uo)) {
|
||||
new_bo = vmw_user_object_buffer(&vps->uo);
|
||||
if (old_bo != new_bo) {
|
||||
ret = ttm_bo_reserve(&new_bo->tbo, false, false, NULL);
|
||||
if (ret != 0)
|
||||
ret = ttm_bo_reserve(&new_bo->tbo, false, false, &ctx);
|
||||
if (ret != 0) {
|
||||
if (old_bo) {
|
||||
ttm_bo_unreserve(&old_bo->tbo);
|
||||
ww_acquire_fini(&ctx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
new_bo = NULL;
|
||||
}
|
||||
@@ -803,10 +811,12 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
hotspot_x, hotspot_y);
|
||||
}
|
||||
|
||||
if (old_bo)
|
||||
ttm_bo_unreserve(&old_bo->tbo);
|
||||
if (new_bo)
|
||||
ttm_bo_unreserve(&new_bo->tbo);
|
||||
if (old_bo)
|
||||
ttm_bo_unreserve(&old_bo->tbo);
|
||||
|
||||
ww_acquire_fini(&ctx);
|
||||
|
||||
du->cursor_x = new_state->crtc_x + du->set_gui_x;
|
||||
du->cursor_y = new_state->crtc_y + du->set_gui_y;
|
||||
|
||||
@@ -896,7 +896,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
|
||||
.busy_domain = VMW_BO_DOMAIN_SYS,
|
||||
.bo_type = ttm_bo_type_device,
|
||||
.size = size,
|
||||
.pin = true
|
||||
.pin = true,
|
||||
.keep_resv = true,
|
||||
};
|
||||
|
||||
if (!vmw_shader_id_ok(user_key, shader_type))
|
||||
@@ -906,10 +907,6 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
|
||||
ret = ttm_bo_reserve(&buf->tbo, false, true, NULL);
|
||||
if (unlikely(ret != 0))
|
||||
goto no_reserve;
|
||||
|
||||
/* Map and copy shader bytecode. */
|
||||
ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map);
|
||||
if (unlikely(ret != 0)) {
|
||||
|
||||
@@ -572,15 +572,14 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
|
||||
.busy_domain = domain,
|
||||
.bo_type = ttm_bo_type_kernel,
|
||||
.size = bo_size,
|
||||
.pin = true
|
||||
.pin = true,
|
||||
.keep_resv = true,
|
||||
};
|
||||
|
||||
ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
|
||||
BUG_ON(ret != 0);
|
||||
ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx);
|
||||
if (likely(ret == 0)) {
|
||||
struct vmw_ttm_tt *vmw_tt =
|
||||
|
||||
@@ -417,7 +417,7 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
|
||||
* Bspec: 72161
|
||||
*/
|
||||
const u8 mocs_write_idx = gt->mocs.uc_index;
|
||||
const u8 mocs_read_idx = hwe->class == XE_ENGINE_CLASS_COMPUTE &&
|
||||
const u8 mocs_read_idx = hwe->class == XE_ENGINE_CLASS_COMPUTE && IS_DGFX(xe) &&
|
||||
(GRAPHICS_VER(xe) >= 20 || xe->info.platform == XE_PVC) ?
|
||||
gt->mocs.wb_index : gt->mocs.uc_index;
|
||||
u32 ring_cmd_cctl_val = REG_FIELD_PREP(CMD_CCTL_WRITE_OVERRIDE_MASK, mocs_write_idx) |
|
||||
|
||||
@@ -1980,6 +1980,7 @@ static const struct xe_mmio_range xe2_oa_mux_regs[] = {
|
||||
{ .start = 0x5194, .end = 0x5194 }, /* SYS_MEM_LAT_MEASURE_MERTF_GRP_3D */
|
||||
{ .start = 0x8704, .end = 0x8704 }, /* LMEM_LAT_MEASURE_MCFG_GRP */
|
||||
{ .start = 0xB1BC, .end = 0xB1BC }, /* L3_BANK_LAT_MEASURE_LBCF_GFX */
|
||||
{ .start = 0xD0E0, .end = 0xD0F4 }, /* VISACTL */
|
||||
{ .start = 0xE18C, .end = 0xE18C }, /* SAMPLER_MODE */
|
||||
{ .start = 0xE590, .end = 0xE590 }, /* TDL_LSC_LAT_MEASURE_TDL_GFX */
|
||||
{ .start = 0x13000, .end = 0x137FC }, /* PES_0_PESL0 - PES_63_UPPER_PESL3 */
|
||||
|
||||
@@ -125,7 +125,7 @@ static int ltc2991_get_curr(struct ltc2991_state *st, u32 reg, int channel,
|
||||
|
||||
/* Vx-Vy, 19.075uV/LSB */
|
||||
*val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 19075,
|
||||
st->r_sense_uohm[channel]);
|
||||
(s32)st->r_sense_uohm[channel]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
||||
*val = sign_extend32(regval,
|
||||
reg == TMP51X_SHUNT_CURRENT_RESULT ?
|
||||
16 - tmp51x_get_pga_shift(data) : 15);
|
||||
*val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms);
|
||||
*val = DIV_ROUND_CLOSEST(*val * 10 * (long)MILLI, (long)data->shunt_uohms);
|
||||
|
||||
break;
|
||||
case TMP51X_BUS_VOLTAGE_RESULT:
|
||||
case TMP51X_BUS_VOLTAGE_H_LIMIT:
|
||||
@@ -223,7 +224,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
||||
case TMP51X_BUS_CURRENT_RESULT:
|
||||
// Current = (ShuntVoltage * CalibrationRegister) / 4096
|
||||
*val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
|
||||
*val = DIV_ROUND_CLOSEST(*val, MILLI);
|
||||
*val = DIV_ROUND_CLOSEST(*val, (long)MILLI);
|
||||
break;
|
||||
case TMP51X_LOCAL_TEMP_RESULT:
|
||||
case TMP51X_REMOTE_TEMP_RESULT_1:
|
||||
@@ -263,7 +264,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val)
|
||||
* The user enter current value and we convert it to
|
||||
* voltage. 1lsb = 10uV
|
||||
*/
|
||||
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI);
|
||||
val = DIV_ROUND_CLOSEST(val * (long)data->shunt_uohms, 10 * (long)MILLI);
|
||||
max_val = U16_MAX >> tmp51x_get_pga_shift(data);
|
||||
regval = clamp_val(val, -max_val, max_val);
|
||||
break;
|
||||
|
||||
@@ -130,6 +130,8 @@
|
||||
#define ID_P_PM_BLOCKED BIT(31)
|
||||
#define ID_P_MASK GENMASK(31, 27)
|
||||
|
||||
#define ID_SLAVE_NACK BIT(0)
|
||||
|
||||
enum rcar_i2c_type {
|
||||
I2C_RCAR_GEN1,
|
||||
I2C_RCAR_GEN2,
|
||||
@@ -166,6 +168,7 @@ struct rcar_i2c_priv {
|
||||
int irq;
|
||||
|
||||
struct i2c_client *host_notify_client;
|
||||
u8 slave_flags;
|
||||
};
|
||||
|
||||
#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent)
|
||||
@@ -655,6 +658,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
||||
{
|
||||
u32 ssr_raw, ssr_filtered;
|
||||
u8 value;
|
||||
int ret;
|
||||
|
||||
ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff;
|
||||
ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER);
|
||||
@@ -670,7 +674,10 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
||||
rcar_i2c_write(priv, ICRXTX, value);
|
||||
rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
|
||||
} else {
|
||||
i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
|
||||
ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
|
||||
if (ret)
|
||||
priv->slave_flags |= ID_SLAVE_NACK;
|
||||
|
||||
rcar_i2c_read(priv, ICRXTX); /* dummy read */
|
||||
rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
|
||||
}
|
||||
@@ -683,18 +690,21 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
||||
if (ssr_filtered & SSR) {
|
||||
i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
|
||||
rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
|
||||
priv->slave_flags &= ~ID_SLAVE_NACK;
|
||||
rcar_i2c_write(priv, ICSIER, SAR);
|
||||
rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
|
||||
}
|
||||
|
||||
/* master wants to write to us */
|
||||
if (ssr_filtered & SDR) {
|
||||
int ret;
|
||||
|
||||
value = rcar_i2c_read(priv, ICRXTX);
|
||||
ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
|
||||
/* Send NACK in case of error */
|
||||
rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0));
|
||||
if (ret)
|
||||
priv->slave_flags |= ID_SLAVE_NACK;
|
||||
|
||||
/* Send NACK in case of error, but it will come 1 byte late :( */
|
||||
rcar_i2c_write(priv, ICSCR, SIE | SDBS |
|
||||
(priv->slave_flags & ID_SLAVE_NACK ? FNA : 0));
|
||||
rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
|
||||
}
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ static int i2c_atr_bus_notifier_call(struct notifier_block *nb,
|
||||
dev_name(dev), ret);
|
||||
break;
|
||||
|
||||
case BUS_NOTIFY_DEL_DEVICE:
|
||||
case BUS_NOTIFY_REMOVED_DEVICE:
|
||||
i2c_atr_detach_client(client->adapter, client);
|
||||
break;
|
||||
|
||||
|
||||
@@ -1562,6 +1562,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
||||
res = device_add(&adap->dev);
|
||||
if (res) {
|
||||
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
|
||||
put_device(&adap->dev);
|
||||
goto out_list;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ enum testunit_regs {
|
||||
|
||||
enum testunit_flags {
|
||||
TU_FLAG_IN_PROCESS,
|
||||
TU_FLAG_NACK,
|
||||
};
|
||||
|
||||
struct testunit_data {
|
||||
@@ -90,8 +91,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
|
||||
|
||||
switch (event) {
|
||||
case I2C_SLAVE_WRITE_REQUESTED:
|
||||
if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags))
|
||||
return -EBUSY;
|
||||
if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) {
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(tu->regs, 0, TU_NUM_REGS);
|
||||
tu->reg_idx = 0;
|
||||
@@ -99,8 +102,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
|
||||
break;
|
||||
|
||||
case I2C_SLAVE_WRITE_RECEIVED:
|
||||
if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags))
|
||||
return -EBUSY;
|
||||
if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) {
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tu->reg_idx < TU_NUM_REGS)
|
||||
tu->regs[tu->reg_idx] = *val;
|
||||
@@ -129,6 +134,8 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
|
||||
* here because we still need them in the workqueue!
|
||||
*/
|
||||
tu->reg_idx = 0;
|
||||
|
||||
clear_bit(TU_FLAG_NACK, &tu->flags);
|
||||
break;
|
||||
|
||||
case I2C_SLAVE_READ_PROCESSED:
|
||||
@@ -151,6 +158,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
|
||||
break;
|
||||
}
|
||||
|
||||
/* If an error occurred somewhen, we NACK everything until next STOP */
|
||||
if (ret)
|
||||
set_bit(TU_FLAG_NACK, &tu->flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
|
||||
pm_runtime_no_callbacks(&pdev->dev);
|
||||
|
||||
/* switch to first parent as active master */
|
||||
i2c_demux_activate_master(priv, 0);
|
||||
err = i2c_demux_activate_master(priv, 0);
|
||||
if (err)
|
||||
goto err_rollback;
|
||||
|
||||
err = device_create_file(&pdev->dev, &dev_attr_available_masters);
|
||||
if (err)
|
||||
|
||||
@@ -2269,6 +2269,7 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
|
||||
qp_attr->retry_cnt = qplib_qp->retry_cnt;
|
||||
qp_attr->rnr_retry = qplib_qp->rnr_retry;
|
||||
qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer;
|
||||
qp_attr->port_num = __to_ib_port_num(qplib_qp->port_id);
|
||||
qp_attr->rq_psn = qplib_qp->rq.psn;
|
||||
qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic;
|
||||
qp_attr->sq_psn = qplib_qp->sq.psn;
|
||||
|
||||
@@ -264,6 +264,10 @@ void bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
|
||||
int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
|
||||
void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry);
|
||||
|
||||
static inline u32 __to_ib_port_num(u16 port_id)
|
||||
{
|
||||
return (u32)port_id + 1;
|
||||
}
|
||||
|
||||
unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
|
||||
void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
|
||||
|
||||
@@ -1479,6 +1479,7 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
qp->dest_qpn = le32_to_cpu(sb->dest_qp_id);
|
||||
memcpy(qp->smac, sb->src_mac, 6);
|
||||
qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
|
||||
qp->port_id = le16_to_cpu(sb->port_id);
|
||||
bail:
|
||||
dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
|
||||
sbuf.sb, sbuf.dma_addr);
|
||||
|
||||
@@ -298,6 +298,7 @@ struct bnxt_qplib_qp {
|
||||
u32 dest_qpn;
|
||||
u8 smac[6];
|
||||
u16 vlan_id;
|
||||
u16 port_id;
|
||||
u8 nw_type;
|
||||
struct bnxt_qplib_ah ah;
|
||||
|
||||
|
||||
@@ -1961,7 +1961,7 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
|
||||
if (!is_v4(its_dev->its))
|
||||
return -EINVAL;
|
||||
|
||||
guard(raw_spinlock_irq)(&its_dev->event_map.vlpi_lock);
|
||||
guard(raw_spinlock)(&its_dev->event_map.vlpi_lock);
|
||||
|
||||
/* Unmap request? */
|
||||
if (!info)
|
||||
|
||||
@@ -1530,7 +1530,7 @@ static int gic_retrigger(struct irq_data *data)
|
||||
static int gic_cpu_pm_notifier(struct notifier_block *self,
|
||||
unsigned long cmd, void *v)
|
||||
{
|
||||
if (cmd == CPU_PM_EXIT) {
|
||||
if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
|
||||
if (gic_dist_security_disabled())
|
||||
gic_enable_redist(true);
|
||||
gic_cpu_sys_reg_enable();
|
||||
|
||||
@@ -35,11 +35,10 @@ void __init irqchip_init(void)
|
||||
int platform_irqchip_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *par_np = of_irq_find_parent(np);
|
||||
struct device_node *par_np __free(device_node) = of_irq_find_parent(np);
|
||||
of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
if (!irq_init_cb) {
|
||||
of_node_put(par_np);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -55,7 +54,6 @@ int platform_irqchip_probe(struct platform_device *pdev)
|
||||
* interrupt controller can check for specific domains as necessary.
|
||||
*/
|
||||
if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
|
||||
of_node_put(par_np);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor,
|
||||
op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto);
|
||||
|
||||
if (op->dummy.nbytes)
|
||||
op->dummy.buswidth = spi_nor_get_protocol_data_nbits(proto);
|
||||
op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto);
|
||||
|
||||
if (op->data.nbytes)
|
||||
op->data.buswidth = spi_nor_get_protocol_data_nbits(proto);
|
||||
|
||||
@@ -923,7 +923,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
|
||||
|
||||
static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
unsigned int phy_id = phy_data->phydev->phy_id;
|
||||
|
||||
@@ -945,14 +944,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
phy_write(phy_data->phydev, 0x04, 0x0d01);
|
||||
phy_write(phy_data->phydev, 0x00, 0x9140);
|
||||
|
||||
linkmode_set_bit_array(phy_10_100_features_array,
|
||||
ARRAY_SIZE(phy_10_100_features_array),
|
||||
supported);
|
||||
linkmode_set_bit_array(phy_gbit_features_array,
|
||||
ARRAY_SIZE(phy_gbit_features_array),
|
||||
supported);
|
||||
|
||||
linkmode_copy(phy_data->phydev->supported, supported);
|
||||
linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
|
||||
|
||||
phy_support_asym_pause(phy_data->phydev);
|
||||
|
||||
@@ -964,7 +956,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
|
||||
static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
|
||||
unsigned int phy_id = phy_data->phydev->phy_id;
|
||||
@@ -1028,13 +1019,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
reg = phy_read(phy_data->phydev, 0x00);
|
||||
phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
|
||||
|
||||
linkmode_set_bit_array(phy_10_100_features_array,
|
||||
ARRAY_SIZE(phy_10_100_features_array),
|
||||
supported);
|
||||
linkmode_set_bit_array(phy_gbit_features_array,
|
||||
ARRAY_SIZE(phy_gbit_features_array),
|
||||
supported);
|
||||
linkmode_copy(phy_data->phydev->supported, supported);
|
||||
linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
|
||||
phy_support_asym_pause(phy_data->phydev);
|
||||
|
||||
netif_dbg(pdata, drv, pdata->netdev,
|
||||
|
||||
@@ -4558,7 +4558,7 @@ void bnxt_set_ring_params(struct bnxt *bp)
|
||||
/* Changing allocation mode of RX rings.
|
||||
* TODO: Update when extending xdp_rxq_info to support allocation modes.
|
||||
*/
|
||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
static void __bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
{
|
||||
struct net_device *dev = bp->dev;
|
||||
|
||||
@@ -4579,15 +4579,30 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
bp->rx_skb_func = bnxt_rx_page_skb;
|
||||
}
|
||||
bp->rx_dir = DMA_BIDIRECTIONAL;
|
||||
/* Disable LRO or GRO_HW */
|
||||
netdev_update_features(dev);
|
||||
} else {
|
||||
dev->max_mtu = bp->max_mtu;
|
||||
bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
|
||||
bp->rx_dir = DMA_FROM_DEVICE;
|
||||
bp->rx_skb_func = bnxt_rx_skb;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
{
|
||||
__bnxt_set_rx_skb_mode(bp, page_mode);
|
||||
|
||||
if (!page_mode) {
|
||||
int rx, tx;
|
||||
|
||||
bnxt_get_max_rings(bp, &rx, &tx, true);
|
||||
if (rx > 1) {
|
||||
bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
|
||||
bp->dev->hw_features |= NETIF_F_LRO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update LRO and GRO_HW availability */
|
||||
netdev_update_features(bp->dev);
|
||||
}
|
||||
|
||||
static void bnxt_free_vnic_attributes(struct bnxt *bp)
|
||||
@@ -15909,7 +15924,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (bp->max_fltr < BNXT_MAX_FLTR)
|
||||
bp->max_fltr = BNXT_MAX_FLTR;
|
||||
bnxt_init_l2_fltr_tbl(bp);
|
||||
bnxt_set_rx_skb_mode(bp, false);
|
||||
__bnxt_set_rx_skb_mode(bp, false);
|
||||
bnxt_set_tpa_flags(bp);
|
||||
bnxt_set_ring_params(bp);
|
||||
bnxt_rdma_aux_device_init(bp);
|
||||
|
||||
@@ -2796,7 +2796,7 @@ void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data);
|
||||
u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx);
|
||||
void bnxt_set_tpa_flags(struct bnxt *bp);
|
||||
void bnxt_set_ring_params(struct bnxt *);
|
||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
||||
void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
||||
void bnxt_insert_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
||||
void bnxt_del_one_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
||||
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
|
||||
|
||||
@@ -422,15 +422,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
|
||||
bnxt_set_rx_skb_mode(bp, true);
|
||||
xdp_features_set_redirect_target(dev, true);
|
||||
} else {
|
||||
int rx, tx;
|
||||
|
||||
xdp_features_clear_redirect_target(dev);
|
||||
bnxt_set_rx_skb_mode(bp, false);
|
||||
bnxt_get_max_rings(bp, &rx, &tx, true);
|
||||
if (rx > 1) {
|
||||
bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
|
||||
bp->dev->hw_features |= NETIF_F_LRO;
|
||||
}
|
||||
}
|
||||
bp->tx_nr_rings_xdp = tx_xdp;
|
||||
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
|
||||
|
||||
@@ -1591,19 +1591,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget)
|
||||
fec_enet_tx_queue(ndev, i, budget);
|
||||
}
|
||||
|
||||
static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
|
||||
static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
|
||||
struct bufdesc *bdp, int index)
|
||||
{
|
||||
struct page *new_page;
|
||||
dma_addr_t phys_addr;
|
||||
|
||||
new_page = page_pool_dev_alloc_pages(rxq->page_pool);
|
||||
WARN_ON(!new_page);
|
||||
rxq->rx_skb_info[index].page = new_page;
|
||||
if (unlikely(!new_page))
|
||||
return -ENOMEM;
|
||||
|
||||
rxq->rx_skb_info[index].page = new_page;
|
||||
rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;
|
||||
phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;
|
||||
bdp->cbd_bufaddr = cpu_to_fec32(phys_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32
|
||||
@@ -1698,6 +1701,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
||||
int cpu = smp_processor_id();
|
||||
struct xdp_buff xdp;
|
||||
struct page *page;
|
||||
__fec32 cbd_bufaddr;
|
||||
u32 sub_len = 4;
|
||||
|
||||
#if !defined(CONFIG_M5272)
|
||||
@@ -1766,12 +1770,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
||||
|
||||
index = fec_enet_get_bd_index(bdp, &rxq->bd);
|
||||
page = rxq->rx_skb_info[index].page;
|
||||
cbd_bufaddr = bdp->cbd_bufaddr;
|
||||
if (fec_enet_update_cbd(rxq, bdp, index)) {
|
||||
ndev->stats.rx_dropped++;
|
||||
goto rx_processing_done;
|
||||
}
|
||||
|
||||
dma_sync_single_for_cpu(&fep->pdev->dev,
|
||||
fec32_to_cpu(bdp->cbd_bufaddr),
|
||||
fec32_to_cpu(cbd_bufaddr),
|
||||
pkt_len,
|
||||
DMA_FROM_DEVICE);
|
||||
prefetch(page_address(page));
|
||||
fec_enet_update_cbd(rxq, bdp, index);
|
||||
|
||||
if (xdp_prog) {
|
||||
xdp_buff_clear_frags_flag(&xdp);
|
||||
|
||||
@@ -1047,5 +1047,10 @@ static inline void ice_clear_rdma_cap(struct ice_pf *pf)
|
||||
clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
|
||||
}
|
||||
|
||||
static inline enum ice_phy_model ice_get_phy_model(const struct ice_hw *hw)
|
||||
{
|
||||
return hw->ptp.phy_model;
|
||||
}
|
||||
|
||||
extern const struct xdp_metadata_ops ice_xdp_md_ops;
|
||||
#endif /* _ICE_H_ */
|
||||
|
||||
@@ -40,11 +40,17 @@ static struct ice_adapter *ice_adapter_new(void)
|
||||
spin_lock_init(&adapter->ptp_gltsyn_time_lock);
|
||||
refcount_set(&adapter->refcount, 1);
|
||||
|
||||
mutex_init(&adapter->ports.lock);
|
||||
INIT_LIST_HEAD(&adapter->ports.ports);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
static void ice_adapter_free(struct ice_adapter *adapter)
|
||||
{
|
||||
WARN_ON(!list_empty(&adapter->ports.ports));
|
||||
mutex_destroy(&adapter->ports.lock);
|
||||
|
||||
kfree(adapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,22 +4,42 @@
|
||||
#ifndef _ICE_ADAPTER_H_
|
||||
#define _ICE_ADAPTER_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
#include <linux/refcount_types.h>
|
||||
|
||||
struct pci_dev;
|
||||
struct ice_pf;
|
||||
|
||||
/**
|
||||
* struct ice_port_list - data used to store the list of adapter ports
|
||||
*
|
||||
* This structure contains data used to maintain a list of adapter ports
|
||||
*
|
||||
* @ports: list of ports
|
||||
* @lock: protect access to the ports list
|
||||
*/
|
||||
struct ice_port_list {
|
||||
struct list_head ports;
|
||||
/* To synchronize the ports list operations */
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ice_adapter - PCI adapter resources shared across PFs
|
||||
* @ptp_gltsyn_time_lock: Spinlock protecting access to the GLTSYN_TIME
|
||||
* register of the PTP clock.
|
||||
* @refcount: Reference count. struct ice_pf objects hold the references.
|
||||
* @ctrl_pf: Control PF of the adapter
|
||||
* @ports: Ports list
|
||||
*/
|
||||
struct ice_adapter {
|
||||
refcount_t refcount;
|
||||
/* For access to the GLTSYN_TIME register */
|
||||
spinlock_t ptp_gltsyn_time_lock;
|
||||
|
||||
refcount_t refcount;
|
||||
struct ice_pf *ctrl_pf;
|
||||
struct ice_port_list ports;
|
||||
};
|
||||
|
||||
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev);
|
||||
|
||||
@@ -1648,6 +1648,7 @@ struct ice_aqc_get_port_options_elem {
|
||||
#define ICE_AQC_PORT_OPT_MAX_LANE_25G 5
|
||||
#define ICE_AQC_PORT_OPT_MAX_LANE_50G 6
|
||||
#define ICE_AQC_PORT_OPT_MAX_LANE_100G 7
|
||||
#define ICE_AQC_PORT_OPT_MAX_LANE_200G 8
|
||||
|
||||
u8 global_scid[2];
|
||||
u8 phy_scid[2];
|
||||
|
||||
@@ -4074,6 +4074,57 @@ ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
|
||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_phy_lane_number - Get PHY lane number for current adapter
|
||||
* @hw: pointer to the hw struct
|
||||
*
|
||||
* Return: PHY lane number on success, negative error code otherwise.
|
||||
*/
|
||||
int ice_get_phy_lane_number(struct ice_hw *hw)
|
||||
{
|
||||
struct ice_aqc_get_port_options_elem *options;
|
||||
unsigned int lport = 0;
|
||||
unsigned int lane;
|
||||
int err;
|
||||
|
||||
options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL);
|
||||
if (!options)
|
||||
return -ENOMEM;
|
||||
|
||||
for (lane = 0; lane < ICE_MAX_PORT_PER_PCI_DEV; lane++) {
|
||||
u8 options_count = ICE_AQC_PORT_OPT_MAX;
|
||||
u8 speed, active_idx, pending_idx;
|
||||
bool active_valid, pending_valid;
|
||||
|
||||
err = ice_aq_get_port_options(hw, options, &options_count, lane,
|
||||
true, &active_idx, &active_valid,
|
||||
&pending_idx, &pending_valid);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
if (!active_valid)
|
||||
continue;
|
||||
|
||||
speed = options[active_idx].max_lane_speed;
|
||||
/* If we don't get speed for this lane, it's unoccupied */
|
||||
if (speed > ICE_AQC_PORT_OPT_MAX_LANE_200G)
|
||||
continue;
|
||||
|
||||
if (hw->pf_id == lport) {
|
||||
kfree(options);
|
||||
return lane;
|
||||
}
|
||||
|
||||
lport++;
|
||||
}
|
||||
|
||||
/* PHY lane not found */
|
||||
err = -ENXIO;
|
||||
err:
|
||||
kfree(options);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_sff_eeprom
|
||||
* @hw: pointer to the HW struct
|
||||
|
||||
@@ -193,6 +193,7 @@ ice_aq_get_port_options(struct ice_hw *hw,
|
||||
int
|
||||
ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
|
||||
u8 new_option);
|
||||
int ice_get_phy_lane_number(struct ice_hw *hw);
|
||||
int
|
||||
ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
|
||||
u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
|
||||
|
||||
@@ -1144,7 +1144,7 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
|
||||
if (link_up == old_link && link_speed == old_link_speed)
|
||||
return 0;
|
||||
|
||||
ice_ptp_link_change(pf, pf->hw.pf_id, link_up);
|
||||
ice_ptp_link_change(pf, link_up);
|
||||
|
||||
if (ice_is_dcb_active(pf)) {
|
||||
if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
|
||||
@@ -6744,7 +6744,7 @@ static int ice_up_complete(struct ice_vsi *vsi)
|
||||
ice_print_link_msg(vsi, true);
|
||||
netif_tx_start_all_queues(vsi->netdev);
|
||||
netif_carrier_on(vsi->netdev);
|
||||
ice_ptp_link_change(pf, pf->hw.pf_id, true);
|
||||
ice_ptp_link_change(pf, true);
|
||||
}
|
||||
|
||||
/* Perform an initial read of the statistics registers now to
|
||||
@@ -7214,7 +7214,7 @@ int ice_down(struct ice_vsi *vsi)
|
||||
|
||||
if (vsi->netdev) {
|
||||
vlan_err = ice_vsi_del_vlan_zero(vsi);
|
||||
ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false);
|
||||
ice_ptp_link_change(vsi->back, false);
|
||||
netif_carrier_off(vsi->netdev);
|
||||
netif_tx_disable(vsi->netdev);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,18 @@ static const struct ptp_pin_desc ice_pin_desc_e810t[] = {
|
||||
{ "U.FL2", UFL2, PTP_PF_NONE, 2, { 0, } },
|
||||
};
|
||||
|
||||
static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf)
|
||||
{
|
||||
return !pf->adapter ? NULL : pf->adapter->ctrl_pf;
|
||||
}
|
||||
|
||||
static struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf);
|
||||
|
||||
return !ctrl_pf ? NULL : &ctrl_pf->ptp;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_sma_config_e810t
|
||||
* @hw: pointer to the hw struct
|
||||
@@ -800,8 +812,8 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
struct ice_ptp_port *port;
|
||||
unsigned int i;
|
||||
|
||||
mutex_lock(&pf->ptp.ports_owner.lock);
|
||||
list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) {
|
||||
mutex_lock(&pf->adapter->ports.lock);
|
||||
list_for_each_entry(port, &pf->adapter->ports.ports, list_node) {
|
||||
struct ice_ptp_tx *tx = &port->tx;
|
||||
|
||||
if (!tx || !tx->init)
|
||||
@@ -809,7 +821,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_process_tx_tstamp(tx);
|
||||
}
|
||||
mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
mutex_unlock(&pf->adapter->ports.lock);
|
||||
|
||||
for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
@@ -974,7 +986,7 @@ ice_ptp_flush_all_tx_tracker(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp_port *port;
|
||||
|
||||
list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member)
|
||||
list_for_each_entry(port, &pf->adapter->ports.ports, list_node)
|
||||
ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
|
||||
}
|
||||
|
||||
@@ -1363,7 +1375,7 @@ ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_lock(&ptp_port->ps_lock);
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
err = ice_stop_phy_timer_eth56g(hw, port, true);
|
||||
break;
|
||||
@@ -1409,7 +1421,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_lock(&ptp_port->ps_lock);
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
err = ice_start_phy_timer_eth56g(hw, port);
|
||||
break;
|
||||
@@ -1454,10 +1466,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
/**
|
||||
* ice_ptp_link_change - Reconfigure PTP after link status change
|
||||
* @pf: Board private structure
|
||||
* @port: Port for which the PHY start is set
|
||||
* @linkup: Link is up or down
|
||||
*/
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
|
||||
{
|
||||
struct ice_ptp_port *ptp_port;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -1465,14 +1476,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(port >= hw->ptp.num_lports))
|
||||
return;
|
||||
|
||||
ptp_port = &pf->ptp.port;
|
||||
if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
|
||||
port *= 2;
|
||||
if (WARN_ON_ONCE(ptp_port->port_num != port))
|
||||
return;
|
||||
|
||||
/* Update cached link status for this port immediately */
|
||||
ptp_port->link_up = linkup;
|
||||
@@ -1480,8 +1484,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
/* Skip HW writes if reset is in progress */
|
||||
if (pf->hw.reset_ongoing)
|
||||
return;
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_E810:
|
||||
/* Do not reconfigure E810 PHY */
|
||||
return;
|
||||
@@ -1514,7 +1517,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
|
||||
ice_ptp_reset_ts_memory(hw);
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G: {
|
||||
int port;
|
||||
|
||||
@@ -1553,7 +1556,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
case ICE_PHY_UNSUP:
|
||||
default:
|
||||
dev_warn(dev, "%s: Unexpected PHY model %d\n", __func__,
|
||||
hw->ptp.phy_model);
|
||||
ice_get_phy_model(hw));
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
@@ -1575,10 +1578,10 @@ static void ice_ptp_restart_all_phy(struct ice_pf *pf)
|
||||
{
|
||||
struct list_head *entry;
|
||||
|
||||
list_for_each(entry, &pf->ptp.ports_owner.ports) {
|
||||
list_for_each(entry, &pf->adapter->ports.ports) {
|
||||
struct ice_ptp_port *port = list_entry(entry,
|
||||
struct ice_ptp_port,
|
||||
list_member);
|
||||
list_node);
|
||||
|
||||
if (port->link_up)
|
||||
ice_ptp_port_phy_restart(port);
|
||||
@@ -2059,7 +2062,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
/* For Vernier mode on E82X, we need to recalibrate after new settime.
|
||||
* Start with marking timestamps as invalid.
|
||||
*/
|
||||
if (hw->ptp.phy_model == ICE_PHY_E82X) {
|
||||
if (ice_get_phy_model(hw) == ICE_PHY_E82X) {
|
||||
err = ice_ptp_clear_phy_offset_ready_e82x(hw);
|
||||
if (err)
|
||||
dev_warn(ice_pf_to_dev(pf), "Failed to mark timestamps as invalid before settime\n");
|
||||
@@ -2083,7 +2086,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
/* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
if (hw->ptp.phy_model == ICE_PHY_E82X)
|
||||
if (ice_get_phy_model(hw) == ICE_PHY_E82X)
|
||||
ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
@@ -2895,6 +2898,50 @@ err:
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
static bool ice_is_primary(struct ice_hw *hw)
|
||||
{
|
||||
return ice_is_e825c(hw) && ice_is_dual(hw) ?
|
||||
!!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) : true;
|
||||
}
|
||||
|
||||
static int ice_ptp_setup_adapter(struct ice_pf *pf)
|
||||
{
|
||||
if (!ice_pf_src_tmr_owned(pf) || !ice_is_primary(&pf->hw))
|
||||
return -EPERM;
|
||||
|
||||
pf->adapter->ctrl_pf = pf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ice_ptp_setup_pf(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf);
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
|
||||
if (WARN_ON(!ctrl_ptp) || ice_get_phy_model(&pf->hw) == ICE_PHY_UNSUP)
|
||||
return -ENODEV;
|
||||
|
||||
INIT_LIST_HEAD(&ptp->port.list_node);
|
||||
mutex_lock(&pf->adapter->ports.lock);
|
||||
|
||||
list_add(&ptp->port.list_node,
|
||||
&pf->adapter->ports.ports);
|
||||
mutex_unlock(&pf->adapter->ports.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ice_ptp_cleanup_pf(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
|
||||
if (ice_get_phy_model(&pf->hw) != ICE_PHY_UNSUP) {
|
||||
mutex_lock(&pf->adapter->ports.lock);
|
||||
list_del(&ptp->port.list_node);
|
||||
mutex_unlock(&pf->adapter->ports.lock);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device
|
||||
* @aux_dev: auxiliary device to get the auxiliary PF for
|
||||
@@ -2946,9 +2993,9 @@ static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev,
|
||||
if (WARN_ON(!owner_pf))
|
||||
return -ENODEV;
|
||||
|
||||
INIT_LIST_HEAD(&aux_pf->ptp.port.list_member);
|
||||
INIT_LIST_HEAD(&aux_pf->ptp.port.list_node);
|
||||
mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
list_add(&aux_pf->ptp.port.list_member,
|
||||
list_add(&aux_pf->ptp.port.list_node,
|
||||
&owner_pf->ptp.ports_owner.ports);
|
||||
mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
|
||||
@@ -2965,7 +3012,7 @@ static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev)
|
||||
struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
|
||||
mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
list_del(&aux_pf->ptp.port.list_member);
|
||||
list_del(&aux_pf->ptp.port.list_node);
|
||||
mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
}
|
||||
|
||||
@@ -3025,7 +3072,7 @@ ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name)
|
||||
* ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver
|
||||
* @pf: Board private structure
|
||||
*/
|
||||
static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
static int __always_unused ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
{
|
||||
struct auxiliary_driver *aux_driver;
|
||||
struct ice_ptp *ptp;
|
||||
@@ -3068,7 +3115,7 @@ static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
* ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver
|
||||
* @pf: Board private structure
|
||||
*/
|
||||
static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
static void __always_unused ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
{
|
||||
struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver;
|
||||
|
||||
@@ -3087,15 +3134,12 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
*/
|
||||
int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
{
|
||||
struct auxiliary_device *aux_dev;
|
||||
struct ice_pf *owner_pf;
|
||||
struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf);
|
||||
struct ptp_clock *clock;
|
||||
|
||||
aux_dev = &pf->ptp.port.aux_dev;
|
||||
owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
if (!owner_pf)
|
||||
if (!ctrl_ptp)
|
||||
return -1;
|
||||
clock = owner_pf->ptp.clock;
|
||||
clock = ctrl_ptp->clock;
|
||||
|
||||
return clock ? ptp_clock_index(clock) : -1;
|
||||
}
|
||||
@@ -3155,15 +3199,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err_clk;
|
||||
|
||||
err = ice_ptp_register_auxbus_driver(pf);
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
goto err_aux;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_aux:
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
err_exit:
|
||||
@@ -3209,7 +3245,7 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_init(&ptp_port->ps_lock);
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx,
|
||||
ptp_port->port_num);
|
||||
@@ -3239,7 +3275,7 @@ static void ice_ptp_release_auxbus_device(struct device *dev)
|
||||
* ice_ptp_create_auxbus_device - Create PTP auxiliary bus device
|
||||
* @pf: Board private structure
|
||||
*/
|
||||
static int ice_ptp_create_auxbus_device(struct ice_pf *pf)
|
||||
static __always_unused int ice_ptp_create_auxbus_device(struct ice_pf *pf)
|
||||
{
|
||||
struct auxiliary_device *aux_dev;
|
||||
struct ice_ptp *ptp;
|
||||
@@ -3286,7 +3322,7 @@ aux_err:
|
||||
* ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device
|
||||
* @pf: Board private structure
|
||||
*/
|
||||
static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
static __always_unused void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
{
|
||||
struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev;
|
||||
|
||||
@@ -3307,7 +3343,7 @@ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
*/
|
||||
static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
{
|
||||
switch (pf->hw.ptp.phy_model) {
|
||||
switch (ice_get_phy_model(&pf->hw)) {
|
||||
case ICE_PHY_E82X:
|
||||
/* E822 based PHY has the clock owner process the interrupt
|
||||
* for all ports.
|
||||
@@ -3339,10 +3375,17 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err;
|
||||
int lane_num, err;
|
||||
|
||||
ptp->state = ICE_PTP_INITIALIZING;
|
||||
|
||||
lane_num = ice_get_phy_lane_number(hw);
|
||||
if (lane_num < 0) {
|
||||
err = lane_num;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
ptp->port.port_num = (u8)lane_num;
|
||||
ice_ptp_init_hw(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
@@ -3350,19 +3393,22 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
if (ice_pf_src_tmr_owned(pf)) {
|
||||
if (ice_pf_src_tmr_owned(pf) && ice_is_primary(hw)) {
|
||||
err = ice_ptp_setup_adapter(pf);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
err = ice_ptp_init_owner(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
ptp->port.port_num = hw->pf_id;
|
||||
if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
|
||||
ptp->port.port_num = hw->pf_id * 2;
|
||||
err = ice_ptp_setup_pf(pf);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
|
||||
err = ice_ptp_init_port(pf, &ptp->port);
|
||||
if (err)
|
||||
goto err;
|
||||
goto err_exit;
|
||||
|
||||
/* Start the PHY timestamping block */
|
||||
ice_ptp_reset_phy_timestamping(pf);
|
||||
@@ -3370,20 +3416,16 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Configure initial Tx interrupt settings */
|
||||
ice_ptp_cfg_tx_interrupt(pf);
|
||||
|
||||
err = ice_ptp_create_auxbus_device(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
goto err;
|
||||
goto err_exit;
|
||||
|
||||
dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
|
||||
return;
|
||||
|
||||
err:
|
||||
err_exit:
|
||||
/* If we registered a PTP clock, release it */
|
||||
if (pf->ptp.clock) {
|
||||
ptp_clock_unregister(ptp->clock);
|
||||
@@ -3410,7 +3452,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
ice_ptp_remove_auxbus_device(pf);
|
||||
ice_ptp_cleanup_pf(pf);
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
@@ -3425,9 +3467,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
pf->ptp.kworker = NULL;
|
||||
}
|
||||
|
||||
if (ice_pf_src_tmr_owned(pf))
|
||||
ice_ptp_unregister_auxbus_driver(pf);
|
||||
|
||||
if (!pf->ptp.clock)
|
||||
return;
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ struct ice_ptp_tx {
|
||||
* ready for PTP functionality. It is used to track the port initialization
|
||||
* and determine when the port's PHY offset is valid.
|
||||
*
|
||||
* @list_member: list member structure of auxiliary device
|
||||
* @list_node: list member structure
|
||||
* @tx: Tx timestamp tracking for this port
|
||||
* @aux_dev: auxiliary device associated with this port
|
||||
* @ov_work: delayed work task for tracking when PHY offset is valid
|
||||
@@ -179,7 +179,7 @@ struct ice_ptp_tx {
|
||||
* @port_num: the port number this structure represents
|
||||
*/
|
||||
struct ice_ptp_port {
|
||||
struct list_head list_member;
|
||||
struct list_head list_node;
|
||||
struct ice_ptp_tx tx;
|
||||
struct auxiliary_device aux_dev;
|
||||
struct kthread_delayed_work ov_work;
|
||||
@@ -205,6 +205,7 @@ enum ice_ptp_tx_interrupt {
|
||||
* @ports: list of porst handled by this port owner
|
||||
* @lock: protect access to ports list
|
||||
*/
|
||||
|
||||
struct ice_ptp_port_owner {
|
||||
struct auxiliary_driver aux_driver;
|
||||
struct list_head ports;
|
||||
@@ -331,7 +332,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
void ice_ptp_release(struct ice_pf *pf);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
|
||||
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
|
||||
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
{
|
||||
@@ -379,7 +380,7 @@ static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
}
|
||||
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_release(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = {
|
||||
.rx_offset = {
|
||||
.serdes = 0xffffeb27, /* -10.42424 */
|
||||
.no_fec = 0xffffcccd, /* -25.6 */
|
||||
.fc = 0xfffe0014, /* -255.96 */
|
||||
.fc = 0xfffc557b, /* -469.26 */
|
||||
.sfd = 0x4a4, /* 2.32 */
|
||||
.bs_ds = 0x32 /* 0.0969697 */
|
||||
}
|
||||
|
||||
@@ -804,7 +804,7 @@ static u32 ice_ptp_tmr_cmd_to_port_reg(struct ice_hw *hw,
|
||||
/* Certain hardware families share the same register values for the
|
||||
* port register and source timer register.
|
||||
*/
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_tmr_cmd_to_src_reg(hw, cmd) & TS_CMD_MASK_E810;
|
||||
default:
|
||||
@@ -877,31 +877,46 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
|
||||
* The following functions operate on devices with the ETH 56G PHY.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
|
||||
* @hw: pointer to the HW struct
|
||||
* @port: destination port
|
||||
*
|
||||
* Return: destination sideband queue PHY device.
|
||||
*/
|
||||
static enum ice_sbq_msg_dev ice_ptp_get_dest_dev_e825(struct ice_hw *hw,
|
||||
u8 port)
|
||||
{
|
||||
/* On a single complex E825, PHY 0 is always destination device phy_0
|
||||
* and PHY 1 is phy_0_peer.
|
||||
*/
|
||||
if (port >= hw->ptp.ports_per_phy)
|
||||
return eth56g_phy_1;
|
||||
else
|
||||
return eth56g_phy_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_write_phy_eth56g - Write a PHY port register
|
||||
* @hw: pointer to the HW struct
|
||||
* @phy_idx: PHY index
|
||||
* @port: destination port
|
||||
* @addr: PHY register address
|
||||
* @val: Value to write
|
||||
*
|
||||
* Return: 0 on success, other error codes when failed to write to PHY
|
||||
*/
|
||||
static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||
u32 val)
|
||||
static int ice_write_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 val)
|
||||
{
|
||||
struct ice_sbq_msg_input phy_msg;
|
||||
struct ice_sbq_msg_input msg = {
|
||||
.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
|
||||
.opcode = ice_sbq_msg_wr,
|
||||
.msg_addr_low = lower_16_bits(addr),
|
||||
.msg_addr_high = upper_16_bits(addr),
|
||||
.data = val
|
||||
};
|
||||
int err;
|
||||
|
||||
phy_msg.opcode = ice_sbq_msg_wr;
|
||||
|
||||
phy_msg.msg_addr_low = lower_16_bits(addr);
|
||||
phy_msg.msg_addr_high = upper_16_bits(addr);
|
||||
|
||||
phy_msg.data = val;
|
||||
phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
|
||||
if (err)
|
||||
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
||||
err);
|
||||
@@ -912,41 +927,36 @@ static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||
/**
|
||||
* ice_read_phy_eth56g - Read a PHY port register
|
||||
* @hw: pointer to the HW struct
|
||||
* @phy_idx: PHY index
|
||||
* @port: destination port
|
||||
* @addr: PHY register address
|
||||
* @val: Value to write
|
||||
*
|
||||
* Return: 0 on success, other error codes when failed to read from PHY
|
||||
*/
|
||||
static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||
u32 *val)
|
||||
static int ice_read_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 *val)
|
||||
{
|
||||
struct ice_sbq_msg_input phy_msg;
|
||||
struct ice_sbq_msg_input msg = {
|
||||
.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
|
||||
.opcode = ice_sbq_msg_rd,
|
||||
.msg_addr_low = lower_16_bits(addr),
|
||||
.msg_addr_high = upper_16_bits(addr)
|
||||
};
|
||||
int err;
|
||||
|
||||
phy_msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
phy_msg.msg_addr_low = lower_16_bits(addr);
|
||||
phy_msg.msg_addr_high = upper_16_bits(addr);
|
||||
|
||||
phy_msg.data = 0;
|
||||
phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
|
||||
if (err) {
|
||||
err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
|
||||
if (err)
|
||||
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
else
|
||||
*val = msg.data;
|
||||
|
||||
*val = phy_msg.data;
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_phy_res_address_eth56g - Calculate a PHY port register address
|
||||
* @port: Port number to be written
|
||||
* @hw: pointer to the HW struct
|
||||
* @lane: Lane number to be written
|
||||
* @res_type: resource type (register/memory)
|
||||
* @offset: Offset from PHY port register base
|
||||
* @addr: The result address
|
||||
@@ -955,17 +965,19 @@ static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||
* * %0 - success
|
||||
* * %EINVAL - invalid port number or resource type
|
||||
*/
|
||||
static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
|
||||
u32 offset, u32 *addr)
|
||||
static int ice_phy_res_address_eth56g(struct ice_hw *hw, u8 lane,
|
||||
enum eth56g_res_type res_type,
|
||||
u32 offset,
|
||||
u32 *addr)
|
||||
{
|
||||
u8 lane = port % ICE_PORTS_PER_QUAD;
|
||||
u8 phy = ICE_GET_QUAD_NUM(port);
|
||||
|
||||
if (res_type >= NUM_ETH56G_PHY_RES)
|
||||
return -EINVAL;
|
||||
|
||||
*addr = eth56g_phy_res[res_type].base[phy] +
|
||||
/* Lanes 4..7 are in fact 0..3 on a second PHY */
|
||||
lane %= hw->ptp.ports_per_phy;
|
||||
*addr = eth56g_phy_res[res_type].base[0] +
|
||||
lane * eth56g_phy_res[res_type].step + offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -985,19 +997,17 @@ static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
|
||||
static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||
u32 val, enum eth56g_res_type res_type)
|
||||
{
|
||||
u8 phy_port = port % hw->ptp.ports_per_phy;
|
||||
u8 phy_idx = port / hw->ptp.ports_per_phy;
|
||||
u32 addr;
|
||||
int err;
|
||||
|
||||
if (port >= hw->ptp.num_lports)
|
||||
return -EINVAL;
|
||||
|
||||
err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
|
||||
err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ice_write_phy_eth56g(hw, phy_idx, addr, val);
|
||||
return ice_write_phy_eth56g(hw, port, addr, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,19 +1026,17 @@ static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||
static int ice_read_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||
u32 *val, enum eth56g_res_type res_type)
|
||||
{
|
||||
u8 phy_port = port % hw->ptp.ports_per_phy;
|
||||
u8 phy_idx = port / hw->ptp.ports_per_phy;
|
||||
u32 addr;
|
||||
int err;
|
||||
|
||||
if (port >= hw->ptp.num_lports)
|
||||
return -EINVAL;
|
||||
|
||||
err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
|
||||
err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ice_read_phy_eth56g(hw, phy_idx, addr, val);
|
||||
return ice_read_phy_eth56g(hw, port, addr, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1177,6 +1185,56 @@ static int ice_write_port_mem_eth56g(struct ice_hw *hw, u8 port, u16 offset,
|
||||
return ice_write_port_eth56g(hw, port, offset, val, ETH56G_PHY_MEM_PTP);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_write_quad_ptp_reg_eth56g - Write a PHY quad register
|
||||
* @hw: pointer to the HW struct
|
||||
* @offset: PHY register offset
|
||||
* @port: Port number
|
||||
* @val: Value to write
|
||||
*
|
||||
* Return:
|
||||
* * %0 - success
|
||||
* * %EIO - invalid port number or resource type
|
||||
* * %other - failed to write to PHY
|
||||
*/
|
||||
static int ice_write_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
|
||||
u32 offset, u32 val)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
if (port >= hw->ptp.num_lports)
|
||||
return -EIO;
|
||||
|
||||
addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
|
||||
|
||||
return ice_write_phy_eth56g(hw, port, addr, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_read_quad_ptp_reg_eth56g - Read a PHY quad register
|
||||
* @hw: pointer to the HW struct
|
||||
* @offset: PHY register offset
|
||||
* @port: Port number
|
||||
* @val: Value to read
|
||||
*
|
||||
* Return:
|
||||
* * %0 - success
|
||||
* * %EIO - invalid port number or resource type
|
||||
* * %other - failed to read from PHY
|
||||
*/
|
||||
static int ice_read_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
|
||||
u32 offset, u32 *val)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
if (port >= hw->ptp.num_lports)
|
||||
return -EIO;
|
||||
|
||||
addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
|
||||
|
||||
return ice_read_phy_eth56g(hw, port, addr, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_is_64b_phy_reg_eth56g - Check if this is a 64bit PHY register
|
||||
* @low_addr: the low address to check
|
||||
@@ -1896,7 +1954,6 @@ ice_phy_get_speed_eth56g(struct ice_link_status *li)
|
||||
*/
|
||||
static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||
{
|
||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
@@ -1911,8 +1968,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||
switch (ice_phy_get_speed_eth56g(&hw->port_info->phy.link_info)) {
|
||||
case ICE_ETH56G_LNK_SPD_1G:
|
||||
case ICE_ETH56G_LNK_SPD_2_5G:
|
||||
err = ice_read_ptp_reg_eth56g(hw, port_blk,
|
||||
PHY_GPCS_CONFIG_REG0, &val);
|
||||
err = ice_read_quad_ptp_reg_eth56g(hw, port,
|
||||
PHY_GPCS_CONFIG_REG0, &val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_GPCS_CONFIG_REG0, status: %d",
|
||||
err);
|
||||
@@ -1923,8 +1980,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||
val |= FIELD_PREP(PHY_GPCS_CONFIG_REG0_TX_THR_M,
|
||||
ICE_ETH56G_NOMINAL_TX_THRESH);
|
||||
|
||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
||||
PHY_GPCS_CONFIG_REG0, val);
|
||||
err = ice_write_quad_ptp_reg_eth56g(hw, port,
|
||||
PHY_GPCS_CONFIG_REG0, val);
|
||||
if (err) {
|
||||
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_GPCS_CONFIG_REG0, status: %d",
|
||||
err);
|
||||
@@ -1965,50 +2022,47 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||
*/
|
||||
int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
|
||||
{
|
||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
||||
u8 blk_port = port & (ICE_PORTS_PER_QUAD - 1);
|
||||
u8 quad_lane = port % ICE_PORTS_PER_QUAD;
|
||||
u32 addr, val, peer_delay;
|
||||
bool enable, sfd_ena;
|
||||
u32 val, peer_delay;
|
||||
int err;
|
||||
|
||||
enable = hw->ptp.phy.eth56g.onestep_ena;
|
||||
peer_delay = hw->ptp.phy.eth56g.peer_delay;
|
||||
sfd_ena = hw->ptp.phy.eth56g.sfd_ena;
|
||||
|
||||
/* PHY_PTP_1STEP_CONFIG */
|
||||
err = ice_read_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, &val);
|
||||
addr = PHY_PTP_1STEP_CONFIG;
|
||||
err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (enable)
|
||||
val |= blk_port;
|
||||
val |= BIT(quad_lane);
|
||||
else
|
||||
val &= ~blk_port;
|
||||
val &= ~BIT(quad_lane);
|
||||
|
||||
val &= ~(PHY_PTP_1STEP_T1S_UP64_M | PHY_PTP_1STEP_T1S_DELTA_M);
|
||||
|
||||
err = ice_write_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, val);
|
||||
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* PHY_PTP_1STEP_PEER_DELAY */
|
||||
addr = PHY_PTP_1STEP_PEER_DELAY(quad_lane);
|
||||
val = FIELD_PREP(PHY_PTP_1STEP_PD_DELAY_M, peer_delay);
|
||||
if (peer_delay)
|
||||
val |= PHY_PTP_1STEP_PD_ADD_PD_M;
|
||||
val |= PHY_PTP_1STEP_PD_DLY_V_M;
|
||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
||||
PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
|
||||
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val &= ~PHY_PTP_1STEP_PD_DLY_V_M;
|
||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
||||
PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
|
||||
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* PHY_MAC_XIF_MODE */
|
||||
err = ice_read_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, &val);
|
||||
addr = PHY_MAC_XIF_MODE;
|
||||
err = ice_read_mac_reg_eth56g(hw, port, addr, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2028,7 +2082,7 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
|
||||
FIELD_PREP(PHY_MAC_XIF_TS_BIN_MODE_M, enable) |
|
||||
FIELD_PREP(PHY_MAC_XIF_TS_SFD_ENA_M, sfd_ena);
|
||||
|
||||
return ice_write_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, val);
|
||||
return ice_write_mac_reg_eth56g(hw, port, addr, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2070,21 +2124,22 @@ static u32 ice_ptp_calc_bitslip_eth56g(struct ice_hw *hw, u8 port, u32 bs,
|
||||
bool fc, bool rs,
|
||||
enum ice_eth56g_link_spd spd)
|
||||
{
|
||||
u8 port_offset = port & (ICE_PORTS_PER_QUAD - 1);
|
||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
||||
u32 bitslip;
|
||||
int err;
|
||||
|
||||
if (!bs || rs)
|
||||
return 0;
|
||||
|
||||
if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G)
|
||||
if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G) {
|
||||
err = ice_read_gpcs_reg_eth56g(hw, port, PHY_GPCS_BITSLIP,
|
||||
&bitslip);
|
||||
else
|
||||
err = ice_read_ptp_reg_eth56g(hw, port_blk,
|
||||
PHY_REG_SD_BIT_SLIP(port_offset),
|
||||
&bitslip);
|
||||
} else {
|
||||
u8 quad_lane = port % ICE_PORTS_PER_QUAD;
|
||||
u32 addr;
|
||||
|
||||
addr = PHY_REG_SD_BIT_SLIP(quad_lane);
|
||||
err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &bitslip);
|
||||
}
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
@@ -2644,59 +2699,29 @@ static int ice_get_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw, u8 port,
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_is_muxed_topo - detect breakout 2x50G topology for E825C
|
||||
* @hw: pointer to the HW struct
|
||||
*
|
||||
* Return: true if it's 2x50 breakout topology, false otherwise
|
||||
*/
|
||||
static bool ice_is_muxed_topo(struct ice_hw *hw)
|
||||
{
|
||||
u8 link_topo;
|
||||
bool mux;
|
||||
u32 val;
|
||||
|
||||
val = rd32(hw, GLGEN_SWITCH_MODE_CONFIG);
|
||||
mux = FIELD_GET(GLGEN_SWITCH_MODE_CONFIG_25X4_QUAD_M, val);
|
||||
val = rd32(hw, GLGEN_MAC_LINK_TOPO);
|
||||
link_topo = FIELD_GET(GLGEN_MAC_LINK_TOPO_LINK_TOPO_M, val);
|
||||
|
||||
return (mux && link_topo == ICE_LINK_TOPO_UP_TO_2_LINKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_init_phy_e825c - initialize PHY parameters
|
||||
* ice_ptp_init_phy_e825 - initialize PHY parameters
|
||||
* @hw: pointer to the HW struct
|
||||
*/
|
||||
static void ice_ptp_init_phy_e825c(struct ice_hw *hw)
|
||||
static void ice_ptp_init_phy_e825(struct ice_hw *hw)
|
||||
{
|
||||
struct ice_ptp_hw *ptp = &hw->ptp;
|
||||
struct ice_eth56g_params *params;
|
||||
u8 phy;
|
||||
u32 phy_rev;
|
||||
int err;
|
||||
|
||||
ptp->phy_model = ICE_PHY_ETH56G;
|
||||
params = &ptp->phy.eth56g;
|
||||
params->onestep_ena = false;
|
||||
params->peer_delay = 0;
|
||||
params->sfd_ena = false;
|
||||
params->phy_addr[0] = eth56g_phy_0;
|
||||
params->phy_addr[1] = eth56g_phy_1;
|
||||
params->num_phys = 2;
|
||||
ptp->ports_per_phy = 4;
|
||||
ptp->num_lports = params->num_phys * ptp->ports_per_phy;
|
||||
|
||||
ice_sb_access_ena_eth56g(hw, true);
|
||||
for (phy = 0; phy < params->num_phys; phy++) {
|
||||
u32 phy_rev;
|
||||
int err;
|
||||
|
||||
err = ice_read_phy_eth56g(hw, phy, PHY_REG_REVISION, &phy_rev);
|
||||
if (err || phy_rev != PHY_REVISION_ETH56G) {
|
||||
ptp->phy_model = ICE_PHY_UNSUP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw);
|
||||
err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev);
|
||||
if (err || phy_rev != PHY_REVISION_ETH56G)
|
||||
ptp->phy_model = ICE_PHY_UNSUP;
|
||||
}
|
||||
|
||||
/* E822 family functions
|
||||
@@ -2715,10 +2740,9 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||
struct ice_sbq_msg_input *msg, u8 port,
|
||||
u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
int phy_port, quadtype;
|
||||
|
||||
phy_port = port % hw->ptp.ports_per_phy;
|
||||
phy = port / hw->ptp.ports_per_phy;
|
||||
quadtype = ICE_GET_QUAD_NUM(port) %
|
||||
ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
||||
|
||||
@@ -2730,12 +2754,7 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||
msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
|
||||
}
|
||||
|
||||
if (phy == 0)
|
||||
msg->dest_dev = rmn_0;
|
||||
else if (phy == 1)
|
||||
msg->dest_dev = rmn_1;
|
||||
else
|
||||
msg->dest_dev = rmn_2;
|
||||
msg->dest_dev = rmn_0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5395,7 +5414,7 @@ void ice_ptp_init_hw(struct ice_hw *hw)
|
||||
else if (ice_is_e810(hw))
|
||||
ice_ptp_init_phy_e810(ptp);
|
||||
else if (ice_is_e825c(hw))
|
||||
ice_ptp_init_phy_e825c(hw);
|
||||
ice_ptp_init_phy_e825(hw);
|
||||
else
|
||||
ptp->phy_model = ICE_PHY_UNSUP;
|
||||
}
|
||||
@@ -5418,7 +5437,7 @@ void ice_ptp_init_hw(struct ice_hw *hw)
|
||||
static int ice_ptp_write_port_cmd(struct ice_hw *hw, u8 port,
|
||||
enum ice_ptp_tmr_cmd cmd)
|
||||
{
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_ptp_write_port_cmd_eth56g(hw, port, cmd);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -5483,7 +5502,7 @@ static int ice_ptp_port_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
u32 port;
|
||||
|
||||
/* PHY models which can program all ports simultaneously */
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_port_cmd_e810(hw, cmd);
|
||||
default:
|
||||
@@ -5562,7 +5581,7 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
|
||||
|
||||
/* PHY timers */
|
||||
/* Fill Rx and Tx ports and send msg to PHY */
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
err = ice_ptp_prep_phy_time_eth56g(hw,
|
||||
(u32)(time & 0xFFFFFFFF));
|
||||
@@ -5608,7 +5627,7 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
err = ice_ptp_prep_phy_incval_eth56g(hw, incval);
|
||||
break;
|
||||
@@ -5677,7 +5696,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
err = ice_ptp_prep_phy_adj_eth56g(hw, adj);
|
||||
break;
|
||||
@@ -5710,7 +5729,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
*/
|
||||
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
{
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_read_ptp_tstamp_eth56g(hw, block, idx, tstamp);
|
||||
case ICE_PHY_E810:
|
||||
@@ -5740,7 +5759,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_clear_ptp_tstamp_eth56g(hw, block, idx);
|
||||
case ICE_PHY_E810:
|
||||
@@ -5803,7 +5822,7 @@ static int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
|
||||
*/
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw)
|
||||
{
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
ice_ptp_reset_ts_memory_eth56g(hw);
|
||||
break;
|
||||
@@ -5832,7 +5851,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
/* Clear event err indications for auxiliary pins */
|
||||
(void)rd32(hw, GLTSYN_STAT(src_idx));
|
||||
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_ptp_init_phc_eth56g(hw);
|
||||
case ICE_PHY_E810:
|
||||
@@ -5857,7 +5876,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
*/
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
{
|
||||
switch (hw->ptp.phy_model) {
|
||||
switch (ice_get_phy_model(hw)) {
|
||||
case ICE_PHY_ETH56G:
|
||||
return ice_get_phy_tx_tstamp_ready_eth56g(hw, block,
|
||||
tstamp_ready);
|
||||
|
||||
@@ -452,6 +452,11 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool ice_is_dual(struct ice_hw *hw)
|
||||
{
|
||||
return !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_DUAL_M);
|
||||
}
|
||||
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
#define ICE_PTP_CLOCK_INDEX_0 0x00
|
||||
|
||||
@@ -850,7 +850,6 @@ struct ice_mbx_data {
|
||||
|
||||
struct ice_eth56g_params {
|
||||
u8 num_phys;
|
||||
u8 phy_addr[2];
|
||||
bool onestep_ena;
|
||||
bool sfd_ena;
|
||||
u32 peer_delay;
|
||||
@@ -881,7 +880,6 @@ struct ice_ptp_hw {
|
||||
union ice_phy_params phy;
|
||||
u8 num_lports;
|
||||
u8 ports_per_phy;
|
||||
bool is_2x50g_muxed_topo;
|
||||
};
|
||||
|
||||
/* Port hardware description */
|
||||
|
||||
@@ -724,6 +724,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
|
||||
/* check esn */
|
||||
if (x->props.flags & XFRM_STATE_ESN)
|
||||
mlx5e_ipsec_update_esn_state(sa_entry);
|
||||
else
|
||||
/* According to RFC4303, section "3.3.3. Sequence Number Generation",
|
||||
* the first packet sent using a given SA will contain a sequence
|
||||
* number of 1.
|
||||
*/
|
||||
sa_entry->esn_state.esn = 1;
|
||||
|
||||
mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs);
|
||||
|
||||
@@ -768,9 +774,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
|
||||
MLX5_IPSEC_RESCHED);
|
||||
|
||||
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
|
||||
x->props.mode == XFRM_MODE_TUNNEL)
|
||||
xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
|
||||
MLX5E_IPSEC_TUNNEL_SA);
|
||||
x->props.mode == XFRM_MODE_TUNNEL) {
|
||||
xa_lock_bh(&ipsec->sadb);
|
||||
__xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
|
||||
MLX5E_IPSEC_TUNNEL_SA);
|
||||
xa_unlock_bh(&ipsec->sadb);
|
||||
}
|
||||
|
||||
out:
|
||||
x->xso.offload_handle = (unsigned long)sa_entry;
|
||||
@@ -797,7 +806,6 @@ err_xfrm:
|
||||
static void mlx5e_xfrm_del_state(struct xfrm_state *x)
|
||||
{
|
||||
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
|
||||
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
|
||||
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
|
||||
struct mlx5e_ipsec_sa_entry *old;
|
||||
|
||||
@@ -806,12 +814,6 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
|
||||
|
||||
old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id);
|
||||
WARN_ON(old != sa_entry);
|
||||
|
||||
if (attrs->mode == XFRM_MODE_TUNNEL &&
|
||||
attrs->type == XFRM_DEV_OFFLOAD_PACKET)
|
||||
/* Make sure that no ARP requests are running in parallel */
|
||||
flush_workqueue(ipsec->wq);
|
||||
|
||||
}
|
||||
|
||||
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
|
||||
|
||||
@@ -1718,23 +1718,21 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
if (attrs->family == AF_INET)
|
||||
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
|
||||
else
|
||||
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
|
||||
|
||||
setup_fte_no_frags(spec);
|
||||
setup_fte_upper_proto_match(spec, &attrs->upspec);
|
||||
|
||||
switch (attrs->type) {
|
||||
case XFRM_DEV_OFFLOAD_CRYPTO:
|
||||
if (attrs->family == AF_INET)
|
||||
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
|
||||
else
|
||||
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
|
||||
setup_fte_spi(spec, attrs->spi, false);
|
||||
setup_fte_esp(spec);
|
||||
setup_fte_reg_a(spec);
|
||||
break;
|
||||
case XFRM_DEV_OFFLOAD_PACKET:
|
||||
if (attrs->reqid)
|
||||
setup_fte_reg_c4(spec, attrs->reqid);
|
||||
setup_fte_reg_c4(spec, attrs->reqid);
|
||||
err = setup_pkt_reformat(ipsec, attrs, &flow_act);
|
||||
if (err)
|
||||
goto err_pkt_reformat;
|
||||
|
||||
@@ -91,8 +91,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
|
||||
EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
|
||||
|
||||
static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
||||
struct mlx5_accel_esp_xfrm_attrs *attrs)
|
||||
struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
{
|
||||
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
|
||||
void *aso_ctx;
|
||||
|
||||
aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
|
||||
@@ -120,8 +121,12 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
||||
* active.
|
||||
*/
|
||||
MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
|
||||
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT)
|
||||
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) {
|
||||
MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
|
||||
if (!attrs->replay_esn.trigger)
|
||||
MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
|
||||
sa_entry->esn_state.esn);
|
||||
}
|
||||
|
||||
if (attrs->lft.hard_packet_limit != XFRM_INF) {
|
||||
MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
|
||||
@@ -175,7 +180,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
|
||||
res = &mdev->mlx5e_res.hw_objs;
|
||||
if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
|
||||
mlx5e_ipsec_packet_setup(obj, res->pdn, attrs);
|
||||
mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry);
|
||||
|
||||
err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
|
||||
if (!err)
|
||||
|
||||
@@ -2709,6 +2709,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
|
||||
break;
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_TX:
|
||||
root_ns = steering->rdma_tx_root_ns;
|
||||
prio = RDMA_TX_BYPASS_PRIO;
|
||||
break;
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
|
||||
root_ns = steering->rdma_rx_root_ns;
|
||||
|
||||
@@ -530,7 +530,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev,
|
||||
set_tt_map(port_sel, hash_type);
|
||||
err = mlx5_lag_create_definers(ldev, hash_type, ports);
|
||||
if (err)
|
||||
return err;
|
||||
goto clear_port_sel;
|
||||
|
||||
if (port_sel->tunnel) {
|
||||
err = mlx5_lag_create_inner_ttc_table(ldev);
|
||||
@@ -549,6 +549,8 @@ destroy_inner:
|
||||
mlx5_destroy_ttc_table(port_sel->inner.ttc);
|
||||
destroy_definers:
|
||||
mlx5_lag_destroy_definers(ldev);
|
||||
clear_port_sel:
|
||||
memset(port_sel, 0, sizeof(*port_sel));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,7 @@ static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
|
||||
return 0;
|
||||
|
||||
esw_err:
|
||||
mlx5_sf_function_id_erase(table, sf);
|
||||
mlx5_sf_free(table, sf);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -382,6 +382,7 @@ err_alloc_bfreg:
|
||||
|
||||
bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
struct mutex *wc_state_lock = &mdev->wc_state_lock;
|
||||
struct mlx5_core_dev *parent = NULL;
|
||||
|
||||
if (!MLX5_CAP_GEN(mdev, bf)) {
|
||||
@@ -400,32 +401,31 @@ bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
|
||||
*/
|
||||
goto out;
|
||||
|
||||
mutex_lock(&mdev->wc_state_lock);
|
||||
#ifdef CONFIG_MLX5_SF
|
||||
if (mlx5_core_is_sf(mdev)) {
|
||||
parent = mdev->priv.parent_mdev;
|
||||
wc_state_lock = &parent->wc_state_lock;
|
||||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(wc_state_lock);
|
||||
|
||||
if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED)
|
||||
goto unlock;
|
||||
|
||||
#ifdef CONFIG_MLX5_SF
|
||||
if (mlx5_core_is_sf(mdev))
|
||||
parent = mdev->priv.parent_mdev;
|
||||
#endif
|
||||
|
||||
if (parent) {
|
||||
mutex_lock(&parent->wc_state_lock);
|
||||
|
||||
mlx5_core_test_wc(parent);
|
||||
|
||||
mlx5_core_dbg(mdev, "parent set wc_state=%d\n",
|
||||
parent->wc_state);
|
||||
mdev->wc_state = parent->wc_state;
|
||||
|
||||
mutex_unlock(&parent->wc_state_lock);
|
||||
} else {
|
||||
mlx5_core_test_wc(mdev);
|
||||
}
|
||||
|
||||
mlx5_core_test_wc(mdev);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&mdev->wc_state_lock);
|
||||
mutex_unlock(wc_state_lock);
|
||||
out:
|
||||
mlx5_core_dbg(mdev, "wc_state=%d\n", mdev->wc_state);
|
||||
|
||||
|
||||
@@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
|
||||
map_id_full = be64_to_cpu(cbe->map_ptr);
|
||||
map_id = map_id_full;
|
||||
|
||||
if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
||||
if (size_add(pkt_size, data_size) > INT_MAX ||
|
||||
len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
||||
return -EINVAL;
|
||||
if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2756,6 +2756,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
|
||||
.net_features = NETIF_F_RXCSUM,
|
||||
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
|
||||
.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
|
||||
.tx_max_frame_size = SZ_2K,
|
||||
.rx_max_frame_size = SZ_2K,
|
||||
.rx_buffer_size = SZ_2K +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
|
||||
|
||||
@@ -127,15 +127,15 @@ struct cpsw_ale_dev_id {
|
||||
|
||||
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
|
||||
{
|
||||
int idx, idx2;
|
||||
int idx, idx2, index;
|
||||
u32 hi_val = 0;
|
||||
|
||||
idx = start / 32;
|
||||
idx2 = (start + bits - 1) / 32;
|
||||
/* Check if bits to be fetched exceed a word */
|
||||
if (idx != idx2) {
|
||||
idx2 = 2 - idx2; /* flip */
|
||||
hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
|
||||
index = 2 - idx2; /* flip */
|
||||
hi_val = ale_entry[index] << ((idx2 * 32) - start);
|
||||
}
|
||||
start -= idx * 32;
|
||||
idx = 2 - idx; /* flip */
|
||||
@@ -145,16 +145,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
|
||||
static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
|
||||
u32 value)
|
||||
{
|
||||
int idx, idx2;
|
||||
int idx, idx2, index;
|
||||
|
||||
value &= BITMASK(bits);
|
||||
idx = start / 32;
|
||||
idx2 = (start + bits - 1) / 32;
|
||||
/* Check if bits to be set exceed a word */
|
||||
if (idx != idx2) {
|
||||
idx2 = 2 - idx2; /* flip */
|
||||
ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
|
||||
ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
|
||||
index = 2 - idx2; /* flip */
|
||||
ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
|
||||
ale_entry[index] |= (value >> ((idx2 * 32) - start));
|
||||
}
|
||||
start -= idx * 32;
|
||||
idx = 2 - idx; /* flip */
|
||||
|
||||
@@ -2056,6 +2056,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (ecoalesce->rx_max_coalesced_frames > 255 ||
|
||||
ecoalesce->tx_max_coalesced_frames > 255) {
|
||||
NL_SET_ERR_MSG(extack, "frames must be less than 256");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ecoalesce->rx_max_coalesced_frames)
|
||||
lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
|
||||
if (ecoalesce->rx_coalesce_usecs)
|
||||
|
||||
+17
-9
@@ -1526,8 +1526,8 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
|
||||
goto out_encap;
|
||||
}
|
||||
|
||||
gn = net_generic(dev_net(dev), gtp_net_id);
|
||||
list_add_rcu(>p->list, &gn->gtp_dev_list);
|
||||
gn = net_generic(src_net, gtp_net_id);
|
||||
list_add(>p->list, &gn->gtp_dev_list);
|
||||
dev->priv_destructor = gtp_destructor;
|
||||
|
||||
netdev_dbg(dev, "registered new GTP interface\n");
|
||||
@@ -1553,7 +1553,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
|
||||
hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid)
|
||||
pdp_context_delete(pctx);
|
||||
|
||||
list_del_rcu(>p->list);
|
||||
list_del(>p->list);
|
||||
unregister_netdevice_queue(dev, head);
|
||||
}
|
||||
|
||||
@@ -2279,16 +2279,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
|
||||
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
|
||||
int i, j, bucket = cb->args[0], skip = cb->args[1];
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct net_device *dev;
|
||||
struct pdp_ctx *pctx;
|
||||
struct gtp_net *gn;
|
||||
|
||||
gn = net_generic(net, gtp_net_id);
|
||||
|
||||
if (cb->args[4])
|
||||
return 0;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
|
||||
for_each_netdev_rcu(net, dev) {
|
||||
if (dev->rtnl_link_ops != >p_link_ops)
|
||||
continue;
|
||||
|
||||
gtp = netdev_priv(dev);
|
||||
|
||||
if (last_gtp && last_gtp != gtp)
|
||||
continue;
|
||||
else
|
||||
@@ -2483,9 +2486,14 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
|
||||
|
||||
list_for_each_entry(net, net_list, exit_list) {
|
||||
struct gtp_net *gn = net_generic(net, gtp_net_id);
|
||||
struct gtp_dev *gtp;
|
||||
struct gtp_dev *gtp, *gtp_next;
|
||||
struct net_device *dev;
|
||||
|
||||
list_for_each_entry(gtp, &gn->gtp_dev_list, list)
|
||||
for_each_netdev(net, dev)
|
||||
if (dev->rtnl_link_ops == >p_link_ops)
|
||||
gtp_dellink(dev, dev_to_kill);
|
||||
|
||||
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
|
||||
gtp_dellink(gtp->dev, dev_to_kill);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-5
@@ -206,8 +206,8 @@ static int pfcp_newlink(struct net *net, struct net_device *dev,
|
||||
goto exit_del_pfcp_sock;
|
||||
}
|
||||
|
||||
pn = net_generic(dev_net(dev), pfcp_net_id);
|
||||
list_add_rcu(&pfcp->list, &pn->pfcp_dev_list);
|
||||
pn = net_generic(net, pfcp_net_id);
|
||||
list_add(&pfcp->list, &pn->pfcp_dev_list);
|
||||
|
||||
netdev_dbg(dev, "registered new PFCP interface\n");
|
||||
|
||||
@@ -224,7 +224,7 @@ static void pfcp_dellink(struct net_device *dev, struct list_head *head)
|
||||
{
|
||||
struct pfcp_dev *pfcp = netdev_priv(dev);
|
||||
|
||||
list_del_rcu(&pfcp->list);
|
||||
list_del(&pfcp->list);
|
||||
unregister_netdevice_queue(dev, head);
|
||||
}
|
||||
|
||||
@@ -247,11 +247,16 @@ static int __net_init pfcp_net_init(struct net *net)
|
||||
static void __net_exit pfcp_net_exit(struct net *net)
|
||||
{
|
||||
struct pfcp_net *pn = net_generic(net, pfcp_net_id);
|
||||
struct pfcp_dev *pfcp;
|
||||
struct pfcp_dev *pfcp, *pfcp_next;
|
||||
struct net_device *dev;
|
||||
LIST_HEAD(list);
|
||||
|
||||
rtnl_lock();
|
||||
list_for_each_entry(pfcp, &pn->pfcp_dev_list, list)
|
||||
for_each_netdev(net, dev)
|
||||
if (dev->rtnl_link_ops == &pfcp_link_ops)
|
||||
pfcp_dellink(dev, &list);
|
||||
|
||||
list_for_each_entry_safe(pfcp, pfcp_next, &pn->pfcp_dev_list, list)
|
||||
pfcp_dellink(pfcp->dev, &list);
|
||||
|
||||
unregister_netdevice_many(&list);
|
||||
|
||||
@@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
|
||||
*/
|
||||
id->nsfeat |= 1 << 4;
|
||||
/* NPWG = Namespace Preferred Write Granularity. 0's based */
|
||||
id->npwg = lpp0b;
|
||||
id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev));
|
||||
/* NPWA = Namespace Preferred Write Alignment. 0's based */
|
||||
id->npwa = id->npwg;
|
||||
/* NPDG = Namespace Preferred Deallocate Granularity. 0's based */
|
||||
|
||||
@@ -283,6 +283,9 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
|
||||
init_waitqueue_head(&dell_bl->wait_queue);
|
||||
dell_bl->dev = dev;
|
||||
|
||||
serdev_device_set_drvdata(serdev, dell_bl);
|
||||
serdev_device_set_client_ops(serdev, &dell_uart_bl_serdev_ops);
|
||||
|
||||
ret = devm_serdev_device_open(dev, serdev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "opening UART device\n");
|
||||
@@ -290,8 +293,6 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
|
||||
/* 9600 bps, no flow control, these are the default but set them to be sure */
|
||||
serdev_device_set_baudrate(serdev, 9600);
|
||||
serdev_device_set_flow_control(serdev, false);
|
||||
serdev_device_set_drvdata(serdev, dell_bl);
|
||||
serdev_device_set_client_ops(serdev, &dell_uart_bl_serdev_ops);
|
||||
|
||||
get_version[0] = DELL_SOF(GET_CMD_LEN);
|
||||
get_version[1] = CMD_GET_VERSION;
|
||||
|
||||
@@ -804,6 +804,7 @@ EXPORT_SYMBOL_GPL(isst_if_cdev_unregister);
|
||||
static const struct x86_cpu_id isst_cpu_ids[] = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, 0),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED),
|
||||
|
||||
@@ -81,6 +81,7 @@ static const struct x86_cpu_id tpmi_cpu_ids[] = {
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, NULL),
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, NULL),
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL),
|
||||
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, NULL),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL),
|
||||
X86_MATCH_VFM(INTEL_PANTHERCOVE_X, NULL),
|
||||
{}
|
||||
|
||||
@@ -199,14 +199,15 @@ static int yt2_1380_fc_serdev_probe(struct serdev_device *serdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
serdev_device_set_drvdata(serdev, fc);
|
||||
serdev_device_set_client_ops(serdev, &yt2_1380_fc_serdev_ops);
|
||||
|
||||
ret = devm_serdev_device_open(dev, serdev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "opening UART device\n");
|
||||
|
||||
serdev_device_set_baudrate(serdev, 600);
|
||||
serdev_device_set_flow_control(serdev, false);
|
||||
serdev_device_set_drvdata(serdev, fc);
|
||||
serdev_device_set_client_ops(serdev, &yt2_1380_fc_serdev_ops);
|
||||
|
||||
ret = devm_extcon_register_notifier_all(dev, fc->extcon, &fc->nb);
|
||||
if (ret)
|
||||
|
||||
@@ -770,7 +770,7 @@ static void imx8mp_blk_ctrl_remove(struct platform_device *pdev)
|
||||
|
||||
of_genpd_del_provider(pdev->dev.of_node);
|
||||
|
||||
for (i = 0; bc->onecell_data.num_domains; i++) {
|
||||
for (i = 0; i < bc->onecell_data.num_domains; i++) {
|
||||
struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
|
||||
|
||||
pm_genpd_remove(&domain->genpd);
|
||||
|
||||
@@ -176,6 +176,7 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
|
||||
vdev->dev.parent = dev;
|
||||
priv->vdev = vdev;
|
||||
|
||||
device_set_of_node_from_dev(&vdev->dev, dev);
|
||||
error = platform_device_add(vdev);
|
||||
if (error)
|
||||
goto err_device_put;
|
||||
|
||||
@@ -10631,14 +10631,17 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the default power management level for runtime and system PM.
|
||||
* Set the default power management level for runtime and system PM if
|
||||
* not set by the host controller drivers.
|
||||
* Default power saving mode is to keep UFS link in Hibern8 state
|
||||
* and UFS device in sleep state.
|
||||
*/
|
||||
hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
|
||||
if (!hba->rpm_lvl)
|
||||
hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
|
||||
UFS_SLEEP_PWR_MODE,
|
||||
UIC_LINK_HIBERN8_STATE);
|
||||
hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
|
||||
if (!hba->spm_lvl)
|
||||
hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
|
||||
UFS_SLEEP_PWR_MODE,
|
||||
UIC_LINK_HIBERN8_STATE);
|
||||
|
||||
|
||||
+4
-2
@@ -413,8 +413,10 @@ int afs_proc_addr_prefs_write(struct file *file, char *buf, size_t size)
|
||||
|
||||
do {
|
||||
argc = afs_split_string(&buf, argv, ARRAY_SIZE(argv));
|
||||
if (argc < 0)
|
||||
return argc;
|
||||
if (argc < 0) {
|
||||
ret = argc;
|
||||
goto done;
|
||||
}
|
||||
if (argc < 2)
|
||||
goto inval;
|
||||
|
||||
|
||||
@@ -797,6 +797,10 @@ static int get_canonical_dev_path(const char *dev_path, char *canonical)
|
||||
if (ret)
|
||||
goto out;
|
||||
resolved_path = d_path(&path, path_buf, PATH_MAX);
|
||||
if (IS_ERR(resolved_path)) {
|
||||
ret = PTR_ERR(resolved_path);
|
||||
goto out;
|
||||
}
|
||||
ret = strscpy(canonical, resolved_path, PATH_MAX);
|
||||
out:
|
||||
kfree(path_buf);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/namei.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/string.h>
|
||||
@@ -576,7 +577,7 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
|
||||
*/
|
||||
static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
|
||||
{
|
||||
char *secctx;
|
||||
int err;
|
||||
|
||||
_enter(",%s", args);
|
||||
|
||||
@@ -585,16 +586,16 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cache->secctx) {
|
||||
if (cache->have_secid) {
|
||||
pr_err("Second security context specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
secctx = kstrdup(args, GFP_KERNEL);
|
||||
if (!secctx)
|
||||
return -ENOMEM;
|
||||
err = security_secctx_to_secid(args, strlen(args), &cache->secid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cache->secctx = secctx;
|
||||
cache->have_secid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -820,7 +821,6 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
|
||||
put_cred(cache->cache_cred);
|
||||
|
||||
kfree(cache->rootdirname);
|
||||
kfree(cache->secctx);
|
||||
kfree(cache->tag);
|
||||
|
||||
_leave("");
|
||||
|
||||
@@ -122,7 +122,6 @@ struct cachefiles_cache {
|
||||
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
|
||||
#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */
|
||||
char *rootdirname; /* name of cache root directory */
|
||||
char *secctx; /* LSM security context */
|
||||
char *tag; /* cache binding tag */
|
||||
refcount_t unbind_pincount;/* refcount to do daemon unbind */
|
||||
struct xarray reqs; /* xarray of pending on-demand requests */
|
||||
@@ -130,6 +129,8 @@ struct cachefiles_cache {
|
||||
struct xarray ondemand_ids; /* xarray for ondemand_id allocation */
|
||||
u32 ondemand_id_next;
|
||||
u32 msg_id_next;
|
||||
u32 secid; /* LSM security id */
|
||||
bool have_secid; /* whether "secid" was set */
|
||||
};
|
||||
|
||||
static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)
|
||||
|
||||
@@ -18,7 +18,7 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
|
||||
struct cred *new;
|
||||
int ret;
|
||||
|
||||
_enter("{%s}", cache->secctx);
|
||||
_enter("{%u}", cache->have_secid ? cache->secid : 0);
|
||||
|
||||
new = prepare_kernel_cred(current);
|
||||
if (!new) {
|
||||
@@ -26,8 +26,8 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cache->secctx) {
|
||||
ret = set_security_override_from_ctx(new, cache->secctx);
|
||||
if (cache->have_secid) {
|
||||
ret = set_security_override(new, cache->secid);
|
||||
if (ret < 0) {
|
||||
put_cred(new);
|
||||
pr_err("Security denies permission to nominate security context: error %d\n",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/close_range.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/init_task.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
+3
-1
@@ -419,11 +419,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
goto bail_no_root;
|
||||
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
|
||||
if (!res) {
|
||||
if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {
|
||||
if (fd.entrylength != sizeof(rec.dir)) {
|
||||
res = -EIO;
|
||||
goto bail_hfs_find;
|
||||
}
|
||||
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
|
||||
if (rec.type != HFS_CDR_DIR)
|
||||
res = -EIO;
|
||||
}
|
||||
if (res)
|
||||
goto bail_hfs_find;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user