Merge 6.12.28 into android16-6.12-lts
GKI (arm64) relevant 33 out of 166 changes, affecting 52 files +454/-3630aaae77be5ALSA: usb-audio: Add retry on -EPROTO from usb_set_interface() [1 file, +7/-0]fdf0ae5e9eALSA: usb-audio: Add second USB ID for Jabra Evolve 65 headset [1 file, +2/-1]38d9ca7405binder: fix offset calculation in debug log [1 file, +1/-1]f1dfc94584drm/fdinfo: Protect against driver unbind [1 file, +6/-0]090c8714efarm64: errata: Add missing sentinels to Spectre-BHB MIDR arrays [1 file, +2/-0]eb9b72e4femm/memblock: pass size instead of end to memblock_set_node() [1 file, +1/-1]9c4ddea497mm/memblock: repeat setting reserved region nid if array is doubled [1 file, +10/-0]0988dd0263tracing: Do not take trace_event_sem in print_event_fields() [1 file, +2/-2]f451082572dm-bufio: don't schedule in atomic context [1 file, +8/-1]510aea4ef0dm: always update the array size in realloc_argv on success [1 file, +3/-2]2e303d0107iommu: Fix two issues in iommu_copy_struct_from_user() [1 file, +4/-4]573b047229cpufreq: Avoid using inconsistent policy->min and policy->max [1 file, +25/-7]962d88304ccpufreq: Fix setting policy limits when frequency tables are used [4 files, +73/-41]1f27a3e93btracing: Fix oob write in trace_seq_to_buffer() [1 file, +3/-2]220395054cASoC: soc-core: Stop using of_property_read_bool() for non-boolean properties [1 file, +13/-19]29a4a29112ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence [1 file, +4/-1]65d3c57061xsk: Fix race condition in AF_XDP generic RX path [4 files, +6/-6]fe81c26d2dBluetooth: hci_conn: Remove alloc from critical section [1 file, +10/-18]eb8b860e87Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver [6 files, +95/-107]620810ac1fBluetooth: hci_conn: Fix not setting timeout for BIG Create Sync [7 files, +88/-109]432572d536Bluetooth: L2CAP: copy RX timestamp to new fragments [1 file, +3/-0]6b1355860dscsi: ufs: core: Remove redundant query_complete trace [1 file, +0/-2]5ad0b1b554nvme-pci: fix queue unquiesce check on slot_reset [1 file, +1/-1]6effe1c0fanet: ipv6: fix UDPv6 GSO segmentation with NAT [1 file, +60/-1]c0dba059b1net: use sock_gen_put() when sk_state is TCP_TIME_WAIT [2 files, +2/-2]e10ec6e32bblk-mq: create correct map for fallback case [1 file, +1/-2]dab2a13059mm, slab: clean up slab->obj_exts always [1 file, +7/-20]0a188c0e19sch_htb: make htb_qlen_notify() idempotent [1 file, +2/-0]969d8beaa2firmware: arm_scmi: Balance device refcount when destroying devices [1 file, +3/-0]3b41b5efaekernel: param: rename locate_module_kobject [1 file, +3/-3]69113bf740kernel: globalize lookup_or_create_module_kobject() [2 files, +3/-1]e1eea69858drivers: base: handle module_kobject creation [1 file, +5/-8]db62809197dm: fix copying after src array boundaries [1 file, +1/-1] Changes in 6.12.28 Bluetooth: btusb: add Foxconn 0xe0fc for Qualcomm WCN785x Bluetooth: btusb: Add one more ID 0x0489:0xe0f3 for Qualcomm WCN785x Bluetooth: btusb: Add one more ID 0x13d3:0x3623 for Qualcomm WCN785x Bluetooth: btusb: Add ID 0x2c7c:0x0130 for Qualcomm WCN785x Bluetooth: btusb: Add new VID/PID for WCN785x Bluetooth: btusb: Add 13 USB device IDs for Qualcomm WCN785x Revert "rndis_host: Flag RNDIS modems as WWAN devices" ALSA: usb-audio: Add retry on -EPROTO from usb_set_interface() ALSA: usb-audio: Add second USB ID for Jabra Evolve 65 headset binder: fix offset calculation in debug log btrfs: adjust subpage bit start based on sectorsize btrfs: fix COW handling in run_delalloc_nocow() cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode drm/fdinfo: Protect against driver unbind drm/nouveau: Fix WARN_ON in nouveau_fence_context_kill() EDAC/altera: Test the correct error reg offset EDAC/altera: Set DDR and SDMMC interrupt mask before registration i2c: imx-lpi2c: Fix clock count when probe defers arm64: errata: Add missing sentinels to Spectre-BHB MIDR arrays parisc: Fix double SIGFPE crash perf/x86/intel: Only check the group flag for X86 leader perf/x86/intel: KVM: Mask PEBS_ENABLE loaded for guest with vCPU's value. amd-xgbe: Fix to ensure dependent features are toggled with RX checksum offload irqchip/qcom-mpm: Prevent crash when trying to handle non-wake GPIOs mm/memblock: pass size instead of end to memblock_set_node() mm/memblock: repeat setting reserved region nid if array is doubled mmc: renesas_sdhi: Fix error handling in renesas_sdhi_probe spi: tegra114: Don't fail set_cs_timing when delays are zero tracing: Do not take trace_event_sem in print_event_fields() wifi: brcm80211: fmac: Add error handling for brcmf_usb_dl_writeimage() x86/boot/sev: Support memory acceptance in the EFI stub under SVSM dm-bufio: don't schedule in atomic context dm-integrity: fix a warning on invalid table line dm: always update the array size in realloc_argv on success drm/amdgpu: Fix offset for HDP remap in nbio v7.11 drm: Select DRM_KMS_HELPER from DRM_DEBUG_DP_MST_TOPOLOGY_REFS iommu/amd: Fix potential buffer overflow in parse_ivrs_acpihid iommu/arm-smmu-v3: Fix iommu_device_probe bug due to duplicated stream ids iommu/arm-smmu-v3: Fix pgsize_bit for sva domains iommu/vt-d: Apply quirk_iommu_igfx for 8086:0044 (QM57/QS57) iommu: Fix two issues in iommu_copy_struct_from_user() platform/x86/amd: pmc: Require at least 2.5 seconds between HW sleep cycles platform/x86/intel-uncore-freq: Fix missing uncore sysfs during CPU hotplug ksmbd: fix use-after-free in ksmbd_session_rpc_open ksmbd: fix use-after-free in kerberos authentication ksmbd: fix use-after-free in session logoff smb: client: fix zero length for mkdir POSIX create context cpufreq: Avoid using inconsistent policy->min and policy->max cpufreq: Fix setting policy limits when frequency tables are used tracing: Fix oob write in trace_seq_to_buffer() drm/amd/display: Default IPS to RCG_IN_ACTIVE_IPS2_IN_OFF ASoC: soc-core: Stop using of_property_read_bool() for non-boolean properties ASoC: cs-amp-lib-test: Don't select SND_SOC_CS_AMP_LIB ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence book3s64/radix : Align section vmemmap start address to PAGE_SIZE pinctrl: imx: Return NULL if no group is matched and found powerpc/boot: Check for ld-option support ASoC: Intel: sof_sdw: Add NULL check in asoc_sdw_rt_dmic_rtd_init() ALSA: hda/realtek - Enable speaker for HP platform drm/i915/pxp: fix undefined reference to `intel_pxp_gsccs_is_ready_for_sessions' wifi: iwlwifi: don't warn if the NIC is gone in resume wifi: iwlwifi: fix the check for the SCRATCH register upon resume wifi: plfxlc: Remove erroneous assert in plfxlc_mac_release powerpc/boot: Fix dash warning vxlan: vnifilter: Fix unlocked deletion of default FDB entry xsk: Fix race condition in AF_XDP generic RX path net/mlx5e: Use custom tunnel header for vxlan gbp net/mlx5: E-Switch, Initialize MAC Address for Default GID net/mlx5e: TC, Continue the attr process even if encap entry is invalid net/mlx5e: Fix lock order in mlx5e_tx_reporter_ptpsq_unhealthy_recover net/mlx5: E-switch, Fix error handling for enabling roce accel/ivpu: Correct DCT interrupt handling ASoC: amd: acp: Fix NULL pointer deref in acp_i2s_set_tdm_slot Bluetooth: hci_conn: Remove alloc from critical section Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync Bluetooth: btintel_pcie: Avoid redundant buffer allocation Bluetooth: btusb: avoid NULL pointer dereference in skb_dequeue() Bluetooth: btintel_pcie: Add additional to checks to clear TX/RX paths Bluetooth: L2CAP: copy RX timestamp to new fragments net: mscc: ocelot: delete PVID VLAN when readding it as non-PVID octeon_ep_vf: Resolve netdevice usage count issue bnxt_en: improve TX timestamping FIFO configuration rtase: Modify the condition used to detect overflow in rtase_calc_time_mitigation net: ethernet: mtk-star-emac: fix spinlock recursion issues on rx/tx poll net: ethernet: mtk-star-emac: rearm interrupts in rx_poll only when advised net: ethernet: mtk_eth_soc: sync mtk_clks_source_name array pds_core: make pdsc_auxbus_dev_del() void pds_core: specify auxiliary_device to be created pds_core: remove write-after-free of client_id net_sched: drr: Fix double list add in class with netem as child qdisc net_sched: hfsc: Fix a UAF vulnerability in class with netem as child qdisc net_sched: ets: Fix double list add in class with netem as child qdisc net_sched: qfq: Fix double list add in class with netem as child qdisc ice: Check VF VSI Pointer Value in ice_vc_add_fdir_fltr() idpf: fix offloads support for encapsulated packets scsi: ufs: core: Remove redundant query_complete trace ALSA: ump: Fix buffer overflow at UMP SysEx message conversion nvme-pci: fix queue unquiesce check on slot_reset drm/tests: shmem: Fix memleak drm/mipi-dbi: Fix blanking for non-16 bit formats net: dlink: Correct endianness handling of led_mode net: mdio: mux-meson-gxl: set reversed bit when using internal phy idpf: fix potential memory leak on kcalloc() failure idpf: protect shutdown from reset igc: fix lock order in igc_ptp_reset net: ethernet: mtk_eth_soc: fix SER panic with 4GB+ RAM net: dsa: felix: fix broken taprio gate states after clock jump net: ipv6: fix UDPv6 GSO segmentation with NAT ALSA: hda/realtek: Fix built-mic regression on other ASUS models bnxt_en: Fix error handling path in bnxt_init_chip() bnxt_en: Fix ethtool selftest output in one of the failure cases bnxt_en: Add missing skb_mark_for_recycle() in bnxt_rx_vlan() bnxt_en: call pci_alloc_irq_vectors() after bnxt_reserve_rings() bnxt_en: Fix coredump logic to free allocated buffer bnxt_en: Fix out-of-bound memcpy() during ethtool -w bnxt_en: Fix ethtool -d byte order for 32-bit values nvme-tcp: fix premature queue removal and I/O failover nvme-tcp: select CONFIG_TLS from CONFIG_NVME_TCP_TLS nvmet-tcp: select CONFIG_TLS from CONFIG_NVME_TARGET_TCP_TLS ASoC: simple-card-utils: Fix pointer check in graph_util_parse_link_direction bnxt_en: fix module unload sequence net: use sock_gen_put() when sk_state is TCP_TIME_WAIT ptp: ocp: Fix NULL dereference in Adva board SMA sysfs operations net: lan743x: Fix memleak issue when GSO enabled net: fec: ERR007885 Workaround for conventional TX octeon_ep: Fix host hang issue during device reboot net: hns3: store rx VLAN tag offload state for VF net: hns3: fix an interrupt residual problem net: hns3: fixed debugfs tm_qset size net: hns3: defer calling ptp_clock_register() net: vertexcom: mse102x: Fix possible stuck of SPI interrupt net: vertexcom: mse102x: Fix LEN_MASK net: vertexcom: mse102x: Add range check for CMD_RTS net: vertexcom: mse102x: Fix RX error handling blk-mq: create correct map for fallback case mm, slab: clean up slab->obj_exts always bcachefs: Remove incorrect __counted_by annotation net: Fix the devmem sock opts and msgs for parisc accel/ivpu: Make DB_ID and JOB_ID allocations incremental accel/ivpu: Use xa_alloc_cyclic() instead of custom function accel/ivpu: Fix a typo accel/ivpu: Update VPU FW API headers accel/ivpu: Abort all jobs after command queue unregister accel/ivpu: Fix locking order in ivpu_job_submit accel/ivpu: Add handling of VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW sch_htb: make htb_qlen_notify() idempotent sch_drr: make drr_qlen_notify() idempotent sch_hfsc: make hfsc_qlen_notify() idempotent sch_qfq: make qfq_qlen_notify() idempotent sch_ets: make est_qlen_notify() idempotent drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change firmware: arm_scmi: Balance device refcount when destroying devices firmware: arm_ffa: Skip Rx buffer ownership release if not acquired arm64: dts: imx95: Correct the range of PCIe app-reg region ARM: dts: opos6ul: add ksz8081 phy properties arm64: dts: st: Adjust interrupt-controller for stm32mp25 SoCs arm64: dts: st: Use 128kB size for aliased GIC400 register access on stm32mp25 SoCs Revert "drm/meson: vclk: fix calculation of 59.94 fractional rates" kernel: param: rename locate_module_kobject kernel: globalize lookup_or_create_module_kobject() drivers: base: handle module_kobject creation drm/amd/display: Add scoped mutexes for amdgpu_dm_dhcp drm/amd/display: Fix slab-use-after-free in hdcp dm: fix copying after src array boundaries Linux 6.12.28 Change-Id: I79f3d50a10acfe53f329b4b5a4af502f488c61f3 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 27
|
||||
SUBLEVEL = 28
|
||||
EXTRAVERSION =
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
reg = <1>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
|
||||
micrel,led-mode = <1>;
|
||||
clocks = <&clks IMX6UL_CLK_ENET_REF>;
|
||||
clock-names = "rmii-ref";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1478,7 +1478,7 @@
|
||||
reg = <0 0x4c300000 0 0x10000>,
|
||||
<0 0x60100000 0 0xfe00000>,
|
||||
<0 0x4c360000 0 0x10000>,
|
||||
<0 0x4c340000 0 0x2000>;
|
||||
<0 0x4c340000 0 0x4000>;
|
||||
reg-names = "dbi", "config", "atu", "app";
|
||||
ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
|
||||
<0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
|
||||
@@ -1518,7 +1518,7 @@
|
||||
reg = <0 0x4c300000 0 0x10000>,
|
||||
<0 0x4c360000 0 0x1000>,
|
||||
<0 0x4c320000 0 0x1000>,
|
||||
<0 0x4c340000 0 0x2000>,
|
||||
<0 0x4c340000 0 0x4000>,
|
||||
<0 0x4c370000 0 0x10000>,
|
||||
<0x9 0 1 0>;
|
||||
reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space";
|
||||
@@ -1545,7 +1545,7 @@
|
||||
reg = <0 0x4c380000 0 0x10000>,
|
||||
<8 0x80100000 0 0xfe00000>,
|
||||
<0 0x4c3e0000 0 0x10000>,
|
||||
<0 0x4c3c0000 0 0x2000>;
|
||||
<0 0x4c3c0000 0 0x4000>;
|
||||
reg-names = "dbi", "config", "atu", "app";
|
||||
ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>,
|
||||
<0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>;
|
||||
@@ -1585,7 +1585,7 @@
|
||||
reg = <0 0x4c380000 0 0x10000>,
|
||||
<0 0x4c3e0000 0 0x1000>,
|
||||
<0 0x4c3a0000 0 0x1000>,
|
||||
<0 0x4c3c0000 0 0x2000>,
|
||||
<0 0x4c3c0000 0 0x4000>,
|
||||
<0 0x4c3f0000 0 0x10000>,
|
||||
<0xa 0 1 0>;
|
||||
reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
|
||||
|
||||
@@ -114,14 +114,13 @@
|
||||
};
|
||||
|
||||
intc: interrupt-controller@4ac00000 {
|
||||
compatible = "arm,cortex-a7-gic";
|
||||
compatible = "arm,gic-400";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <1>;
|
||||
interrupt-controller;
|
||||
reg = <0x0 0x4ac10000 0x0 0x1000>,
|
||||
<0x0 0x4ac20000 0x0 0x2000>,
|
||||
<0x0 0x4ac40000 0x0 0x2000>,
|
||||
<0x0 0x4ac60000 0x0 0x2000>;
|
||||
<0x0 0x4ac20000 0x0 0x20000>,
|
||||
<0x0 0x4ac40000 0x0 0x20000>,
|
||||
<0x0 0x4ac60000 0x0 0x20000>;
|
||||
};
|
||||
|
||||
psci {
|
||||
|
||||
@@ -132,11 +132,15 @@
|
||||
#define SO_PASSPIDFD 0x404A
|
||||
#define SO_PEERPIDFD 0x404B
|
||||
|
||||
#define SO_DEVMEM_LINEAR 78
|
||||
#define SCM_TS_OPT_ID 0x404C
|
||||
|
||||
#define SO_RCVPRIORITY 0x404D
|
||||
|
||||
#define SO_DEVMEM_LINEAR 0x404E
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 79
|
||||
#define SO_DEVMEM_DMABUF 0x404F
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 80
|
||||
#define SO_DEVMEM_DONTNEED 0x4050
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
||||
@@ -97,9 +97,19 @@ handle_fpe(struct pt_regs *regs)
|
||||
|
||||
memcpy(regs->fr, frcopy, sizeof regs->fr);
|
||||
if (signalcode != 0) {
|
||||
force_sig_fault(signalcode >> 24, signalcode & 0xffffff,
|
||||
(void __user *) regs->iaoq[0]);
|
||||
return -1;
|
||||
int sig = signalcode >> 24;
|
||||
|
||||
if (sig == SIGFPE) {
|
||||
/*
|
||||
* Clear floating point trap bit to avoid trapping
|
||||
* again on the first floating-point instruction in
|
||||
* the userspace signal handler.
|
||||
*/
|
||||
regs->fr[0] &= ~(1ULL << 38);
|
||||
}
|
||||
force_sig_fault(sig, signalcode & 0xffffff,
|
||||
(void __user *) regs->iaoq[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return signalcode ? -1 : 0;
|
||||
|
||||
@@ -234,10 +234,8 @@ fi
|
||||
|
||||
# suppress some warnings in recent ld versions
|
||||
nowarn="-z noexecstack"
|
||||
if ! ld_is_lld; then
|
||||
if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then
|
||||
nowarn="$nowarn --no-warn-rwx-segments"
|
||||
fi
|
||||
if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then
|
||||
nowarn="$nowarn --no-warn-rwx-segments"
|
||||
fi
|
||||
|
||||
platformo=$object/"$platform".o
|
||||
|
||||
@@ -1132,6 +1132,19 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
/*
|
||||
* Make sure we align the start vmemmap addr so that we calculate
|
||||
* the correct start_pfn in altmap boundary check to decided whether
|
||||
* we should use altmap or RAM based backing memory allocation. Also
|
||||
* the address need to be aligned for set_pte operation.
|
||||
|
||||
* If the start addr is already PMD_SIZE aligned we will try to use
|
||||
* a pmd mapping. We don't want to be too aggressive here beacause
|
||||
* that will cause more allocations in RAM. So only if the namespace
|
||||
* vmemmap start addr is PMD_SIZE aligned we will use PMD mapping.
|
||||
*/
|
||||
|
||||
start = ALIGN_DOWN(start, PAGE_SIZE);
|
||||
for (addr = start; addr < end; addr = next) {
|
||||
next = pmd_addr_end(addr, end);
|
||||
|
||||
@@ -1157,8 +1170,8 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in
|
||||
* in altmap block allocation failures, in which case
|
||||
* we fallback to RAM for vmemmap allocation.
|
||||
*/
|
||||
if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) ||
|
||||
altmap_cross_boundary(altmap, addr, PMD_SIZE))) {
|
||||
if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap &&
|
||||
altmap_cross_boundary(altmap, addr, PMD_SIZE))) {
|
||||
/*
|
||||
* make sure we don't create altmap mappings
|
||||
* covering things outside the device.
|
||||
|
||||
@@ -34,14 +34,11 @@ static bool early_is_tdx_guest(void)
|
||||
|
||||
void arch_accept_memory(phys_addr_t start, phys_addr_t end)
|
||||
{
|
||||
static bool sevsnp;
|
||||
|
||||
/* Platform-specific memory-acceptance call goes here */
|
||||
if (early_is_tdx_guest()) {
|
||||
if (!tdx_accept_memory(start, end))
|
||||
panic("TDX: Failed to accept memory\n");
|
||||
} else if (sevsnp || (sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) {
|
||||
sevsnp = true;
|
||||
} else if (early_is_sevsnp_guest()) {
|
||||
snp_accept_memory(start, end);
|
||||
} else {
|
||||
error("Cannot accept memory: unknown platform\n");
|
||||
|
||||
@@ -644,3 +644,43 @@ void sev_prep_identity_maps(unsigned long top_level_pgt)
|
||||
|
||||
sev_verify_cbit(top_level_pgt);
|
||||
}
|
||||
|
||||
bool early_is_sevsnp_guest(void)
|
||||
{
|
||||
static bool sevsnp;
|
||||
|
||||
if (sevsnp)
|
||||
return true;
|
||||
|
||||
if (!(sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED))
|
||||
return false;
|
||||
|
||||
sevsnp = true;
|
||||
|
||||
if (!snp_vmpl) {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
/*
|
||||
* CPUID Fn8000_001F_EAX[28] - SVSM support
|
||||
*/
|
||||
eax = 0x8000001f;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
if (eax & BIT(28)) {
|
||||
struct msr m;
|
||||
|
||||
/* Obtain the address of the calling area to use */
|
||||
boot_rdmsr(MSR_SVSM_CAA, &m);
|
||||
boot_svsm_caa = (void *)m.q;
|
||||
boot_svsm_caa_pa = m.q;
|
||||
|
||||
/*
|
||||
* The real VMPL level cannot be discovered, but the
|
||||
* memory acceptance routines make no use of that so
|
||||
* any non-zero value suffices here.
|
||||
*/
|
||||
snp_vmpl = U8_MAX;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
bool sev_snp_enabled(void);
|
||||
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
|
||||
u64 sev_get_status(void);
|
||||
bool early_is_sevsnp_guest(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool sev_snp_enabled(void) { return false; }
|
||||
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
|
||||
static inline u64 sev_get_status(void) { return 0; }
|
||||
static inline bool early_is_sevsnp_guest(void) { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -753,7 +753,7 @@ void x86_pmu_enable_all(int added)
|
||||
}
|
||||
}
|
||||
|
||||
static inline int is_x86_event(struct perf_event *event)
|
||||
int is_x86_event(struct perf_event *event)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
@@ -4333,7 +4333,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
|
||||
arr[pebs_enable] = (struct perf_guest_switch_msr){
|
||||
.msr = MSR_IA32_PEBS_ENABLE,
|
||||
.host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask,
|
||||
.guest = pebs_mask & ~cpuc->intel_ctrl_host_mask,
|
||||
.guest = pebs_mask & ~cpuc->intel_ctrl_host_mask & kvm_pmu->pebs_enable,
|
||||
};
|
||||
|
||||
if (arr[pebs_enable].host) {
|
||||
|
||||
@@ -110,9 +110,16 @@ static inline bool is_topdown_event(struct perf_event *event)
|
||||
return is_metric_event(event) || is_slots_event(event);
|
||||
}
|
||||
|
||||
int is_x86_event(struct perf_event *event);
|
||||
|
||||
static inline bool check_leader_group(struct perf_event *leader, int flags)
|
||||
{
|
||||
return is_x86_event(leader) ? !!(leader->hw.flags & flags) : false;
|
||||
}
|
||||
|
||||
static inline bool is_branch_counters_group(struct perf_event *event)
|
||||
{
|
||||
return event->group_leader->hw.flags & PERF_X86_EVENT_BRANCH_COUNTERS;
|
||||
return check_leader_group(event->group_leader, PERF_X86_EVENT_BRANCH_COUNTERS);
|
||||
}
|
||||
|
||||
struct amd_nb {
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
__stringify(DRM_IVPU_DRIVER_MINOR) "."
|
||||
#endif
|
||||
|
||||
static struct lock_class_key submitted_jobs_xa_lock_class_key;
|
||||
|
||||
int ivpu_dbg_mask;
|
||||
module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644);
|
||||
MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros.");
|
||||
@@ -260,6 +258,9 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file)
|
||||
if (ret)
|
||||
goto err_xa_erase;
|
||||
|
||||
file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1));
|
||||
file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK;
|
||||
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
drm_dev_exit(idx);
|
||||
|
||||
@@ -452,26 +453,6 @@ static const struct drm_driver driver = {
|
||||
.minor = DRM_IVPU_DRIVER_MINOR,
|
||||
};
|
||||
|
||||
static void ivpu_context_abort_invalid(struct ivpu_device *vdev)
|
||||
{
|
||||
struct ivpu_file_priv *file_priv;
|
||||
unsigned long ctx_id;
|
||||
|
||||
mutex_lock(&vdev->context_list_lock);
|
||||
|
||||
xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
|
||||
if (!file_priv->has_mmu_faults || file_priv->aborted)
|
||||
continue;
|
||||
|
||||
mutex_lock(&file_priv->lock);
|
||||
ivpu_context_abort_locked(file_priv);
|
||||
file_priv->aborted = true;
|
||||
mutex_unlock(&file_priv->lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
}
|
||||
|
||||
static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
{
|
||||
struct ivpu_device *vdev = arg;
|
||||
@@ -485,9 +466,6 @@ static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
|
||||
case IVPU_HW_IRQ_SRC_IPC:
|
||||
ivpu_ipc_irq_thread_handler(vdev);
|
||||
break;
|
||||
case IVPU_HW_IRQ_SRC_MMU_EVTQ:
|
||||
ivpu_context_abort_invalid(vdev);
|
||||
break;
|
||||
case IVPU_HW_IRQ_SRC_DCT:
|
||||
ivpu_pm_dct_irq_thread_handler(vdev);
|
||||
break;
|
||||
@@ -604,13 +582,21 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
|
||||
xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
|
||||
xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
|
||||
xa_init_flags(&vdev->db_xa, XA_FLAGS_ALLOC1);
|
||||
lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key);
|
||||
INIT_LIST_HEAD(&vdev->bo_list);
|
||||
|
||||
vdev->db_limit.min = IVPU_MIN_DB;
|
||||
vdev->db_limit.max = IVPU_MAX_DB;
|
||||
|
||||
INIT_WORK(&vdev->context_abort_work, ivpu_context_abort_thread_handler);
|
||||
|
||||
ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock);
|
||||
if (ret)
|
||||
goto err_xa_destroy;
|
||||
|
||||
ret = drmm_mutex_init(&vdev->drm, &vdev->submitted_jobs_lock);
|
||||
if (ret)
|
||||
goto err_xa_destroy;
|
||||
|
||||
ret = drmm_mutex_init(&vdev->drm, &vdev->bo_list_lock);
|
||||
if (ret)
|
||||
goto err_xa_destroy;
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#define IVPU_MIN_DB 1
|
||||
#define IVPU_MAX_DB 255
|
||||
|
||||
#define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0)
|
||||
#define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8)
|
||||
|
||||
#define IVPU_NUM_ENGINES 2
|
||||
#define IVPU_NUM_PRIORITIES 4
|
||||
#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES)
|
||||
@@ -134,12 +137,16 @@ struct ivpu_device {
|
||||
struct mutex context_list_lock; /* Protects user context addition/removal */
|
||||
struct xarray context_xa;
|
||||
struct xa_limit context_xa_limit;
|
||||
struct work_struct context_abort_work;
|
||||
|
||||
struct xarray db_xa;
|
||||
struct xa_limit db_limit;
|
||||
u32 db_next;
|
||||
|
||||
struct mutex bo_list_lock; /* Protects bo_list */
|
||||
struct list_head bo_list;
|
||||
|
||||
struct mutex submitted_jobs_lock; /* Protects submitted_jobs */
|
||||
struct xarray submitted_jobs_xa;
|
||||
struct ivpu_ipc_consumer job_done_consumer;
|
||||
|
||||
@@ -171,6 +178,8 @@ struct ivpu_file_priv {
|
||||
struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */
|
||||
struct list_head ms_instance_list;
|
||||
struct ivpu_bo *ms_info_bo;
|
||||
struct xa_limit job_limit;
|
||||
u32 job_id_next;
|
||||
bool has_mmu_faults;
|
||||
bool bound;
|
||||
bool aborted;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define PLL_PROFILING_FREQ_DEFAULT 38400000
|
||||
#define PLL_PROFILING_FREQ_HIGH 400000000
|
||||
|
||||
#define DCT_DEFAULT_ACTIVE_PERCENT 15u
|
||||
#define DCT_DEFAULT_ACTIVE_PERCENT 30u
|
||||
#define DCT_PERIOD_US 35300u
|
||||
|
||||
int ivpu_hw_btrs_info_init(struct ivpu_device *vdev);
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include "vpu_boot_api.h"
|
||||
|
||||
#define CMD_BUF_IDX 0
|
||||
#define JOB_ID_JOB_MASK GENMASK(7, 0)
|
||||
#define JOB_ID_CONTEXT_MASK GENMASK(31, 8)
|
||||
#define JOB_MAX_BUFFER_COUNT 65535
|
||||
|
||||
static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq)
|
||||
@@ -79,7 +77,6 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev,
|
||||
|
||||
static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
|
||||
{
|
||||
struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB};
|
||||
struct ivpu_device *vdev = file_priv->vdev;
|
||||
struct ivpu_cmdq *cmdq;
|
||||
int ret;
|
||||
@@ -88,8 +85,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
|
||||
if (!cmdq)
|
||||
return NULL;
|
||||
|
||||
ret = xa_alloc(&vdev->db_xa, &cmdq->db_id, NULL, db_xa_limit, GFP_KERNEL);
|
||||
if (ret) {
|
||||
ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret);
|
||||
goto err_free_cmdq;
|
||||
}
|
||||
@@ -337,6 +335,8 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv)
|
||||
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS)
|
||||
ivpu_jsm_context_release(vdev, file_priv->ctx.id);
|
||||
|
||||
file_priv->aborted = true;
|
||||
}
|
||||
|
||||
static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
|
||||
@@ -354,7 +354,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
entry = &cmdq->jobq->job[tail];
|
||||
entry = &cmdq->jobq->slot[tail].job;
|
||||
entry->batch_buf_addr = job->cmd_buf_vpu_addr;
|
||||
entry->job_id = job->job_id;
|
||||
entry->flags = 0;
|
||||
@@ -469,16 +469,14 @@ static struct ivpu_job *ivpu_job_remove_from_submitted_jobs(struct ivpu_device *
|
||||
{
|
||||
struct ivpu_job *job;
|
||||
|
||||
xa_lock(&vdev->submitted_jobs_xa);
|
||||
job = __xa_erase(&vdev->submitted_jobs_xa, job_id);
|
||||
lockdep_assert_held(&vdev->submitted_jobs_lock);
|
||||
|
||||
job = xa_erase(&vdev->submitted_jobs_xa, job_id);
|
||||
if (xa_empty(&vdev->submitted_jobs_xa) && job) {
|
||||
vdev->busy_time = ktime_add(ktime_sub(ktime_get(), vdev->busy_start_ts),
|
||||
vdev->busy_time);
|
||||
}
|
||||
|
||||
xa_unlock(&vdev->submitted_jobs_xa);
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
@@ -486,6 +484,28 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32
|
||||
{
|
||||
struct ivpu_job *job;
|
||||
|
||||
lockdep_assert_held(&vdev->submitted_jobs_lock);
|
||||
|
||||
job = xa_load(&vdev->submitted_jobs_xa, job_id);
|
||||
if (!job)
|
||||
return -ENOENT;
|
||||
|
||||
if (job_status == VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW) {
|
||||
guard(mutex)(&job->file_priv->lock);
|
||||
|
||||
if (job->file_priv->has_mmu_faults)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Mark context as faulty and defer destruction of the job to jobs abort thread
|
||||
* handler to synchronize between both faults and jobs returning context violation
|
||||
* status and ensure both are handled in the same way
|
||||
*/
|
||||
job->file_priv->has_mmu_faults = true;
|
||||
queue_work(system_wq, &vdev->context_abort_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
job = ivpu_job_remove_from_submitted_jobs(vdev, job_id);
|
||||
if (!job)
|
||||
return -ENOENT;
|
||||
@@ -503,6 +523,10 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32
|
||||
ivpu_stop_job_timeout_detection(vdev);
|
||||
|
||||
ivpu_rpm_put(vdev);
|
||||
|
||||
if (!xa_empty(&vdev->submitted_jobs_xa))
|
||||
ivpu_start_job_timeout_detection(vdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -511,15 +535,18 @@ void ivpu_jobs_abort_all(struct ivpu_device *vdev)
|
||||
struct ivpu_job *job;
|
||||
unsigned long id;
|
||||
|
||||
mutex_lock(&vdev->submitted_jobs_lock);
|
||||
|
||||
xa_for_each(&vdev->submitted_jobs_xa, id, job)
|
||||
ivpu_job_signal_and_destroy(vdev, id, DRM_IVPU_JOB_STATUS_ABORTED);
|
||||
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
}
|
||||
|
||||
static int ivpu_job_submit(struct ivpu_job *job, u8 priority)
|
||||
{
|
||||
struct ivpu_file_priv *file_priv = job->file_priv;
|
||||
struct ivpu_device *vdev = job->vdev;
|
||||
struct xa_limit job_id_range;
|
||||
struct ivpu_cmdq *cmdq;
|
||||
bool is_first_job;
|
||||
int ret;
|
||||
@@ -528,27 +555,25 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&vdev->submitted_jobs_lock);
|
||||
mutex_lock(&file_priv->lock);
|
||||
|
||||
cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority);
|
||||
cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority);
|
||||
if (!cmdq) {
|
||||
ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n",
|
||||
file_priv->ctx.id, job->engine_idx, priority);
|
||||
ret = -EINVAL;
|
||||
goto err_unlock_file_priv;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1));
|
||||
job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK;
|
||||
|
||||
xa_lock(&vdev->submitted_jobs_xa);
|
||||
is_first_job = xa_empty(&vdev->submitted_jobs_xa);
|
||||
ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL);
|
||||
if (ret) {
|
||||
ret = xa_alloc_cyclic(&vdev->submitted_jobs_xa, &job->job_id, job, file_priv->job_limit,
|
||||
&file_priv->job_id_next, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n",
|
||||
file_priv->ctx.id);
|
||||
ret = -EBUSY;
|
||||
goto err_unlock_submitted_jobs_xa;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
ret = ivpu_cmdq_push_job(cmdq, job);
|
||||
@@ -570,20 +595,20 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority)
|
||||
job->job_id, file_priv->ctx.id, job->engine_idx, priority,
|
||||
job->cmd_buf_vpu_addr, cmdq->jobq->header.tail);
|
||||
|
||||
xa_unlock(&vdev->submitted_jobs_xa);
|
||||
|
||||
mutex_unlock(&file_priv->lock);
|
||||
|
||||
if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW))
|
||||
if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW)) {
|
||||
ivpu_job_signal_and_destroy(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_erase_xa:
|
||||
__xa_erase(&vdev->submitted_jobs_xa, job->job_id);
|
||||
err_unlock_submitted_jobs_xa:
|
||||
xa_unlock(&vdev->submitted_jobs_xa);
|
||||
err_unlock_file_priv:
|
||||
xa_erase(&vdev->submitted_jobs_xa, job->job_id);
|
||||
err_unlock:
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
mutex_unlock(&file_priv->lock);
|
||||
ivpu_rpm_put(vdev);
|
||||
return ret;
|
||||
@@ -753,7 +778,6 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
|
||||
struct vpu_jsm_msg *jsm_msg)
|
||||
{
|
||||
struct vpu_ipc_msg_payload_job_done *payload;
|
||||
int ret;
|
||||
|
||||
if (!jsm_msg) {
|
||||
ivpu_err(vdev, "IPC message has no JSM payload\n");
|
||||
@@ -766,9 +790,10 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
|
||||
}
|
||||
|
||||
payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload;
|
||||
ret = ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status);
|
||||
if (!ret && !xa_empty(&vdev->submitted_jobs_xa))
|
||||
ivpu_start_job_timeout_detection(vdev);
|
||||
|
||||
mutex_lock(&vdev->submitted_jobs_lock);
|
||||
ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status);
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
}
|
||||
|
||||
void ivpu_job_done_consumer_init(struct ivpu_device *vdev)
|
||||
@@ -781,3 +806,41 @@ void ivpu_job_done_consumer_fini(struct ivpu_device *vdev)
|
||||
{
|
||||
ivpu_ipc_consumer_del(vdev, &vdev->job_done_consumer);
|
||||
}
|
||||
|
||||
void ivpu_context_abort_thread_handler(struct work_struct *work)
|
||||
{
|
||||
struct ivpu_device *vdev = container_of(work, struct ivpu_device, context_abort_work);
|
||||
struct ivpu_file_priv *file_priv;
|
||||
unsigned long ctx_id;
|
||||
struct ivpu_job *job;
|
||||
unsigned long id;
|
||||
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW)
|
||||
ivpu_jsm_reset_engine(vdev, 0);
|
||||
|
||||
mutex_lock(&vdev->context_list_lock);
|
||||
xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
|
||||
if (!file_priv->has_mmu_faults || file_priv->aborted)
|
||||
continue;
|
||||
|
||||
mutex_lock(&file_priv->lock);
|
||||
ivpu_context_abort_locked(file_priv);
|
||||
mutex_unlock(&file_priv->lock);
|
||||
}
|
||||
mutex_unlock(&vdev->context_list_lock);
|
||||
|
||||
if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW)
|
||||
return;
|
||||
|
||||
ivpu_jsm_hws_resume_engine(vdev, 0);
|
||||
/*
|
||||
* In hardware scheduling mode NPU already has stopped processing jobs
|
||||
* and won't send us any further notifications, thus we have to free job related resources
|
||||
* and notify userspace
|
||||
*/
|
||||
mutex_lock(&vdev->submitted_jobs_lock);
|
||||
xa_for_each(&vdev->submitted_jobs_xa, id, job)
|
||||
if (job->file_priv->aborted)
|
||||
ivpu_job_signal_and_destroy(vdev, job->job_id, DRM_IVPU_JOB_STATUS_ABORTED);
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
|
||||
|
||||
void ivpu_job_done_consumer_init(struct ivpu_device *vdev);
|
||||
void ivpu_job_done_consumer_fini(struct ivpu_device *vdev);
|
||||
void ivpu_context_abort_thread_handler(struct work_struct *work);
|
||||
|
||||
void ivpu_jobs_abort_all(struct ivpu_device *vdev);
|
||||
|
||||
|
||||
@@ -48,9 +48,10 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type)
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE);
|
||||
IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE);
|
||||
|
||||
@@ -917,8 +917,7 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev)
|
||||
REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons);
|
||||
}
|
||||
|
||||
if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_MMU_EVTQ))
|
||||
ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
|
||||
queue_work(system_wq, &vdev->context_abort_work);
|
||||
}
|
||||
|
||||
void ivpu_mmu_evtq_dump(struct ivpu_device *vdev)
|
||||
|
||||
@@ -421,16 +421,17 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent)
|
||||
active_us = (DCT_PERIOD_US * active_percent) / 100;
|
||||
inactive_us = DCT_PERIOD_US - active_us;
|
||||
|
||||
vdev->pm->dct_active_percent = active_percent;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT requested %u%% (D0: %uus, D0i2: %uus)\n",
|
||||
active_percent, active_us, inactive_us);
|
||||
|
||||
ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us);
|
||||
if (ret) {
|
||||
ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vdev->pm->dct_active_percent = active_percent;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n",
|
||||
active_percent, active_us, inactive_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -438,15 +439,16 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vdev->pm->dct_active_percent = 0;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT requested to be disabled\n");
|
||||
|
||||
ret = ivpu_jsm_dct_disable(vdev);
|
||||
if (ret) {
|
||||
ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vdev->pm->dct_active_percent = 0;
|
||||
|
||||
ivpu_dbg(vdev, PM, "DCT disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -458,7 +460,7 @@ void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev)
|
||||
if (ivpu_hw_btrs_dct_get_request(vdev, &enable))
|
||||
return;
|
||||
|
||||
if (vdev->pm->dct_active_percent)
|
||||
if (enable)
|
||||
ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT);
|
||||
else
|
||||
ret = ivpu_pm_dct_disable(vdev);
|
||||
|
||||
@@ -30,11 +30,12 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
ktime_t total, now = 0;
|
||||
|
||||
xa_lock(&vdev->submitted_jobs_xa);
|
||||
mutex_lock(&vdev->submitted_jobs_lock);
|
||||
|
||||
total = vdev->busy_time;
|
||||
if (!xa_empty(&vdev->submitted_jobs_xa))
|
||||
now = ktime_sub(ktime_get(), vdev->busy_start_ts);
|
||||
xa_unlock(&vdev->submitted_jobs_xa);
|
||||
mutex_unlock(&vdev->submitted_jobs_lock);
|
||||
|
||||
return sysfs_emit(buf, "%lld\n", ktime_to_us(ktime_add(total, now)));
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright (c) 2020-2023, Intel Corporation.
|
||||
* Copyright (c) 2020-2024, Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef VPU_BOOT_API_H
|
||||
#define VPU_BOOT_API_H
|
||||
|
||||
/*
|
||||
* =========== FW API version information beginning ================
|
||||
* The bellow values will be used to construct the version info this way:
|
||||
* The below values will be used to construct the version info this way:
|
||||
* fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) |
|
||||
* VPU_BOOT_API_VER_MINOR;
|
||||
* VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes
|
||||
@@ -27,19 +26,18 @@
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
* Resets to 0 if Major version is incremented.
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_MINOR 24
|
||||
#define VPU_BOOT_API_VER_MINOR 26
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_PATCH 0
|
||||
#define VPU_BOOT_API_VER_PATCH 3
|
||||
|
||||
/*
|
||||
* Index in the API version table
|
||||
* Must be unique for each API
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_INDEX 0
|
||||
/* ------------ FW API version information end ---------------------*/
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
@@ -164,8 +162,6 @@ enum vpu_trace_destination {
|
||||
/* VPU 30xx HW component IDs are sequential, so define first and last IDs. */
|
||||
#define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT
|
||||
#define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15
|
||||
#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST
|
||||
#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST
|
||||
|
||||
struct vpu_boot_l2_cache_config {
|
||||
u8 use;
|
||||
@@ -199,6 +195,17 @@ struct vpu_warm_boot_section {
|
||||
*/
|
||||
#define POWER_PROFILE_SURVIVABILITY 0x1
|
||||
|
||||
/**
|
||||
* Enum for dvfs_mode boot param.
|
||||
*/
|
||||
enum vpu_governor {
|
||||
VPU_GOV_DEFAULT = 0, /* Default Governor for the system */
|
||||
VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */
|
||||
VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */
|
||||
VPU_GOV_POWER_SAVE = 3, /* Power save governor */
|
||||
VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */
|
||||
};
|
||||
|
||||
struct vpu_boot_params {
|
||||
u32 magic;
|
||||
u32 vpu_id;
|
||||
@@ -301,7 +308,14 @@ struct vpu_boot_params {
|
||||
u32 temp_sensor_period_ms;
|
||||
/** PLL ratio for efficient clock frequency */
|
||||
u32 pn_freq_pll_ratio;
|
||||
/** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */
|
||||
/**
|
||||
* DVFS Mode:
|
||||
* 0 - Default, DVFS mode selected by the firmware
|
||||
* 1 - Max Performance
|
||||
* 2 - On Demand
|
||||
* 3 - Power Save
|
||||
* 4 - On Demand Priority Aware
|
||||
*/
|
||||
u32 dvfs_mode;
|
||||
/**
|
||||
* Depending on DVFS Mode:
|
||||
@@ -332,8 +346,8 @@ struct vpu_boot_params {
|
||||
u64 d0i3_entry_vpu_ts;
|
||||
/*
|
||||
* The system time of the host operating system in microseconds.
|
||||
* E.g the number of microseconds since 1st of January 1970, or whatever date the
|
||||
* host operating system uses to maintain system time.
|
||||
* E.g the number of microseconds since 1st of January 1970, or whatever
|
||||
* date the host operating system uses to maintain system time.
|
||||
* This value will be used to track system time on the VPU.
|
||||
* The KMD is required to update this value on every VPU reset.
|
||||
*/
|
||||
@@ -382,10 +396,7 @@ struct vpu_boot_params {
|
||||
u32 pad6[734];
|
||||
};
|
||||
|
||||
/*
|
||||
* Magic numbers set between host and vpu to detect corruptio of tracing init
|
||||
*/
|
||||
|
||||
/* Magic numbers set between host and vpu to detect corruption of tracing init */
|
||||
#define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE)
|
||||
|
||||
/* Tracing buffer message format definitions */
|
||||
@@ -405,7 +416,9 @@ struct vpu_tracing_buffer_header {
|
||||
u32 host_canary_start;
|
||||
/* offset from start of buffer for trace entries */
|
||||
u32 read_index;
|
||||
u32 pad_to_cache_line_size_0[14];
|
||||
/* keeps track of wrapping on the reader side */
|
||||
u32 read_wrap_count;
|
||||
u32 pad_to_cache_line_size_0[13];
|
||||
/* End of first cache line */
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
*/
|
||||
#define VPU_JSM_API_VER_MINOR 16
|
||||
#define VPU_JSM_API_VER_MINOR 25
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/*
|
||||
* Number of Priority Bands for Hardware Scheduling
|
||||
* Bands: RealTime, Focus, Normal, Idle
|
||||
* Bands: Idle(0), Normal(1), Focus(2), RealTime(3)
|
||||
*/
|
||||
#define VPU_HWS_NUM_PRIORITY_BANDS 4
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU
|
||||
/* Job status returned when the job was preempted mid-inference */
|
||||
#define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU
|
||||
#define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU
|
||||
|
||||
/*
|
||||
* Host <-> VPU IPC channels.
|
||||
@@ -86,18 +87,58 @@
|
||||
/*
|
||||
* Job flags bit masks.
|
||||
*/
|
||||
#define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001
|
||||
#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000
|
||||
enum {
|
||||
/*
|
||||
* Null submission mask.
|
||||
* When set, batch buffer's commands are not processed but returned as
|
||||
* successful immediately, except fences and timestamps.
|
||||
* When cleared, batch buffer's commands are processed normally.
|
||||
* Used for testing and profiling purposes.
|
||||
*/
|
||||
VPU_JOB_FLAGS_NULL_SUBMISSION_MASK = (1 << 0U),
|
||||
/*
|
||||
* Inline command mask.
|
||||
* When set, the object in job queue is an inline command (see struct vpu_inline_cmd below).
|
||||
* When cleared, the object in job queue is a job (see struct vpu_job_queue_entry below).
|
||||
*/
|
||||
VPU_JOB_FLAGS_INLINE_CMD_MASK = (1 << 1U),
|
||||
/*
|
||||
* VPU private data mask.
|
||||
* Reserved for the VPU to store private data about the job (or inline command)
|
||||
* while being processed.
|
||||
*/
|
||||
VPU_JOB_FLAGS_PRIVATE_DATA_MASK = 0xFFFF0000U
|
||||
};
|
||||
|
||||
/*
|
||||
* Sizes of the reserved areas in jobs, in bytes.
|
||||
* Job queue flags bit masks.
|
||||
*/
|
||||
#define VPU_JOB_RESERVED_BYTES 8
|
||||
enum {
|
||||
/*
|
||||
* No job done notification mask.
|
||||
* When set, indicates that no job done notification should be sent for any
|
||||
* job from this queue. When cleared, indicates that job done notification
|
||||
* should be sent for every job completed from this queue.
|
||||
*/
|
||||
VPU_JOB_QUEUE_FLAGS_NO_JOB_DONE_MASK = (1 << 0U),
|
||||
/*
|
||||
* Native fence usage mask.
|
||||
* When set, indicates that job queue uses native fences (as inline commands
|
||||
* in job queue). Such queues may also use legacy fences (as commands in batch buffers).
|
||||
* When cleared, indicates the job queue only uses legacy fences.
|
||||
* NOTE: For queues using native fences, VPU expects that all jobs in the queue
|
||||
* are immediately followed by an inline command object. This object is expected
|
||||
* to be a fence signal command in most cases, but can also be a NOP in case the host
|
||||
* does not need per-job fence signalling. Other inline commands objects can be
|
||||
* inserted between "job and inline command" pairs.
|
||||
*/
|
||||
VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U),
|
||||
|
||||
/*
|
||||
* Sizes of the reserved areas in job queues, in bytes.
|
||||
*/
|
||||
#define VPU_JOB_QUEUE_RESERVED_BYTES 52
|
||||
/*
|
||||
* Enable turbo mode for testing NPU performance; not recommended for regular usage.
|
||||
*/
|
||||
VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U)
|
||||
};
|
||||
|
||||
/*
|
||||
* Max length (including trailing NULL char) of trace entity name (e.g., the
|
||||
@@ -140,24 +181,113 @@
|
||||
*/
|
||||
#define VPU_HWS_INVALID_CMDQ_HANDLE 0ULL
|
||||
|
||||
/*
|
||||
* Inline commands types.
|
||||
*/
|
||||
/*
|
||||
* NOP.
|
||||
* VPU does nothing other than consuming the inline command object.
|
||||
*/
|
||||
#define VPU_INLINE_CMD_TYPE_NOP 0x0
|
||||
/*
|
||||
* Fence wait.
|
||||
* VPU waits for the fence current value to reach monitored value.
|
||||
* Fence wait operations are executed upon job dispatching. While waiting for
|
||||
* the fence to be satisfied, VPU blocks fetching of the next objects in the queue.
|
||||
* Jobs present in the queue prior to the fence wait object may be processed
|
||||
* concurrently.
|
||||
*/
|
||||
#define VPU_INLINE_CMD_TYPE_FENCE_WAIT 0x1
|
||||
/*
|
||||
* Fence signal.
|
||||
* VPU sets the fence current value to the provided value. If new current value
|
||||
* is equal to or higher than monitored value, VPU sends fence signalled notification
|
||||
* to the host. Fence signal operations are executed upon completion of all the jobs
|
||||
* present in the queue prior to them, and in-order relative to each other in the queue.
|
||||
* But jobs in-between them may be processed concurrently and may complete out-of-order.
|
||||
*/
|
||||
#define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2
|
||||
|
||||
/*
|
||||
* Job scheduling priority bands for both hardware scheduling and OS scheduling.
|
||||
*/
|
||||
enum vpu_job_scheduling_priority_band {
|
||||
VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE = 0,
|
||||
VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL = 1,
|
||||
VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS = 2,
|
||||
VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME = 3,
|
||||
VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Job format.
|
||||
* Jobs defines the actual workloads to be executed by a given engine.
|
||||
*/
|
||||
struct vpu_job_queue_entry {
|
||||
u64 batch_buf_addr; /**< Address of VPU commands batch buffer */
|
||||
u32 job_id; /**< Job ID */
|
||||
u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */
|
||||
u64 root_page_table_addr; /**< Address of root page table to use for this job */
|
||||
u64 root_page_table_update_counter; /**< Page tables update events counter */
|
||||
u64 primary_preempt_buf_addr;
|
||||
/**< Address of VPU commands batch buffer */
|
||||
u64 batch_buf_addr;
|
||||
/**< Job ID */
|
||||
u32 job_id;
|
||||
/**< Flags bit field, see VPU_JOB_FLAGS_* above */
|
||||
u32 flags;
|
||||
/**
|
||||
* Doorbell ring timestamp taken by KMD from SoC's global system clock, in
|
||||
* microseconds. NPU can convert this value to its own fixed clock's timebase,
|
||||
* to match other profiling timestamps.
|
||||
*/
|
||||
u64 doorbell_timestamp;
|
||||
/**< Extra id for job tracking, used only in the firmware perf traces */
|
||||
u64 host_tracking_id;
|
||||
/**< Address of the primary preemption buffer to use for this job */
|
||||
u32 primary_preempt_buf_size;
|
||||
u64 primary_preempt_buf_addr;
|
||||
/**< Size of the primary preemption buffer to use for this job */
|
||||
u32 secondary_preempt_buf_size;
|
||||
u32 primary_preempt_buf_size;
|
||||
/**< Size of secondary preemption buffer to use for this job */
|
||||
u64 secondary_preempt_buf_addr;
|
||||
u32 secondary_preempt_buf_size;
|
||||
/**< Address of secondary preemption buffer to use for this job */
|
||||
u8 reserved_0[VPU_JOB_RESERVED_BYTES];
|
||||
u64 secondary_preempt_buf_addr;
|
||||
u64 reserved_0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Inline command format.
|
||||
* Inline commands are the commands executed at scheduler level (typically,
|
||||
* synchronization directives). Inline command and job objects must be of
|
||||
* the same size and have flags field at same offset.
|
||||
*/
|
||||
struct vpu_inline_cmd {
|
||||
u64 reserved_0;
|
||||
/* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */
|
||||
u32 type;
|
||||
/* Flags bit field, see VPU_JOB_FLAGS_* above. */
|
||||
u32 flags;
|
||||
/* Inline command payload. Depends on inline command type. */
|
||||
union {
|
||||
/* Fence (wait and signal) commands' payload. */
|
||||
struct {
|
||||
/* Fence object handle. */
|
||||
u64 fence_handle;
|
||||
/* User VA of the current fence value. */
|
||||
u64 current_value_va;
|
||||
/* User VA of the monitored fence value (read-only). */
|
||||
u64 monitored_value_va;
|
||||
/* Value to wait for or write in fence location. */
|
||||
u64 value;
|
||||
/* User VA of the log buffer in which to add log entry on completion. */
|
||||
u64 log_buffer_va;
|
||||
} fence;
|
||||
/* Other commands do not have a payload. */
|
||||
/* Payload definition for future inline commands can be inserted here. */
|
||||
u64 reserved_1[6];
|
||||
} payload;
|
||||
};
|
||||
|
||||
/*
|
||||
* Job queue slots can be populated either with job objects or inline command objects.
|
||||
*/
|
||||
union vpu_jobq_slot {
|
||||
struct vpu_job_queue_entry job;
|
||||
struct vpu_inline_cmd inline_cmd;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -167,7 +297,21 @@ struct vpu_job_queue_header {
|
||||
u32 engine_idx;
|
||||
u32 head;
|
||||
u32 tail;
|
||||
u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES];
|
||||
u32 flags;
|
||||
/* Set to 1 to indicate priority_band field is valid */
|
||||
u32 priority_band_valid;
|
||||
/*
|
||||
* Priority for the work of this job queue, valid only if the HWS is NOT used
|
||||
* and the `priority_band_valid` is set to 1. It is applied only during
|
||||
* the VPU_JSM_MSG_REGISTER_DB message processing.
|
||||
* The device firmware might use the `priority_band` to optimize the power
|
||||
* management logic, but it will not affect the order of jobs.
|
||||
* Available priority bands: @see enum vpu_job_scheduling_priority_band
|
||||
*/
|
||||
u32 priority_band;
|
||||
/* Inside realtime band assigns a further priority, limited to 0..31 range */
|
||||
u32 realtime_priority_level;
|
||||
u32 reserved_0[9];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -175,7 +319,7 @@ struct vpu_job_queue_header {
|
||||
*/
|
||||
struct vpu_job_queue {
|
||||
struct vpu_job_queue_header header;
|
||||
struct vpu_job_queue_entry job[];
|
||||
union vpu_jobq_slot slot[];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -197,9 +341,7 @@ enum vpu_trace_entity_type {
|
||||
struct vpu_hws_log_buffer_header {
|
||||
/* Written by VPU after adding a log entry. Initialised by host to 0. */
|
||||
u32 first_free_entry_index;
|
||||
/* Incremented by VPU every time the VPU overwrites the 0th entry;
|
||||
* initialised by host to 0.
|
||||
*/
|
||||
/* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */
|
||||
u32 wraparound_count;
|
||||
/*
|
||||
* This is the number of buffers that can be stored in the log buffer provided by the host.
|
||||
@@ -230,14 +372,80 @@ struct vpu_hws_log_buffer_entry {
|
||||
u64 operation_data[2];
|
||||
};
|
||||
|
||||
/* Native fence log buffer types. */
|
||||
enum vpu_hws_native_fence_log_type {
|
||||
VPU_HWS_NATIVE_FENCE_LOG_TYPE_WAITS = 1,
|
||||
VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2
|
||||
};
|
||||
|
||||
/* HWS native fence log buffer header. */
|
||||
struct vpu_hws_native_fence_log_header {
|
||||
union {
|
||||
struct {
|
||||
/* Index of the first free entry in buffer. */
|
||||
u32 first_free_entry_idx;
|
||||
/* Incremented each time NPU wraps around the buffer to write next entry. */
|
||||
u32 wraparound_count;
|
||||
};
|
||||
/* Field allowing atomic update of both fields above. */
|
||||
u64 atomic_wraparound_and_entry_idx;
|
||||
};
|
||||
/* Log buffer type, see enum vpu_hws_native_fence_log_type. */
|
||||
u64 type;
|
||||
/* Allocated number of entries in the log buffer. */
|
||||
u64 entry_nb;
|
||||
u64 reserved[2];
|
||||
};
|
||||
|
||||
/* Native fence log operation types. */
|
||||
enum vpu_hws_native_fence_log_op {
|
||||
VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0,
|
||||
VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1
|
||||
};
|
||||
|
||||
/* HWS native fence log entry. */
|
||||
struct vpu_hws_native_fence_log_entry {
|
||||
/* Newly signaled/unblocked fence value. */
|
||||
u64 fence_value;
|
||||
/* Native fence object handle to which this operation belongs. */
|
||||
u64 fence_handle;
|
||||
/* Operation type, see enum vpu_hws_native_fence_log_op. */
|
||||
u64 op_type;
|
||||
u64 reserved_0;
|
||||
/*
|
||||
* VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence
|
||||
* wait was started (in NPU SysTime).
|
||||
*/
|
||||
u64 fence_wait_start_ts;
|
||||
u64 reserved_1;
|
||||
/* Timestamp at which fence operation was completed (in NPU SysTime). */
|
||||
u64 fence_end_ts;
|
||||
};
|
||||
|
||||
/* Native fence log buffer. */
|
||||
struct vpu_hws_native_fence_log_buffer {
|
||||
struct vpu_hws_native_fence_log_header header;
|
||||
struct vpu_hws_native_fence_log_entry entry[];
|
||||
};
|
||||
|
||||
/*
|
||||
* Host <-> VPU IPC messages types.
|
||||
*/
|
||||
enum vpu_ipc_msg_type {
|
||||
VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF,
|
||||
|
||||
/* IPC Host -> Device, Async commands */
|
||||
VPU_JSM_MSG_ASYNC_CMD = 0x1100,
|
||||
VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD,
|
||||
/**
|
||||
* Preempt engine. The NPU stops (preempts) all the jobs currently
|
||||
* executing on the target engine making the engine become idle and ready to
|
||||
* execute new jobs.
|
||||
* NOTE: The NPU does not remove unstarted jobs (if any) from job queues of
|
||||
* the target engine, but it stops processing them (until the queue doorbell
|
||||
* is rung again); the host is responsible to reset the job queue, either
|
||||
* after preemption or when resubmitting jobs to the queue.
|
||||
*/
|
||||
VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101,
|
||||
VPU_JSM_MSG_REGISTER_DB = 0x1102,
|
||||
VPU_JSM_MSG_UNREGISTER_DB = 0x1103,
|
||||
@@ -323,9 +531,10 @@ enum vpu_ipc_msg_type {
|
||||
* NOTE: Please introduce new ASYNC commands before this one. *
|
||||
*/
|
||||
VPU_JSM_MSG_STATE_DUMP = 0x11FF,
|
||||
|
||||
/* IPC Host -> Device, General commands */
|
||||
VPU_JSM_MSG_GENERAL_CMD = 0x1200,
|
||||
VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD,
|
||||
VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD,
|
||||
/**
|
||||
* Control dyndbg behavior by executing a dyndbg command; equivalent to
|
||||
* Linux command: `echo '<dyndbg_cmd>' > <debugfs>/dynamic_debug/control`.
|
||||
@@ -335,8 +544,12 @@ enum vpu_ipc_msg_type {
|
||||
* Perform the save procedure for the D0i3 entry
|
||||
*/
|
||||
VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202,
|
||||
|
||||
/* IPC Device -> Host, Job completion */
|
||||
VPU_JSM_MSG_JOB_DONE = 0x2100,
|
||||
/* IPC Device -> Host, Fence signalled */
|
||||
VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101,
|
||||
|
||||
/* IPC Device -> Host, Async command completion */
|
||||
VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200,
|
||||
VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE,
|
||||
@@ -422,6 +635,7 @@ enum vpu_ipc_msg_type {
|
||||
* NOTE: Please introduce new ASYNC responses before this one. *
|
||||
*/
|
||||
VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF,
|
||||
|
||||
/* IPC Device -> Host, General command completion */
|
||||
VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300,
|
||||
VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE,
|
||||
@@ -600,11 +814,6 @@ struct vpu_jsm_metric_streamer_update {
|
||||
u64 next_buffer_size;
|
||||
};
|
||||
|
||||
struct vpu_ipc_msg_payload_blob_deinit {
|
||||
/* 64-bit unique ID for the blob to be de-initialized. */
|
||||
u64 blob_id;
|
||||
};
|
||||
|
||||
struct vpu_ipc_msg_payload_job_done {
|
||||
/* Engine to which the job was submitted. */
|
||||
u32 engine_idx;
|
||||
@@ -622,6 +831,21 @@ struct vpu_ipc_msg_payload_job_done {
|
||||
u64 cmdq_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* Notification message upon native fence signalling.
|
||||
* @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED
|
||||
*/
|
||||
struct vpu_ipc_msg_payload_native_fence_signalled {
|
||||
/* Engine ID. */
|
||||
u32 engine_idx;
|
||||
/* Host SSID. */
|
||||
u32 host_ssid;
|
||||
/* CMDQ ID */
|
||||
u64 cmdq_id;
|
||||
/* Fence object handle. */
|
||||
u64 fence_handle;
|
||||
};
|
||||
|
||||
struct vpu_jsm_engine_reset_context {
|
||||
/* Host SSID */
|
||||
u32 host_ssid;
|
||||
@@ -700,11 +924,6 @@ struct vpu_ipc_msg_payload_get_power_level_count_done {
|
||||
u8 power_limit[16];
|
||||
};
|
||||
|
||||
struct vpu_ipc_msg_payload_blob_deinit_done {
|
||||
/* 64-bit unique ID for the blob de-initialized. */
|
||||
u64 blob_id;
|
||||
};
|
||||
|
||||
/* HWS priority band setup request / response */
|
||||
struct vpu_ipc_msg_payload_hws_priority_band_setup {
|
||||
/*
|
||||
@@ -794,7 +1013,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties {
|
||||
u32 reserved_0;
|
||||
/* Command queue id */
|
||||
u64 cmdq_id;
|
||||
/* Priority band to assign to work of this context */
|
||||
/*
|
||||
* Priority band to assign to work of this context.
|
||||
* Available priority bands: @see enum vpu_job_scheduling_priority_band
|
||||
*/
|
||||
u32 priority_band;
|
||||
/* Inside realtime band assigns a further priority */
|
||||
u32 realtime_priority_level;
|
||||
@@ -869,9 +1091,7 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log {
|
||||
*/
|
||||
u64 notify_index;
|
||||
/*
|
||||
* Enable extra events to be output to log for debug of scheduling algorithm.
|
||||
* Interpreted by VPU as a boolean to enable or disable, expected values are
|
||||
* 0 and 1.
|
||||
* Field is now deprecated, will be removed when KMD is updated to support removal
|
||||
*/
|
||||
u32 enable_extra_events;
|
||||
/* Zero Padding */
|
||||
@@ -1243,10 +1463,10 @@ union vpu_ipc_msg_payload {
|
||||
struct vpu_jsm_metric_streamer_start metric_streamer_start;
|
||||
struct vpu_jsm_metric_streamer_stop metric_streamer_stop;
|
||||
struct vpu_jsm_metric_streamer_update metric_streamer_update;
|
||||
struct vpu_ipc_msg_payload_blob_deinit blob_deinit;
|
||||
struct vpu_ipc_msg_payload_ssid_release ssid_release;
|
||||
struct vpu_jsm_hws_register_db hws_register_db;
|
||||
struct vpu_ipc_msg_payload_job_done job_done;
|
||||
struct vpu_ipc_msg_payload_native_fence_signalled native_fence_signalled;
|
||||
struct vpu_ipc_msg_payload_engine_reset_done engine_reset_done;
|
||||
struct vpu_ipc_msg_payload_engine_preempt_done engine_preempt_done;
|
||||
struct vpu_ipc_msg_payload_register_db_done register_db_done;
|
||||
@@ -1254,7 +1474,6 @@ union vpu_ipc_msg_payload {
|
||||
struct vpu_ipc_msg_payload_query_engine_hb_done query_engine_hb_done;
|
||||
struct vpu_ipc_msg_payload_get_power_level_count_done get_power_level_count_done;
|
||||
struct vpu_jsm_metric_streamer_done metric_streamer_done;
|
||||
struct vpu_ipc_msg_payload_blob_deinit_done blob_deinit_done;
|
||||
struct vpu_ipc_msg_payload_trace_config trace_config;
|
||||
struct vpu_ipc_msg_payload_trace_capability_rsp trace_capability;
|
||||
struct vpu_ipc_msg_payload_trace_get_name trace_get_name;
|
||||
|
||||
@@ -6641,7 +6641,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
|
||||
seq_printf(m, " node %d", buffer->target_node->debug_id);
|
||||
seq_printf(m, " size %zd:%zd offset %lx\n",
|
||||
buffer->data_size, buffer->offsets_size,
|
||||
proc->alloc.buffer - buffer->user_data);
|
||||
buffer->user_data - proc->alloc.buffer);
|
||||
}
|
||||
|
||||
static void print_binder_work_ilocked(struct seq_file *m,
|
||||
|
||||
@@ -42,16 +42,13 @@ int module_add_driver(struct module *mod, const struct device_driver *drv)
|
||||
if (mod)
|
||||
mk = &mod->mkobj;
|
||||
else if (drv->mod_name) {
|
||||
struct kobject *mkobj;
|
||||
|
||||
/* Lookup built-in module entry in /sys/modules */
|
||||
mkobj = kset_find_obj(module_kset, drv->mod_name);
|
||||
if (mkobj) {
|
||||
mk = container_of(mkobj, struct module_kobject, kobj);
|
||||
/* Lookup or create built-in module entry in /sys/modules */
|
||||
mk = lookup_or_create_module_kobject(drv->mod_name);
|
||||
if (mk) {
|
||||
/* remember our module structure */
|
||||
drv->p->mkobj = mk;
|
||||
/* kset_find_obj took a reference */
|
||||
kobject_put(mkobj);
|
||||
/* lookup_or_create_module_kobject took a reference */
|
||||
kobject_put(&mk->kobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -581,8 +581,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
/* This is a debug event that comes from IML and OP image when it
|
||||
* starts execution. There is no need pass this event to stack.
|
||||
*/
|
||||
if (skb->data[2] == 0x97)
|
||||
if (skb->data[2] == 0x97) {
|
||||
hci_recv_diag(hdev, skb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return hci_recv_frame(hdev, skb);
|
||||
@@ -598,7 +600,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
||||
u8 pkt_type;
|
||||
u16 plen;
|
||||
u32 pcie_pkt_type;
|
||||
struct sk_buff *new_skb;
|
||||
void *pdata;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
||||
@@ -675,24 +676,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
||||
|
||||
bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen);
|
||||
|
||||
new_skb = bt_skb_alloc(plen, GFP_ATOMIC);
|
||||
if (!new_skb) {
|
||||
bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u",
|
||||
skb->len);
|
||||
ret = -ENOMEM;
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
hci_skb_pkt_type(new_skb) = pkt_type;
|
||||
skb_put_data(new_skb, skb->data, plen);
|
||||
hci_skb_pkt_type(skb) = pkt_type;
|
||||
hdev->stat.byte_rx += plen;
|
||||
skb_trim(skb, plen);
|
||||
|
||||
if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT)
|
||||
ret = btintel_pcie_recv_event(hdev, new_skb);
|
||||
ret = btintel_pcie_recv_event(hdev, skb);
|
||||
else
|
||||
ret = hci_recv_frame(hdev, new_skb);
|
||||
ret = hci_recv_frame(hdev, skb);
|
||||
skb = NULL; /* skb is freed in the callee */
|
||||
|
||||
exit_error:
|
||||
if (skb)
|
||||
kfree_skb(skb);
|
||||
|
||||
if (ret)
|
||||
hdev->stat.err_rx++;
|
||||
|
||||
@@ -706,16 +703,10 @@ static void btintel_pcie_rx_work(struct work_struct *work)
|
||||
struct btintel_pcie_data *data = container_of(work,
|
||||
struct btintel_pcie_data, rx_work);
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
||||
/* Process the sk_buf in queue and send to the HCI layer */
|
||||
while ((skb = skb_dequeue(&data->rx_skb_q))) {
|
||||
err = btintel_pcie_recv_frame(data, skb);
|
||||
if (err)
|
||||
bt_dev_err(hdev, "Failed to send received frame: %d",
|
||||
err);
|
||||
kfree_skb(skb);
|
||||
btintel_pcie_recv_frame(data, skb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,10 +761,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
|
||||
bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia);
|
||||
|
||||
/* Check CR_TIA and CR_HIA for change */
|
||||
if (cr_tia == cr_hia) {
|
||||
bt_dev_warn(hdev, "RXQ: no new CD found");
|
||||
if (cr_tia == cr_hia)
|
||||
return;
|
||||
}
|
||||
|
||||
rxq = &data->rxq;
|
||||
|
||||
@@ -809,6 +798,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data)
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data)
|
||||
{
|
||||
return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
|
||||
}
|
||||
|
||||
static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data)
|
||||
{
|
||||
return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
|
||||
}
|
||||
|
||||
static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct msix_entry *entry = dev_id;
|
||||
@@ -836,12 +835,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
||||
btintel_pcie_msix_gp0_handler(data);
|
||||
|
||||
/* For TX */
|
||||
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0)
|
||||
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
|
||||
btintel_pcie_msix_tx_handle(data);
|
||||
if (!btintel_pcie_is_rxq_empty(data))
|
||||
btintel_pcie_msix_rx_handle(data);
|
||||
}
|
||||
|
||||
/* For RX */
|
||||
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1)
|
||||
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) {
|
||||
btintel_pcie_msix_rx_handle(data);
|
||||
if (!btintel_pcie_is_txackq_empty(data))
|
||||
btintel_pcie_msix_tx_handle(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Before sending the interrupt the HW disables it to prevent a nested
|
||||
|
||||
@@ -372,6 +372,42 @@ static const struct usb_device_id quirks_table[] = {
|
||||
/* QCA WCN785x chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0fc), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f3), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe100), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe103), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe10a), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe10d), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11b), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11c), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11f), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe141), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14a), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14b), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14d), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3623), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3624), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0130), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0131), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0132), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||
@@ -2927,22 +2963,16 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
|
||||
bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==0: not a dump pkt.
|
||||
* < 0: fails to handle a dump pkt
|
||||
* > 0: otherwise.
|
||||
*/
|
||||
/* Return: 0 on success, negative errno on failure. */
|
||||
static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
int ret = 1;
|
||||
int ret = 0;
|
||||
u8 pkt_type;
|
||||
u8 *sk_ptr;
|
||||
unsigned int sk_len;
|
||||
u16 seqno;
|
||||
u32 dump_size;
|
||||
|
||||
struct hci_event_hdr *event_hdr;
|
||||
struct hci_acl_hdr *acl_hdr;
|
||||
struct qca_dump_hdr *dump_hdr;
|
||||
struct btusb_data *btdata = hci_get_drvdata(hdev);
|
||||
struct usb_device *udev = btdata->udev;
|
||||
@@ -2952,30 +2982,14 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
sk_len = skb->len;
|
||||
|
||||
if (pkt_type == HCI_ACLDATA_PKT) {
|
||||
acl_hdr = hci_acl_hdr(skb);
|
||||
if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
|
||||
return 0;
|
||||
sk_ptr += HCI_ACL_HDR_SIZE;
|
||||
sk_len -= HCI_ACL_HDR_SIZE;
|
||||
event_hdr = (struct hci_event_hdr *)sk_ptr;
|
||||
} else {
|
||||
event_hdr = hci_event_hdr(skb);
|
||||
}
|
||||
|
||||
if ((event_hdr->evt != HCI_VENDOR_PKT)
|
||||
|| (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
|
||||
return 0;
|
||||
|
||||
sk_ptr += HCI_EVENT_HDR_SIZE;
|
||||
sk_len -= HCI_EVENT_HDR_SIZE;
|
||||
|
||||
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
|
||||
if ((sk_len < offsetof(struct qca_dump_hdr, data))
|
||||
|| (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS)
|
||||
|| (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
|
||||
return 0;
|
||||
|
||||
/*it is dump pkt now*/
|
||||
seqno = le16_to_cpu(dump_hdr->seqno);
|
||||
if (seqno == 0) {
|
||||
set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags);
|
||||
@@ -3049,17 +3063,84 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return: true if the ACL packet is a dump packet, false otherwise. */
|
||||
static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
u8 *sk_ptr;
|
||||
unsigned int sk_len;
|
||||
|
||||
struct hci_event_hdr *event_hdr;
|
||||
struct hci_acl_hdr *acl_hdr;
|
||||
struct qca_dump_hdr *dump_hdr;
|
||||
|
||||
sk_ptr = skb->data;
|
||||
sk_len = skb->len;
|
||||
|
||||
acl_hdr = hci_acl_hdr(skb);
|
||||
if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
|
||||
return false;
|
||||
|
||||
sk_ptr += HCI_ACL_HDR_SIZE;
|
||||
sk_len -= HCI_ACL_HDR_SIZE;
|
||||
event_hdr = (struct hci_event_hdr *)sk_ptr;
|
||||
|
||||
if ((event_hdr->evt != HCI_VENDOR_PKT) ||
|
||||
(event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
|
||||
return false;
|
||||
|
||||
sk_ptr += HCI_EVENT_HDR_SIZE;
|
||||
sk_len -= HCI_EVENT_HDR_SIZE;
|
||||
|
||||
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
|
||||
if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
|
||||
(dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
|
||||
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return: true if the event packet is a dump packet, false otherwise. */
|
||||
static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
u8 *sk_ptr;
|
||||
unsigned int sk_len;
|
||||
|
||||
struct hci_event_hdr *event_hdr;
|
||||
struct qca_dump_hdr *dump_hdr;
|
||||
|
||||
sk_ptr = skb->data;
|
||||
sk_len = skb->len;
|
||||
|
||||
event_hdr = hci_event_hdr(skb);
|
||||
|
||||
if ((event_hdr->evt != HCI_VENDOR_PKT)
|
||||
|| (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
|
||||
return false;
|
||||
|
||||
sk_ptr += HCI_EVENT_HDR_SIZE;
|
||||
sk_len -= HCI_EVENT_HDR_SIZE;
|
||||
|
||||
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
|
||||
if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
|
||||
(dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
|
||||
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
if (handle_dump_pkt_qca(hdev, skb))
|
||||
return 0;
|
||||
if (acl_pkt_is_dump_qca(hdev, skb))
|
||||
return handle_dump_pkt_qca(hdev, skb);
|
||||
return hci_recv_frame(hdev, skb);
|
||||
}
|
||||
|
||||
static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
if (handle_dump_pkt_qca(hdev, skb))
|
||||
return 0;
|
||||
if (evt_pkt_is_dump_qca(hdev, skb))
|
||||
return handle_dump_pkt_qca(hdev, skb);
|
||||
return hci_recv_frame(hdev, skb);
|
||||
}
|
||||
|
||||
|
||||
@@ -538,18 +538,20 @@ void cpufreq_disable_fast_switch(struct cpufreq_policy *policy)
|
||||
EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch);
|
||||
|
||||
static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq, unsigned int relation)
|
||||
unsigned int target_freq,
|
||||
unsigned int min, unsigned int max,
|
||||
unsigned int relation)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned int old_target_freq = target_freq;
|
||||
|
||||
target_freq = clamp_val(target_freq, policy->min, policy->max);
|
||||
target_freq = clamp_val(target_freq, min, max);
|
||||
trace_android_vh_cpufreq_resolve_freq(policy, &target_freq, old_target_freq);
|
||||
|
||||
if (!policy->freq_table)
|
||||
return target_freq;
|
||||
|
||||
idx = cpufreq_frequency_table_target(policy, target_freq, relation);
|
||||
idx = cpufreq_frequency_table_target(policy, target_freq, min, max, relation);
|
||||
policy->cached_resolved_idx = idx;
|
||||
policy->cached_target_freq = target_freq;
|
||||
return policy->freq_table[idx].frequency;
|
||||
@@ -569,7 +571,21 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
|
||||
unsigned int min = READ_ONCE(policy->min);
|
||||
unsigned int max = READ_ONCE(policy->max);
|
||||
|
||||
/*
|
||||
* If this function runs in parallel with cpufreq_set_policy(), it may
|
||||
* read policy->min before the update and policy->max after the update
|
||||
* or the other way around, so there is no ordering guarantee.
|
||||
*
|
||||
* Resolve this by always honoring the max (in case it comes from
|
||||
* thermal throttling or similar).
|
||||
*/
|
||||
if (unlikely(min > max))
|
||||
min = max;
|
||||
|
||||
return __resolve_freq(policy, target_freq, min, max, CPUFREQ_RELATION_LE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
|
||||
|
||||
@@ -2343,7 +2359,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
|
||||
if (cpufreq_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
target_freq = __resolve_freq(policy, target_freq, relation);
|
||||
target_freq = __resolve_freq(policy, target_freq, policy->min,
|
||||
policy->max, relation);
|
||||
|
||||
trace_android_vh_cpufreq_target(policy, &target_freq, old_target_freq);
|
||||
|
||||
@@ -2669,11 +2686,18 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
||||
* Resolve policy min/max to available frequencies. It ensures
|
||||
* no frequency resolution will neither overshoot the requested maximum
|
||||
* nor undershoot the requested minimum.
|
||||
*
|
||||
* Avoid storing intermediate values in policy->max or policy->min and
|
||||
* compiler optimizations around them because they may be accessed
|
||||
* concurrently by cpufreq_driver_resolve_freq() during the update.
|
||||
*/
|
||||
policy->min = new_data.min;
|
||||
policy->max = new_data.max;
|
||||
policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
|
||||
policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
|
||||
WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max,
|
||||
new_data.min, new_data.max,
|
||||
CPUFREQ_RELATION_H));
|
||||
new_data.min = __resolve_freq(policy, new_data.min, new_data.min,
|
||||
new_data.max, CPUFREQ_RELATION_L);
|
||||
WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
|
||||
|
||||
trace_cpu_frequency_limits(policy);
|
||||
|
||||
cpufreq_update_pressure(policy);
|
||||
|
||||
@@ -76,7 +76,8 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,
|
||||
return freq_next;
|
||||
}
|
||||
|
||||
index = cpufreq_frequency_table_target(policy, freq_next, relation);
|
||||
index = cpufreq_frequency_table_target(policy, freq_next, policy->min,
|
||||
policy->max, relation);
|
||||
freq_req = freq_table[index].frequency;
|
||||
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
|
||||
freq_avg = freq_req - freq_reduc;
|
||||
|
||||
@@ -117,8 +117,8 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy)
|
||||
EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);
|
||||
|
||||
int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
unsigned int target_freq, unsigned int min,
|
||||
unsigned int max, unsigned int relation)
|
||||
{
|
||||
struct cpufreq_frequency_table optimal = {
|
||||
.driver_data = ~0,
|
||||
@@ -149,7 +149,7 @@ int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
|
||||
cpufreq_for_each_valid_entry_idx(pos, table, i) {
|
||||
freq = pos->frequency;
|
||||
|
||||
if ((freq < policy->min) || (freq > policy->max))
|
||||
if (freq < min || freq > max)
|
||||
continue;
|
||||
if (freq == target_freq) {
|
||||
optimal.driver_data = i;
|
||||
|
||||
@@ -600,6 +600,9 @@ static bool turbo_is_disabled(void)
|
||||
{
|
||||
u64 misc_en;
|
||||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_IDA))
|
||||
return true;
|
||||
|
||||
rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
|
||||
|
||||
return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
|
||||
|
||||
@@ -99,7 +99,7 @@ static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id)
|
||||
if (status & priv->ecc_stat_ce_mask) {
|
||||
regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset,
|
||||
&err_addr);
|
||||
if (priv->ecc_uecnt_offset)
|
||||
if (priv->ecc_cecnt_offset)
|
||||
regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset,
|
||||
&err_count);
|
||||
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count,
|
||||
@@ -1005,9 +1005,6 @@ altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
|
||||
}
|
||||
}
|
||||
|
||||
/* Interrupt mode set to every SBERR */
|
||||
regmap_write(ecc_mgr_map, ALTR_A10_ECC_INTMODE_OFST,
|
||||
ALTR_A10_ECC_INTMODE);
|
||||
/* Enable ECC */
|
||||
ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base +
|
||||
ALTR_A10_ECC_CTRL_OFST));
|
||||
@@ -2127,6 +2124,10 @@ static int altr_edac_a10_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(edac->ecc_mgr_map);
|
||||
}
|
||||
|
||||
/* Set irq mask for DDR SBE to avoid any pending irq before registration */
|
||||
regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST,
|
||||
(A10_SYSMGR_ECC_INTMASK_SDMMCB | A10_SYSMGR_ECC_INTMASK_DDR0));
|
||||
|
||||
edac->irq_chip.name = pdev->dev.of_node->name;
|
||||
edac->irq_chip.irq_mask = a10_eccmgr_irq_mask;
|
||||
edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask;
|
||||
|
||||
@@ -249,6 +249,8 @@ struct altr_sdram_mc_data {
|
||||
#define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94
|
||||
#define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98
|
||||
#define A10_SYSMGR_ECC_INTMASK_OCRAM BIT(1)
|
||||
#define A10_SYSMGR_ECC_INTMASK_SDMMCB BIT(16)
|
||||
#define A10_SYSMGR_ECC_INTMASK_DDR0 BIT(17)
|
||||
|
||||
#define A10_SYSMGR_ECC_INTSTAT_SERR_OFST 0x9C
|
||||
#define A10_SYSMGR_ECC_INTSTAT_DERR_OFST 0xA0
|
||||
|
||||
@@ -260,6 +260,9 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
/* Drop the refcnt bumped implicitly by device_find_child */
|
||||
put_device(dev);
|
||||
|
||||
return to_scmi_dev(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
|
||||
bool "Enable refcount backtrace history in the DP MST helpers"
|
||||
depends on STACKTRACE_SUPPORT
|
||||
select STACKDEPOT
|
||||
depends on DRM_KMS_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
depends on DEBUG_KERNEL
|
||||
depends on EXPERT
|
||||
help
|
||||
|
||||
@@ -361,7 +361,7 @@ static void nbio_v7_11_get_clockgating_state(struct amdgpu_device *adev,
|
||||
*flags |= AMD_CG_SUPPORT_BIF_LS;
|
||||
}
|
||||
|
||||
#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
|
||||
#define MMIO_REG_HOLE_OFFSET 0x44000
|
||||
|
||||
static void nbio_v7_11_set_reg_remap(struct amdgpu_device *adev)
|
||||
{
|
||||
|
||||
@@ -1887,26 +1887,6 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode(
|
||||
|
||||
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
|
||||
case IP_VERSION(3, 5, 0):
|
||||
/*
|
||||
* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to
|
||||
* cause a hard hang. A fix exists for newer PMFW.
|
||||
*
|
||||
* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest
|
||||
* IPS state in all cases, except for s0ix and all displays off (DPMS),
|
||||
* where IPS2 is allowed.
|
||||
*
|
||||
* When checking pmfw version, use the major and minor only.
|
||||
*/
|
||||
if ((adev->pm.fw_version & 0x00FFFF00) < 0x005D6300)
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
else if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(11, 5, 0))
|
||||
/*
|
||||
* Other ASICs with DCN35 that have residency issues with
|
||||
* IPS2 in idle.
|
||||
* We want them to use IPS2 only in display off cases.
|
||||
*/
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
case IP_VERSION(3, 5, 1):
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
|
||||
@@ -172,7 +172,10 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
|
||||
struct mod_hdcp_display_adjustment display_adjust;
|
||||
unsigned int conn_index = aconnector->base.index;
|
||||
|
||||
mutex_lock(&hdcp_w->mutex);
|
||||
guard(mutex)(&hdcp_w->mutex);
|
||||
drm_connector_get(&aconnector->base);
|
||||
if (hdcp_w->aconnector[conn_index])
|
||||
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||
hdcp_w->aconnector[conn_index] = aconnector;
|
||||
|
||||
memset(&link_adjust, 0, sizeof(link_adjust));
|
||||
@@ -209,7 +212,6 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
|
||||
mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output);
|
||||
|
||||
process_output(hdcp_w);
|
||||
mutex_unlock(&hdcp_w->mutex);
|
||||
}
|
||||
|
||||
static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
||||
@@ -220,8 +222,7 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
||||
struct drm_connector_state *conn_state = aconnector->base.state;
|
||||
unsigned int conn_index = aconnector->base.index;
|
||||
|
||||
mutex_lock(&hdcp_w->mutex);
|
||||
hdcp_w->aconnector[conn_index] = aconnector;
|
||||
guard(mutex)(&hdcp_w->mutex);
|
||||
|
||||
/* the removal of display will invoke auth reset -> hdcp destroy and
|
||||
* we'd expect the Content Protection (CP) property changed back to
|
||||
@@ -237,9 +238,11 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
||||
}
|
||||
|
||||
mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
|
||||
|
||||
if (hdcp_w->aconnector[conn_index]) {
|
||||
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||
hdcp_w->aconnector[conn_index] = NULL;
|
||||
}
|
||||
process_output(hdcp_w);
|
||||
mutex_unlock(&hdcp_w->mutex);
|
||||
}
|
||||
|
||||
void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
||||
@@ -247,7 +250,7 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
|
||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
||||
unsigned int conn_index;
|
||||
|
||||
mutex_lock(&hdcp_w->mutex);
|
||||
guard(mutex)(&hdcp_w->mutex);
|
||||
|
||||
mod_hdcp_reset_connection(&hdcp_w->hdcp, &hdcp_w->output);
|
||||
|
||||
@@ -256,11 +259,13 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
|
||||
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) {
|
||||
hdcp_w->encryption_status[conn_index] =
|
||||
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
|
||||
if (hdcp_w->aconnector[conn_index]) {
|
||||
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||
hdcp_w->aconnector[conn_index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
process_output(hdcp_w);
|
||||
|
||||
mutex_unlock(&hdcp_w->mutex);
|
||||
}
|
||||
|
||||
void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
||||
@@ -277,7 +282,7 @@ static void event_callback(struct work_struct *work)
|
||||
hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
|
||||
callback_dwork);
|
||||
|
||||
mutex_lock(&hdcp_work->mutex);
|
||||
guard(mutex)(&hdcp_work->mutex);
|
||||
|
||||
cancel_delayed_work(&hdcp_work->callback_dwork);
|
||||
|
||||
@@ -285,8 +290,6 @@ static void event_callback(struct work_struct *work)
|
||||
&hdcp_work->output);
|
||||
|
||||
process_output(hdcp_work);
|
||||
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
}
|
||||
|
||||
static void event_property_update(struct work_struct *work)
|
||||
@@ -323,7 +326,7 @@ static void event_property_update(struct work_struct *work)
|
||||
continue;
|
||||
|
||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||
mutex_lock(&hdcp_work->mutex);
|
||||
guard(mutex)(&hdcp_work->mutex);
|
||||
|
||||
if (conn_state->commit) {
|
||||
ret = wait_for_completion_interruptible_timeout(&conn_state->commit->hw_done,
|
||||
@@ -355,7 +358,6 @@ static void event_property_update(struct work_struct *work)
|
||||
drm_hdcp_update_content_protection(connector,
|
||||
DRM_MODE_CONTENT_PROTECTION_DESIRED);
|
||||
}
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||
}
|
||||
}
|
||||
@@ -368,7 +370,7 @@ static void event_property_validate(struct work_struct *work)
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
unsigned int conn_index;
|
||||
|
||||
mutex_lock(&hdcp_work->mutex);
|
||||
guard(mutex)(&hdcp_work->mutex);
|
||||
|
||||
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX;
|
||||
conn_index++) {
|
||||
@@ -408,8 +410,6 @@ static void event_property_validate(struct work_struct *work)
|
||||
schedule_work(&hdcp_work->property_update_work);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
}
|
||||
|
||||
static void event_watchdog_timer(struct work_struct *work)
|
||||
@@ -420,7 +420,7 @@ static void event_watchdog_timer(struct work_struct *work)
|
||||
struct hdcp_workqueue,
|
||||
watchdog_timer_dwork);
|
||||
|
||||
mutex_lock(&hdcp_work->mutex);
|
||||
guard(mutex)(&hdcp_work->mutex);
|
||||
|
||||
cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
|
||||
|
||||
@@ -429,8 +429,6 @@ static void event_watchdog_timer(struct work_struct *work)
|
||||
&hdcp_work->output);
|
||||
|
||||
process_output(hdcp_work);
|
||||
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
}
|
||||
|
||||
static void event_cpirq(struct work_struct *work)
|
||||
@@ -439,13 +437,11 @@ static void event_cpirq(struct work_struct *work)
|
||||
|
||||
hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
|
||||
|
||||
mutex_lock(&hdcp_work->mutex);
|
||||
guard(mutex)(&hdcp_work->mutex);
|
||||
|
||||
mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
|
||||
|
||||
process_output(hdcp_work);
|
||||
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
}
|
||||
|
||||
void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
||||
@@ -479,7 +475,7 @@ static bool enable_assr(void *handle, struct dc_link *link)
|
||||
|
||||
dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
|
||||
|
||||
mutex_lock(&psp->dtm_context.mutex);
|
||||
guard(mutex)(&psp->dtm_context.mutex);
|
||||
memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
|
||||
|
||||
dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
|
||||
@@ -494,8 +490,6 @@ static bool enable_assr(void *handle, struct dc_link *link)
|
||||
res = false;
|
||||
}
|
||||
|
||||
mutex_unlock(&psp->dtm_context.mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -504,6 +498,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
||||
struct hdcp_workqueue *hdcp_work = handle;
|
||||
struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
|
||||
int link_index = aconnector->dc_link->link_index;
|
||||
unsigned int conn_index = aconnector->base.index;
|
||||
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
|
||||
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
|
||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
||||
@@ -557,13 +552,14 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
||||
(!!aconnector->base.state) ?
|
||||
aconnector->base.state->hdcp_content_type : -1);
|
||||
|
||||
mutex_lock(&hdcp_w->mutex);
|
||||
guard(mutex)(&hdcp_w->mutex);
|
||||
|
||||
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
|
||||
|
||||
drm_connector_get(&aconnector->base);
|
||||
if (hdcp_w->aconnector[conn_index])
|
||||
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||
hdcp_w->aconnector[conn_index] = aconnector;
|
||||
process_output(hdcp_w);
|
||||
mutex_unlock(&hdcp_w->mutex);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -938,6 +938,10 @@ void drm_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
struct drm_file *file = f->private_data;
|
||||
struct drm_device *dev = file->minor->dev;
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
int idx;
|
||||
|
||||
if (!drm_dev_enter(dev, &idx))
|
||||
return;
|
||||
|
||||
drm_printf(&p, "drm-driver:\t%s\n", dev->driver->name);
|
||||
drm_printf(&p, "drm-client-id:\t%llu\n", file->client_id);
|
||||
@@ -952,6 +956,8 @@ void drm_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
|
||||
if (dev->driver->show_fdinfo)
|
||||
dev->driver->show_fdinfo(&p, file);
|
||||
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_show_fdinfo);
|
||||
|
||||
|
||||
@@ -404,12 +404,16 @@ static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev)
|
||||
u16 height = drm->mode_config.min_height;
|
||||
u16 width = drm->mode_config.min_width;
|
||||
struct mipi_dbi *dbi = &dbidev->dbi;
|
||||
size_t len = width * height * 2;
|
||||
const struct drm_format_info *dst_format;
|
||||
size_t len;
|
||||
int idx;
|
||||
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return;
|
||||
|
||||
dst_format = drm_format_info(dbidev->pixel_format);
|
||||
len = drm_format_info_min_pitch(dst_format, 0, width) * height;
|
||||
|
||||
memset(dbidev->tx_buf, 0, len);
|
||||
|
||||
mipi_dbi_set_window_address(dbidev, 0, width - 1, 0, height - 1);
|
||||
|
||||
@@ -23,6 +23,7 @@ int intel_pxp_gsccs_init(struct intel_pxp *pxp);
|
||||
|
||||
int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id);
|
||||
void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
|
||||
bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
|
||||
|
||||
#else
|
||||
static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
|
||||
@@ -34,8 +35,11 @@ static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
|
||||
|
||||
#endif /*__INTEL_PXP_GSCCS_H__ */
|
||||
|
||||
@@ -790,13 +790,13 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
FREQ_1000_1001(params[i].pixel_freq));
|
||||
DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
|
||||
i, params[i].phy_freq,
|
||||
FREQ_1000_1001(params[i].phy_freq/1000)*1000);
|
||||
FREQ_1000_1001(params[i].phy_freq/10)*10);
|
||||
/* Match strict frequency */
|
||||
if (phy_freq == params[i].phy_freq &&
|
||||
vclk_freq == params[i].vclk_freq)
|
||||
return MODE_OK;
|
||||
/* Match 1000/1001 variant */
|
||||
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) &&
|
||||
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
|
||||
vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
|
||||
return MODE_OK;
|
||||
}
|
||||
@@ -1070,7 +1070,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
|
||||
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
|
||||
if ((phy_freq == params[freq].phy_freq ||
|
||||
phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) &&
|
||||
phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
|
||||
(vclk_freq == params[freq].vclk_freq ||
|
||||
vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
|
||||
if (vclk_freq != params[freq].vclk_freq)
|
||||
|
||||
@@ -90,7 +90,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
|
||||
while (!list_empty(&fctx->pending)) {
|
||||
fence = list_entry(fctx->pending.next, typeof(*fence), head);
|
||||
|
||||
if (error)
|
||||
if (error && !dma_fence_is_signaled_locked(&fence->base))
|
||||
dma_fence_set_error(&fence->base, error);
|
||||
|
||||
if (nouveau_fence_signal(fence))
|
||||
|
||||
@@ -216,6 +216,9 @@ static void drm_gem_shmem_test_get_pages_sgt(struct kunit *test)
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt);
|
||||
KUNIT_EXPECT_NULL(test, shmem->sgt);
|
||||
|
||||
ret = kunit_add_action_or_reset(test, kfree_wrapper, sgt);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
ret = kunit_add_action_or_reset(test, sg_free_table_wrapper, sgt);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
|
||||
@@ -381,12 +381,6 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
|
||||
blit_cctl_val,
|
||||
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
|
||||
},
|
||||
/* Use Fixed slice CCS mode */
|
||||
{ XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"),
|
||||
XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)),
|
||||
XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE,
|
||||
RCU_MODE_FIXED_SLICE_CCS_MODE))
|
||||
},
|
||||
/* Disable WMTP if HW doesn't support it */
|
||||
{ XE_RTP_NAME("DISABLE_WMTP_ON_UNSUPPORTED_HW"),
|
||||
XE_RTP_RULES(FUNC(xe_rtp_cfeg_wmtp_disabled)),
|
||||
@@ -454,6 +448,12 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
|
||||
XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ,
|
||||
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
|
||||
},
|
||||
/* Use Fixed slice CCS mode */
|
||||
{ XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"),
|
||||
XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)),
|
||||
XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE,
|
||||
RCU_MODE_FIXED_SLICE_CCS_MODE))
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -652,9 +652,9 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
rpm_disable:
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3655,6 +3655,14 @@ found:
|
||||
while (*uid == '0' && *(uid + 1))
|
||||
uid++;
|
||||
|
||||
if (strlen(hid) >= ACPIHID_HID_LEN) {
|
||||
pr_err("Invalid command line: hid is too long\n");
|
||||
return 1;
|
||||
} else if (strlen(uid) >= ACPIHID_UID_LEN) {
|
||||
pr_err("Invalid command line: uid is too long\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = early_acpihid_map_size++;
|
||||
memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
|
||||
memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
|
||||
|
||||
@@ -397,6 +397,12 @@ struct iommu_domain *arm_smmu_sva_domain_alloc(struct device *dev,
|
||||
return ERR_CAST(smmu_domain);
|
||||
smmu_domain->domain.type = IOMMU_DOMAIN_SVA;
|
||||
smmu_domain->domain.ops = &arm_smmu_sva_domain_ops;
|
||||
|
||||
/*
|
||||
* Choose page_size as the leaf page size for invalidation when
|
||||
* ARM_SMMU_FEAT_RANGE_INV is present
|
||||
*/
|
||||
smmu_domain->domain.pgsize_bitmap = PAGE_SIZE;
|
||||
smmu_domain->smmu = smmu;
|
||||
|
||||
ret = xa_alloc(&arm_smmu_asid_xa, &asid, smmu_domain,
|
||||
|
||||
@@ -3006,6 +3006,7 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
||||
mutex_lock(&smmu->streams_mutex);
|
||||
for (i = 0; i < fwspec->num_ids; i++) {
|
||||
struct arm_smmu_stream *new_stream = &master->streams[i];
|
||||
struct rb_node *existing;
|
||||
u32 sid = fwspec->ids[i];
|
||||
|
||||
new_stream->id = sid;
|
||||
@@ -3016,10 +3017,20 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
||||
break;
|
||||
|
||||
/* Insert into SID tree */
|
||||
if (rb_find_add(&new_stream->node, &smmu->streams,
|
||||
arm_smmu_streams_cmp_node)) {
|
||||
dev_warn(master->dev, "stream %u already in tree\n",
|
||||
sid);
|
||||
existing = rb_find_add(&new_stream->node, &smmu->streams,
|
||||
arm_smmu_streams_cmp_node);
|
||||
if (existing) {
|
||||
struct arm_smmu_master *existing_master =
|
||||
rb_entry(existing, struct arm_smmu_stream, node)
|
||||
->master;
|
||||
|
||||
/* Bridged PCI devices may end up with duplicated IDs */
|
||||
if (existing_master == master)
|
||||
continue;
|
||||
|
||||
dev_warn(master->dev,
|
||||
"stream %u already in tree from dev %s\n", sid,
|
||||
dev_name(existing_master->dev));
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4666,6 +4666,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
|
||||
|
||||
/* QM57/QS57 integrated gfx malfunctions with dmar */
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_iommu_igfx);
|
||||
|
||||
/* Broadwell igfx malfunctions with dmar */
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
|
||||
@@ -4743,7 +4746,6 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
|
||||
|
||||
|
||||
@@ -227,6 +227,9 @@ static int qcom_mpm_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pin == GPIO_NO_WAKE_IRQ)
|
||||
return irq_domain_disconnect_hierarchy(domain, virq);
|
||||
|
||||
ret = irq_domain_set_hwirq_and_chip(domain, virq, pin,
|
||||
&qcom_mpm_chip, priv);
|
||||
if (ret)
|
||||
|
||||
@@ -5173,7 +5173,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
|
||||
BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
|
||||
BUG_ON(!list_empty(&ic->wait_list));
|
||||
|
||||
if (ic->mode == 'B')
|
||||
if (ic->mode == 'B' && ic->bitmap_flush_work.work.func)
|
||||
cancel_delayed_work_sync(&ic->bitmap_flush_work);
|
||||
if (ic->metadata_wq)
|
||||
destroy_workqueue(ic->metadata_wq);
|
||||
|
||||
@@ -523,8 +523,9 @@ static char **realloc_argv(unsigned int *size, char **old_argv)
|
||||
gfp = GFP_NOIO;
|
||||
}
|
||||
argv = kmalloc_array(new_size, sizeof(*argv), gfp);
|
||||
if (argv && old_argv) {
|
||||
memcpy(argv, old_argv, *size * sizeof(*argv));
|
||||
if (argv) {
|
||||
if (old_argv)
|
||||
memcpy(argv, old_argv, *size * sizeof(*argv));
|
||||
*size = new_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -1112,26 +1112,26 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
num_irqs = platform_irq_count(pdev);
|
||||
if (num_irqs < 0) {
|
||||
ret = num_irqs;
|
||||
goto eirq;
|
||||
goto edisclk;
|
||||
}
|
||||
|
||||
/* There must be at least one IRQ source */
|
||||
if (!num_irqs) {
|
||||
ret = -ENXIO;
|
||||
goto eirq;
|
||||
goto edisclk;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_irqs; i++) {
|
||||
irq = platform_get_irq(pdev, i);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
goto eirq;
|
||||
goto edisclk;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq, 0,
|
||||
dev_name(&pdev->dev), host);
|
||||
if (ret)
|
||||
goto eirq;
|
||||
goto edisclk;
|
||||
}
|
||||
|
||||
ret = tmio_mmc_host_probe(host);
|
||||
@@ -1143,8 +1143,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
|
||||
return ret;
|
||||
|
||||
eirq:
|
||||
tmio_mmc_host_remove(host);
|
||||
edisclk:
|
||||
renesas_sdhi_clk_disable(host);
|
||||
efree:
|
||||
|
||||
@@ -1543,7 +1543,7 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
|
||||
struct tc_taprio_qopt_offload *taprio;
|
||||
struct ocelot_port *ocelot_port;
|
||||
struct timespec64 base_ts;
|
||||
int port;
|
||||
int i, port;
|
||||
u32 val;
|
||||
|
||||
mutex_lock(&ocelot->fwd_domain_lock);
|
||||
@@ -1575,6 +1575,9 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
|
||||
QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M,
|
||||
QSYS_PARAM_CFG_REG_3);
|
||||
|
||||
for (i = 0; i < taprio->num_entries; i++)
|
||||
vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]);
|
||||
|
||||
ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
|
||||
QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
|
||||
QSYS_TAS_PARAM_CFG_CTRL);
|
||||
|
||||
@@ -172,34 +172,31 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf,
|
||||
return padev;
|
||||
}
|
||||
|
||||
int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
|
||||
void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf,
|
||||
struct pds_auxiliary_dev **pd_ptr)
|
||||
{
|
||||
struct pds_auxiliary_dev *padev;
|
||||
int err = 0;
|
||||
|
||||
if (!cf)
|
||||
return -ENODEV;
|
||||
if (!*pd_ptr)
|
||||
return;
|
||||
|
||||
mutex_lock(&pf->config_lock);
|
||||
|
||||
padev = pf->vfs[cf->vf_id].padev;
|
||||
if (padev) {
|
||||
pds_client_unregister(pf, padev->client_id);
|
||||
auxiliary_device_delete(&padev->aux_dev);
|
||||
auxiliary_device_uninit(&padev->aux_dev);
|
||||
padev->client_id = 0;
|
||||
}
|
||||
pf->vfs[cf->vf_id].padev = NULL;
|
||||
padev = *pd_ptr;
|
||||
pds_client_unregister(pf, padev->client_id);
|
||||
auxiliary_device_delete(&padev->aux_dev);
|
||||
auxiliary_device_uninit(&padev->aux_dev);
|
||||
*pd_ptr = NULL;
|
||||
|
||||
mutex_unlock(&pf->config_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
|
||||
int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf,
|
||||
enum pds_core_vif_types vt,
|
||||
struct pds_auxiliary_dev **pd_ptr)
|
||||
{
|
||||
struct pds_auxiliary_dev *padev;
|
||||
char devname[PDS_DEVNAME_LEN];
|
||||
enum pds_core_vif_types vt;
|
||||
unsigned long mask;
|
||||
u16 vt_support;
|
||||
int client_id;
|
||||
@@ -208,6 +205,9 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
|
||||
if (!cf)
|
||||
return -ENODEV;
|
||||
|
||||
if (vt >= PDS_DEV_TYPE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pf->config_lock);
|
||||
|
||||
mask = BIT_ULL(PDSC_S_FW_DEAD) |
|
||||
@@ -219,17 +219,10 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* We only support vDPA so far, so it is the only one to
|
||||
* be verified that it is available in the Core device and
|
||||
* enabled in the devlink param. In the future this might
|
||||
* become a loop for several VIF types.
|
||||
*/
|
||||
|
||||
/* Verify that the type is supported and enabled. It is not
|
||||
* an error if there is no auxbus device support for this
|
||||
* VF, it just means something else needs to happen with it.
|
||||
*/
|
||||
vt = PDS_DEV_TYPE_VDPA;
|
||||
vt_support = !!le16_to_cpu(pf->dev_ident.vif_types[vt]);
|
||||
if (!(vt_support &&
|
||||
pf->viftype_status[vt].supported &&
|
||||
@@ -255,7 +248,7 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
|
||||
err = PTR_ERR(padev);
|
||||
goto out_unlock;
|
||||
}
|
||||
pf->vfs[cf->vf_id].padev = padev;
|
||||
*pd_ptr = padev;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&pf->config_lock);
|
||||
|
||||
@@ -303,8 +303,11 @@ void pdsc_health_thread(struct work_struct *work);
|
||||
int pdsc_register_notify(struct notifier_block *nb);
|
||||
void pdsc_unregister_notify(struct notifier_block *nb);
|
||||
void pdsc_notify(unsigned long event, void *data);
|
||||
int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf);
|
||||
int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf);
|
||||
int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf,
|
||||
enum pds_core_vif_types vt,
|
||||
struct pds_auxiliary_dev **pd_ptr);
|
||||
void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf,
|
||||
struct pds_auxiliary_dev **pd_ptr);
|
||||
|
||||
void pdsc_process_adminq(struct pdsc_qcq *qcq);
|
||||
void pdsc_work_thread(struct work_struct *work);
|
||||
|
||||
@@ -56,8 +56,11 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id,
|
||||
for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) {
|
||||
struct pdsc *vf = pdsc->vfs[vf_id].vf;
|
||||
|
||||
err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) :
|
||||
pdsc_auxbus_dev_del(vf, pdsc);
|
||||
if (ctx->val.vbool)
|
||||
err = pdsc_auxbus_dev_add(vf, pdsc, vt_entry->vif_id,
|
||||
&pdsc->vfs[vf_id].padev);
|
||||
else
|
||||
pdsc_auxbus_dev_del(vf, pdsc, &pdsc->vfs[vf_id].padev);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
@@ -190,7 +190,8 @@ static int pdsc_init_vf(struct pdsc *vf)
|
||||
devl_unlock(dl);
|
||||
|
||||
pf->vfs[vf->vf_id].vf = vf;
|
||||
err = pdsc_auxbus_dev_add(vf, pf);
|
||||
err = pdsc_auxbus_dev_add(vf, pf, PDS_DEV_TYPE_VDPA,
|
||||
&pf->vfs[vf->vf_id].padev);
|
||||
if (err) {
|
||||
devl_lock(dl);
|
||||
devl_unregister(dl);
|
||||
@@ -417,7 +418,7 @@ static void pdsc_remove(struct pci_dev *pdev)
|
||||
|
||||
pf = pdsc_get_pf_struct(pdsc->pdev);
|
||||
if (!IS_ERR(pf)) {
|
||||
pdsc_auxbus_dev_del(pdsc, pf);
|
||||
pdsc_auxbus_dev_del(pdsc, pf, &pf->vfs[pdsc->vf_id].padev);
|
||||
pf->vfs[pdsc->vf_id].vf = NULL;
|
||||
}
|
||||
} else {
|
||||
@@ -482,7 +483,8 @@ static void pdsc_reset_prepare(struct pci_dev *pdev)
|
||||
|
||||
pf = pdsc_get_pf_struct(pdsc->pdev);
|
||||
if (!IS_ERR(pf))
|
||||
pdsc_auxbus_dev_del(pdsc, pf);
|
||||
pdsc_auxbus_dev_del(pdsc, pf,
|
||||
&pf->vfs[pdsc->vf_id].padev);
|
||||
}
|
||||
|
||||
pdsc_unmap_bars(pdsc);
|
||||
@@ -527,7 +529,8 @@ static void pdsc_reset_done(struct pci_dev *pdev)
|
||||
|
||||
pf = pdsc_get_pf_struct(pdsc->pdev);
|
||||
if (!IS_ERR(pf))
|
||||
pdsc_auxbus_dev_add(pdsc, pf);
|
||||
pdsc_auxbus_dev_add(pdsc, pf, PDS_DEV_TYPE_VDPA,
|
||||
&pf->vfs[pdsc->vf_id].padev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -373,8 +373,13 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
|
||||
}
|
||||
|
||||
/* Set up the header page info */
|
||||
xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa,
|
||||
XGBE_SKB_ALLOC_SIZE);
|
||||
if (pdata->netdev->features & NETIF_F_RXCSUM) {
|
||||
xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa,
|
||||
XGBE_SKB_ALLOC_SIZE);
|
||||
} else {
|
||||
xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa,
|
||||
pdata->rx_buf_size);
|
||||
}
|
||||
|
||||
/* Set up the buffer page info */
|
||||
xgbe_set_buffer_data(&rdata->rx.buf, &ring->rx_buf_pa,
|
||||
|
||||
@@ -320,6 +320,18 @@ static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata)
|
||||
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE);
|
||||
}
|
||||
|
||||
static void xgbe_disable_sph_mode(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < pdata->channel_count; i++) {
|
||||
if (!pdata->channel[i]->rx_ring)
|
||||
break;
|
||||
|
||||
XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_CR, SPH, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int xgbe_write_rss_reg(struct xgbe_prv_data *pdata, unsigned int type,
|
||||
unsigned int index, unsigned int val)
|
||||
{
|
||||
@@ -3545,8 +3557,12 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
|
||||
xgbe_config_tx_coalesce(pdata);
|
||||
xgbe_config_rx_buffer_size(pdata);
|
||||
xgbe_config_tso_mode(pdata);
|
||||
xgbe_config_sph_mode(pdata);
|
||||
xgbe_config_rss(pdata);
|
||||
|
||||
if (pdata->netdev->features & NETIF_F_RXCSUM) {
|
||||
xgbe_config_sph_mode(pdata);
|
||||
xgbe_config_rss(pdata);
|
||||
}
|
||||
|
||||
desc_if->wrapper_tx_desc_init(pdata);
|
||||
desc_if->wrapper_rx_desc_init(pdata);
|
||||
xgbe_enable_dma_interrupts(pdata);
|
||||
@@ -3702,5 +3718,9 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
|
||||
hw_if->disable_vxlan = xgbe_disable_vxlan;
|
||||
hw_if->set_vxlan_id = xgbe_set_vxlan_id;
|
||||
|
||||
/* For Split Header*/
|
||||
hw_if->enable_sph = xgbe_config_sph_mode;
|
||||
hw_if->disable_sph = xgbe_disable_sph_mode;
|
||||
|
||||
DBGPR("<--xgbe_init_function_ptrs\n");
|
||||
}
|
||||
|
||||
@@ -2257,10 +2257,17 @@ static int xgbe_set_features(struct net_device *netdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((features & NETIF_F_RXCSUM) && !rxcsum)
|
||||
if ((features & NETIF_F_RXCSUM) && !rxcsum) {
|
||||
hw_if->enable_sph(pdata);
|
||||
hw_if->enable_vxlan(pdata);
|
||||
hw_if->enable_rx_csum(pdata);
|
||||
else if (!(features & NETIF_F_RXCSUM) && rxcsum)
|
||||
schedule_work(&pdata->restart_work);
|
||||
} else if (!(features & NETIF_F_RXCSUM) && rxcsum) {
|
||||
hw_if->disable_sph(pdata);
|
||||
hw_if->disable_vxlan(pdata);
|
||||
hw_if->disable_rx_csum(pdata);
|
||||
schedule_work(&pdata->restart_work);
|
||||
}
|
||||
|
||||
if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan)
|
||||
hw_if->enable_rx_vlan_stripping(pdata);
|
||||
|
||||
@@ -865,6 +865,10 @@ struct xgbe_hw_if {
|
||||
void (*enable_vxlan)(struct xgbe_prv_data *);
|
||||
void (*disable_vxlan)(struct xgbe_prv_data *);
|
||||
void (*set_vxlan_id)(struct xgbe_prv_data *);
|
||||
|
||||
/* For Split Header */
|
||||
void (*enable_sph)(struct xgbe_prv_data *pdata);
|
||||
void (*disable_sph)(struct xgbe_prv_data *pdata);
|
||||
};
|
||||
|
||||
/* This structure represents implementation specific routines for an
|
||||
|
||||
@@ -1986,6 +1986,7 @@ static struct sk_buff *bnxt_rx_vlan(struct sk_buff *skb, u8 cmp_type,
|
||||
}
|
||||
return skb;
|
||||
vlan_err:
|
||||
skb_mark_for_recycle(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -3320,6 +3321,9 @@ static void bnxt_free_tx_skbs(struct bnxt *bp)
|
||||
}
|
||||
netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i));
|
||||
}
|
||||
|
||||
if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
|
||||
bnxt_ptp_free_txts_skbs(bp->ptp_cfg);
|
||||
}
|
||||
|
||||
static void bnxt_free_one_rx_ring(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
|
||||
@@ -11076,6 +11080,9 @@ static void bnxt_init_napi(struct bnxt *bp)
|
||||
poll_fn = bnxt_poll_p5;
|
||||
else if (BNXT_CHIP_TYPE_NITRO_A0(bp))
|
||||
cp_nr_rings--;
|
||||
|
||||
set_bit(BNXT_STATE_NAPI_DISABLED, &bp->state);
|
||||
|
||||
for (i = 0; i < cp_nr_rings; i++) {
|
||||
bnapi = bp->bnapi[i];
|
||||
netif_napi_add(bp->dev, &bnapi->napi, poll_fn);
|
||||
@@ -11844,13 +11851,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
|
||||
set_bit(BNXT_STATE_ABORT_ERR, &bp->state);
|
||||
return rc;
|
||||
}
|
||||
/* IRQ will be initialized later in bnxt_request_irq()*/
|
||||
bnxt_clear_int_mode(bp);
|
||||
rc = bnxt_init_int_mode(bp);
|
||||
if (rc) {
|
||||
clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state);
|
||||
netdev_err(bp->dev, "init int mode failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
rc = bnxt_cancel_reservations(bp, fw_reset);
|
||||
}
|
||||
@@ -12249,8 +12251,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
|
||||
/* VF-reps may need to be re-opened after the PF is re-opened */
|
||||
if (BNXT_PF(bp))
|
||||
bnxt_vf_reps_open(bp);
|
||||
if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
|
||||
WRITE_ONCE(bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS);
|
||||
bnxt_ptp_init_rtc(bp, true);
|
||||
bnxt_ptp_cfg_tstamp_filters(bp);
|
||||
if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
|
||||
@@ -15421,8 +15421,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
|
||||
|
||||
bnxt_rdma_aux_device_del(bp);
|
||||
|
||||
bnxt_ptp_clear(bp);
|
||||
unregister_netdev(dev);
|
||||
bnxt_ptp_clear(bp);
|
||||
|
||||
bnxt_rdma_aux_device_uninit(bp);
|
||||
|
||||
|
||||
@@ -66,20 +66,30 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
|
||||
}
|
||||
}
|
||||
|
||||
if (info->dest_buf) {
|
||||
if ((info->seg_start + off + len) <=
|
||||
BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
|
||||
memcpy(info->dest_buf + off, dma_buf, len);
|
||||
} else {
|
||||
rc = -ENOBUFS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmn_req->req_type ==
|
||||
cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE))
|
||||
info->dest_buf_size += len;
|
||||
|
||||
if (info->dest_buf) {
|
||||
if ((info->seg_start + off + len) <=
|
||||
BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
|
||||
u16 copylen = min_t(u16, len,
|
||||
info->dest_buf_size - off);
|
||||
|
||||
memcpy(info->dest_buf + off, dma_buf, copylen);
|
||||
if (copylen < len)
|
||||
break;
|
||||
} else {
|
||||
rc = -ENOBUFS;
|
||||
if (cmn_req->req_type ==
|
||||
cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) {
|
||||
kfree(info->dest_buf);
|
||||
info->dest_buf = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE))
|
||||
break;
|
||||
|
||||
|
||||
@@ -2041,6 +2041,17 @@ static int bnxt_get_regs_len(struct net_device *dev)
|
||||
return reg_len;
|
||||
}
|
||||
|
||||
#define BNXT_PCIE_32B_ENTRY(start, end) \
|
||||
{ offsetof(struct pcie_ctx_hw_stats, start), \
|
||||
offsetof(struct pcie_ctx_hw_stats, end) }
|
||||
|
||||
static const struct {
|
||||
u16 start;
|
||||
u16 end;
|
||||
} bnxt_pcie_32b_entries[] = {
|
||||
BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]),
|
||||
};
|
||||
|
||||
static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
|
||||
void *_p)
|
||||
{
|
||||
@@ -2072,12 +2083,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
|
||||
req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
|
||||
rc = hwrm_req_send(bp, req);
|
||||
if (!rc) {
|
||||
__le64 *src = (__le64 *)hw_pcie_stats;
|
||||
u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
|
||||
int i;
|
||||
u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN);
|
||||
u8 *src = (u8 *)hw_pcie_stats;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
|
||||
dst[i] = le64_to_cpu(src[i]);
|
||||
for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) {
|
||||
if (i >= bnxt_pcie_32b_entries[j].start &&
|
||||
i <= bnxt_pcie_32b_entries[j].end) {
|
||||
u32 *dst32 = (u32 *)(dst + i);
|
||||
|
||||
*dst32 = le32_to_cpu(*(__le32 *)(src + i));
|
||||
i += 4;
|
||||
if (i > bnxt_pcie_32b_entries[j].end &&
|
||||
j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1)
|
||||
j++;
|
||||
} else {
|
||||
u64 *dst64 = (u64 *)(dst + i);
|
||||
|
||||
*dst64 = le64_to_cpu(*(__le64 *)(src + i));
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
hwrm_req_drop(bp, req);
|
||||
}
|
||||
@@ -4848,6 +4874,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
|
||||
if (!bp->num_tests || !BNXT_PF(bp))
|
||||
return;
|
||||
|
||||
memset(buf, 0, sizeof(u64) * bp->num_tests);
|
||||
if (etest->flags & ETH_TEST_FL_OFFLINE &&
|
||||
bnxt_ulp_registered(bp->edev)) {
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
@@ -4855,7 +4882,6 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(u64) * bp->num_tests);
|
||||
if (!netif_running(dev)) {
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
return;
|
||||
|
||||
@@ -777,6 +777,27 @@ next_slot:
|
||||
return HZ;
|
||||
}
|
||||
|
||||
void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp)
|
||||
{
|
||||
struct bnxt_ptp_tx_req *txts_req;
|
||||
u16 cons = ptp->txts_cons;
|
||||
|
||||
/* make sure ptp aux worker finished with
|
||||
* possible BNXT_STATE_OPEN set
|
||||
*/
|
||||
ptp_cancel_worker_sync(ptp->ptp_clock);
|
||||
|
||||
ptp->tx_avail = BNXT_MAX_TX_TS;
|
||||
while (cons != ptp->txts_prod) {
|
||||
txts_req = &ptp->txts_req[cons];
|
||||
if (!IS_ERR_OR_NULL(txts_req->tx_skb))
|
||||
dev_kfree_skb_any(txts_req->tx_skb);
|
||||
cons = NEXT_TXTS(cons);
|
||||
}
|
||||
ptp->txts_cons = cons;
|
||||
ptp_schedule_worker(ptp->ptp_clock, 0);
|
||||
}
|
||||
|
||||
int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod)
|
||||
{
|
||||
spin_lock_bh(&ptp->ptp_tx_lock);
|
||||
@@ -1095,7 +1116,6 @@ out:
|
||||
void bnxt_ptp_clear(struct bnxt *bp)
|
||||
{
|
||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
||||
int i;
|
||||
|
||||
if (!ptp)
|
||||
return;
|
||||
@@ -1107,12 +1127,5 @@ void bnxt_ptp_clear(struct bnxt *bp)
|
||||
kfree(ptp->ptp_info.pin_config);
|
||||
ptp->ptp_info.pin_config = NULL;
|
||||
|
||||
for (i = 0; i < BNXT_MAX_TX_TS; i++) {
|
||||
if (ptp->txts_req[i].tx_skb) {
|
||||
dev_kfree_skb_any(ptp->txts_req[i].tx_skb);
|
||||
ptp->txts_req[i].tx_skb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bnxt_unmap_ptp_regs(bp);
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp);
|
||||
void bnxt_ptp_reapply_pps(struct bnxt *bp);
|
||||
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
|
||||
int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
|
||||
void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp);
|
||||
int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod);
|
||||
void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod);
|
||||
int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
|
||||
|
||||
@@ -352,7 +352,7 @@ parse_eeprom (struct net_device *dev)
|
||||
eth_hw_addr_set(dev, psrom->mac_addr);
|
||||
|
||||
if (np->chip_id == CHIP_IP1000A) {
|
||||
np->led_mode = psrom->led_mode;
|
||||
np->led_mode = le16_to_cpu(psrom->led_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -335,7 +335,7 @@ typedef struct t_SROM {
|
||||
u16 sub_system_id; /* 0x06 */
|
||||
u16 pci_base_1; /* 0x08 (IP1000A only) */
|
||||
u16 pci_base_2; /* 0x0a (IP1000A only) */
|
||||
u16 led_mode; /* 0x0c (IP1000A only) */
|
||||
__le16 led_mode; /* 0x0c (IP1000A only) */
|
||||
u16 reserved1[9]; /* 0x0e-0x1f */
|
||||
u8 mac_addr[6]; /* 0x20-0x25 */
|
||||
u8 reserved2[10]; /* 0x26-0x2f */
|
||||
|
||||
@@ -714,7 +714,12 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
|
||||
txq->bd.cur = bdp;
|
||||
|
||||
/* Trigger transmission start */
|
||||
writel(0, txq->bd.reg_desc_active);
|
||||
if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active))
|
||||
writel(0, txq->bd.reg_desc_active);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
|
||||
.name = "tm_qset",
|
||||
.cmd = HNAE3_DBG_CMD_TM_QSET,
|
||||
.dentry = HNS3_DBG_DENTRY_TM,
|
||||
.buf_len = HNS3_DBG_READ_LEN,
|
||||
.buf_len = HNS3_DBG_READ_LEN_1MB,
|
||||
.init = hns3_dbg_common_file_init,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -473,20 +473,14 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector,
|
||||
writel(mask_en, tqp_vector->mask_addr);
|
||||
}
|
||||
|
||||
static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector)
|
||||
static void hns3_irq_enable(struct hns3_enet_tqp_vector *tqp_vector)
|
||||
{
|
||||
napi_enable(&tqp_vector->napi);
|
||||
enable_irq(tqp_vector->vector_irq);
|
||||
|
||||
/* enable vector */
|
||||
hns3_mask_vector_irq(tqp_vector, 1);
|
||||
}
|
||||
|
||||
static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector)
|
||||
static void hns3_irq_disable(struct hns3_enet_tqp_vector *tqp_vector)
|
||||
{
|
||||
/* disable vector */
|
||||
hns3_mask_vector_irq(tqp_vector, 0);
|
||||
|
||||
disable_irq(tqp_vector->vector_irq);
|
||||
napi_disable(&tqp_vector->napi);
|
||||
cancel_work_sync(&tqp_vector->rx_group.dim.work);
|
||||
@@ -707,11 +701,42 @@ static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hns3_enable_irqs_and_tqps(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_irq_enable(&priv->tqp_vector[i]);
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_mask_vector_irq(&priv->tqp_vector[i], 1);
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
hns3_tqp_enable(h->kinfo.tqp[i]);
|
||||
}
|
||||
|
||||
static void hns3_disable_irqs_and_tqps(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
hns3_tqp_disable(h->kinfo.tqp[i]);
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_mask_vector_irq(&priv->tqp_vector[i], 0);
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_irq_disable(&priv->tqp_vector[i]);
|
||||
}
|
||||
|
||||
static int hns3_nic_net_up(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
ret = hns3_nic_reset_all_ring(h);
|
||||
@@ -720,23 +745,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
|
||||
|
||||
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
|
||||
|
||||
/* enable the vectors */
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_vector_enable(&priv->tqp_vector[i]);
|
||||
|
||||
/* enable rcb */
|
||||
for (j = 0; j < h->kinfo.num_tqps; j++)
|
||||
hns3_tqp_enable(h->kinfo.tqp[j]);
|
||||
hns3_enable_irqs_and_tqps(netdev);
|
||||
|
||||
/* start the ae_dev */
|
||||
ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0;
|
||||
if (ret) {
|
||||
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
|
||||
while (j--)
|
||||
hns3_tqp_disable(h->kinfo.tqp[j]);
|
||||
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
hns3_vector_disable(&priv->tqp_vector[j]);
|
||||
hns3_disable_irqs_and_tqps(netdev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -823,17 +838,9 @@ static void hns3_reset_tx_queue(struct hnae3_handle *h)
|
||||
static void hns3_nic_net_down(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||
const struct hnae3_ae_ops *ops;
|
||||
int i;
|
||||
|
||||
/* disable vectors */
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_vector_disable(&priv->tqp_vector[i]);
|
||||
|
||||
/* disable rcb */
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
hns3_tqp_disable(h->kinfo.tqp[i]);
|
||||
hns3_disable_irqs_and_tqps(netdev);
|
||||
|
||||
/* stop ae_dev */
|
||||
ops = priv->ae_handle->ae_algo->ops;
|
||||
@@ -5864,8 +5871,6 @@ int hns3_set_channels(struct net_device *netdev,
|
||||
void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int i;
|
||||
|
||||
if (!if_running)
|
||||
return;
|
||||
@@ -5876,11 +5881,7 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
|
||||
netif_carrier_off(ndev);
|
||||
netif_tx_disable(ndev);
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_vector_disable(&priv->tqp_vector[i]);
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
hns3_tqp_disable(h->kinfo.tqp[i]);
|
||||
hns3_disable_irqs_and_tqps(ndev);
|
||||
|
||||
/* delay ring buffer clearing to hns3_reset_notify_uninit_enet
|
||||
* during reset process, because driver may not be able
|
||||
@@ -5896,7 +5897,6 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int i;
|
||||
|
||||
if (!if_running)
|
||||
return;
|
||||
@@ -5912,11 +5912,7 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
|
||||
|
||||
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++)
|
||||
hns3_vector_enable(&priv->tqp_vector[i]);
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
hns3_tqp_enable(h->kinfo.tqp[i]);
|
||||
hns3_enable_irqs_and_tqps(ndev);
|
||||
|
||||
netif_tx_wake_all_queues(ndev);
|
||||
|
||||
|
||||
@@ -439,6 +439,13 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
|
||||
ptp->info.settime64 = hclge_ptp_settime;
|
||||
|
||||
ptp->info.n_alarm = 0;
|
||||
|
||||
spin_lock_init(&ptp->lock);
|
||||
ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
|
||||
ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
|
||||
hdev->ptp = ptp;
|
||||
|
||||
ptp->clock = ptp_clock_register(&ptp->info, &hdev->pdev->dev);
|
||||
if (IS_ERR(ptp->clock)) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
@@ -450,12 +457,6 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_init(&ptp->lock);
|
||||
ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
|
||||
ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
|
||||
hdev->ptp = ptp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1294,9 +1294,8 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev)
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
|
||||
static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
struct hclge_vf_to_pf_msg send_msg;
|
||||
|
||||
hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
|
||||
@@ -1305,6 +1304,19 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
|
||||
return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
|
||||
}
|
||||
|
||||
static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
int ret;
|
||||
|
||||
ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hdev->rxvtag_strip_en = enable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclgevf_reset_tqp(struct hnae3_handle *handle)
|
||||
{
|
||||
#define HCLGEVF_RESET_ALL_QUEUE_DONE 1U
|
||||
@@ -2206,12 +2218,13 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev)
|
||||
tc_valid, tc_size);
|
||||
}
|
||||
|
||||
static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev)
|
||||
static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev,
|
||||
bool rxvtag_strip_en)
|
||||
{
|
||||
struct hnae3_handle *nic = &hdev->nic;
|
||||
int ret;
|
||||
|
||||
ret = hclgevf_en_hw_strip_rxvtag(nic, true);
|
||||
ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to enable rx vlan offload, ret = %d\n", ret);
|
||||
@@ -2881,7 +2894,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclgevf_init_vlan_config(hdev);
|
||||
ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed(%d) to initialize VLAN config\n", ret);
|
||||
@@ -2996,7 +3009,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
||||
goto err_config;
|
||||
}
|
||||
|
||||
ret = hclgevf_init_vlan_config(hdev);
|
||||
ret = hclgevf_init_vlan_config(hdev, true);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed(%d) to initialize VLAN config\n", ret);
|
||||
|
||||
@@ -253,6 +253,7 @@ struct hclgevf_dev {
|
||||
int *vector_irq;
|
||||
|
||||
bool gro_en;
|
||||
bool rxvtag_strip_en;
|
||||
|
||||
unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
|
||||
|
||||
@@ -2091,6 +2091,11 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
|
||||
pf = vf->pf;
|
||||
dev = ice_pf_to_dev(pf);
|
||||
vf_vsi = ice_get_vf_vsi(vf);
|
||||
if (!vf_vsi) {
|
||||
dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
#define ICE_VF_MAX_FDIR_FILTERS 128
|
||||
if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) ||
|
||||
|
||||
@@ -629,13 +629,13 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all,
|
||||
VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 |\
|
||||
VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6)
|
||||
|
||||
#define IDPF_CAP_RX_CSUM_L4V4 (\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP)
|
||||
#define IDPF_CAP_TX_CSUM_L4V4 (\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP)
|
||||
|
||||
#define IDPF_CAP_RX_CSUM_L4V6 (\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP)
|
||||
#define IDPF_CAP_TX_CSUM_L4V6 (\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP)
|
||||
|
||||
#define IDPF_CAP_RX_CSUM (\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |\
|
||||
@@ -644,11 +644,9 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all,
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP)
|
||||
|
||||
#define IDPF_CAP_SCTP_CSUM (\
|
||||
#define IDPF_CAP_TX_SCTP_CSUM (\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |\
|
||||
VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP)
|
||||
VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP)
|
||||
|
||||
#define IDPF_CAP_TUNNEL_TX_CSUM (\
|
||||
VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL |\
|
||||
|
||||
@@ -703,8 +703,10 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
struct idpf_vport_config *vport_config;
|
||||
netdev_features_t other_offloads = 0;
|
||||
netdev_features_t csum_offloads = 0;
|
||||
netdev_features_t tso_offloads = 0;
|
||||
netdev_features_t dflt_features;
|
||||
netdev_features_t offloads = 0;
|
||||
struct idpf_netdev_priv *np;
|
||||
struct net_device *netdev;
|
||||
u16 idx = vport->idx;
|
||||
@@ -766,53 +768,32 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
|
||||
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS))
|
||||
dflt_features |= NETIF_F_RXHASH;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V4))
|
||||
dflt_features |= NETIF_F_IP_CSUM;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V6))
|
||||
dflt_features |= NETIF_F_IPV6_CSUM;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V4))
|
||||
csum_offloads |= NETIF_F_IP_CSUM;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V6))
|
||||
csum_offloads |= NETIF_F_IPV6_CSUM;
|
||||
if (idpf_is_cap_ena(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM))
|
||||
dflt_features |= NETIF_F_RXCSUM;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_SCTP_CSUM))
|
||||
dflt_features |= NETIF_F_SCTP_CRC;
|
||||
csum_offloads |= NETIF_F_RXCSUM;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_SCTP_CSUM))
|
||||
csum_offloads |= NETIF_F_SCTP_CRC;
|
||||
|
||||
if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV4_TCP))
|
||||
dflt_features |= NETIF_F_TSO;
|
||||
tso_offloads |= NETIF_F_TSO;
|
||||
if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV6_TCP))
|
||||
dflt_features |= NETIF_F_TSO6;
|
||||
tso_offloads |= NETIF_F_TSO6;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_SEG_CAPS,
|
||||
VIRTCHNL2_CAP_SEG_IPV4_UDP |
|
||||
VIRTCHNL2_CAP_SEG_IPV6_UDP))
|
||||
dflt_features |= NETIF_F_GSO_UDP_L4;
|
||||
tso_offloads |= NETIF_F_GSO_UDP_L4;
|
||||
if (idpf_is_cap_ena_all(adapter, IDPF_RSC_CAPS, IDPF_CAP_RSC))
|
||||
offloads |= NETIF_F_GRO_HW;
|
||||
/* advertise to stack only if offloads for encapsulated packets is
|
||||
* supported
|
||||
*/
|
||||
if (idpf_is_cap_ena(vport->adapter, IDPF_SEG_CAPS,
|
||||
VIRTCHNL2_CAP_SEG_TX_SINGLE_TUNNEL)) {
|
||||
offloads |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM |
|
||||
NETIF_F_GSO_PARTIAL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
||||
NETIF_F_GSO_IPXIP4 |
|
||||
NETIF_F_GSO_IPXIP6 |
|
||||
0;
|
||||
|
||||
if (!idpf_is_cap_ena_all(vport->adapter, IDPF_CSUM_CAPS,
|
||||
IDPF_CAP_TUNNEL_TX_CSUM))
|
||||
netdev->gso_partial_features |=
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
|
||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
|
||||
offloads |= NETIF_F_TSO_MANGLEID;
|
||||
}
|
||||
other_offloads |= NETIF_F_GRO_HW;
|
||||
if (idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_LOOPBACK))
|
||||
offloads |= NETIF_F_LOOPBACK;
|
||||
other_offloads |= NETIF_F_LOOPBACK;
|
||||
|
||||
netdev->features |= dflt_features;
|
||||
netdev->hw_features |= dflt_features | offloads;
|
||||
netdev->hw_enc_features |= dflt_features | offloads;
|
||||
netdev->features |= dflt_features | csum_offloads | tso_offloads;
|
||||
netdev->hw_features |= netdev->features | other_offloads;
|
||||
netdev->vlan_features |= netdev->features | other_offloads;
|
||||
netdev->hw_enc_features |= dflt_features | other_offloads;
|
||||
idpf_set_ethtool_ops(netdev);
|
||||
SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
|
||||
|
||||
@@ -1127,11 +1108,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
|
||||
num_max_q = max(max_q->max_txq, max_q->max_rxq);
|
||||
vport->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL);
|
||||
if (!vport->q_vector_idxs) {
|
||||
kfree(vport);
|
||||
if (!vport->q_vector_idxs)
|
||||
goto free_vport;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
idpf_vport_init(vport, max_q);
|
||||
|
||||
/* This alloc is done separate from the LUT because it's not strictly
|
||||
@@ -1141,11 +1120,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
*/
|
||||
rss_data = &adapter->vport_config[idx]->user_config.rss_data;
|
||||
rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL);
|
||||
if (!rss_data->rss_key) {
|
||||
kfree(vport);
|
||||
if (!rss_data->rss_key)
|
||||
goto free_vector_idxs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Initialize default rss key */
|
||||
netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size);
|
||||
|
||||
@@ -1158,6 +1135,13 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
adapter->next_vport = idpf_get_free_slot(adapter);
|
||||
|
||||
return vport;
|
||||
|
||||
free_vector_idxs:
|
||||
kfree(vport->q_vector_idxs);
|
||||
free_vport:
|
||||
kfree(vport);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -89,6 +89,7 @@ static void idpf_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct idpf_adapter *adapter = pci_get_drvdata(pdev);
|
||||
|
||||
cancel_delayed_work_sync(&adapter->serv_task);
|
||||
cancel_delayed_work_sync(&adapter->vc_event_task);
|
||||
idpf_vc_core_deinit(adapter);
|
||||
idpf_deinit_dflt_mbx(adapter);
|
||||
|
||||
@@ -1290,6 +1290,8 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
/* reset the tstamp_config */
|
||||
igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
|
||||
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
|
||||
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||
|
||||
switch (adapter->hw.mac.type) {
|
||||
@@ -1308,7 +1310,6 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
if (!igc_is_crosststamp_supported(adapter))
|
||||
break;
|
||||
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
|
||||
wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
|
||||
|
||||
@@ -1332,7 +1333,6 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
|
||||
|
||||
igc_ptm_reset(hw);
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
break;
|
||||
default:
|
||||
/* No work to do. */
|
||||
@@ -1349,5 +1349,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
out:
|
||||
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
||||
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
|
||||
wrfl();
|
||||
}
|
||||
|
||||
@@ -1184,7 +1184,7 @@ static void octep_hb_timeout_task(struct work_struct *work)
|
||||
miss_cnt);
|
||||
rtnl_lock();
|
||||
if (netif_running(oct->netdev))
|
||||
octep_stop(oct->netdev);
|
||||
dev_close(oct->netdev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -835,7 +835,9 @@ static void octep_vf_tx_timeout(struct net_device *netdev, unsigned int txqueue)
|
||||
struct octep_vf_device *oct = netdev_priv(netdev);
|
||||
|
||||
netdev_hold(netdev, NULL, GFP_ATOMIC);
|
||||
schedule_work(&oct->tx_timeout_task);
|
||||
if (!schedule_work(&oct->tx_timeout_task))
|
||||
netdev_put(netdev, NULL);
|
||||
|
||||
}
|
||||
|
||||
static int octep_vf_set_mac(struct net_device *netdev, void *p)
|
||||
|
||||
@@ -269,12 +269,8 @@ static const char * const mtk_clks_source_name[] = {
|
||||
"ethwarp_wocpu2",
|
||||
"ethwarp_wocpu1",
|
||||
"ethwarp_wocpu0",
|
||||
"top_usxgmii0_sel",
|
||||
"top_usxgmii1_sel",
|
||||
"top_sgm0_sel",
|
||||
"top_sgm1_sel",
|
||||
"top_xfi_phy0_xtal_sel",
|
||||
"top_xfi_phy1_xtal_sel",
|
||||
"top_eth_gmii_sel",
|
||||
"top_eth_refck_50m_sel",
|
||||
"top_eth_sys_200m_sel",
|
||||
@@ -2206,14 +2202,18 @@ skip_rx:
|
||||
ring->data[idx] = new_data;
|
||||
rxd->rxd1 = (unsigned int)dma_addr;
|
||||
release_desc:
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
|
||||
if (unlikely(dma_addr == DMA_MAPPING_ERROR))
|
||||
addr64 = FIELD_GET(RX_DMA_ADDR64_MASK,
|
||||
rxd->rxd2);
|
||||
else
|
||||
addr64 = RX_DMA_PREP_ADDR64(dma_addr);
|
||||
}
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
rxd->rxd2 = RX_DMA_LSO;
|
||||
else
|
||||
rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) &&
|
||||
likely(dma_addr != DMA_MAPPING_ERROR))
|
||||
rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
|
||||
rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size) | addr64;
|
||||
|
||||
ring->calc_idx = idx;
|
||||
done++;
|
||||
|
||||
@@ -1163,6 +1163,7 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
|
||||
struct net_device *ndev = priv->ndev;
|
||||
unsigned int head = ring->head;
|
||||
unsigned int entry = ring->tail;
|
||||
unsigned long flags;
|
||||
|
||||
while (entry != head && count < (MTK_STAR_RING_NUM_DESCS - 1)) {
|
||||
ret = mtk_star_tx_complete_one(priv);
|
||||
@@ -1182,9 +1183,9 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
|
||||
netif_wake_queue(ndev);
|
||||
|
||||
if (napi_complete(napi)) {
|
||||
spin_lock(&priv->lock);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
mtk_star_enable_dma_irq(priv, false, true);
|
||||
spin_unlock(&priv->lock);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1341,16 +1342,16 @@ push_new_skb:
|
||||
static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct mtk_star_priv *priv;
|
||||
unsigned long flags;
|
||||
int work_done = 0;
|
||||
|
||||
priv = container_of(napi, struct mtk_star_priv, rx_napi);
|
||||
|
||||
work_done = mtk_star_rx(priv, budget);
|
||||
if (work_done < budget) {
|
||||
napi_complete_done(napi, work_done);
|
||||
spin_lock(&priv->lock);
|
||||
if (work_done < budget && napi_complete_done(napi, work_done)) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
mtk_star_enable_dma_irq(priv, true, false);
|
||||
spin_unlock(&priv->lock);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return work_done;
|
||||
|
||||
@@ -177,6 +177,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
|
||||
|
||||
priv = ptpsq->txqsq.priv;
|
||||
|
||||
rtnl_lock();
|
||||
mutex_lock(&priv->state_lock);
|
||||
chs = &priv->channels;
|
||||
netdev = priv->netdev;
|
||||
@@ -184,22 +185,19 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
|
||||
carrier_ok = netif_carrier_ok(netdev);
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
rtnl_lock();
|
||||
mlx5e_deactivate_priv_channels(priv);
|
||||
rtnl_unlock();
|
||||
|
||||
mlx5e_ptp_close(chs->ptp);
|
||||
err = mlx5e_ptp_open(priv, &chs->params, chs->c[0]->lag_port, &chs->ptp);
|
||||
|
||||
rtnl_lock();
|
||||
mlx5e_activate_priv_channels(priv);
|
||||
rtnl_unlock();
|
||||
|
||||
/* return carrier back if needed */
|
||||
if (carrier_ok)
|
||||
netif_carrier_on(netdev);
|
||||
|
||||
mutex_unlock(&priv->state_lock);
|
||||
rtnl_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -165,9 +165,6 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
|
||||
struct flow_match_enc_keyid enc_keyid;
|
||||
void *misc_c, *misc_v;
|
||||
|
||||
misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters);
|
||||
misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters);
|
||||
|
||||
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
|
||||
return 0;
|
||||
|
||||
@@ -182,6 +179,30 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
|
||||
err = mlx5e_tc_tun_parse_vxlan_gbp_option(priv, spec, f);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* We can't mix custom tunnel headers with symbolic ones and we
|
||||
* don't have a symbolic field name for GBP, so we use custom
|
||||
* tunnel headers in this case. We need hardware support to
|
||||
* match on custom tunnel headers, but we already know it's
|
||||
* supported because the previous call successfully checked for
|
||||
* that.
|
||||
*/
|
||||
misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
|
||||
misc_parameters_5);
|
||||
misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
misc_parameters_5);
|
||||
|
||||
/* Shift by 8 to account for the reserved bits in the vxlan
|
||||
* header after the VNI.
|
||||
*/
|
||||
MLX5_SET(fte_match_set_misc5, misc_c, tunnel_header_1,
|
||||
be32_to_cpu(enc_keyid.mask->keyid) << 8);
|
||||
MLX5_SET(fte_match_set_misc5, misc_v, tunnel_header_1,
|
||||
be32_to_cpu(enc_keyid.key->keyid) << 8);
|
||||
|
||||
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* match on VNI is required */
|
||||
@@ -195,6 +216,11 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
|
||||
misc_parameters);
|
||||
misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
misc_parameters);
|
||||
|
||||
MLX5_SET(fte_match_set_misc, misc_c, vxlan_vni,
|
||||
be32_to_cpu(enc_keyid.mask->keyid));
|
||||
MLX5_SET(fte_match_set_misc, misc_v, vxlan_vni,
|
||||
|
||||
@@ -1750,9 +1750,6 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr
|
||||
!list_is_first(&attr->list, &flow->attrs))
|
||||
return 0;
|
||||
|
||||
if (flow_flag_test(flow, SLOW))
|
||||
return 0;
|
||||
|
||||
esw_attr = attr->esw_attr;
|
||||
if (!esw_attr->split_count ||
|
||||
esw_attr->split_count == esw_attr->out_count - 1)
|
||||
@@ -1766,7 +1763,7 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr
|
||||
for (i = esw_attr->split_count; i < esw_attr->out_count; i++) {
|
||||
/* external dest with encap is considered as internal by firmware */
|
||||
if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK &&
|
||||
!(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP_VALID))
|
||||
!(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP))
|
||||
ext_dest = true;
|
||||
else
|
||||
int_dest = true;
|
||||
|
||||
@@ -3514,7 +3514,9 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
|
||||
int err;
|
||||
|
||||
mutex_init(&esw->offloads.termtbl_mutex);
|
||||
mlx5_rdma_enable_roce(esw->dev);
|
||||
err = mlx5_rdma_enable_roce(esw->dev);
|
||||
if (err)
|
||||
goto err_roce;
|
||||
|
||||
err = mlx5_esw_host_number_init(esw);
|
||||
if (err)
|
||||
@@ -3575,6 +3577,7 @@ err_vport_metadata:
|
||||
esw_offloads_metadata_uninit(esw);
|
||||
err_metadata:
|
||||
mlx5_rdma_disable_roce(esw->dev);
|
||||
err_roce:
|
||||
mutex_destroy(&esw->offloads.termtbl_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *
|
||||
|
||||
static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
|
||||
{
|
||||
u8 mac[ETH_ALEN] = {};
|
||||
union ib_gid gid;
|
||||
u8 mac[ETH_ALEN];
|
||||
|
||||
mlx5_rdma_make_default_gid(dev, &gid);
|
||||
return mlx5_core_roce_gid_set(dev, 0,
|
||||
@@ -140,17 +140,17 @@ void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
|
||||
mlx5_nic_vport_disable_roce(dev);
|
||||
}
|
||||
|
||||
void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
|
||||
int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!MLX5_CAP_GEN(dev, roce))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
err = mlx5_nic_vport_enable_roce(dev);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mlx5_rdma_add_roce_addr(dev);
|
||||
@@ -165,10 +165,11 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
|
||||
goto del_roce_addr;
|
||||
}
|
||||
|
||||
return;
|
||||
return err;
|
||||
|
||||
del_roce_addr:
|
||||
mlx5_rdma_del_roce_addr(dev);
|
||||
disable_roce:
|
||||
mlx5_nic_vport_disable_roce(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#ifdef CONFIG_MLX5_ESWITCH
|
||||
|
||||
void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev);
|
||||
int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev);
|
||||
void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev);
|
||||
|
||||
#else /* CONFIG_MLX5_ESWITCH */
|
||||
|
||||
static inline void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) {}
|
||||
static inline int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) { return 0; }
|
||||
static inline void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) {}
|
||||
|
||||
#endif /* CONFIG_MLX5_ESWITCH */
|
||||
|
||||
@@ -1815,6 +1815,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
|
||||
if (nr_frags <= 0) {
|
||||
tx->frame_data0 |= TX_DESC_DATA0_LS_;
|
||||
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
||||
tx->frame_last = tx->frame_first;
|
||||
}
|
||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||
tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
|
||||
@@ -1884,6 +1885,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
|
||||
tx->frame_first = 0;
|
||||
tx->frame_data0 = 0;
|
||||
tx->frame_tail = 0;
|
||||
tx->frame_last = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -1924,16 +1926,18 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx,
|
||||
TX_DESC_DATA0_DTYPE_DATA_) {
|
||||
tx->frame_data0 |= TX_DESC_DATA0_LS_;
|
||||
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
||||
tx->frame_last = tx->frame_tail;
|
||||
}
|
||||
|
||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||
buffer_info = &tx->buffer_info[tx->frame_tail];
|
||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_last];
|
||||
buffer_info = &tx->buffer_info[tx->frame_last];
|
||||
buffer_info->skb = skb;
|
||||
if (time_stamp)
|
||||
buffer_info->flags |= TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED;
|
||||
if (ignore_sync)
|
||||
buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
|
||||
|
||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||
tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
|
||||
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
||||
tx->last_tail = tx->frame_tail;
|
||||
|
||||
@@ -980,6 +980,7 @@ struct lan743x_tx {
|
||||
u32 frame_first;
|
||||
u32 frame_data0;
|
||||
u32 frame_tail;
|
||||
u32 frame_last;
|
||||
|
||||
struct lan743x_tx_buffer_info *buffer_info;
|
||||
|
||||
|
||||
@@ -830,6 +830,7 @@ EXPORT_SYMBOL(ocelot_vlan_prepare);
|
||||
int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
|
||||
bool untagged)
|
||||
{
|
||||
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
||||
int err;
|
||||
|
||||
/* Ignore VID 0 added to our RX filter by the 8021q module, since
|
||||
@@ -849,6 +850,11 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
|
||||
ocelot_bridge_vlan_find(ocelot, vid));
|
||||
if (err)
|
||||
return err;
|
||||
} else if (ocelot_port->pvid_vlan &&
|
||||
ocelot_bridge_vlan_find(ocelot, vid) == ocelot_port->pvid_vlan) {
|
||||
err = ocelot_port_set_pvid(ocelot, port, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Untagged egress vlan clasification */
|
||||
|
||||
@@ -1924,8 +1924,8 @@ static u16 rtase_calc_time_mitigation(u32 time_us)
|
||||
|
||||
time_us = min_t(int, time_us, RTASE_MITI_MAX_TIME);
|
||||
|
||||
msb = fls(time_us);
|
||||
if (msb >= RTASE_MITI_COUNT_BIT_NUM) {
|
||||
if (time_us > RTASE_MITI_TIME_COUNT_MASK) {
|
||||
msb = fls(time_us);
|
||||
time_unit = msb - RTASE_MITI_COUNT_BIT_NUM;
|
||||
time_count = time_us >> (msb - RTASE_MITI_COUNT_BIT_NUM);
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -33,7 +34,7 @@
|
||||
#define CMD_CTR (0x2 << CMD_SHIFT)
|
||||
|
||||
#define CMD_MASK GENMASK(15, CMD_SHIFT)
|
||||
#define LEN_MASK GENMASK(CMD_SHIFT - 1, 0)
|
||||
#define LEN_MASK GENMASK(CMD_SHIFT - 2, 0)
|
||||
|
||||
#define DET_CMD_LEN 4
|
||||
#define DET_SOF_LEN 2
|
||||
@@ -262,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp,
|
||||
}
|
||||
|
||||
static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
|
||||
unsigned int frame_len)
|
||||
unsigned int frame_len, bool drop)
|
||||
{
|
||||
struct mse102x_net_spi *mses = to_mse102x_spi(mse);
|
||||
struct spi_transfer *xfer = &mses->spi_xfer;
|
||||
@@ -280,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
|
||||
netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",
|
||||
__func__, ret);
|
||||
mse->stats.xfer_err++;
|
||||
} else if (drop) {
|
||||
netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__);
|
||||
ret = -EINVAL;
|
||||
} else if (*sof != cpu_to_be16(DET_SOF)) {
|
||||
netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",
|
||||
__func__, *sof);
|
||||
@@ -307,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
|
||||
struct sk_buff *skb;
|
||||
unsigned int rxalign;
|
||||
unsigned int rxlen;
|
||||
bool drop = false;
|
||||
__be16 rx = 0;
|
||||
u16 cmd_resp;
|
||||
u8 *rxpkt;
|
||||
@@ -329,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
|
||||
net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",
|
||||
__func__, cmd_resp);
|
||||
mse->stats.invalid_rts++;
|
||||
return;
|
||||
drop = true;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
net_dbg_ratelimited("%s: Unexpected response to first CMD\n",
|
||||
@@ -337,12 +343,20 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
|
||||
}
|
||||
|
||||
rxlen = cmd_resp & LEN_MASK;
|
||||
if (!rxlen) {
|
||||
net_dbg_ratelimited("%s: No frame length defined\n", __func__);
|
||||
if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) {
|
||||
net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
|
||||
rxlen);
|
||||
mse->stats.invalid_len++;
|
||||
return;
|
||||
drop = true;
|
||||
}
|
||||
|
||||
/* In case of a invalid CMD_RTS, the frame must be consumed anyway.
|
||||
* So assume the maximum possible frame length.
|
||||
*/
|
||||
drop:
|
||||
if (drop)
|
||||
rxlen = VLAN_ETH_FRAME_LEN;
|
||||
|
||||
rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
|
||||
skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
|
||||
if (!skb)
|
||||
@@ -353,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
|
||||
* They are copied, but ignored.
|
||||
*/
|
||||
rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;
|
||||
if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) {
|
||||
if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) {
|
||||
mse->ndev->stats.rx_errors++;
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
@@ -509,6 +523,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse)
|
||||
static int mse102x_net_open(struct net_device *ndev)
|
||||
{
|
||||
struct mse102x_net *mse = netdev_priv(ndev);
|
||||
struct mse102x_net_spi *mses = to_mse102x_spi(mse);
|
||||
int ret;
|
||||
|
||||
ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,
|
||||
@@ -524,6 +539,13 @@ static int mse102x_net_open(struct net_device *ndev)
|
||||
|
||||
netif_carrier_on(ndev);
|
||||
|
||||
/* The SPI interrupt can stuck in case of pending packet(s).
|
||||
* So poll for possible packet(s) to re-arm the interrupt.
|
||||
*/
|
||||
mutex_lock(&mses->lock);
|
||||
mse102x_rx_pkt_spi(mse);
|
||||
mutex_unlock(&mses->lock);
|
||||
|
||||
netif_dbg(mse, ifup, ndev, "network device up\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define REG2_LEDACT GENMASK(23, 22)
|
||||
#define REG2_LEDLINK GENMASK(25, 24)
|
||||
#define REG2_DIV4SEL BIT(27)
|
||||
#define REG2_REVERSED BIT(28)
|
||||
#define REG2_ADCBYPASS BIT(30)
|
||||
#define REG2_CLKINSEL BIT(31)
|
||||
#define ETH_REG3 0x4
|
||||
@@ -65,7 +66,7 @@ static void gxl_enable_internal_mdio(struct gxl_mdio_mux *priv)
|
||||
* The only constraint is that it must match the one in
|
||||
* drivers/net/phy/meson-gxl.c to properly match the PHY.
|
||||
*/
|
||||
writel(FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
|
||||
writel(REG2_REVERSED | FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
|
||||
priv->regs + ETH_REG2);
|
||||
|
||||
/* Enable the internal phy */
|
||||
|
||||
@@ -630,16 +630,6 @@ static const struct driver_info zte_rndis_info = {
|
||||
.tx_fixup = rndis_tx_fixup,
|
||||
};
|
||||
|
||||
static const struct driver_info wwan_rndis_info = {
|
||||
.description = "Mobile Broadband RNDIS device",
|
||||
.flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
|
||||
.bind = rndis_bind,
|
||||
.unbind = rndis_unbind,
|
||||
.status = rndis_status,
|
||||
.rx_fixup = rndis_rx_fixup,
|
||||
.tx_fixup = rndis_tx_fixup,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static const struct usb_device_id products [] = {
|
||||
@@ -676,11 +666,9 @@ static const struct usb_device_id products [] = {
|
||||
USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
|
||||
.driver_info = (unsigned long) &rndis_info,
|
||||
}, {
|
||||
/* Mobile Broadband Modem, seen in Novatel Verizon USB730L and
|
||||
* Telit FN990A (RNDIS)
|
||||
*/
|
||||
/* Novatel Verizon USB730L */
|
||||
USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
|
||||
.driver_info = (unsigned long)&wwan_rndis_info,
|
||||
.driver_info = (unsigned long) &rndis_info,
|
||||
},
|
||||
{ }, // END
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user