Merge remote-tracking branch 'sm8350/lineage-20' into lineage-23.2

* sm8350/lineage-20: (306 commits)
  ANDROID: gki_defconfig: reduce KFENCE pool size
  ANDROID: GKI: enable KFENCE by setting the sample interval to 500ms
  ANDROID: GKI: Enable KFENCE
  UPSTREAM: random: split initialization into early step and later step
  UPSTREAM: kfence: avoid passing -g for test
  UPSTREAM: net: add and use skb_unclone_keeptruesize() helper
  UPSTREAM: kfence: fix memory leak when cat kfence objects
  UPSTREAM: kfence: unconditionally use unbound work queue
  UPSTREAM: kfence: use TASK_IDLE when awaiting allocation
  UPSTREAM: kfence: fix is_kfence_address() for addresses below KFENCE_POOL_SIZE
  FROMLIST: kfence: skip all GFP_ZONEMASK allocations
  FROMLIST: kfence: move the size check to the beginning of __kfence_alloc()
  ANDROID: kasan: fix interoperability with KFENCE
  UPSTREAM: arm64: mm: don't use CON and BLK mapping if KFENCE is enabled
  ANDROID: kfence: clean up unused variables
  FROMGIT: kfence: use power-efficient work queue to run delayed work
  FROMGIT: kfence: maximize allocation wait timeout duration
  FROMGIT: kfence: await for allocation using wait_event
  FROMGIT: kfence: zero guard page after out-of-bounds access
  UPSTREAM: kfence: make compatible with kmemleak
  ...

Change-Id: Id1436b77692839dc2394f500bba42487fac1b2b4
This commit is contained in:
Michael Bestas 2026-05-07 18:19:43 +03:00
commit 376925d57f
No known key found for this signature in database
209 changed files with 10117 additions and 1291 deletions

View file

@ -265,6 +265,71 @@ Description: Specific uncompressed frame descriptors
bmCapabilities - still image support, fixed frame-rate
support
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased
Date: Oct 2025
KernelVersion: 5.4
Description: Framebased format descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name
Date: Oct 2025
KernelVersion: 5.4
Description: Specific framebased format descriptors
================== =======================================
bFormatIndex unique id for this format descriptor;
only defined after parent header is
linked into the streaming class;
read-only
bmaControls this format's data for bmaControls in
the streaming header
bmInterlaceFlags specifies interlace information,
read-only
bAspectRatioY the X dimension of the picture aspect
ratio, read-only
bAspectRatioX the Y dimension of the picture aspect
ratio, read-only
bDefaultFrameIndex optimum frame index for this stream
bBitsPerPixel number of bits per pixel used to
specify color in the decoded video
frame
guidFormat globally unique id used to identify
stream-encoding format
================== =======================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name/name
Date: Sept 2024
KernelVersion: 5.15
Description: Specific framebased frame descriptors
========================= =====================================
bFrameIndex unique id for this framedescriptor;
only defined after parent format is
linked into the streaming header;
read-only
dwFrameInterval indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
dwDefaultFrameInterval the frame interval the device would
like to use as default
dwBytesPerLine Specifies the number of bytes per line
of video for packed fixed frame size
formats, allowing the receiver to
perform stride alignment of the video.
If the bVariableSize value (above) is
TRUE (1), or if the format does not
permit such alignment, this value shall
be set to zero (0).
dwMaxBitRate the maximum bit rate at the shortest
frame interval in bps
dwMinBitRate the minimum bit rate at the longest
frame interval in bps
wHeight height of decoded bitmap frame in px
wWidth width of decoded bitmam frame in px
bmCapabilities still image support, fixed frame-rate
support
========================= =====================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
Date: Dec 2014
KernelVersion: 4.0

View file

@ -3187,6 +3187,21 @@
in certain environments such as networked servers or
real-time systems.
no_hash_pointers
Force pointers printed to the console or buffers to be
unhashed. By default, when a pointer is printed via %p
format string, that pointer is "hashed", i.e. obscured
by hashing the pointer value. This is a security feature
that hides actual kernel addresses from unprivileged
users, but it also makes debugging the kernel more
difficult since unequal pointers can no longer be
compared. However, if this command-line option is
specified, then all normal pointers will have their true
value printed. Pointers printed via %pK may still be
hashed. This option should only be specified when
debugging the kernel. Please do not use on production
kernels.
nohibernate [HIBERNATION] Disable hibernation and resume.
nohz= [KNL] Boottime enable/disable dynamic ticks

View file

@ -21,6 +21,7 @@ whole; patches welcome!
kasan
ubsan
kmemleak
kfence
gdb-kernel-debugging
kgdb
kselftest

View file

@ -0,0 +1,298 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright (C) 2020, Google LLC.
Kernel Electric-Fence (KFENCE)
==============================
Kernel Electric-Fence (KFENCE) is a low-overhead sampling-based memory safety
error detector. KFENCE detects heap out-of-bounds access, use-after-free, and
invalid-free errors.
KFENCE is designed to be enabled in production kernels, and has near zero
performance overhead. Compared to KASAN, KFENCE trades performance for
precision. The main motivation behind KFENCE's design, is that with enough
total uptime KFENCE will detect bugs in code paths not typically exercised by
non-production test workloads. One way to quickly achieve a large enough total
uptime is when the tool is deployed across a large fleet of machines.
Usage
-----
To enable KFENCE, configure the kernel with::
CONFIG_KFENCE=y
To build a kernel with KFENCE support, but disabled by default (to enable, set
``kfence.sample_interval`` to non-zero value), configure the kernel with::
CONFIG_KFENCE=y
CONFIG_KFENCE_SAMPLE_INTERVAL=0
KFENCE provides several other configuration options to customize behaviour (see
the respective help text in ``lib/Kconfig.kfence`` for more info).
Tuning performance
~~~~~~~~~~~~~~~~~~
The most important parameter is KFENCE's sample interval, which can be set via
the kernel boot parameter ``kfence.sample_interval`` in milliseconds. The
sample interval determines the frequency with which heap allocations will be
guarded by KFENCE. The default is configurable via the Kconfig option
``CONFIG_KFENCE_SAMPLE_INTERVAL``. Setting ``kfence.sample_interval=0``
disables KFENCE.
The KFENCE memory pool is of fixed size, and if the pool is exhausted, no
further KFENCE allocations occur. With ``CONFIG_KFENCE_NUM_OBJECTS`` (default
255), the number of available guarded objects can be controlled. Each object
requires 2 pages, one for the object itself and the other one used as a guard
page; object pages are interleaved with guard pages, and every object page is
therefore surrounded by two guard pages.
The total memory dedicated to the KFENCE memory pool can be computed as::
( #objects + 1 ) * 2 * PAGE_SIZE
Using the default config, and assuming a page size of 4 KiB, results in
dedicating 2 MiB to the KFENCE memory pool.
Note: On architectures that support huge pages, KFENCE will ensure that the
pool is using pages of size ``PAGE_SIZE``. This will result in additional page
tables being allocated.
Error reports
~~~~~~~~~~~~~
A typical out-of-bounds access looks like this::
==================================================================
BUG: KFENCE: out-of-bounds read in test_out_of_bounds_read+0xa3/0x22b
Out-of-bounds read at 0xffffffffb672efff (1B left of kfence-#17):
test_out_of_bounds_read+0xa3/0x22b
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
kfence-#17 [0xffffffffb672f000-0xffffffffb672f01f, size=32, cache=kmalloc-32] allocated by task 507:
test_alloc+0xf3/0x25b
test_out_of_bounds_read+0x98/0x22b
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
CPU: 4 PID: 107 Comm: kunit_try_catch Not tainted 5.8.0-rc6+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014
==================================================================
The header of the report provides a short summary of the function involved in
the access. It is followed by more detailed information about the access and
its origin. Note that, real kernel addresses are only shown when using the
kernel command line option ``no_hash_pointers``.
Use-after-free accesses are reported as::
==================================================================
BUG: KFENCE: use-after-free read in test_use_after_free_read+0xb3/0x143
Use-after-free read at 0xffffffffb673dfe0 (in kfence-#24):
test_use_after_free_read+0xb3/0x143
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
kfence-#24 [0xffffffffb673dfe0-0xffffffffb673dfff, size=32, cache=kmalloc-32] allocated by task 507:
test_alloc+0xf3/0x25b
test_use_after_free_read+0x76/0x143
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
freed by task 507:
test_use_after_free_read+0xa8/0x143
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
CPU: 4 PID: 109 Comm: kunit_try_catch Tainted: G W 5.8.0-rc6+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014
==================================================================
KFENCE also reports on invalid frees, such as double-frees::
==================================================================
BUG: KFENCE: invalid free in test_double_free+0xdc/0x171
Invalid free of 0xffffffffb6741000:
test_double_free+0xdc/0x171
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
kfence-#26 [0xffffffffb6741000-0xffffffffb674101f, size=32, cache=kmalloc-32] allocated by task 507:
test_alloc+0xf3/0x25b
test_double_free+0x76/0x171
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
freed by task 507:
test_double_free+0xa8/0x171
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
CPU: 4 PID: 111 Comm: kunit_try_catch Tainted: G W 5.8.0-rc6+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014
==================================================================
KFENCE also uses pattern-based redzones on the other side of an object's guard
page, to detect out-of-bounds writes on the unprotected side of the object.
These are reported on frees::
==================================================================
BUG: KFENCE: memory corruption in test_kmalloc_aligned_oob_write+0xef/0x184
Corrupted memory at 0xffffffffb6797ff9 [ 0xac . . . . . . ] (in kfence-#69):
test_kmalloc_aligned_oob_write+0xef/0x184
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
kfence-#69 [0xffffffffb6797fb0-0xffffffffb6797ff8, size=73, cache=kmalloc-96] allocated by task 507:
test_alloc+0xf3/0x25b
test_kmalloc_aligned_oob_write+0x57/0x184
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
CPU: 4 PID: 120 Comm: kunit_try_catch Tainted: G W 5.8.0-rc6+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014
==================================================================
For such errors, the address where the corruption occurred as well as the
invalidly written bytes (offset from the address) are shown; in this
representation, '.' denote untouched bytes. In the example above ``0xac`` is
the value written to the invalid address at offset 0, and the remaining '.'
denote that no following bytes have been touched. Note that, real values are
only shown if the kernel was booted with ``no_hash_pointers``; to avoid
information disclosure otherwise, '!' is used instead to denote invalidly
written bytes.
And finally, KFENCE may also report on invalid accesses to any protected page
where it was not possible to determine an associated object, e.g. if adjacent
object pages had not yet been allocated::
==================================================================
BUG: KFENCE: invalid read in test_invalid_access+0x26/0xe0
Invalid read at 0xffffffffb670b00a:
test_invalid_access+0x26/0xe0
kunit_try_run_case+0x51/0x85
kunit_generic_run_threadfn_adapter+0x16/0x30
kthread+0x137/0x160
ret_from_fork+0x22/0x30
CPU: 4 PID: 124 Comm: kunit_try_catch Tainted: G W 5.8.0-rc6+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014
==================================================================
DebugFS interface
~~~~~~~~~~~~~~~~~
Some debugging information is exposed via debugfs:
* The file ``/sys/kernel/debug/kfence/stats`` provides runtime statistics.
* The file ``/sys/kernel/debug/kfence/objects`` provides a list of objects
allocated via KFENCE, including those already freed but protected.
Implementation Details
----------------------
Guarded allocations are set up based on the sample interval. After expiration
of the sample interval, the next allocation through the main allocator (SLAB or
SLUB) returns a guarded allocation from the KFENCE object pool (allocation
sizes up to PAGE_SIZE are supported). At this point, the timer is reset, and
the next allocation is set up after the expiration of the interval. To "gate" a
KFENCE allocation through the main allocator's fast-path without overhead,
KFENCE relies on static branches via the static keys infrastructure. The static
branch is toggled to redirect the allocation to KFENCE.
KFENCE objects each reside on a dedicated page, at either the left or right
page boundaries selected at random. The pages to the left and right of the
object page are "guard pages", whose attributes are changed to a protected
state, and cause page faults on any attempted access. Such page faults are then
intercepted by KFENCE, which handles the fault gracefully by reporting an
out-of-bounds access, and marking the page as accessible so that the faulting
code can (wrongly) continue executing (set ``panic_on_warn`` to panic instead).
To detect out-of-bounds writes to memory within the object's page itself,
KFENCE also uses pattern-based redzones. For each object page, a redzone is set
up for all non-object memory. For typical alignments, the redzone is only
required on the unguarded side of an object. Because KFENCE must honor the
cache's requested alignment, special alignments may result in unprotected gaps
on either side of an object, all of which are redzoned.
The following figure illustrates the page layout::
---+-----------+-----------+-----------+-----------+-----------+---
| xxxxxxxxx | O : | xxxxxxxxx | : O | xxxxxxxxx |
| xxxxxxxxx | B : | xxxxxxxxx | : B | xxxxxxxxx |
| x GUARD x | J : RED- | x GUARD x | RED- : J | x GUARD x |
| xxxxxxxxx | E : ZONE | xxxxxxxxx | ZONE : E | xxxxxxxxx |
| xxxxxxxxx | C : | xxxxxxxxx | : C | xxxxxxxxx |
| xxxxxxxxx | T : | xxxxxxxxx | : T | xxxxxxxxx |
---+-----------+-----------+-----------+-----------+-----------+---
Upon deallocation of a KFENCE object, the object's page is again protected and
the object is marked as freed. Any further access to the object causes a fault
and KFENCE reports a use-after-free access. Freed objects are inserted at the
tail of KFENCE's freelist, so that the least recently freed objects are reused
first, and the chances of detecting use-after-frees of recently freed objects
is increased.
Interface
---------
The following describes the functions which are used by allocators as well as
page handling code to set up and deal with KFENCE allocations.
.. kernel-doc:: include/linux/kfence.h
:functions: is_kfence_address
kfence_shutdown_cache
kfence_alloc kfence_free __kfence_free
kfence_ksize kfence_object_start
kfence_handle_page_fault
Related Tools
-------------
In userspace, a similar approach is taken by `GWP-ASan
<http://llvm.org/docs/GwpAsan.html>`_. GWP-ASan also relies on guard pages and
a sampling strategy to detect memory unsafety bugs at scale. KFENCE's design is
directly influenced by GWP-ASan, and can be seen as its kernel sibling. Another
similar but non-sampling approach, that also inspired the name "KFENCE", can be
found in the userspace `Electric Fence Malloc Debugger
<https://linux.die.net/man/3/efence>`_.
In the kernel, several tools exist to debug memory access errors, and in
particular KASAN can detect all bug classes that KFENCE can detect. While KASAN
is more precise, relying on compiler instrumentation, this comes at a
performance cost.
It is worth highlighting that KASAN and KFENCE are complementary, with
different target environments. For instance, KASAN is the better debugging-aid,
where test cases or reproducers exists: due to the lower chance to detect the
error, it would require more effort using KFENCE to debug. Deployments at scale
that cannot afford to enable KASAN, however, would benefit from using KFENCE to
discover bugs due to code paths not exercised by test cases or fuzzers.

View file

@ -1823,18 +1823,20 @@ if precise results are needed.
3.8 /proc/<pid>/fdinfo/<fd> - Information about opened file
---------------------------------------------------------------
This file provides information associated with an opened file. The regular
files have at least three fields -- 'pos', 'flags' and mnt_id. The 'pos'
represents the current offset of the opened file in decimal form [see lseek(2)
for details], 'flags' denotes the octal O_xxx mask the file has been
created with [see open(2) for details] and 'mnt_id' represents mount ID of
the file system containing the opened file [see 3.5 /proc/<pid>/mountinfo
for details].
files have at least four fields -- 'pos', 'flags', 'mnt_id' and 'ino'.
The 'pos' represents the current offset of the opened file in decimal
form [see lseek(2) for details], 'flags' denotes the octal O_xxx mask the
file has been created with [see open(2) for details] and 'mnt_id' represents
mount ID of the file system containing the opened file [see 3.5
/proc/<pid>/mountinfo for details]. 'ino' represents the inode number of
the file.
A typical output is
pos: 0
flags: 0100002
mnt_id: 19
ino: 63107
All locks associated with a file descriptor are shown in its fdinfo too.
@ -1848,6 +1850,7 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 04002
mnt_id: 9
ino: 63107
eventfd-count: 5a
where 'eventfd-count' is hex value of a counter.
@ -1857,6 +1860,7 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 04002
mnt_id: 9
ino: 63107
sigmask: 0000000000000200
where 'sigmask' is hex value of the signal mask associated
@ -1867,6 +1871,7 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 02
mnt_id: 9
ino: 63107
tfd: 5 events: 1d data: ffffffffffffffff pos:0 ino:61af sdev:7
where 'tfd' is a target file descriptor number in decimal form,
@ -1883,6 +1888,8 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 02000000
mnt_id: 9
ino: 63107
inotify wd:3 ino:9e7e sdev:800013 mask:800afce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:7e9e0000640d1b6d
where 'wd' is a watch descriptor in decimal form, ie a target file
@ -1905,6 +1912,7 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 02
mnt_id: 9
ino: 63107
fanotify flags:10 event-flags:0
fanotify mnt_id:12 mflags:40 mask:38 ignored_mask:40000003
fanotify ino:4f969 sdev:800013 mflags:0 mask:3b ignored_mask:40000000 fhandle-bytes:8 fhandle-type:1 f_handle:69f90400c275b5b4
@ -1927,6 +1935,7 @@ pair provide additional information particular to the objects they represent.
pos: 0
flags: 02
mnt_id: 9
ino: 63107
clockid: 0
ticks: 0
settime flags: 01
@ -1941,6 +1950,22 @@ pair provide additional information particular to the objects they represent.
with TIMER_ABSTIME option which will be shown in 'settime flags', but 'it_value'
still exhibits timer's remaining time.
DMA Buffer files
~~~~~~~~~~~~~~~~
::
pos: 0
flags: 04002
mnt_id: 9
ino: 63107
size: 32768
count: 2
exp_name: system-heap
where 'size' is the size of the DMA buffer in bytes. 'count' is the file count of
the DMA buffer file. 'exp_name' is the name of the DMA buffer exporter.
3.9 /proc/<pid>/map_files - Information about memory mapped files
---------------------------------------------------------------------
This directory contains symbolic links which represent memory mapped files

View file

@ -1660,6 +1660,14 @@ accept_ra_min_hop_limit - INTEGER
Default: 1
accept_ra_min_lft - INTEGER
Minimum acceptable lifetime value in Router Advertisement.
RA sections with a lifetime less than this value shall be
ignored. Zero lifetimes stay unaffected.
Default: 0
accept_ra_pinfo - BOOLEAN
Learn Prefix Information in Router Advertisement.

View file

@ -596,9 +596,11 @@ CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
endif # CROSS_COMPILE
ifeq ($(LLVM_IAS),0)
CLANG_FLAGS += -no-integrated-as
CLANG_FLAGS += -fno-integrated-as
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
else
CLANG_FLAGS += -fintegrated-as
endif
CLANG_FLAGS += -Werror=unknown-warning-option
KBUILD_CPPFLAGS += $(CLANG_FLAGS)
@ -871,7 +873,8 @@ DEBUG_CFLAGS += -gsplit-dwarf
else
DEBUG_CFLAGS += -g
endif
ifeq ($(LLVM_IAS),1)
ifdef CONFIG_AS_IS_LLVM
KBUILD_AFLAGS += -g
else
KBUILD_AFLAGS += -Wa,-gdwarf-2

View file

@ -1 +1 @@
LTS_5.4.289_4c8fb3275889
LTS_5.4.302_91d385eb2a41

View file

@ -124,6 +124,8 @@
#define SO_DETACH_REUSEPORT_BPF 68
#define SO_NETNS_COOKIE 71
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64

View file

@ -51,6 +51,10 @@ CONFIG_CNSS_ASYNC=y
CONFIG_CNSS_QCA6490=y
CONFIG_CNSS_UTILS=y
# CONFIG_CNSS_GENL is not set
CONFIG_CNSS=m
CONFIG_CNSS_CRYPTO=y
CONFIG_CNSS_PCI=y
CONFIG_CNSS_LOGGER=m
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_PACKET=y
CONFIG_UNIX=y

View file

@ -15,7 +15,6 @@ generic-y += mmiowb.h
generic-y += msi.h
generic-y += parport.h
generic-y += preempt.h
generic-y += seccomp.h
generic-y += serial.h
generic-y += trace_clock.h

View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
#include <asm-generic/seccomp.h>
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_ARM
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "arm"
#endif /* _ASM_SECCOMP_H */

View file

@ -129,6 +129,7 @@ config ARM64
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
select HAVE_ARCH_KFENCE
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT

View file

@ -209,14 +209,27 @@ CONFIG_L2TP=y
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_NET_ACT_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BT=y
@ -589,6 +602,9 @@ CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_KFENCE=y
CONFIG_KFENCE_SAMPLE_INTERVAL=500
CONFIG_KFENCE_NUM_OBJECTS=63
CONFIG_SOFTLOCKUP_DETECTOR=y
# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_PANIC_ON_OOPS=y

View file

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arm64 KFENCE support.
*
* Copyright (C) 2020, Google LLC.
*/
#ifndef __ASM_KFENCE_H
#define __ASM_KFENCE_H
#include <asm/cacheflush.h>
static inline bool arch_kfence_init_pool(void) { return true; }
static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
set_memory_valid(addr, 1, !protect);
return true;
}
#endif /* __ASM_KFENCE_H */

View file

@ -19,4 +19,13 @@
#include <asm-generic/seccomp.h>
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_AARCH64
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "aarch64"
#ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_ARM
# define SECCOMP_ARCH_COMPAT_NR __NR_compat_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "arm"
#endif
#endif /* _ASM_SECCOMP_H */

View file

@ -10,6 +10,7 @@
#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/extable.h>
#include <linux/kfence.h>
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/hardirq.h>
@ -327,6 +328,9 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr,
} else if (addr < PAGE_SIZE) {
msg = "NULL pointer dereference";
} else {
if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
return;
msg = "paging request";
}

View file

@ -471,7 +471,8 @@ static void __init map_mem(pgd_t *pgdp)
struct memblock_region *reg;
int flags = 0;
if (rodata_full || debug_pagealloc_enabled())
if (rodata_full || debug_pagealloc_enabled() ||
IS_ENABLED(CONFIG_KFENCE))
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
/*
@ -1470,7 +1471,12 @@ int arch_add_memory(int nid, u64 start, u64 size,
return -1;
}
if (rodata_full || debug_pagealloc_enabled())
/*
* KFENCE requires linear map to be mapped at page granularity, so that
* it is possible to protect/unprotect single pages in the KFENCE pool.
*/
if (rodata_full || debug_pagealloc_enabled() ||
IS_ENABLED(CONFIG_KFENCE))
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),

View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
#include <asm-generic/seccomp.h>
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_CSKY
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "csky"
#endif /* _ASM_SECCOMP_H */

View file

@ -9,12 +9,12 @@ static inline const int *get_compat_mode1_syscalls(void)
static const int syscalls_O32[] = {
__NR_O32_Linux + 3, __NR_O32_Linux + 4,
__NR_O32_Linux + 1, __NR_O32_Linux + 193,
0, /* null terminated */
-1, /* negative terminated */
};
static const int syscalls_N32[] = {
__NR_N32_Linux + 0, __NR_N32_Linux + 1,
__NR_N32_Linux + 58, __NR_N32_Linux + 211,
0, /* null terminated */
-1, /* negative terminated */
};
if (IS_ENABLED(CONFIG_MIPS32_O32) && test_thread_flag(TIF_32BIT_REGS))

View file

@ -135,6 +135,8 @@
#define SO_DETACH_REUSEPORT_BPF 68
#define SO_NETNS_COOKIE 71
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64

View file

@ -19,7 +19,6 @@ generic-y += mm-arch-hooks.h
generic-y += mmiowb.h
generic-y += percpu.h
generic-y += preempt.h
generic-y += seccomp.h
generic-y += trace_clock.h
generic-y += user.h
generic-y += vga.h

View file

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
#include <asm-generic/seccomp.h>
#ifdef CONFIG_64BIT
# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_PARISC64
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "parisc64"
# ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_PARISC
# define SECCOMP_ARCH_COMPAT_NR NR_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "parisc"
# endif
#else /* !CONFIG_64BIT */
# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_PARISC
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "parisc"
#endif
#endif /* _ASM_SECCOMP_H */

View file

@ -116,6 +116,8 @@
#define SO_DETACH_REUSEPORT_BPF 0x4042
#define SO_NETNS_COOKIE 0x4045
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64

View file

@ -8,4 +8,27 @@
#include <asm-generic/seccomp.h>
#ifdef __LITTLE_ENDIAN__
#define __SECCOMP_ARCH_LE __AUDIT_ARCH_LE
#define __SECCOMP_ARCH_LE_NAME "le"
#else
#define __SECCOMP_ARCH_LE 0
#define __SECCOMP_ARCH_LE_NAME
#endif
#ifdef CONFIG_PPC64
# define SECCOMP_ARCH_NATIVE (AUDIT_ARCH_PPC64 | __SECCOMP_ARCH_LE)
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "ppc64" __SECCOMP_ARCH_LE_NAME
# ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT (AUDIT_ARCH_PPC | __SECCOMP_ARCH_LE)
# define SECCOMP_ARCH_COMPAT_NR NR_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "ppc" __SECCOMP_ARCH_LE_NAME
# endif
#else /* !CONFIG_PPC64 */
# define SECCOMP_ARCH_NATIVE (AUDIT_ARCH_PPC | __SECCOMP_ARCH_LE)
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "ppc" __SECCOMP_ARCH_LE_NAME
#endif
#endif /* _ASM_POWERPC_SECCOMP_H */

View file

@ -38,7 +38,7 @@ ifeq ($(CONFIG_LD_IS_LLD),y)
ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0)
KBUILD_CFLAGS += -mno-relax
KBUILD_AFLAGS += -mno-relax
ifneq ($(LLVM_IAS),1)
ifndef CONFIG_AS_IS_LLVM
KBUILD_CFLAGS += -Wa,-mno-relax
KBUILD_AFLAGS += -Wa,-mno-relax
endif

View file

@ -16,4 +16,13 @@
#include <asm-generic/seccomp.h>
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_S390X
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "s390x"
#ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_S390
# define SECCOMP_ARCH_COMPAT_NR NR_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "s390"
#endif
#endif /* _ASM_S390_SECCOMP_H */

View file

@ -8,4 +8,14 @@
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define __SECCOMP_ARCH_LE __AUDIT_ARCH_LE
#else
#define __SECCOMP_ARCH_LE 0
#endif
#define SECCOMP_ARCH_NATIVE (AUDIT_ARCH_SH | __SECCOMP_ARCH_LE)
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "sh"
#endif /* __ASM_SECCOMP_H */

View file

@ -117,6 +117,8 @@
#define SO_DETACH_REUSEPORT_BPF 0x0047
#define SO_NETNS_COOKIE 0x0050
#if !defined(__KERNEL__)

View file

@ -139,6 +139,7 @@ config X86
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if X86_64
select HAVE_ARCH_KFENCE
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT

View file

@ -188,14 +188,27 @@ CONFIG_L2TP=y
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_NET_ACT_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BT=y
@ -520,6 +533,9 @@ CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_KFENCE=y
CONFIG_KFENCE_SAMPLE_INTERVAL=500
CONFIG_KFENCE_NUM_OBJECTS=63
CONFIG_SOFTLOCKUP_DETECTOR=y
# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_PANIC_ON_OOPS=y

View file

@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* x86 KFENCE support.
*
* Copyright (C) 2020, Google LLC.
*/
#ifndef _ASM_X86_KFENCE_H
#define _ASM_X86_KFENCE_H
#include <linux/bug.h>
#include <linux/kfence.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/set_memory.h>
#include <asm/tlbflush.h>
/* Force 4K pages for __kfence_pool. */
static inline bool arch_kfence_init_pool(void)
{
unsigned long addr;
for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
addr += PAGE_SIZE) {
unsigned int level;
if (!lookup_address(addr, &level))
return false;
if (level != PG_LEVEL_4K)
set_memory_4k(addr, 1);
}
return true;
}
/* Protect the given page and flush TLB. */
static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
unsigned int level;
pte_t *pte = lookup_address(addr, &level);
if (WARN_ON(!pte || level != PG_LEVEL_4K))
return false;
/*
* We need to avoid IPIs, as we may get KFENCE allocations or faults
* with interrupts disabled. Therefore, the below is best-effort, and
* does not flush TLBs on all CPUs. We can tolerate some inaccuracy;
* lazy fault handling takes care of faults after the page is PRESENT.
*/
if (protect)
set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
else
set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
/* Flush this CPU's TLB. */
__flush_tlb_one_kernel(addr);
return true;
}
#endif /* _ASM_X86_KFENCE_H */

View file

@ -16,6 +16,26 @@
#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
#endif
#ifdef CONFIG_X86_64
# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_X86_64
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "x86_64"
# ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_I386
# define SECCOMP_ARCH_COMPAT_NR IA32_NR_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "ia32"
# endif
/*
* x32 will have __X32_SYSCALL_BIT set in syscall number. We don't support
* caching them and they are treated as out of range syscalls, which will
* always pass through the BPF filter.
*/
#else /* !CONFIG_X86_64 */
# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_I386
# define SECCOMP_ARCH_NATIVE_NR NR_syscalls
# define SECCOMP_ARCH_NATIVE_NAME "ia32"
#endif
#include <asm-generic/seccomp.h>
#endif /* _ASM_X86_SECCOMP_H */

View file

@ -9,6 +9,7 @@
#include <linux/kdebug.h> /* oops_begin/end, ... */
#include <linux/extable.h> /* search_exception_tables */
#include <linux/memblock.h> /* max_low_pfn */
#include <linux/kfence.h> /* kfence_handle_page_fault */
#include <linux/kprobes.h> /* NOKPROBE_SYMBOL, ... */
#include <linux/mmiotrace.h> /* kmmio_handler, ... */
#include <linux/perf_event.h> /* perf_sw_event */
@ -801,6 +802,11 @@ no_context(struct pt_regs *regs, unsigned long error_code,
if (IS_ENABLED(CONFIG_EFI))
efi_recover_from_page_fault(address);
/* Only not-present faults should be handled by KFENCE. */
if (!(error_code & X86_PF_PROT) &&
kfence_handle_page_fault(address, error_code & X86_PF_WRITE, regs))
return;
oops:
/*
* Oops. The kernel tried to access some bad page. We'll have to

View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
#include <asm-generic/seccomp.h>
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_XTENSA
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "xtensa"
#endif /* _ASM_SECCOMP_H */

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/* Uncomment this block to log an error on every VERIFY failure */
@ -62,6 +62,7 @@
#define TZ_PIL_AUTH_QDSP6_PROC 1
#define FASTRPC_DMAHANDLE_NOMAP (16)
#define FASTRPC_MAP_DMA_HANDLE 0x20000
#define FASTRPC_ENOSUCH 39
#define DEBUGFS_SIZE 3072
@ -1128,7 +1129,7 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map)
}
static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
uintptr_t va, size_t len, int mflags, int refs,
uintptr_t va, size_t len, int mflags, bool refs,
struct fastrpc_mmap **ppmap)
{
struct fastrpc_mmap *match = NULL, *map = NULL;
@ -1306,7 +1307,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
dma_free_attrs(me->dev, map->size, (void *)map->va,
(dma_addr_t)map->phys, (unsigned long)map->attr);
}
} else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
} else if (map->flags & FASTRPC_DMAHANDLE_NOMAP) {
trace_fastrpc_dma_unmap(cid, map->phys, map->size);
if (!IS_ERR_OR_NULL(map->table))
dma_buf_unmap_attachment(map->attach, map->table,
@ -1391,6 +1392,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
unsigned long flags;
int err = 0, vmid, sgl_index = 0;
struct scatterlist *sgl = NULL;
bool take_ref = true;
if (!fl) {
err = -EBADF;
@ -1404,7 +1406,9 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
}
chan = &apps->channel[cid];
if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
if (mflags & FASTRPC_MAP_DMA_HANDLE)
take_ref = false;
if (!fastrpc_mmap_find(fl, fd, va, len, mflags, take_ref, ppmap))
return 0;
map = kzalloc(sizeof(*map), GFP_KERNEL);
VERIFY(err, !IS_ERR_OR_NULL(map));
@ -1442,7 +1446,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
if (err)
goto bail;
}
} else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
} else if (mflags & FASTRPC_DMAHANDLE_NOMAP) {
if (map->attr & FASTRPC_ATTR_KEEP_MAP) {
ADSPRPC_ERR("Invalid attribute 0x%x for fd %d\n",
map->attr, fd);
@ -2502,10 +2506,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
mutex_lock(&ctx->fl->map_mutex);
for (i = bufs; i < bufs + handles; i++) {
int dmaflags = 0;
int dmaflags = FASTRPC_MAP_DMA_HANDLE;
if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
dmaflags = FASTRPC_DMAHANDLE_NOMAP;
dmaflags |= FASTRPC_DMAHANDLE_NOMAP;
if (ctx->fds && (ctx->fds[i] != -1))
err = fastrpc_mmap_create(ctx->fl, ctx->fds[i],
FASTRPC_ATTR_NOVA, 0, 0, dmaflags,
@ -2666,7 +2670,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
if (ctx->maps[i]) {
/* check if map still exist */
if (!fastrpc_mmap_find(ctx->fl, ctx->fds[i], 0, 0,
0, 0, &mmap)) {
0, false, &mmap)) {
if (mmap) {
pages[i].addr = mmap->phys;
pages[i].size = mmap->size;
@ -2881,7 +2885,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
if (!fdlist[i])
break;
if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
0, 0, &mmap)) {
0, false, &mmap)) {
if (mmap && mmap->dma_handle_refs) {
mmap->dma_handle_refs = 0;
fastrpc_mmap_free(mmap, 0);
@ -4961,7 +4965,7 @@ static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
}
mutex_lock(&fl->internal_map_mutex);
mutex_lock(&fl->map_mutex);
err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map);
err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, false, &map);
if (err) {
ADSPRPC_ERR(
"mapping not found to unmap fd 0x%x, va 0x%llx, len 0x%x, err %d\n",

View file

@ -799,16 +799,11 @@ early_param("random.trust_cpu", parse_trust_cpu);
early_param("random.trust_bootloader", parse_trust_bootloader);
/*
* The first collection of entropy occurs at system boot while interrupts
* are still turned off. Here we push in latent entropy, RDSEED, a timestamp,
* utsname(), and the command line. Depending on the above configuration knob,
* RDSEED may be considered sufficient for initialization. Note that much
* earlier setup may already have pushed entropy into the input pool by the
* time we get here.
* This is called extremely early, before time keeping functionality is
* available, but arch randomness is. Interrupts are not yet enabled.
*/
int __init random_init(const char *command_line)
void __init random_init_early(const char *command_line)
{
ktime_t now = ktime_get_real();
unsigned int i, arch_bits;
unsigned long entropy;
@ -821,22 +816,41 @@ int __init random_init(const char *command_line)
i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) {
if (!arch_get_random_seed_long_early(&entropy) &&
!arch_get_random_long_early(&entropy)) {
entropy = random_get_entropy();
arch_bits -= sizeof(entropy) * 8;
continue;
}
_mix_pool_bytes(&entropy, sizeof(entropy));
}
_mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(utsname(), sizeof(*(utsname())));
_mix_pool_bytes(command_line, strlen(command_line));
add_latent_entropy();
_mix_pool_bytes(command_line, strlen(command_line));
/* Reseed if already seeded by earlier phases. */
if (crng_ready())
crng_reseed();
else if (trust_cpu)
_credit_init_bits(arch_bits);
}
return 0;
/*
* This is called a little bit after the prior function, and now there is
* access to timestamps counters. Interrupts are not yet enabled.
*/
void __init random_init(void)
{
unsigned long entropy = random_get_entropy();
ktime_t now = ktime_get_real();
_mix_pool_bytes(utsname(), sizeof(*(utsname())));
_mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(&entropy, sizeof(entropy));
add_latent_entropy();
/* Reseed if already seeded by earlier phases. */
if (crng_ready())
crng_reseed();
WARN(!entropy, "Missing cycle counter and fallback timer; RNG "
"entropy collection will consequently suffer.");
}
/*

View file

@ -329,10 +329,6 @@ int qcedev_check_and_map_buffer(void *handle,
mapped_size = binfo->ion_buf.mapped_buf_size;
atomic_inc(&binfo->ref_count);
/* Add buffer mapping information to regd buffer list */
mutex_lock(&qce_hndl->registeredbufs.lock);
list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
/* Make sure the offset is within the mapped range */
@ -344,6 +340,13 @@ int qcedev_check_and_map_buffer(void *handle,
goto unmap;
}
if (!found) {
/* Add buffer mapping information to regd buffer list */
mutex_lock(&qce_hndl->registeredbufs.lock);
list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
/* return the mapped virtual address adjusted by offset */
*vaddr += offset;
@ -352,9 +355,6 @@ int qcedev_check_and_map_buffer(void *handle,
unmap:
if (!found) {
qcedev_unmap_buffer(handle, mem_client, binfo);
mutex_lock(&qce_hndl->registeredbufs.lock);
list_del(&binfo->list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
error:

View file

@ -882,7 +882,7 @@ int __suspend_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type)
struct bwmon *m = to_bwmon(hw);
mon_irq_disable(m, type);
free_irq(m->irq, m);
disable_irq(m->irq);
mon_disable(m, type);
mon_irq_clear(m, type);
@ -908,7 +908,6 @@ static __always_inline
int __resume_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type)
{
struct bwmon *m = to_bwmon(hw);
int ret;
irq_handler_t handler;
switch (type) {
@ -924,15 +923,7 @@ int __resume_bw_hwmon(struct bw_hwmon *hw, enum mon_reg_type type)
}
mon_clear(m, false, type);
ret = request_threaded_irq(m->irq, handler, bwmon_intr_thread,
IRQF_ONESHOT | IRQF_SHARED,
dev_name(m->dev), m);
if (ret < 0) {
dev_err(m->dev, "Unable to register interrupt handler! (%d)\n",
ret);
return ret;
}
enable_irq(m->irq);
mon_irq_enable(m, type);
mon_enable(m, type);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/atomic.h>
@ -2524,6 +2525,12 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan,
for_each_sg(sgl, sg, sg_len, i) {
tre = sg_virt(sg);
if (!tre) {
kfree(gpi_desc);
GPII_ERR(gpii, gpii_chan->chid, "TRE address is null\n");
return NULL;
}
if (sg_len == 1) {
tre_type =
MSM_GPI_TRE_TYPE(((struct msm_gpi_tre *)tre));

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk/qcom.h>
@ -2523,6 +2524,7 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
struct cpu_gpu_lock *lock = ptr;
u32 *data = ptr + sizeof(*lock);
int i, offset = 0;
u32 pending_pairs = 2; /* No of pairs to add: <select,value> and <cntl,1> */
if (cpu_gpu_lock(lock)) {
cpu_gpu_unlock(lock);
@ -2546,6 +2548,13 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
offset += 2;
}
/* Ensure there is enough space in the reglist buffer for new pairs */
if ((offset + (pending_pairs * 2)) >=
(adreno_dev->pwrup_reglist->size / sizeof(u32))) {
cpu_gpu_unlock(lock);
return -ENOSPC;
}
/*
* For all targets A6XX_RBBM_PERFCTR_CNTL needs to be the last entry,
* so overwrite the existing A6XX_RBBM_PERFCNTL_CTRL and add it back to

View file

@ -593,7 +593,7 @@ static int find_vma_block(struct a6xx_gmu_device *gmu, u32 addr, u32 size)
{
int i;
for (i = 0; i < GMU_MEM_TYPE_MAX; i++) {
for (i = 0; i < gmu->num_vmas; i++) {
struct gmu_vma_entry *vma = &gmu->vma[i];
if ((addr >= vma->start) &&
@ -2685,10 +2685,13 @@ int a6xx_gmu_probe(struct kgsl_device *device,
if (ret)
goto error;
if (adreno_is_a650_family(adreno_dev))
if (adreno_is_a650_family(adreno_dev)) {
gmu->vma = a6xx_gmu_vma;
else
gmu->num_vmas = ARRAY_SIZE(a6xx_gmu_vma);
} else {
gmu->vma = a6xx_gmu_vma_legacy;
gmu->num_vmas = ARRAY_SIZE(a6xx_gmu_vma_legacy);
}
/* Map and reserve GMU CSRs registers */
ret = a6xx_gmu_reg_probe(adreno_dev);

View file

@ -187,6 +187,8 @@ struct a6xx_gmu_device {
/** @global_entries: To keep track of number of gmu buffers */
u32 global_entries;
struct gmu_vma_entry *vma;
/** @num_vmas: Number of entries in the @vma array */
u32 num_vmas;
unsigned int log_wptr_retention;
/** @cm3_fault: whether gmu received a cm3 fault interrupt */
atomic_t cm3_fault;

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <uapi/linux/msm_ion.h>
@ -355,6 +355,7 @@ static void kgsl_destroy_ion(struct kgsl_memdesc *memdesc)
}
memdesc->sgt = NULL;
entry->priv_data = NULL;
}
static const struct kgsl_memdesc_ops kgsl_dmabuf_ops = {
@ -4054,9 +4055,9 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private,
return addr;
}
static unsigned long get_align(struct kgsl_mem_entry *entry)
unsigned long kgsl_get_align(struct kgsl_memdesc *memdesc)
{
int bit = kgsl_memdesc_get_align(&entry->memdesc);
u32 bit = kgsl_memdesc_get_align(memdesc);
if (bit >= ilog2(SZ_2M))
return SZ_2M;
@ -4065,7 +4066,7 @@ static unsigned long get_align(struct kgsl_mem_entry *entry)
else if (bit >= ilog2(SZ_64K))
return SZ_64K;
return SZ_4K;
return PAGE_SIZE;
}
static unsigned long set_svm_area(struct file *file,
@ -4098,7 +4099,7 @@ static unsigned long get_svm_unmapped_area(struct file *file,
{
struct kgsl_device_private *dev_priv = file->private_data;
struct kgsl_process_private *private = dev_priv->process_priv;
unsigned long align = get_align(entry);
unsigned long align = kgsl_get_align(&entry->memdesc);
unsigned long ret, iova;
u64 start = 0, end = 0;
struct vm_area_struct *vma;

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef __KGSL_H
#define __KGSL_H
@ -473,6 +473,8 @@ void kgsl_mmu_remove_global(struct kgsl_device *device,
struct kgsl_memdesc *memdesc);
/* Helper functions */
unsigned long kgsl_get_align(struct kgsl_memdesc *memdesc);
int kgsl_request_irq(struct platform_device *pdev, const char *name,
irq_handler_t handler, void *data);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2002,2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/debugfs.h>
@ -146,7 +147,7 @@ static const char *memtype_str(int memtype)
static char get_alignflag(const struct kgsl_memdesc *m)
{
int align = kgsl_memdesc_get_align(m);
u32 align = kgsl_memdesc_get_align(m);
if (align >= ilog2(SZ_1M))
return 'L';

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitfield.h>
@ -2229,8 +2229,7 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
size = kgsl_memdesc_footprint(memdesc);
align = max_t(uint64_t, 1 << kgsl_memdesc_get_align(memdesc),
PAGE_SIZE);
align = kgsl_get_align(memdesc);
if (memdesc->flags & KGSL_MEMFLAGS_FORCE_32BIT) {
start = pt->compat_va_start;

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef __KGSL_SHAREDMEM_H
#define __KGSL_SHAREDMEM_H
@ -157,7 +158,7 @@ void kgsl_free_globals(struct kgsl_device *device);
*
* Returns the alignment requested, as power of 2 exponent.
*/
static inline int
static inline u32
kgsl_memdesc_get_align(const struct kgsl_memdesc *memdesc)
{
return MEMFLAGS(memdesc->flags, KGSL_MEMALIGN_MASK,

View file

@ -244,8 +244,12 @@ static void fast_smmu_unmap_page(struct device *dev, dma_addr_t iova,
}
spin_lock_irqsave(&mapping->lock, flags);
av8l_fast_unmap_public(mapping->pgtbl_ops, iova, len);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, iova, len)))
goto fail;
__fast_smmu_free_iova(mapping, iova, len);
fail:
spin_unlock_irqrestore(&mapping->lock, flags);
trace_unmap(to_msm_iommu_domain(mapping->domain), iova - offset, len,
@ -385,7 +389,8 @@ static void fast_smmu_unmap_sg(struct device *dev,
len = ALIGN(sg_dma_address(sg) + sg_dma_len(sg) - (start - offset),
FAST_PAGE_SIZE);
av8l_fast_unmap_public(mapping->pgtbl_ops, start, len);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, start, len)))
return;
spin_lock_irqsave(&mapping->lock, flags);
__fast_smmu_free_iova(mapping, start, len);
@ -653,7 +658,10 @@ static void fast_smmu_free(struct device *dev, size_t size,
size = ALIGN(size, FAST_PAGE_SIZE);
spin_lock_irqsave(&mapping->lock, flags);
av8l_fast_unmap_public(mapping->pgtbl_ops, dma_handle, size);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, dma_handle, size)))
goto fail;
__fast_smmu_free_iova(mapping, dma_handle, size);
spin_unlock_irqrestore(&mapping->lock, flags);
@ -674,6 +682,11 @@ static void fast_smmu_free(struct device *dev, size_t size,
if (page)
dma_free_contiguous(dev, page, size);
return;
fail:
spin_unlock_irqrestore(&mapping->lock, flags);
}
static int fast_smmu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,

View file

@ -127,7 +127,14 @@
#define PTE_SH_IDX(pte) (pte & AV8L_FAST_PTE_SH_MASK)
#define iopte_pmd_offset(pmds, base, iova) (pmds + ((iova - base) >> 12))
#define iopte_pmd_offset(pmds, base, iova) \
({ \
typeof(iova) __iova = (iova); \
typeof(base) __base = (base); \
typeof(pmds) __pmds = (pmds); \
(__iova < __base) ? ERR_PTR(-EINVAL) : \
__pmds + ((__iova - ALIGN_DOWN(__base, SZ_2M)) >> AV8L_FAST_PAGE_SHIFT); \
})
static inline dma_addr_t av8l_dma_addr(void *addr)
{
@ -202,6 +209,12 @@ void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops, u64 base,
struct io_pgtable *iop = iof_pgtable_ops_to_pgtable(ops);
av8l_fast_iopte *pmdp = iopte_pmd_offset(data->pmds, data->base, base);
if (IS_ERR(pmdp)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return;
}
for (i = base >> AV8L_FAST_PAGE_SHIFT;
i <= (end >> AV8L_FAST_PAGE_SHIFT); ++i) {
if (!(*pmdp & AV8L_FAST_PTE_VALID)) {
@ -254,6 +267,12 @@ static int av8l_fast_map(struct io_pgtable_ops *ops, unsigned long iova,
unsigned long i, nptes = size >> AV8L_FAST_PAGE_SHIFT;
av8l_fast_iopte pte;
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return -EINVAL;
}
pte = av8l_fast_prot_to_pte(data, prot);
paddr &= AV8L_FAST_PTE_ADDR_MASK;
for (i = 0; i < nptes; i++, paddr += SZ_4K) {
@ -286,6 +305,12 @@ __av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
ptep = iopte_pmd_offset(data->pmds, data->base, iova);
nptes = size >> AV8L_FAST_PAGE_SHIFT;
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return 0;
}
memset(ptep, val, sizeof(*ptep) * nptes);
av8l_clean_range(&iop->cfg, ptep, ptep + nptes);
if (!allow_stale_tlb)
@ -295,10 +320,10 @@ __av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
}
/* caller must take care of tlb cache maintenance */
void av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
size_t av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
size_t size)
{
__av8l_fast_unmap(ops, iova, size, true);
return __av8l_fast_unmap(ops, iova, size, true);
}
static size_t av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
@ -383,6 +408,12 @@ static bool av8l_fast_iova_coherent(struct io_pgtable_ops *ops,
struct av8l_fast_io_pgtable *data = iof_pgtable_ops_to_data(ops);
av8l_fast_iopte *ptep = iopte_pmd_offset(data->pmds, data->base, iova);
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return false;
}
return ((PTE_MAIR_IDX(*ptep) == AV8L_FAST_MAIR_ATTR_IDX_CACHE) &&
((PTE_SH_IDX(*ptep) == AV8L_FAST_PTE_SH_OS) ||
(PTE_SH_IDX(*ptep) == AV8L_FAST_PTE_SH_IS)));

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/debugfs.h>
@ -135,6 +135,8 @@ static int msm_cvp_initialize_core(struct platform_device *pdev,
INIT_LIST_HEAD(&core->instances);
mutex_init(&core->lock);
mutex_init(&core->clk_lock);
mutex_init(&core->idr_mtx);
idr_init(&core->sess_idr);
core->state = CVP_CORE_UNINIT;
for (i = SYS_MSG_INDEX(SYS_MSG_START);
@ -506,6 +508,8 @@ static int msm_cvp_remove(struct platform_device *pdev)
msm_cvp_free_platform_resources(&core->resources);
sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group);
dev_set_drvdata(&pdev->dev, NULL);
idr_destroy(&core->sess_idr);
mutex_destroy(&core->idr_mtx);
mutex_destroy(&core->lock);
mutex_destroy(&core->clk_lock);
kfree(core);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <asm/memory.h>
@ -29,6 +30,7 @@
#include "cvp_hfi_helper.h"
#include "cvp_hfi_io.h"
#include "msm_cvp_dsp.h"
#include "msm_cvp.h"
#define FIRMWARE_SIZE 0X00A00000
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
@ -469,6 +471,7 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
{
int rc;
struct cvp_hal_session *temp;
struct msm_cvp_inst *inst = NULL;
if (msm_cvp_dsp_disable)
return 0;
@ -480,9 +483,10 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
/* don't suspend if cvp session is not paused */
if (!(temp->flags & SESSION_PAUSE)) {
inst = (struct msm_cvp_inst *)temp->session_id;
dprintk(CVP_DSP,
"%s: cvp session %x not paused\n",
__func__, hash32_ptr(temp));
__func__, inst->sess_id);
return -EBUSY;
}
}
@ -2224,12 +2228,17 @@ static void __session_clean(struct cvp_hal_session *session)
{
struct cvp_hal_session *temp, *next;
struct iris_hfi_device *device;
struct msm_cvp_core *core = NULL;
struct msm_cvp_inst *inst = NULL;
void *tmp = NULL;
if (!session || !session->device) {
dprintk(CVP_WARN, "%s: invalid params\n", __func__);
return;
}
device = session->device;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
inst = (struct msm_cvp_inst *) session->session_id;
dprintk(CVP_SESS, "deleted the session: %pK\n", session);
/*
* session might have been removed from the device list in
@ -2241,6 +2250,13 @@ static void __session_clean(struct cvp_hal_session *session)
break;
}
}
/* Remove the IDR id assigned to this session */
mutex_lock(&core->idr_mtx);
tmp = idr_remove(&core->sess_idr, inst->sess_id);
if (tmp != session)
dprintk(CVP_WARN, "%s: session\n", __func__);
mutex_unlock(&core->idr_mtx);
/* Poison the session handle with zeros */
*session = (struct cvp_hal_session){ {0} };
kfree(session);
@ -2278,6 +2294,9 @@ static int iris_hfi_session_init(void *device, void *session_id,
struct cvp_hfi_cmd_sys_session_init_packet pkt;
struct iris_hfi_device *dev;
struct cvp_hal_session *s;
struct msm_cvp_core *core;
struct msm_cvp_inst *inst;
int id = 0;
if (!device || !new_session) {
dprintk(CVP_ERR, "%s - invalid input\n", __func__);
@ -2285,6 +2304,8 @@ static int iris_hfi_session_init(void *device, void *session_id,
}
dev = device;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
inst = session_id;
mutex_lock(&dev->lock);
s = kzalloc(sizeof(*s), GFP_KERNEL);
@ -2295,15 +2316,35 @@ static int iris_hfi_session_init(void *device, void *session_id,
s->session_id = session_id;
s->device = dev;
mutex_lock(&core->idr_mtx);
idr_preload(GFP_KERNEL);
/* Need to think if we can use core->lock or dev->lock or need a
* different new lock for this?
*/
id = idr_alloc(&core->sess_idr, (void *)s, 0x7FFF0000, INT_MAX, GFP_NOWAIT);
idr_preload_end();
mutex_unlock(&core->idr_mtx);
if (id < 0) {
dprintk(CVP_ERR,
"%s: idr allocation failed for session %pK of inst %pK\n",
__func__, s, session_id);
goto err_session_init_fail;
}
dprintk(CVP_SESS,
"%s: inst %pK, session %pK\n", __func__, session_id, s);
"%s: inst %pK, session %pK, idr_id = 0x%x\n", __func__, session_id, s, id);
list_add_tail(&s->list, &dev->sess_head);
__set_default_sys_properties(device);
inst->sess_id = id;
if (call_hfi_pkt_op(dev, session_init, &pkt, s)) {
dprintk(CVP_ERR, "session_init: failed to create packet\n");
inst->sess_id = 0x0000DEAD;
goto err_session_init_fail;
}
@ -2317,6 +2358,7 @@ static int iris_hfi_session_init(void *device, void *session_id,
err_session_init_fail:
if (s)
__session_clean(s);
inst->sess_id = 0;
*new_session = NULL;
mutex_unlock(&dev->lock);
return -EINVAL;
@ -2878,9 +2920,11 @@ static struct cvp_hal_session *__get_session(struct iris_hfi_device *device,
u32 session_id)
{
struct cvp_hal_session *temp = NULL;
struct msm_cvp_inst *inst = NULL;
list_for_each_entry(temp, &device->sess_head, list) {
if (session_id == hash32_ptr(temp))
inst = (struct msm_cvp_inst *)temp->session_id;
if (session_id == inst->sess_id)
return temp;
}
@ -3059,6 +3103,7 @@ static int __response_handler(struct iris_hfi_device *device)
/* Process the packet types that we're interested in */
process_system_msg(info, device, raw_packet);
/* This session_id is a double pointer to the idr_id of session */
session_id = get_session_id(info);
/*
* hfi_process_msg_packet provides a session_id that's a hashed
@ -3070,11 +3115,6 @@ static int __response_handler(struct iris_hfi_device *device)
if (session_id) {
struct cvp_hal_session *session = NULL;
if (upper_32_bits((uintptr_t)*session_id) != 0) {
dprintk(CVP_ERR,
"Upper 32-bits != 0 for sess_id=%pK\n",
*session_id);
}
session = __get_session(device,
(u32)(uintptr_t)*session_id);
if (!session) {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "hfi_packetization.h"
@ -208,7 +209,7 @@ inline int cvp_create_pkt_cmd_sys_session_init(
pkt->size = sizeof(struct cvp_hfi_cmd_sys_session_init_packet);
pkt->packet_type = HFI_CMD_SYS_SESSION_INIT;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->session_type = inst->prop.type;
pkt->session_kmask = inst->prop.kernel_mask;
pkt->session_prio = inst->prop.priority;
@ -266,13 +267,14 @@ int cvp_create_pkt_cmd_session_cmd(struct cvp_hal_session_cmd_pkt *pkt,
int pkt_type, struct cvp_hal_session *session)
{
int rc = 0;
struct msm_cvp_inst *inst = session->session_id;
if (!pkt)
return -EINVAL;
pkt->size = sizeof(struct cvp_hal_session_cmd_pkt);
pkt->packet_type = pkt_type;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
return rc;
}
@ -305,13 +307,14 @@ int cvp_create_pkt_cmd_session_set_buffers(
{
int rc = 0;
struct cvp_hfi_cmd_session_set_buffers_packet *pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!cmd || !session)
if (!cmd || !session || !inst)
return -EINVAL;
pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd;
pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->buf_type.iova = iova;
pkt->buf_type.size = size;
pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet);
@ -324,13 +327,14 @@ int cvp_create_pkt_cmd_session_release_buffers(
struct cvp_hal_session *session)
{
struct cvp_session_release_buffers_packet *pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!cmd || !session)
if (!cmd || !session || !inst)
return -EINVAL;
pkt = (struct cvp_session_release_buffers_packet *)cmd;
pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->num_buffers = 1;
pkt->buffer_type = 0;
pkt->size = sizeof(struct cvp_session_release_buffers_packet) +
@ -347,6 +351,7 @@ int cvp_create_pkt_cmd_session_send(
int def_idx;
struct cvp_hal_session_cmd_pkt *ptr =
(struct cvp_hal_session_cmd_pkt *)in_pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!out_pkt || !in_pkt || !session)
return -EINVAL;
@ -354,7 +359,7 @@ int cvp_create_pkt_cmd_session_send(
if (ptr->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int))
goto error_hfi_packet;
if (ptr->session_id != hash32_ptr(session))
if (ptr->session_id != inst->sess_id)
goto error_hfi_packet;
def_idx = get_pkt_index(ptr);

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitops.h>
@ -462,7 +462,7 @@ static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core,
retry:
if (mutex_trylock(&core->lock)) {
list_for_each_entry(inst, &core->instances, list) {
if (hash32_ptr(inst->session) == session_id) {
if (inst->sess_id == session_id) {
match = true;
break;
}

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp.h"
@ -14,6 +15,47 @@ struct cvp_power_level {
unsigned long bw_sum;
};
void *get_sessObj_from_idr(struct msm_cvp_inst *inst)
{
void *sessObj = NULL;
struct msm_cvp_core *core = NULL;
if (!inst || !inst->core) {
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
return NULL;
}
core = inst->core;
mutex_lock(&core->idr_mtx);
sessObj = idr_find(&core->sess_idr, inst->sess_id);
mutex_unlock(&core->idr_mtx);
if (!sessObj)
dprintk(CVP_ERR, "%s: Could not find the sess obj for given idr id\n",
__func__);
return sessObj;
}
u32 get_sessId_from_idr(void *session)
{
void *ptr = NULL;
u32 sess_id = -1;
struct msm_cvp_core *core = NULL;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
if (!session || !core)
return -EINVAL;
mutex_lock(&core->idr_mtx);
idr_for_each_entry(&core->sess_idr, ptr, sess_id) {
if (ptr == session) {
mutex_unlock(&core->idr_mtx);
return sess_id;
}
}
mutex_unlock(&core->idr_mtx);
return sess_id;
}
static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
struct cvp_kmd_session_info *session)
{
@ -30,7 +72,7 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
return -ECONNRESET;
s->cur_cmd_type = CVP_KMD_GET_SESSION_INFO;
session->session_id = hash32_ptr(inst->session);
session->session_id = inst->sess_id;
dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id);
s->cur_cmd_type = 0;
@ -699,6 +741,13 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
f->output_index = kfc->output_index;
}
if (f->num_fences >= (MAX_HFI_FENCE_SIZE / 2)) {
dprintk(CVP_ERR, "%s: Max number of fences exceeded! Max number supported: %d",
__func__, (MAX_HFI_FENCE_SIZE / 2));
cvp_free_fence_data(f);
msm_cvp_unmap_frame(inst, pkt->client_data.kdata);
goto exit;
}
dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n",
__func__, f->frame_id, pkt->client_data.kdata);
@ -1227,7 +1276,7 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
sq->state = QUEUE_STOP;
pr_info(CVP_DBG_TAG "Stop session: %pK session_id = %d\n",
"sess", inst, hash32_ptr(inst->session));
"sess", inst, inst->sess_id);
spin_unlock(&sq->lock);
wake_up_all(&inst->session_queue.wq);
@ -1251,7 +1300,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)
sq->state = QUEUE_STOP;
dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
spin_unlock(&sq->lock);
wake_up_all(&inst->session_queue.wq);
@ -1551,7 +1600,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
dprintk(CVP_SYNX, "%s: (%#x) flush frame %llu %llu wait_list\n",
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
__func__, inst->sess_id, ktid, f->frame_id);
list_del_init(&f->list);
msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata);
@ -1564,7 +1613,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
dprintk(CVP_SYNX, "%s: (%#x)flush frame %llu %llu sched_list\n",
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
__func__, inst->sess_id, ktid, f->frame_id);
cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, synx_state);
}
@ -1612,14 +1661,14 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
return -ECONNRESET;
dprintk(CVP_SESS, "session %llx (%#x)flush all starts\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
q = &inst->fence_cmd_queue;
hdev = inst->core->device;
cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL);
dprintk(CVP_SESS, "%s: (%#x) send flush to fw\n",
__func__, hash32_ptr(inst->session));
__func__, inst->sess_id);
/* Send flush to FW */
rc = call_hfi_op(hdev, session_flush, (void *)inst->session);
@ -1636,7 +1685,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
__func__, rc);
dprintk(CVP_SESS, "%s: (%#x) received flush from fw\n",
__func__, hash32_ptr(inst->session));
__func__, inst->sess_id);
exit:
rc = cvp_drain_fence_sched_list(inst);
@ -1859,10 +1908,10 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)
return -EINVAL;
}
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
session = (struct cvp_hal_session *)inst->session;
if (!session)
session = (struct cvp_hal_session *)get_sessObj_from_idr(inst);
if (!session || session != inst->session)
return rc;
rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE);
@ -1883,7 +1932,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst)
}
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
/* set default frequency */
inst->clk_data.core_id = 0;

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _MSM_CVP_H_
@ -34,4 +35,6 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst);
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst);
int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst);
void *get_sessObj_from_idr(struct msm_cvp_inst *inst);
u32 get_sessId_from_idr(void *session);
#endif

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp_common.h"
@ -14,7 +14,7 @@
do { \
clear_bit(idx, &inst->dma_cache.usage_bitmap); \
dprintk(CVP_MEM, "clear %x bit %d dma_cache bitmap 0x%llx\n", \
hash32_ptr(inst->session), smem->bitmap_index, \
inst->sess_id, smem->bitmap_index, \
inst->dma_cache.usage_bitmap); \
} while (0)
@ -22,7 +22,7 @@
do { \
set_bit(idx, &inst->dma_cache.usage_bitmap); \
dprintk(CVP_MEM, "Set %x bit %d dma_cache bitmap 0x%llx\n", \
hash32_ptr(inst->session), idx, \
inst->sess_id, idx, \
inst->dma_cache.usage_bitmap); \
} while (0)
@ -36,7 +36,7 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst,
if (smem->dma_buf) {
dprintk(tag,
"%s: %x : %s size %d flags %#x iova %#x idx %d ref %d",
str, hash32_ptr(inst->session), smem->dma_buf->name,
str, inst->sess_id, smem->dma_buf->name,
smem->size, smem->flags, smem->device_addr,
smem->bitmap_index, smem->refcount);
}
@ -51,13 +51,13 @@ static void print_internal_buffer(u32 tag, const char *str,
if (cbuf->smem->dma_buf) {
dprintk(tag,
"%s: %x : fd %d off %d %s size %d iova %#x",
str, hash32_ptr(inst->session), cbuf->fd,
str, inst->sess_id, cbuf->fd,
cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size,
cbuf->smem->device_addr);
} else {
dprintk(tag,
"%s: %x : idx %2d fd %d off %d size %d iova %#x",
str, hash32_ptr(inst->session), cbuf->fd,
str, inst->sess_id, cbuf->fd,
cbuf->offset, cbuf->size, cbuf->smem->device_addr);
}
}
@ -77,7 +77,7 @@ void print_client_buffer(u32 tag, const char *str,
dprintk(tag,
"%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n",
str, hash32_ptr(inst->session), cbuf->index, cbuf->fd,
str, inst->sess_id, cbuf->index, cbuf->fd,
cbuf->offset, cbuf->size, cbuf->type, cbuf->flags);
}
@ -154,7 +154,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
}
if (buf->index) {
rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd,
rc = cvp_dsp_register_buffer(inst->sess_id, buf->fd,
smem->dma_buf->size, buf->size, buf->offset,
buf->index, (uint32_t)smem->device_addr);
if (rc) {
@ -227,7 +227,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
}
if (buf->index) {
rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd,
rc = cvp_dsp_deregister_buffer(inst->sess_id, buf->fd,
cbuf->smem->dma_buf->size, buf->size, buf->offset,
buf->index, (uint32_t)cbuf->smem->device_addr);
if (rc) {
@ -545,7 +545,7 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid)
ktid &= (FENCE_BIT - 1);
dprintk(CVP_MEM, "%s: (%#x) unmap frame %llu\n",
__func__, hash32_ptr(inst->session), ktid);
__func__, inst->sess_id, ktid);
found = false;
mutex_lock(&inst->frames.lock);
@ -587,7 +587,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
smem = pbuf->smem;
dprintk(CVP_MEM, "unmap persist: %x %d %d %#x",
hash32_ptr(inst->session), pbuf->fd,
inst->sess_id, pbuf->fd,
pbuf->size, smem->device_addr);
if (smem->bitmap_index >= MAX_DMABUF_NUMS) {
@ -785,7 +785,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst)
list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list,
list) {
print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf);
rc = cvp_dsp_deregister_buffer(hash32_ptr(session),
rc = cvp_dsp_deregister_buffer(inst->sess_id,
cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size,
cbuf->offset, cbuf->index,
(uint32_t)cbuf->smem->device_addr);
@ -955,7 +955,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst)
if (buf->ownership == DRIVER) {
dprintk(CVP_MEM,
"%s: %x : fd %d %s size %d",
"free arp", hash32_ptr(inst->session), buf->fd,
"free arp", inst->sess_id, buf->fd,
smem->dma_buf->name, buf->size);
msm_cvp_smem_free(smem);
kmem_cache_free(cvp_driver->smem_cache, smem);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/jiffies.h>
@ -195,23 +196,31 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core,
{
int rc = 0;
struct cvp_hfi_device *hdev;
struct msm_cvp_inst *s;
struct msm_cvp_inst *inst;
void *sessObj = NULL;
s = cvp_get_inst(core, session_id);
if (!s) {
dprintk(CVP_ERR, "%s session doesn't exit\n",
inst = cvp_get_inst(core, session_id);
if (!inst) {
dprintk(CVP_ERR, "%s Inst doesn't exit\n",
__builtin_return_address(0));
return NULL;
}
hdev = s->core->device;
rc = call_hfi_op(hdev, validate_session, s->session, __func__);
if (rc) {
cvp_put_inst(s);
s = NULL;
sessObj = get_sessObj_from_idr(inst);
if (!sessObj || sessObj != inst->session) {
dprintk(CVP_ERR,
"Either sessionObj is null or not matching with inst->session\n");
return NULL;
}
return s;
hdev = inst->core->device;
rc = call_hfi_op(hdev, validate_session, sessObj, __func__);
if (rc) {
cvp_put_inst(inst);
inst = NULL;
}
return inst;
}
static void cvp_handle_session_cmd_done(enum hal_command_response cmd,
@ -486,7 +495,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
}
dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__,
hash32_ptr(inst->session));
inst->sess_id);
signal_session_msg_receipt(cmd, inst);
cvp_put_inst(inst);
@ -568,7 +577,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
hdev = inst->core->device;
dprintk(CVP_ERR, "Session error received for inst %pK session %x\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
if (response->status == CVP_ERR_MAX_CLIENTS) {
dprintk(CVP_WARN, "Too many clients, rejecting %pK", inst);
@ -901,7 +910,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
if (rc) {
dprintk(CVP_ERR,
@ -914,7 +923,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
inst->core->resources.msm_cvp_hw_rsp_timeout));
if (!rc) {
dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n",
__func__, inst, hash32_ptr(inst->session));
__func__, inst, inst->sess_id);
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dump_hfi_queue(hdev->hfi_device_data);
msm_cvp_comm_generate_sys_error(inst);
@ -1268,7 +1277,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
}
dprintk(CVP_SESS,
"Trying to move inst: %pK (%#x) from: %#x to %#x\n",
inst, hash32_ptr(inst->session), inst->state, state);
inst, inst->sess_id, inst->state, state);
mutex_lock(&inst->sync_lock);
if (inst->state == MSM_CVP_CORE_INVALID) {
@ -1281,7 +1290,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
flipped_state = get_flipped_state(inst->state, state);
dprintk(CVP_SESS,
"inst: %pK (%#x) flipped_state = %#x %x\n",
inst, hash32_ptr(inst->session), flipped_state, state);
inst, inst->sess_id, flipped_state, state);
switch (flipped_state) {
case MSM_CVP_CORE_UNINIT_DONE:
case MSM_CVP_CORE_INIT:
@ -1491,7 +1500,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
return 0;
}
dprintk(CVP_WARN, "%s: inst %pK, session %x state %d\n", __func__,
inst, hash32_ptr(inst->session), inst->state);
inst, inst->sess_id, inst->state);
/*
* We're internally forcibly killing the session, if fw is aware of
* the session send session_abort to firmware to clean up and release
@ -1503,7 +1512,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
if (rc) {
dprintk(CVP_ERR,
"%s: inst %pK session %x abort failed\n",
__func__, inst, hash32_ptr(inst->session));
__func__, inst, inst->sess_id);
change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID);
} else {
change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/dma-direction.h>
@ -165,7 +166,7 @@ void *msm_cvp_open(int core_id, int session_type)
list_for_each_entry(inst, &core->instances, list)
dprintk(CVP_ERR, "inst %pK, cmd %d id %d\n",
inst, inst->cur_cmd_type,
hash32_ptr(inst->session));
inst->sess_id);
mutex_unlock(&core->lock);
return NULL;
@ -369,7 +370,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst)
synx_uninitialize(inst->synx_session_id);
pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n",
"sess", inst, hash32_ptr(inst->session));
"sess", inst, inst->sess_id);
if (inst->cur_cmd_type)
dprintk(CVP_ERR, "deleted instance has pending cmd %d\n",
inst->cur_cmd_type);

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _MSM_CVP_INTERNAL_H_
@ -290,6 +291,8 @@ struct msm_cvp_core {
unsigned long curr_freq;
struct cvp_cycle_info dyn_clk;
atomic64_t kernel_trans_id;
struct idr sess_idr;
struct mutex idr_mtx;
};
struct msm_cvp_inst {
@ -301,6 +304,7 @@ struct msm_cvp_inst {
struct cvp_session_queue session_queue_fence;
struct cvp_session_event event_handler;
void *session;
u32 sess_id;
enum instance_state state;
struct msm_cvp_list freqs;
struct msm_cvp_list persistbufs;

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp_common.h"
@ -20,7 +21,7 @@ void cvp_dump_fence_queue(struct msm_cvp_inst *inst)
ssid = inst->synx_session_id;
mutex_lock(&q->lock);
dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n",
hash32_ptr(inst->session), q->mode, ssid.client_id);
inst->sess_id, q->mode, ssid.client_id);
dprintk(CVP_WARN, "fence cmdq wait list:\n");
list_for_each_entry(f, &q->wait_list, list) {

View file

@ -27,8 +27,10 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
struct hfi_colour_space *colour_info;
struct hfi_buffer_requirements *bufreq;
struct hfi_extradata_input_crop *crop;
struct hfi_dpb_counts *dpb_count;
u32 ptype, rem_bytes;
u32 size_read = 0;
u8 *data_ptr;
u32 ptype;
inst->error = HFI_ERR_NONE;
@ -38,80 +40,120 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
break;
default:
inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
goto done;
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
return;
}
event.event_type = pkt->event_data1;
num_properties_changed = pkt->event_data2;
if (!num_properties_changed) {
inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
goto done;
}
if (!num_properties_changed)
goto error;
data_ptr = (u8 *)&pkt->ext_event_data[0];
rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
do {
if (rem_bytes < sizeof(u32))
goto error;
ptype = *((u32 *)data_ptr);
data_ptr += sizeof(u32);
rem_bytes -= sizeof(u32);
switch (ptype) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_framesize))
goto error;
frame_sz = (struct hfi_framesize *)data_ptr;
event.width = frame_sz->width;
event.height = frame_sz->height;
data_ptr += sizeof(*frame_sz);
size_read = sizeof(struct hfi_framesize);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_profile_level))
goto error;
profile_level = (struct hfi_profile_level *)data_ptr;
event.profile = profile_level->profile;
event.level = profile_level->level;
data_ptr += sizeof(*profile_level);
size_read = sizeof(struct hfi_profile_level);
break;
case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_bit_depth))
goto error;
pixel_depth = (struct hfi_bit_depth *)data_ptr;
event.bit_depth = pixel_depth->bit_depth;
data_ptr += sizeof(*pixel_depth);
size_read = sizeof(struct hfi_bit_depth);
break;
case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_pic_struct))
goto error;
pic_struct = (struct hfi_pic_struct *)data_ptr;
event.pic_struct = pic_struct->progressive_only;
data_ptr += sizeof(*pic_struct);
size_read = sizeof(struct hfi_pic_struct);
break;
case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_colour_space))
goto error;
colour_info = (struct hfi_colour_space *)data_ptr;
event.colour_space = colour_info->colour_space;
data_ptr += sizeof(*colour_info);
size_read = sizeof(struct hfi_colour_space);
break;
case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(u32))
goto error;
event.entropy_mode = *(u32 *)data_ptr;
data_ptr += sizeof(u32);
size_read = sizeof(u32);
break;
case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_buffer_requirements))
goto error;
bufreq = (struct hfi_buffer_requirements *)data_ptr;
event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
data_ptr += sizeof(*bufreq);
event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);
size_read = sizeof(struct hfi_buffer_requirements);
break;
case HFI_INDEX_EXTRADATA_INPUT_CROP:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_extradata_input_crop))
goto error;
crop = (struct hfi_extradata_input_crop *)data_ptr;
event.input_crop.left = crop->left;
event.input_crop.top = crop->top;
event.input_crop.width = crop->width;
event.input_crop.height = crop->height;
data_ptr += sizeof(*crop);
size_read = sizeof(struct hfi_extradata_input_crop);
break;
case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
if (rem_bytes < sizeof(struct hfi_dpb_counts))
goto error;
dpb_count = (struct hfi_dpb_counts *)data_ptr;
event.buf_count = dpb_count->fw_min_cnt;
size_read = sizeof(struct hfi_dpb_counts);
break;
default:
size_read = 0;
break;
}
data_ptr += size_read;
rem_bytes -= size_read;
num_properties_changed--;
} while (num_properties_changed > 0);
done:
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
return;
error:
inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
}

View file

@ -379,9 +379,21 @@ static int olaps_cmp(const void *a, const void *b)
return st == 0 ? ed : st;
}
/**
* fastrpc_get_buff_overlaps - Detect and handle buffer overlaps in RPC args
* @ctx: The invoke context containing buffer information
*
* This function detects overlapping memory regions in the RPC arguments and
* adjusts the memory mapping accordingly. It handles ION and non-ION buffers
* separately to prevent incorrect overlap detection between different buf types.
* For each buffer type:
* - If a buffer overlaps with a previous buffer of the same type, it adjusts
* the mapping to avoid the overlap
* - If no overlap is detected, it uses the full buffer range
*/
static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx)
{
u64 max_end = 0;
u64 ion_buf_end_pos = 0, non_ion_buf_end_pos = 0;
int i;
for (i = 0; i < ctx->nbufs; ++i) {
@ -393,24 +405,29 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx)
sort(ctx->olaps, ctx->nbufs, sizeof(*ctx->olaps), olaps_cmp, NULL);
for (i = 0; i < ctx->nbufs; ++i) {
/* Falling inside previous range */
if (ctx->olaps[i].start < max_end) {
ctx->olaps[i].mstart = max_end;
ctx->olaps[i].mend = ctx->olaps[i].end;
ctx->olaps[i].offset = max_end - ctx->olaps[i].start;
/* Separate ION and non-ION buffers; fd <= 0 indicates non-ION */
u64 *last_buf_end = (ctx->args[ctx->olaps[i].raix].fd <= 0) ?
&non_ion_buf_end_pos : &ion_buf_end_pos;
if (ctx->olaps[i].end > max_end) {
max_end = ctx->olaps[i].end;
if (ctx->olaps[i].start < *last_buf_end) {
/* Overlap detected within same buffer type */
ctx->olaps[i].mstart = *last_buf_end;
ctx->olaps[i].mend = ctx->olaps[i].end;
ctx->olaps[i].offset = *last_buf_end - ctx->olaps[i].start;
if (ctx->olaps[i].end > *last_buf_end) {
*last_buf_end = ctx->olaps[i].end;
} else {
ctx->olaps[i].mend = 0;
ctx->olaps[i].mstart = 0;
}
} else {
/* No overlap, assign full range */
ctx->olaps[i].mend = ctx->olaps[i].end;
ctx->olaps[i].mstart = ctx->olaps[i].start;
ctx->olaps[i].offset = 0;
max_end = ctx->olaps[i].end;
*last_buf_end = ctx->olaps[i].end;
}
}
}
@ -813,6 +830,22 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
PAGE_SHIFT;
pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE;
/*
* Check for page range overflow and validate page
* range is not greater than map buffer range.
* This prevents potential buffer overflow
* and memory corruption that could be exploited.
*/
if (pages[i].addr > (ULLONG_MAX - pages[i].size) ||
(pages[i].addr + pages[i].size) >
(ctx->maps[i]->phys + ctx->maps[i]->size)) {
err = -EFAULT;
dev_err(dev,
"Invalid buffer addr 0x%llx len 0x%llx IPA 0x%llx size 0x%llx fd %d\n",
ctx->args[i].ptr, len, ctx->maps[i]->phys,
ctx->maps[i]->size, ctx->maps[i]->fd);
goto bail;
}
} else {
if (ctx->olaps[oix].offset == 0) {

View file

@ -2,7 +2,7 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_qpic_nand.h"
@ -1944,7 +1944,7 @@ free_dma:
if (last_pos < ecc_bytes_percw_in_bits)
num_zero_bits++;
if (num_zero_bits > 4) {
if (num_zero_bits > info->flash_dev.ecc_capability) {
*erased_page = false;
goto free_mem;
}
@ -1955,8 +1955,8 @@ free_dma:
num_zero_bits = last_pos = next_pos = 0;
ecc_temp += chip->ecc_parity_bytes;
}
if ((n == cwperpage) && (num_zero_bits <= 4))
if ((n == cwperpage) &&
(num_zero_bits <= info->flash_dev.ecc_capability))
*erased_page = true;
free_mem:
kfree(ecc);
@ -2163,6 +2163,33 @@ static int msm_nand_read_pagescope(struct mtd_info *mtd, loff_t from,
goto free_dma;
/* Check for flash status errors */
pageerr = rawerr = 0;
/*
* PAGE_ERASED bit will set only if all
* CODEWORD_ERASED bit of all codewords
* of the page is set.
*
* PAGE_ERASED bit is a 'logical and' of all
* CODEWORD_ERASED bit of all codewords i.e.
* even if one codeword is detected as not
* an erased codeword, PAGE_ERASED bit will unset.
*/
for (n = rw_params.start_sector; n < cwperpage; n++) {
if ((dma_buffer->result[n].erased_cw_status &
(1 << PAGE_ERASED)) &&
(dma_buffer->result[n].buffer_status &
NUM_ERRORS)) {
err = msm_nand_is_erased_page_ps(mtd,
from, ops,
&rw_params,
&erased_page);
if (err)
goto free_dma;
if (erased_page)
rawerr = -EIO;
break;
}
}
for (n = rw_params.start_sector; n < cwperpage; n++) {
if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
FS_MPU_ERR)) {
@ -2554,7 +2581,7 @@ free_dma:
if (last_pos < ecc_bytes_percw_in_bits)
num_zero_bits++;
if (num_zero_bits > 4) {
if (num_zero_bits > info->flash_dev.ecc_capability) {
*erased_page = false;
goto free_mem;
}
@ -2566,7 +2593,8 @@ free_dma:
ecc_temp += chip->ecc_parity_bytes;
}
if ((n == cwperpage) && (num_zero_bits <= 4))
if ((n == cwperpage) &&
(num_zero_bits <= info->flash_dev.ecc_capability))
*erased_page = true;
free_mem:
kfree(ecc);
@ -2760,6 +2788,33 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
goto free_dma;
/* Check for flash status errors */
pageerr = rawerr = 0;
/*
* PAGE_ERASED bit will set only if all
* CODEWORD_ERASED bit of all codewords
* of the page is set.
*
* PAGE_ERASED bit is a 'logical and' of all
* CODEWORD_ERASED bit of all codewords i.e.
* even if one codeword is detected as not
* an erased codeword, PAGE_ERASED bit will unset.
*/
for (n = rw_params.start_sector; n < cwperpage; n++) {
if ((dma_buffer->result[n].erased_cw_status &
(1 << PAGE_ERASED)) &&
(dma_buffer->result[n].buffer_status &
NUM_ERRORS)) {
err = msm_nand_is_erased_page(mtd,
from, ops,
&rw_params,
&erased_page);
if (err)
goto free_dma;
if (erased_page)
rawerr = -EIO;
break;
}
}
for (n = rw_params.start_sector; n < cwperpage; n++) {
if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
FS_MPU_ERR)) {

View file

@ -154,7 +154,10 @@
#define RESET_ERASED_DET (1 << AUTO_DETECT_RES)
#define ACTIVE_ERASED_DET (0 << AUTO_DETECT_RES)
#define CLR_ERASED_PAGE_DET (RESET_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC | SET_N_MAX_ZEROS)
#define N_MAX_ZEROS 2
#define MAX_ECC_BIT_FLIPS 4
#define SET_N_MAX_ZEROS (MAX_ECC_BIT_FLIPS << N_MAX_ZEROS)
#define MSM_NAND_ERASED_CW_DETECT_STATUS(info) MSM_NAND_REG(info, 0x300EC)
#define PAGE_ALL_ERASED 7
@ -163,6 +166,7 @@
#define CODEWORD_ERASED 4
#define ERASED_PAGE ((1 << PAGE_ALL_ERASED) | (1 << PAGE_ERASED))
#define ERASED_CW ((1 << CODEWORD_ALL_ERASED) | (1 << CODEWORD_ERASED))
#define NUM_ERRORS 0x1f
#define MSM_NAND_CTRL(info) MSM_NAND_REG(info, 0x30F00)
#define BAM_MODE_EN 0

View file

@ -3,7 +3,9 @@
# Makefile for CNSS platform driver
#
obj-$(CONFIG_CNSS_PCI) += cnss_pci.o
obj-$(CONFIG_CNSS_SDIO) += cnss_sdio.o
obj-$(CONFIG_CNSS) += cnss_common.o
obj-$(CONFIG_CNSS_LOGGER) += logger/
obj-$(CONFIG_CNSS) += cnss.o
cnss-$(CONFIG_CNSS_PCI) += cnss_pci.o
cnss-$(CONFIG_CNSS_SDIO) += cnss_sdio.o
cnss-y += cnss_common.o
obj-$(CONFIG_CNSS_LOGGER) += logger/

View file

@ -242,13 +242,21 @@ int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu)
}
EXPORT_SYMBOL(cnss_set_cpus_allowed_ptr);
/* wlan prop driver cannot invoke show_stack
* function directly, so to invoke this function it
* call wcnss_dump_stack function
*/
#define ENTRIES_COUNT 32
void cnss_dump_stack(struct task_struct *task)
{
show_stack(task, NULL);
const int cnss_spaces = 4;
unsigned long cnss_entries[ENTRIES_COUNT] = {0};
struct stack_trace cnss_trace = {
.nr_entries = 0,
.skip = 0,
.entries = &cnss_entries[0],
.max_entries = ENTRIES_COUNT,
};
save_stack_trace_tsk(task, &cnss_trace);
stack_trace_print(cnss_entries, cnss_trace.nr_entries,
cnss_spaces);
}
EXPORT_SYMBOL(cnss_dump_stack);

View file

@ -31,6 +31,8 @@
#include <linux/log2.h>
#include <linux/etherdevice.h>
#include <linux/msm_pcie.h>
#include <linux/of_reserved_mem.h>
#include <linux/cma.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/ramdump.h>
@ -1618,6 +1620,43 @@ static void cnss_pcie_reset_platform_ops(struct device *dev)
dev->platform_data = NULL;
}
#if IS_ENABLED(CONFIG_ARCH_QCOM)
/**
* cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region
* to given PCI device
* @pdev: context pointer of pdev
*
* This function shall call corresponding of_reserved_mem_device* API to
* assign reserved memory region to PCI device based on where the memory is
* defined and attached to (platform device of_node or PCI device of_node)
* in device tree.
*
* Return: 0 for success, negative value for error
*/
static int cnss_pci_of_reserved_mem_device_init(struct pci_dev *pdev)
{
struct device *dev_pci = &pdev->dev;
int ret;
/* Use of_reserved_mem_device_init_by_idx() if reserved memory is
* attached to platform device of_node.
*/
ret = of_reserved_mem_device_init(dev_pci);
if (ret)
pr_err("Failed to init reserved mem device, err = %d\n",
ret);
if (dev_pci->cma_area)
pr_debug("CMA area is %s\n", cma_get_name(dev_pci->cma_area));
return ret;
}
#else
static int cnss_pci_of_reserved_mem_device_init(struct pci_dev *pdev)
{
return 0;
}
#endif
static int cnss_wlan_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@ -1634,6 +1673,7 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
atomic_set(&penv->fw_available, 0);
penv->device_id = pdev->device;
cnss_pci_of_reserved_mem_device_init(pdev);
if (penv->smmu_iova_len) {
ret = cnss_smmu_init(&pdev->dev);
if (ret) {

View file

@ -2179,6 +2179,11 @@ int ep_pcie_core_disable_endpoint(void)
if (atomic_read(&dev->host_wake_pending)) {
EP_PCIE_DBG(dev, "PCIe V%d: wake pending, init wakeup\n",
dev->rev);
/*
* Clear the wake pending otherwise ep_pcie_core_wakeup_host_internal
* will return without WAKE toggle
*/
atomic_set(&dev->host_wake_pending, 0);
ep_pcie_core_wakeup_host_internal(EP_PCIE_EVENT_PM_D3_COLD);
}

View file

@ -39,7 +39,7 @@
/* Wait time on the device for Host to set BHI_INTVEC */
#define MHI_BHI_INTVEC_MAX_CNT 200
#define MHI_BHI_INTVEC_WAIT_MS 50
#define MHI_WAKEUP_TIMEOUT_CNT 20
#define MHI_WAKEUP_TIMEOUT_CNT 25
#define MHI_MASK_CH_EV_LEN 32
#define MHI_RING_CMD_ID 0
#define MHI_RING_PRIMARY_EVT_ID 1

View file

@ -12,6 +12,7 @@
#include "mhi_hwio.h"
#include "mhi_sm.h"
#include <linux/interrupt.h>
#include <linux/delay.h>
#define MHI_SM_DBG(fmt, args...) \
mhi_log(MHI_MSG_DBG, fmt, ##args)
@ -28,7 +29,11 @@
#define PCIE_EP_TIMER_US 500000000
#define MHI_IPA_DISABLE_DELAY_MS 10
#define MHI_IPA_DISABLE_COUNTER 20
/* Maximum wait time for D state transitions to D3hot */
#define M3_DO_WAKEUP_TIMEOUT_MS 2500
static void wait_d3_and_wakeup(struct work_struct *work);
static int mhi_dev_sm_get_mhi_pcie_states(uint32_t *mstate, uint32_t *dstate);
static inline const char *mhi_sm_dev_event_str(enum mhi_dev_event state)
{
@ -235,6 +240,8 @@ struct mhi_sm_dev {
struct mutex mhi_state_lock;
bool syserr_occurred;
struct workqueue_struct *mhi_sm_wq;
struct workqueue_struct *mhi_wake_wq;
struct work_struct mhi_wake_work;
atomic_t pending_device_events;
atomic_t pending_pcie_events;
struct mhi_sm_stats stats;
@ -734,12 +741,12 @@ exit:
* mhi_sm_wakeup_host() - wakeup MHI-host
*@event: MHI state chenge event
*
* Sends wekup event to MHI-host via EP-PCIe, in case MHI is in M3 state.
* Sends wakeup event to MHI-host via EP-PCIe, in case MHI is in M3 state.
*
* Return: 0:success
* negative: failure
*/
static int mhi_sm_wakeup_host(enum mhi_dev_event event)
static int mhi_sm_wakeup_host(void)
{
int res = 0;
enum ep_pcie_event pcie_event;
@ -754,7 +761,8 @@ static int mhi_sm_wakeup_host(enum mhi_dev_event event)
} else if (mhi_sm_ctx->mhi_state == MHI_DEV_M3_STATE) {
/*
* Check and send D3_HOT to enable waking up the host
* using inband PME.
* using inband PME if the host is in D3_HOT state, otherwise
* send D3_COLD to wake up the host.
*/
if (mhi_sm_ctx->d_state == MHI_SM_EP_PCIE_D3_HOT_STATE)
pcie_event = EP_PCIE_EVENT_PM_D3_HOT;
@ -906,9 +914,7 @@ static void mhi_sm_dev_event_manager(struct work_struct *work)
break;
case MHI_DEV_EVENT_HW_ACC_WAKEUP:
case MHI_DEV_EVENT_CORE_WAKEUP:
res = mhi_sm_wakeup_host(chg_event->event);
if (res)
MHI_SM_ERR("Failed to wakeup MHI host\n");
queue_work(mhi_sm_ctx->mhi_wake_wq, &mhi_sm_ctx->mhi_wake_work);
break;
case MHI_DEV_EVENT_CTRL_TRIG:
case MHI_DEV_EVENT_M1_STATE:
@ -1119,9 +1125,19 @@ int mhi_dev_sm_init(struct mhi_dev *mhi_dev)
if (!mhi_sm_ctx->mhi_sm_wq) {
MHI_SM_ERR("Failed to create singlethread_workqueue: sm_wq\n");
res = -ENOMEM;
goto fail_init_wq;
goto fail_init_sm_wq;
}
if (!mhi_sm_ctx->mhi_wake_wq)
mhi_sm_ctx->mhi_wake_wq = alloc_workqueue(
"mhi_wake_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
if (!mhi_sm_ctx->mhi_wake_wq) {
MHI_SM_ERR("Failed to create singlethread_workqueue: wake_wq\n");
res = -ENOMEM;
goto fail_init_wake_wq;
}
INIT_WORK(&mhi_sm_ctx->mhi_wake_work, wait_d3_and_wakeup);
mutex_init(&mhi_sm_ctx->mhi_state_lock);
mhi_sm_ctx->mhi_dev = mhi_dev;
mhi_sm_ctx->mhi_state = MHI_DEV_RESET_STATE;
@ -1134,7 +1150,10 @@ int mhi_dev_sm_init(struct mhi_dev *mhi_dev)
MHI_SM_FUNC_EXIT();
return 0;
fail_init_wq:
fail_init_wake_wq:
flush_workqueue(mhi_sm_ctx->mhi_sm_wq);
destroy_workqueue(mhi_sm_ctx->mhi_sm_wq);
fail_init_sm_wq:
mhi_sm_ctx = NULL;
mhi_sm_debugfs_destroy();
return res;
@ -1162,20 +1181,20 @@ int mhi_dev_sm_exit(struct mhi_dev *mhi_dev)
EXPORT_SYMBOL(mhi_dev_sm_exit);
/**
* mhi_dev_sm_get_mhi_state() -Get current MHI state.
* mhi_dev_sm_get_mhi_pcie_states() -Get current MHI and Pcie states.
* @state: return param
*
* Returns the current MHI state of the state machine.
* Returns the current MHI and PCIe states of the state machine.
*
* Return: 0 success
* -EINVAL: invalid param
* -EFAULT: state machine isn't initialized
*/
int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state)
static int mhi_dev_sm_get_mhi_pcie_states(uint32_t *mstate, uint32_t *dstate)
{
MHI_SM_FUNC_ENTRY();
if (!state) {
if (!mstate || !dstate) {
MHI_SM_ERR("Fail: Null argument\n");
return -EINVAL;
}
@ -1183,15 +1202,60 @@ int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state)
MHI_SM_ERR("Fail: MHI SM is not initialized\n");
return -EFAULT;
}
*state = mhi_sm_ctx->mhi_state;
mutex_lock(&mhi_sm_ctx->mhi_state_lock);
*mstate = mhi_sm_ctx->mhi_state;
*dstate = mhi_sm_ctx->d_state;
mutex_unlock(&mhi_sm_ctx->mhi_state_lock);
MHI_SM_DBG("state machine states are: %s and %s\n",
mhi_sm_mstate_str(*state),
mhi_sm_dstate_str(mhi_sm_ctx->d_state));
mhi_sm_mstate_str(*mstate),
mhi_sm_dstate_str(*dstate));
MHI_SM_FUNC_EXIT();
return 0;
}
EXPORT_SYMBOL(mhi_dev_sm_get_mhi_state);
static void wait_d3_and_wakeup(struct work_struct *work)
{
struct mhi_sm_dev *mhi_sm_ctx = container_of(work, struct mhi_sm_dev, mhi_wake_work);
enum mhi_dev_state mstate;
enum mhi_sm_ep_pcie_state dstate;
ktime_t timeout = 0;
if (mhi_dev_sm_get_mhi_pcie_states(&mstate, &dstate)) {
MHI_SM_ERR("Unable to read states\n");
return;
}
/*
* Handle host wakeup in M3 + D0 states.
* When a MHI WAKE request is received while device is in D0,
* wait for D3 and wakeup the host using inband PME.
* If the MHI state changes to M0 while waiting for D3,
* exit, since both MHI and the device are in active state
*/
if (dstate == MHI_SM_EP_PCIE_D0_STATE) {
timeout = ktime_add_ms(ktime_get(), M3_DO_WAKEUP_TIMEOUT_MS);
while (1) {
mhi_dev_sm_get_mhi_pcie_states(&mstate, &dstate);
if (mstate == MHI_DEV_M0_STATE) {
MHI_SM_DBG("M0 state received\n");
return;
}
if (dstate == MHI_SM_EP_PCIE_D3_HOT_STATE ||
dstate == MHI_SM_EP_PCIE_D3_COLD_STATE) {
MHI_SM_DBG("D3 state received\n");
goto send_host_wakeup;
}
if (ktime_after(ktime_get(), timeout)) {
MHI_SM_ERR("Neither received D3 nor M0 in stipulated time\n");
return;
}
usleep_range(1000, 2000);
}
}
send_host_wakeup:
if (dstate == MHI_SM_EP_PCIE_D3_HOT_STATE || dstate == MHI_SM_EP_PCIE_D3_COLD_STATE)
mhi_sm_wakeup_host();
}
/**
* mhi_dev_sm_set_ready() -Set MHI state to ready.

View file

@ -42,7 +42,6 @@ int mhi_dev_sm_init(struct mhi_dev *dev);
int mhi_dev_sm_exit(struct mhi_dev *dev);
int mhi_dev_sm_set_ready(void);
int mhi_dev_notify_sm_event(enum mhi_dev_event event);
int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state);
int mhi_dev_sm_syserr(void);
void mhi_dev_sm_pcie_handler(struct ep_pcie_notify *notify);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012, 2014-2017, 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -93,6 +93,11 @@ typedef enum {
*/
#define HTT_DATA3_MSG_SVC MAKE_SERVICE_ID(HTT_SERVICE_GROUP,2)
/* HTT_DATA4_MSG_SVC
* H2T channel to transfer MSDU/MPDU queue info from host to target
*/
#define HTT_DATA4_MSG_SVC MAKE_SERVICE_ID(HTT_SERVICE_GROUP,3)
/* raw stream service (i.e. flash, tcmd, calibration apps) */
#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0)

View file

@ -266,9 +266,14 @@
* 3.136 Add htt_ext_present flag in htt_tx_tcl_global_seq_metadata.
* 3.137 Add more HTT_SDWF_MSDUQ_CFG_IND_ERROR codes.
* 3.138 Add T2H MLO_LATENCY_REQ, H2T _RESP msg defs.
* 3.139 Add CLASS_INFO_IDX field in MLO_R_PEER_MAP msg.
* 3.140 Add H2T MPDUQ_AND_MSDUQ_INFO_HDR and MPDUQ_OF_MSDUQ_INFO defs.
* 3.141 Add H2T HTT_AST_INFO for RxOLE.
* 3.142 Add T2H GLOBAL_PEER_ID_UNMAP def, update H2T MPDUQ_OR_MSDUQ_INFO def.
* 3.143 Add T2H HAPS msg def.
*/
#define HTT_CURRENT_VERSION_MAJOR 3
#define HTT_CURRENT_VERSION_MINOR 138
#define HTT_CURRENT_VERSION_MINOR 143
#define HTT_NUM_TX_FRAG_DESC 1024
@ -767,7 +772,10 @@ typedef enum {
HTT_STATS_AST_ENTRY_TAG = 132, /* htt_ast_entry_tlv */
HTT_STATS_TX_PDEV_BE_DL_MU_OFDMA_STATS_TAG = 133, /* htt_tx_pdev_dl_be_mu_ofdma_sch_stats_tlv, TOPIC=advanced */
HTT_STATS_TX_PDEV_BE_UL_MU_OFDMA_STATS_TAG = 134, /* htt_tx_pdev_ul_be_mu_ofdma_sch_stats_tlv, TOPIC=advanced */
HTT_STATS_TX_PDEV_RATE_STATS_BE_OFDMA_TAG = 135, /* htt_tx_pdev_rate_stats_be_ofdma_tlv */
HTT_STATS_TX_PDEV_RATE_BE_BN_OFDMA_TAG = 135, /* htt_stats_tx_pdev_rate_be_bn_ofdma_tlv */
/* retain deprecated name as an alias */
HTT_STATS_TX_PDEV_RATE_STATS_BE_OFDMA_TAG =
HTT_STATS_TX_PDEV_RATE_BE_BN_OFDMA_TAG,
HTT_STATS_RX_PDEV_UL_MUMIMO_TRIG_BE_STATS_TAG = 136, /* htt_rx_pdev_ul_mumimo_trig_be_stats_tlv, TOPIC=advanced */
HTT_STATS_TX_SELFGEN_BE_ERR_STATS_TAG = 137, /* htt_tx_selfgen_be_err_stats_tlv, TOPIC=advanced */
HTT_STATS_TX_SELFGEN_BE_STATS_TAG = 138, /* htt_tx_selfgen_be_stats_tlv, TOPIC=advanced */
@ -775,7 +783,10 @@ typedef enum {
HTT_STATS_TX_PDEV_BE_UL_MU_MIMO_STATS_TAG = 140, /* htt_tx_pdev_be_ul_mu_mimo_sch_stats_tlv */
HTT_STATS_RX_PDEV_BE_UL_MIMO_USER_STATS_TAG = 141, /* htt_rx_pdev_be_ul_mimo_user_stats_tlv */
HTT_STATS_RX_RING_STATS_TAG = 142, /* htt_rx_fw_ring_stats_tlv_v */
HTT_STATS_RX_PDEV_BE_UL_TRIG_STATS_TAG = 143, /* htt_rx_pdev_be_ul_trigger_stats_tlv, TOPIC=advanced */
HTT_STATS_RX_PDEV_BE_BN_UL_TRIG_TAG = 143, /* htt_stats_rx_pdev_be_bn_ul_trig_tlv, TOPIC=advanced */
/* retain deprecated name as an alias */
HTT_STATS_RX_PDEV_BE_UL_TRIG_STATS_TAG =
HTT_STATS_RX_PDEV_BE_BN_UL_TRIG_TAG,
HTT_STATS_TX_PDEV_SAWF_RATE_STATS_TAG = 144, /* htt_tx_pdev_rate_stats_sawf_tlv, TOPIC=advanced */
HTT_STATS_STRM_GEN_MPDUS_TAG = 145, /* htt_stats_strm_gen_mpdus_tlv_t */
HTT_STATS_STRM_GEN_MPDUS_DETAILS_TAG = 146, /* htt_stats_strm_gen_mpdus_details_tlv_t */
@ -844,6 +855,17 @@ typedef enum {
HTT_STATS_PDEV_UL_MUMIMO_DENYLIST_STATS_TAG = 209, /* htt_stats_pdev_ulmumimo_denylist_stats_tlv */
HTT_STATS_PDEV_UL_MUMIMO_SEQ_TERM_STATS_TAG = 210, /* htt_stats_pdev_ulmumimo_seq_term_stats_tlv */
HTT_STATS_PDEV_UL_MUMIMO_HIST_INELIGIBILITY_TAG = 211, /* htt_stats_pdev_ulmumimo_hist_ineligibility_tlv */
HTT_STATS_PHY_PAPRD_PB_TAG = 212, /* htt_stats_phy_paprd_pb_tlv */
HTT_STATS_HDS_PROF_STATS_TAG = 213, /* htt_stat_hds_prof_stats_tlv */
HTT_STATS_TX_PDEV_MDSB_NUM_USERS_HISTOGRAM_TLV_TAG = 214, /* htt_stats_tx_pdev_mdsb_num_users_histogram_tlv */
HTT_STATS_TX_PDEV_PENDING_SEQ_CNT_ON_SCHED_POST_HIST_TAG = 215, /* htt_stats_tx_pdev_pending_seq_cnt_on_sched_post_hist_tlv */
HTT_STATS_TX_PDEV_PENDING_SEQ_CNT_IN_HWQ_HIST_TAG = 216, /* htt_stats_tx_pdev_pending_seq_cnt_in_hwq_hist_tlv */
HTT_STATS_TX_PDEV_PENDING_SEQ_CNT_IN_TXQ_HIST_TAG = 217, /* htt_stats_tx_pdev_pending_seq_cnt_in_txq_hist_tlv */
HTT_STATS_SCHED_TXQ_EARLY_COMPL_TAG = 218, /* htt_stats_sched_txq_early_compl_tlv */
HTT_STATS_RX_PDEV_BN_UL_OFDMA_USER_TAG = 219, /* htt_stats_rx_pdev_bn_ul_ofdma_user_tlv */
HTT_STATS_TX_SELFGEN_BN_ERR_TAG = 220, /* htt_stats_tx_selfgen_bn_err_tlv, TOPIC=advanced */
HTT_STATS_TX_SELFGEN_BN_TAG = 221, /* htt_stats_tx_selfgen_bn_tlv, TOPIC=advanced */
HTT_STATS_TX_SELFGEN_BN_SCHED_STATUS_TAG = 222, /* htt_stats_tx_selfgen_bn_sched_status_tlv, TOPIC=advanced */
HTT_STATS_MAX_TAG,
} htt_stats_tlv_tag_t;
@ -878,47 +900,50 @@ typedef htt_stats_tlv_tag_t htt_tlv_tag_t;
/*=== host -> target messages ===============================================*/
enum htt_h2t_msg_type {
HTT_H2T_MSG_TYPE_VERSION_REQ = 0x0,
HTT_H2T_MSG_TYPE_TX_FRM = 0x1,
HTT_H2T_MSG_TYPE_RX_RING_CFG = 0x2,
HTT_H2T_MSG_TYPE_STATS_REQ = 0x3,
HTT_H2T_MSG_TYPE_SYNC = 0x4,
HTT_H2T_MSG_TYPE_AGGR_CFG = 0x5,
HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG = 0x6,
DEPRECATED_HTT_H2T_MSG_TYPE_MGMT_TX = 0x7, /* no longer used */
HTT_H2T_MSG_TYPE_WDI_IPA_CFG = 0x8,
HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ = 0x9,
HTT_H2T_MSG_TYPE_AGGR_CFG_EX = 0xa, /* per vdev amsdu subfrm limit */
HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb,
HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc,
HTT_H2T_MSG_TYPE_ADD_WDS_ENTRY = 0xd,
HTT_H2T_MSG_TYPE_DELETE_WDS_ENTRY = 0xe,
HTT_H2T_MSG_TYPE_RFS_CONFIG = 0xf,
HTT_H2T_MSG_TYPE_EXT_STATS_REQ = 0x10,
HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11,
HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG = 0x12,
HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG = 0x13,
HTT_H2T_MSG_TYPE_CHAN_CALDATA = 0x14,
HTT_H2T_MSG_TYPE_RX_FISA_CFG = 0x15,
HTT_H2T_MSG_TYPE_3_TUPLE_HASH_CFG = 0x16,
HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE = 0x17,
HTT_H2T_MSG_TYPE_HOST_PADDR_SIZE = 0x18,
HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG = 0x19,
HTT_H2T_MSG_TYPE_VDEVS_TXRX_STATS_CFG = 0x1a,
HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b,
HTT_H2T_SAWF_DEF_QUEUES_MAP_REQ = 0x1c,
HTT_H2T_SAWF_DEF_QUEUES_UNMAP_REQ = 0x1d,
HTT_H2T_SAWF_DEF_QUEUES_MAP_REPORT_REQ = 0x1e,
HTT_H2T_MSG_TYPE_MSI_SETUP = 0x1f,
HTT_H2T_MSG_TYPE_STREAMING_STATS_REQ = 0x20,
HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP = 0x21,
HTT_H2T_MSG_TYPE_VERSION_REQ = 0x0,
HTT_H2T_MSG_TYPE_TX_FRM = 0x1,
HTT_H2T_MSG_TYPE_RX_RING_CFG = 0x2,
HTT_H2T_MSG_TYPE_STATS_REQ = 0x3,
HTT_H2T_MSG_TYPE_SYNC = 0x4,
HTT_H2T_MSG_TYPE_AGGR_CFG = 0x5,
HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG = 0x6,
DEPRECATED_HTT_H2T_MSG_TYPE_MGMT_TX = 0x7, /* no longer used */
HTT_H2T_MSG_TYPE_WDI_IPA_CFG = 0x8,
HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ = 0x9,
HTT_H2T_MSG_TYPE_AGGR_CFG_EX = 0xa, /* per vdev amsdu subfrm limit */
HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb,
HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc,
HTT_H2T_MSG_TYPE_ADD_WDS_ENTRY = 0xd,
HTT_H2T_MSG_TYPE_DELETE_WDS_ENTRY = 0xe,
HTT_H2T_MSG_TYPE_RFS_CONFIG = 0xf,
HTT_H2T_MSG_TYPE_EXT_STATS_REQ = 0x10,
HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11,
HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG = 0x12,
HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG = 0x13,
HTT_H2T_MSG_TYPE_CHAN_CALDATA = 0x14,
HTT_H2T_MSG_TYPE_RX_FISA_CFG = 0x15,
HTT_H2T_MSG_TYPE_3_TUPLE_HASH_CFG = 0x16,
HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE = 0x17,
HTT_H2T_MSG_TYPE_HOST_PADDR_SIZE = 0x18,
HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG = 0x19,
HTT_H2T_MSG_TYPE_VDEVS_TXRX_STATS_CFG = 0x1a,
HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b,
HTT_H2T_SAWF_DEF_QUEUES_MAP_REQ = 0x1c,
HTT_H2T_SAWF_DEF_QUEUES_UNMAP_REQ = 0x1d,
HTT_H2T_SAWF_DEF_QUEUES_MAP_REPORT_REQ = 0x1e,
HTT_H2T_MSG_TYPE_MSI_SETUP = 0x1f,
HTT_H2T_MSG_TYPE_STREAMING_STATS_REQ = 0x20,
HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP = 0x21,
HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_SOC_START_PRE_RESET = 0x22,
HTT_H2T_MSG_TYPE_RX_CCE_SUPER_RULE_SETUP = 0x23,
HTT_H2T_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_RESP = 0x24,
HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG = 0x25,
HTT_H2T_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP = 0x26,
HTT_H2T_MSG_TYPE_SDWF_MSDUQ_RECFG_REQ = 0x27,
HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP = 0x28,
HTT_H2T_MSG_TYPE_RX_CCE_SUPER_RULE_SETUP = 0x23,
HTT_H2T_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_RESP = 0x24,
HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG = 0x25,
HTT_H2T_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP = 0x26,
HTT_H2T_MSG_TYPE_SDWF_MSDUQ_RECFG_REQ = 0x27,
HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP = 0x28,
HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR = 0x29,
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO = 0x2a,
HTT_H2T_MSG_TYPE_AST_INFO = 0x2b,
/* keep this last */
HTT_H2T_NUM_MSGS
@ -11584,6 +11609,507 @@ PREPACK struct htt_h2t_mlo_latency_stats {
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S)); \
} while (0)
/**
* @brief host -> target msg to provide MSDUQ or MPDUQ for new TID in a peer
*
* MSG_TYPE => HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR
*
* @details
* struct htt_h2t_mpduq_and_msduq_info_hdr:
* HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR message is sent by the host to
* target to tell how many mpduq and msduq info TLVs, in units of bytes,
* are present in the htt payload
* Example message contents:
*-------------------------------------------------------------------
*| htt_h2t_mpduq_and_msduq_info_hdr |
*-------------------------------------------------------------------
*| mpduq_info_tlv -> tid 0 , peer_id 1 |
*-------------------------------------------------------------------
*| mpduq_info_tlv -> tid 6, peer_id 1 |
*-------------------------------------------------------------------
*| msduq_info_tlv -> tid 0, peer_id 1 |
*-------------------------------------------------------------------
*| msduq_info_tlv -> tid 0, peer_id 1 |
*-------------------------------------------------------------------
*| msduq_info_tlv -> tid 6, peer_id 1 |
*-------------------------------------------------------------------
*
* As shown in the above exampple, a single htt buffer can hold multiple mpduq
* and msduq info tlvs, the info within the tlvs will indicate the peer and tid
* to which they belong.
*/
/* HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR */
PREPACK struct htt_h2t_mpduq_and_msduq_info_hdr {
A_UINT32 msg_type: 8, /* bits 7:0 */
payload_size_bytes: 12, /* bits 19:8 */
reserved_1a: 12; /* bits 31:20 */
} POSTPACK;
#define HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_M 0x000FFF00
#define HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_S 8
#define HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_AND_MSDUQ_INFO_HDR_PAYLOAD_SIZE_BYTES_S)); \
} while (0)
/**
* @brief host -> target message to provide mpduq for a tid in a peer
*
* MSG_TYPE => HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO
*
* @details
* struct htt_h2t_mpduq_or_msduq_info:
* HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO message is sent by the host to
* specify the configuration of new MPDUQ/MSDUQ for a tid in a peer.
* This message supports the following configuration information:
* 1. Info provided per MPDUQ:
* upper 32 bit address of 256 byte aligned physical address for mpduq
* mpduq number
* pn address space
* 2. Info provided per MSDUQ:
* upper 32 bit address of 256 byte aligned physical address for msduq
* msduq_number
* service class id
*
* The message is interpreted as follows for mpduq type:
* dword0 - b'7:0 - msg_type: Identifies msduq and mpduq info to FW
* This will be set to 0x2a
* (HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO)
* b'12:8 - msduq_mpduq_type: Indicate whether this TLV is for
* a MPDU queue or MSDU queue, and if for a MSDU queue,
* what type.
* For an MPDU queue, it will be fixed value of 30 based
* on enum HTT_H2T_TID_MSDUQ_MPDUQ_TYPE.
* b'16:13 - hw_link_id: Indicates which HW link the message is for.
* This HW link ID is mainly relevant for split PHY
* usecases to identify the correct link in same SOC.
* dword1 - b'31:0 - mpduq_address_39_8: 256 byte aligned mpduq physical
* address, since lowest octet is zero for 256 byte aligned
* physical addresses just passing upper 32 bits of
* 40 bit address
* dword2 - b'11:0 – peer_id
* b'16:12 – tid_num
* b'23:17 – reserved
* b'31:24 - pn_addr_32_39: Upper 8 bits of 40 bit pn physical address
* Note that the mpduq_number is formed from the combination of
* peer_id (in bits 11:0)
* tid_num (in bits 16:12)
* msduq_mpduq_type (in bits 21:17)
* dword3 - b'31:0 - pn_addr_0_31: Lower 32 bits of 40 bit pn physical address
* Additional reserved dwords for future use cases
*
*
* The message is interpreted as follows for any msduq type:
* dword0 - b'7:0 - msg_type: Identifies msduq info to fw
* This will be set to 0x2A
* (HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO)
* b'12:8 - msduq_mpduq_type: type of the msduq based on
* enum HTT_H2T_TID_MSDUQ_MPDUQ_TYPE
* b'16:13 - hw_link_id: Indicates which HW link the message is
* intended for.
* This HW link ID is mainly relevant for split PHY
* usecases to identify the correct link in same SOC.
* dword1 - b'11:0 – peer_id
* b'16:12 – tid_num
* b'23:17 – reserved
* b'31:24 - svc_class_id : service class id of the msduq
* Note that the tx_msduq_number is formed from the combination of
* peer_id (in bits 11:0)
* tid_num (in bits 16:12)
* msduq_mpduq_type (in bits 21:17)
* dword2 - b'31:0 - msduq_address_39_8: 256 byte aligned msduq physical
* address, since lowest octet is zero for 256 byte aligned
* addresses just passing upper 32 bits of 40 bit address
* Additional reserved dwords for future use cases
*/
/*
* Enum describes the various msduq/mpduq types,
* First 8 types correspond to the standard msduq types for data
* Next come custom flows for specific purposes
* enum 30 is reserved for mpduq type
*/
typedef enum {
HTT_H2T_TID_MSDUQ_NONUDP, /* 0 */
HTT_H2T_TID_MSDUQ_UDP, /* 1 */
HTT_H2T_TID_MSDUQ_CUSTOM_0, /* 2 */
HTT_H2T_TID_MSDUQ_CUSTOM_1, /* 3 */
HTT_H2T_TID_MSDUQ_CUSTOM_2, /* 4 */
HTT_H2T_TID_MSDUQ_CUSTOM_3, /* 5 */
HTT_H2T_TID_MSDUQ_CUSTOM_4, /* 6 */
HTT_H2T_TID_MSDUQ_CUSTOM_5, /* 7 */
HTT_H2T_TID_MISC_MSDUQ_TYPE_START, /* 8 */
HTT_H2T_TID_MSDUQ_HOL = HTT_H2T_TID_MISC_MSDUQ_TYPE_START, /* also 8 */
HTT_H2T_TID_MSDUQ_MCAST, /* 9 */
HTT_H2T_TID_MSDUQ_FAST_ROAMING, /* 10 */
HTT_H2T_TID_MSDUQ_DATA_TYPE_END = 29, /* 29 */
HTT_H2T_TID_MPDUQ_TYPE, /* 30 */
HTT_H2T_TID_MSDUQ_MPDUQ_TYPE_END, /* 31 */
} HTT_H2T_TID_MSDUQ_MPDUQ_TYPE;
/*
* Enum to denote tid nums that can be used
* first 8 {0 - 7} numbers correspond to data access category
* {8 - 15} are for user defined usecases
* 16 is used to denote the non-qos tid
*/
typedef enum {
HTT_H2T_DEFAULT_TID_NUM = 0,
HTT_H2T_MAX_VALID_DATA_TID_NUM = 7,
HTT_H2T_NON_QOS_TID_NUM = 16,
HTT_H2T_MAX_TID_NUM = 31,
} H2T_TX_TID;
/* HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO */
PREPACK struct htt_h2t_mpduq_or_msduq_info {
A_UINT32 msg_type: 8, /* bits 7:0 */
msduq_mpduq_type: 5, /* bits 12:8 */
hw_link_id: 4, /* bits 16:13 */
reserved0: 15; /* bits 31:17 */
union {
struct {
A_UINT32 mpduq_address_39_8; /* bits 31:0 */
A_UINT32 mpduq_number: 24, /* bits 23:0 */
pn_addr_39_32: 8; /* bits 31:24 */
A_UINT32 pn_addr_31_0; /* bits 31:0 */
A_UINT32 reserved1a; /* bits 31:0 */
A_UINT32 reserved1b; /* bits 31:0 */
A_UINT32 reserved1c; /* bits 31:0 */
A_UINT32 reserved1d; /* bits 31:0 */
A_UINT32 reserved1e; /* bits 31:0 */
A_UINT32 reserved1f; /* bits 31:0 */
};
struct {
A_UINT32 tx_msduq_number: 24, /* bits 23:0 */
svc_class_id: 8; /* bits 31:24 */
A_UINT32 msduq_address_39_8; /* bits 31:0 */
A_UINT32 reserved2a; /* bits 31:0 */
A_UINT32 reserved2b; /* bits 31:0 */
A_UINT32 reserved2c; /* bits 31:0 */
A_UINT32 reserved2d; /* bits 31:0 */
A_UINT32 reserved2e; /* bits 31:0 */
A_UINT32 reserved2f; /* bits 31:0 */
A_UINT32 reserved2g; /* bits 31:0 */
};
};
} POSTPACK;
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_M 0x00001F00
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_S 8
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_MSDUQ_MPDUQ_TYPE_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_M 0x0001E000
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_S 13
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_INFO_HW_LINK_ID_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_M 0x00000FFF
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_S 0
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_PEER_ID_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_M 0x0001F000
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_S 12
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_TID_NUM_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_M 0x003E0000
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_S 17
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_OR_MSDUQ_NUMBER_MSDUQ_MPDUQ_TYPE_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_M 0xFFFFFFFF
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_S 0
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_ADDRESS_39_8_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_M 0x00FFFFFF
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_S 0
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_GET(_var) \
(((_var) & HTT_H2T_MSG_MPDUQ_INFO_MPDUQ_NUMBER_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_INFO_MPDUQ_NUMBER_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_M 0xFF000000
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_S 24
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_39_32_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_M 0xFFFFFFFF
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_S 0
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_M) >> \
HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_S)
#define HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MPDUQ_INFO_PN_ADDRESS_31_0_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_M 0x00FFFFFF
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_S 0
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_M) >> \
HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_S)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MSDUQ_INFO_TX_MSDUQ_NUMBER_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_M 0xFF000000
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_S 24
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_M) >> \
HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_S)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MSDUQ_INFO_SVC_CLASS_ID_S)); \
} while (0)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_M 0xFFFFFFFF
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_S 0
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_GET(_var) \
(((_var) & HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_M) >> \
HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_S)
#define HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8, _val); \
((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MSDUQ_INFO_MSDUQ_ADDRESS_39_8_S)); \
} while (0)
/*
* @brief host -> target HTT_AST_INFO message
*
* MSG_TYPE => HTT_H2T_MSG_TYPE_AST_INFO
*
* The message would appear as follows:
* |31 24|23 21|20|19|18|17|16|15 8|7 0|
* |--------------+-------------------------------------+-------------------|
* |ast_max_search| ast_table_size | msg_type |
* |------------------------------------------------------------------------|
* | ast_base_addr_31_0 |
* |------------------------------------------------------------------------|
* | ase_hash_key1 |
* |------------------------------------------------------------------------|
* | ase_hash_key2 |
* |------------------------------------------------------------------------|
* | ase_hash_key3 |
* |--------------------+--+--+--+--+--+----------------+-------------------|
* | reserved |L |K |J |I |H | tmo |ast_base_addr_39_32|
* |--------------------+--+--+--+--+--+----------------+-------------------|
*
* The message is interpreted as follows:
* dword0 b'7:0 - msg_type
* 0 b'23:8 - ast table size
* b'31:24 - ast max search
* dword1 - b'31:0 - ast table base address
* dword2 - b'31:0 - ase hash key 1
* dword3 - b'31:0 - ase hash key 2
* dword4 - b'31:0 - ase hash key 3
* dword5 - b'7:0 - ast_base_addr_39_32
* b'15:8 - ast_timeout_threshold
* b'16 - H - ast cache disable knob
* b'17 - I - ast cache faluires disable knob
* b'18 - J - ast cache cmd read bypass
* Bypassing the reads from memory when an entry is not
* found in cache, in case of full cache commands,
* write back or invalidate commands.
* b'19 - K - ast cache write back fx
* If this fix is disabled, then any write back command
* for a cache line will also lead to invalidation of
* that cache line.
* b'20 - L - ast cache only entry command fix
* If enabled, a new cache entry will always be created
* for requests for which matching data was found
* neither in cache nor in memory.
*/
PREPACK struct htt_ast_info_t {
A_UINT32 msg_type: 8,
ast_table_size: 16, /* number of entries in AST */
ast_max_search: 8;
A_UINT32 ast_base_addr; /* base address of the AST table */
A_UINT32 ase_hash_key1;
A_UINT32 ase_hash_key2;
A_UINT32 ase_hash_key3;
A_UINT32 ast_base_addr_39_32: 8, /* 7:0 */
ast_timeout_threshold: 8, /* 15:8 */
ast_cache_disable: 1, /* 16 */
ast_cache_failures_disable: 1, /* 17 */
ast_cache_cmd_read_bypass_dis: 1, /* 18 */
ast_cache_write_back_fix_dis: 1, /* 19 */
ast_cache_only_entry_cmd_fix_dis: 1, /* 20 */
reserved: 11;
} POSTPACK;
#define HTT_AST_INFO_SZ (sizeof(struct htt_ast_info_t))
/* DWORD0 */
#define HTT_AST_INFO_AST_TABLE_SIZE_M 0x00ffff00
#define HTT_AST_INFO_AST_TABLE_SIZE_S 8
#define HTT_AST_INFO_AST_TABLE_SIZE_GET(_var) \
(((_var) & HTT_AST_INFO_AST_TABLE_SIZE_M) >> \
HTT_AST_INFO_AST_TABLE_SIZE_S)
#define HTT_AST_INFO_AST_TABLE_SIZE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_TABLE_SIZE, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_TABLE_SIZE__S)); \
} while (0)
#define HTT_AST_INFO_AST_MAX_SEARCH_M 0xff000000
#define HTT_AST_INFO_AST_MAX_SEARCH_S 24
#define HTT_AST_INFO_AST_MAX_SEARCH_GET(_var) \
(((_var) & HTT_AST_INFO_AST_MAX_SEARCH_M) >> \
HTT_AST_INFO_AST_MAX_SEARCH_S)
#define HTT_AST_INFO_AST_MAX_SEARCH_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_MAX_SEARCH, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_MAX_SEARCH_S)); \
} while (0)
/* DWORD5 */
#define HTT_AST_INFO_AST_BASE_ADDR_39_32_M 0x000000ff
#define HTT_AST_INFO_AST_BASE_ADDR_39_32_S 0
#define HTT_AST_INFO_AST_BASE_ADDR_39_32_GET(_var) \
(((_var) & HTT_AST_INFO_AST_BASE_ADDR_39_32_M) >> \
HTT_AST_INFO_AST_BASE_ADDR_39_32_S)
#define HTT_AST_INFO_AST_BASE_ADDR_39_32_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_BASE_ADDR_39_32, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_BASE_ADDR_39_32_S)); \
} while (0)
#define HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_M 0x0000ff00
#define HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_S 8
#define HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_GET(_var) \
(((_var) & HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_M) >> \
HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_S)
#define HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_TIMEOUT_THRESHOLD, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_TIMEOUT_THRESHOLD_S)); \
} while (0)
#define HTT_AST_INFO_AST_CACHE_DISABLE_M 0x00010000
#define HTT_AST_INFO_AST_CACHE_DISABLE_s 16
#define HTT_AST_INFO_AST_CACHE_DISABLE_GET(_var) \
(((_var) & HTT_AST_INFO_AST_CACHE_DISABLE_M) >> \
HTT_AST_INFO_AST_CACHE_DISABLE_s)
#define HTT_AST_INFO_AST_CACHE_DISABLE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_CACHE_DISABLE, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_CACHE_DISABLE_S)); \
} while (0)
#define HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_M 0x00020000
#define HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_s 17
#define HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_GET(_var) \
(((_var) & HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_M) >> \
HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_s)
#define HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_CACHE_FALUIRES_DISABLE_S)); \
} while (0)
#define HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_M 0x00040000
#define HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_s 18
#define HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_GET(_var) \
(((_var) & HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_M) >> \
HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_s)
#define HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_CACHE_CMD_READ_BYPASS_DIS_S)); \
} while (0)
#define HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_M 0x00080000
#define HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_s 19
#define HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_GET(_var) \
(((_var) & HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_M) >> \
HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_s)
#define HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_CACHE_WRITE_BACK_FIX_DIS_S)); \
} while (0)
#define HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_M 0x00100000
#define HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_s 20
#define HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_GET(_var) \
(((_var) & HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_M) >> \
HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_s)
#define HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS, _val); \
((_var) |= ((_val) << HTT_AST_INFO_AST_CACHE_ONLY_ENTRY_CMD_FIX_DIS_S)); \
} while (0)
/*=== target -> host messages ===============================================*/
@ -11659,6 +12185,8 @@ enum htt_t2h_msg_type {
HTT_T2H_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP_DONE = 0x3b,
HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND = 0x3c,
HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ = 0x3d,
HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP = 0x3e,
HTT_T2H_MSG_TYPE_HAPS = 0x3f,
HTT_T2H_MSG_TYPE_TEST,
@ -14661,40 +15189,41 @@ PREPACK struct htt_tx_offload_deliver_ind_hdr_t
* with, so that the host can use that MLO peer ID to determine which peer
* transmitted the rx frame.
*
* |31 |29 27|26 24|23 20|19 17|16|15 8|7 0|
* |-------------------------------------------------------------------------|
* |RSVD | PRC |NUMLINK| MLO peer ID | msg type |
* |-------------------------------------------------------------------------|
* | MAC addr 3 | MAC addr 2 | MAC addr 1 | MAC addr 0 |
* |-------------------------------------------------------------------------|
* | RSVD_16_31 | MAC addr 5 | MAC addr 4 |
* |-------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 0 |
* |-------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 1 |
* |-------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 2 |
* |-------------------------------------------------------------------------|
* |RSVD |
* |-------------------------------------------------------------------------|
* |RSVD |
* |-------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |-------------------------------------------------------------------------|
* |RSVD_27_31 |CHIPID| VDEVID | SW peer ID |
* |-------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |-------------------------------------------------------------------------|
* |RSVD_27_31 |CHIPID| VDEVID | SW peer ID |
* |-------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |-------------------------------------------------------------------------|
* |RSVD_27_31 |CHIPID| VDEVID | SW peer ID |
* |-------------------------------------------------------------------------|
* |31 |29 27|26|25|24|23 20|19 17|16|15 8|7 0|
* |--------------------------------------------------------------------------|
* |RSVD | PRC | NUMLINK| MLO peer ID | msg type |
* |--------------------------------------------------------------------------|
* | MAC addr 3 | MAC addr 2 | MAC addr 1 | MAC addr 0 |
* |--------------------------------------------------------------------------|
* | RSVD_25_31 |CV| CLASS_INFO_IDX | MAC addr 5 | MAC addr 4 |
* |--------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 0 |
* |--------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 1 |
* |--------------------------------------------------------------------------|
* |CACHE_SET_NUM| TIDMASK |CHIPID|V| Primary TCL AST IDX 2 |
* |--------------------------------------------------------------------------|
* |RSVD |
* |--------------------------------------------------------------------------|
* |RSVD |
* |--------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |--------------------------------------------------------------------------|
* |RSVD_27_31 | CHIPID | VDEVID | SW peer ID |
* |--------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |--------------------------------------------------------------------------|
* |RSVD_27_31 | CHIPID | VDEVID | SW peer ID |
* |--------------------------------------------------------------------------|
* | htt_tlv_hdr_t |
* |--------------------------------------------------------------------------|
* |RSVD_27_31 | CHIPID | VDEVID | SW peer ID |
* |--------------------------------------------------------------------------|
*
* Where:
* PRC - Primary REO CHIPID - 3 Bits Bit24,25,26
* NUMLINK - NUM_LOGICAL_LINKS - 3 Bits Bit27,28,29
* CV - CLASSIFY_INFO_IDX_VALID - 1 Bit Bit24
* V (valid) - 1 Bit Bit17
* CHIPID - 3 Bits
* TIDMASK - 8 Bits
@ -14734,6 +15263,16 @@ PREPACK struct htt_tx_offload_deliver_ind_hdr_t
* Purpose: Identifies which peer node the peer ID is for.
* Value: upper 2 bytes of peer node's MAC address
*
* - CLASS_INFO_IDX
* Bits 23:16
* Purpose: Classify info index assists TCL-L Block in certain families of
* WLAN chips to start finding the flow from the corresponding
* entry in the FLOW LOOK UP TABLE in MLO case
* - CV (CLASS_INFO_IDX_VALID)
* Bit 24
* Purpose: if set indicates that the CLASS_INFO_IDX is valid,
* else ignore the value reported
*
* - PRIMARY_TCL_AST_IDX
* Bits 15:0
* Purpose: Primary TCL AST index for this peer.
@ -14805,6 +15344,11 @@ typedef enum {
#define HTT_RX_MLO_PEER_MAP_MAC_ADDR_U16_M 0x0000ffff
#define HTT_RX_MLO_PEER_MAP_MAC_ADDR_U16_S 0
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_M 0x00ff0000
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_S 16
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_M 0x01000000
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_S 24
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_M 0x0000ffff
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_S 0
#define HTT_RX_MLO_PEER_MAP_AST_INDEX_VALID_FLAG_M 0x00010000
@ -14853,6 +15397,30 @@ typedef enum {
#define HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_GET(word) \
(((word) & HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_M) >> HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_S)
#define HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_SET(word, value) \
do { \
HTT_CHECK_SET_VAL(HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID, value); \
(word) |= (value) << HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_S; \
} while (0)
#define HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_GET(word) \
(((word) & HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_M) >> HTT_RX_MLO_PEER_PRIMARY_REO_CHIP_ID_S)
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_SET(word, value) \
do { \
HTT_CHECK_SET_VAL(HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX, value); \
(word) |= (value) << HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_S; \
} while (0)
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_GET(word) \
(((word) & HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_M) >> HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_S)
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_SET(word, value) \
do { \
HTT_CHECK_SET_VAL(HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG, value); \
(word) |= (value) << HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_S; \
} while (0)
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_GET(word) \
(((word) & HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_M) >> HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_S)
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_SET(word, value) \
do { \
HTT_CHECK_SET_VAL(HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX, value); \
@ -14935,6 +15503,8 @@ typedef enum {
#define HTT_RX_MLO_PEER_MAP_MAC_ADDR_OFFSET 4 /* bytes */
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_OFFSET 8 /* bytes */
#define HTT_RX_MLO_PEER_MAP_CLASSIFY_INFO_IDX_VALID_FLAG_OFFSET 8 /* bytes */
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_0_OFFSET 12 /* bytes */
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_1_OFFSET 16 /* bytes */
#define HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_2_OFFSET 20 /* bytes */
@ -23449,4 +24019,177 @@ PREPACK struct htt_t2h_mlo_latency_req_t {
} while (0)
/* MSG_TYPE => HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP
*
* The following diagram shows the format of the global peer unmap message sent
* from the target to the host. This message is used to send unmap event to host
* after tid and msduq/mpduq cleanup in FW, host cleans up msduq/mpduq based on
* message.
*
* |31 24|23 20|19 8|7 0|
* |-----------------------------------------------------------------------|
* | reserved | hw_link_id | global_peer_id | msg type |
* |-----------------------------------------------------------------------|
* @details
* struct htt_t2h_global_peer_id_unmap_t:
*
* The message is interpreted as follows:
* dword0 - b'7:0 - msg_type: Identifies a request for MLO latency stats
* This will be set to 0x3e
* (HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP)
* b'19:8 - global_peer_id : global peer id assigned by host
* b'23:20 - hw_link_id : hw link id for which unmap is being sent
*
*/
/* HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP */
PREPACK struct htt_t2h_global_peer_id_unmap_t {
A_UINT32 msg_type: 8, /* bits 7:0 */
global_peer_id: 12, /* bits 19:8 */
hw_link_id: 4, /* bits 23:20 */
reserved: 8; /* bits 31:16 */
} POSTPACK;
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_M 0x000FFF00
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_S 8
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_GET(_var) \
(((_var) & HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_M) >> \
HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_S)
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID, _val); \
((_var) |= ((_val) << HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_GLOBAL_PEER_ID_S)); \
} while (0)
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_M 0x00F00000
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_S 20
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_GET(_var) \
(((_var) & HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_M) >> \
HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_S)
#define HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID, _val); \
((_var) |= ((_val) << HTT_T2H_MSG_TYPE_GLOBAL_PEER_ID_UNMAP_HW_LINK_ID_S)); \
} while (0)
/*
* @brief target -> pause/unpause host tx queues based on FW indication
* MSG_TYPE => HTT_T2H_MSG_TYPE_HAPS
*
* @details * Header fields:
*
* |31 22|21 20|19 16|15 8|7 0|
* |---------+-------------+-----------+------------------+---------------|
* | RSVD |time_type |action_code| vdev_id | msg type |
* |----------------------------------------------------------------------|
* | time_high |
* |----------------------------------------------------------------------|
* | time_low |
* |----------------------------------------------------------------------|
*
* dword0 - b'7:0 - msg_type: This will be set to
* 0x3f (HTT_T2H_MSG_TYPE_HAPS)
* b'15:8 - vdev_id
* b'19:16 - action_code (HTT_T2H_HAPS_ACTION_CODE):
* b'0000: Pause
* b'0001: Pause with One-Shot Unpause
* b'0010: Unpause
* values 3-15: reserved
* b'21:20 - time_type
* b'31:22 - rsvd
* reverse action_code at time specified below
* (units are specified by the type_type bitfield)
* dword1 - b'31:0 uint32_t time_high
* dword2 - b'31:0 uint32_t time_low
*/
typedef enum {
HTT_T2H_HAPS_ACTION_PAUSE = 0x00,
HTT_T2H_HAPS_ACTION_PAUSE_WITH_ONESHOT_UNPAUSE = 0x01,
HTT_T2H_HAPS_ACTION_UNPAUSE = 0x02,
} HTT_T2H_HAPS_ACTION_CODE;
typedef enum {
HTT_T2H_HAPS_TIME_TYPE_HOST_QTIME = 0x00,
HTT_T2H_HAPS_TIME_TYPE_TSF = 0x01,
} HTT_T2H_HAPS_TIME_TYPE;
PREPACK struct htt_t2h_power_state_info {
uint32_t msg_type : 8, /* [7:0] */
vdev_id : 8, /* [15:8] */
action_code : 4, /* [19:16] */
time_type: 2, /* [21:20] */
rsvd: 10; /* [31:22] */
uint32_t time_low;
uint32_t time_high;
} POSTPACK;
#define HTT_T2H_POWER_STATE_INFO_SIZE (sizeof(struct htt_t2h_power_state_info))
#define HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_M 0x0000FF00
#define HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_S 8
#define HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_GET(_var) \
(((_var) & HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_M) >> \
HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_S)
#define HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID, _val); \
((_var) |= ((_val) << HTT_T2H_POWER_STATE_INFO_HTT_VDEV_ID_S));\
} while (0)
#define HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_M 0x000F0000
#define HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_S 16
#define HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_GET(_var) \
(((_var) & HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_M) >> \
HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_S)
#define HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE, _val); \
((_var) |= ((_val) << HTT_T2H_POWER_STATE_INFO_HTT_ACTION_CODE_S));\
} while (0)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_M 0x00300000
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_S 20
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_GET(_var) \
(((_var) & HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_M) >> \
HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_S)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE, _val); \
((_var) |= ((_val) << HTT_T2H_POWER_STATE_INFO_HTT_TIME_TYPE_S));\
} while (0)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_M 0xFFFFFFFF
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_S 0
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_GET(_var) \
(((_var) & HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_M) >> \
HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_S)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH, _val); \
((_var) |= ((_val) << HTT_T2H_POWER_STATE_INFO_HTT_TIME_HIGH_S));\
} while (0)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_M 0xFFFFFFFF
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_S 0
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_GET(_var) \
(((_var) & HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_M) >> \
HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_S)
#define HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW, _val); \
((_var) |= ((_val) << HTT_T2H_POWER_STATE_INFO_HTT_TIME_LOW_S));\
} while (0)
#endif

View file

@ -707,6 +707,58 @@ typedef enum HTT_PPDU_STATS_SPATIAL_REUSE HTT_PPDU_STATS_SPATIAL_REUSE;
(((_val) & HTT_PPDU_STATS_COMMON_TRIG_COOKIE_M) >> \
HTT_PPDU_STATS_COMMON_TRIG_COOKIE_S)
#define HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_M 0x00000001
#define HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_S 0
#define HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_GET(_var) \
(((_var) & HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_M) >> \
HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_S)
#define HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE, _val); \
((_var) |= ((_val) << HTT_PPDU_STATS_COMMON_TLV_HTT_SEQ_TYPE_S)); \
} while (0)
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_M 0x00000002
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_S 1
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_GET(_var) \
(((_var) & HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_M) >> \
HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_S)
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER, _val); \
((_var) |= ((_val) << HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BASIC_TRIGGER_S)); \
} while (0)
#define HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_M 0x00000004
#define HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_S 2
#define HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_GET(_var) \
(((_var) & HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_M) >> \
HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_S)
#define HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER, _val); \
((_var) |= ((_val) << HTT_PPDU_STATS_COMMON_TLV_IS_MANUAL_ULOFDMA_TRIGGER_S)); \
} while (0)
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_M 0x00000008
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_S 3
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_GET(_var) \
(((_var) & HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_M) >> \
HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_S)
#define HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_SET(_var, _val) \
do { \
HTT_CHECK_SET_VAL(HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER, _val); \
((_var) |= ((_val) << HTT_PPDU_STATS_COMMON_TLV_IS_COMBINED_UL_BSRP_TRIGGER_S)); \
} while (0)
enum HTT_SEQ_TYPE {
WAL_PPDU_SEQ_TYPE = 0,
HTT_PPDU_SEQ_TYPE = 1,
@ -902,26 +954,26 @@ typedef struct {
* HTT_PPDU_SEQ_TYPE then decoder should interpret the
* seq type as HTT_PPDU_STATS_SEQ_TYPE.
* htt_seq_type field will be set to HTT_PPDU_SEQ_TYPE in
* firmware versions where this field is defined.
* BIT [31: 1] - reserved
* BIT [1 : 1] - is_combined_ul_basic_trigger - Flag to indicate if a
* given UL OFDMA/MU-MIMO Basic trigger is sent combined
* as part of existing DL data sequence.
* BIT [2 : 2] - is_manual_ulofdma_trigger - Flag to indicate if a
* given UL OFDMA trigger is manually triggered from the Host.
* BIT [3 : 3] - is_combined_ul_bsrp_trigger - Flag to indicate if a
* given UL BSRP trigger is sent combined as part of
* an existing DL/UL data sequence
* BIT [31: 4] - reserved
*/
union {
A_UINT32 reserved__htt_seq_type;
struct {
A_UINT32 htt_seq_type: 1,
reserved3: 31;
is_combined_ul_basic_trigger: 1,
is_manual_ulofdma_trigger: 1,
is_combined_ul_bsrp_trigger: 1,
reserved3: 28;
};
};
/* is_manual_ulofdma_trigger:
* Flag to indicate if a given UL OFDMA trigger is manually triggered
* from the Host
*/
A_UINT32 is_manual_ulofdma_trigger;
/* is_combined_ul_bsrp_trigger:
* Flag to indicate if a given UL BSRP trigger is sent combined as
* part of existing DL/UL data sequence
*/
A_UINT32 is_combined_ul_bsrp_trigger;
/* Flag to indicate if the channel chosen is 320_1 / 320_2 */
A_UINT32 chan_type_320mhz;
} htt_ppdu_stats_common_tlv;

File diff suppressed because it is too large Load diff

View file

@ -161,6 +161,18 @@ typedef enum {
MODE_11BE_EHT40_2G = 32, /* For WIN */
#endif
#if defined(SUPPORT_11BN) && SUPPORT_11BN
MODE_11BN_UHR20 = 33,
MODE_11BN_UHR40 = 34,
MODE_11BN_UHR80 = 35,
MODE_11BN_UHR80_80 = 36,
MODE_11BN_UHR160 = 37,
MODE_11BN_UHR160_160 = 38,
MODE_11BN_UHR320 = 39,
MODE_11BN_UHR20_2G = 40,
MODE_11BN_UHR40_2G = 41,
#endif
/*
* MODE_UNKNOWN should not be used within the host / target interface.
* Thus, it is permissible for MODE_UNKNOWN to be conditionally-defined,
@ -262,6 +274,20 @@ typedef enum {
((mode) == MODE_11BE_EHT40_2G))
#endif /* SUPPORT_11BE */
#if defined(SUPPORT_11BN) && SUPPORT_11BN
#define IS_MODE_UHR(mode) (((mode) == MODE_11BN_UHR20) || \
((mode) == MODE_11BN_UHR40) || \
((mode) == MODE_11BN_UHR80) || \
((mode) == MODE_11BN_UHR80_80) || \
((mode) == MODE_11BN_UHR160) || \
((mode) == MODE_11BN_UHR160_160)|| \
((mode) == MODE_11BN_UHR320) || \
((mode) == MODE_11BN_UHR20_2G) || \
((mode) == MODE_11BN_UHR40_2G))
#define IS_MODE_UHR_2G(mode) (((mode) == MODE_11BN_UHR20_2G) || \
((mode) == MODE_11BN_UHR40_2G))
#endif /* SUPPORT_11BN */
#define IS_MODE_VHT_2G(mode) (((mode) == MODE_11AC_VHT20_2G) || \
((mode) == MODE_11AC_VHT40_2G) || \
((mode) == MODE_11AC_VHT80_2G))

View file

@ -196,6 +196,8 @@ typedef enum {
WLAN_MODULE_C2C, /* 0x98 */
WLAN_MODULE_VBSS, /* 0x99 */
WLAN_MODULE_OPT_DATA, /* 0x9a */
WLAN_MODULE_ASD, /* 0x9b */
WLAN_MODULE_ENERGY_MGMT, /* 0x9c */
WLAN_MODULE_ID_MAX,
WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX,

View file

@ -695,6 +695,32 @@ typedef enum {
WMI_SERVICE_UMAC_MIGRATION_SUPPORT = 436, /* Indicates that FW supports UMAC migration */
WMI_SERVICE_STA_TWT_STATS_EXT = 437, /* FW supports additional info in TWT stats and ADD COMPLETION Event */
WMI_SERVICE_OPT_DP_DIAG_SUPPORT = 438, /* FW supports diag QDATA feature */
WMI_SERVICE_MLO_ROAM_PARTNER_BRINGUP_FROM_HOST = 439, /* Indicates FW supports new design in which FW expects the host to bringup the partner link during roaming */
WMI_SERVICE_CTRL_PATH_PEER_BA_STATS = 440, /* FW supports retrieving BlockAck stats through WMI_REQUEST_CTRL_PATH_PEER_STAT */
WMI_SERVICE_CTRL_PATH_STA_DAR_STATS_SUPPORT = 441, /* FW supports DAR stats reporting for STA mode */
WMI_SERVICE_APF_DATA_OFFLOAD_SUPPORT_ENABLED = 442, /* Indicates FW support for APFv6 handling offloads and disable QC data offloads */
WMI_SERVICE_PER_VDEV_TWT_RESP_DISABLE_SUPPORT = 443, /* FW supports vdev level TWT responder disable */
WMI_SERVICE_VENDOR_OUI_ACTION_V2 = 444, /* FW supports vendor OUI action version 2 */
WMI_SERVICE_HW_BLACKLIST_CHAN_SUPPORT = 445, /* Indicates FW support for computing and sending the HW channel blacklist for the current country and applicable power mode */
WMI_SERVICE_NDP_DFS_CHANNEL_SUPPORT = 446, /* FW supports forming NDP on DFS channels */
WMI_SERVICE_WFD_R2 = 447, /* Indicates FW supports WiFi-Direct R2 */
WMI_SERVICE_STA_MLO_RCFG_SUPPORT = 448, /* FW supports STA ML reconfig op */
WMI_SERVICE_PDEV_SUSPEND_EVENT_SUPPORT = 449, /* FW supports PDEV_SUSPEND event */
WMI_SERVICE_PCC_MODE = 450, /* Indicates FW support for PCC (P2P Connection Compatibility) Mode */
WMI_SERVICE_TDLS_NSS_CONFIRM_SUPPORT = 451, /* FW supports confirmation to host requested TDLS NSS operation */
WMI_SERVICE_EM_PCIE_CONFIG_CBW_SUPPORT = 452, /* Indicates support for channel bandwidth based PCIe config adjustment */
WMI_SERVICE_EM_PCIE_CONFIG_LPM_SUPPORT = 453, /* Indicates support for PCIe low power mode L0S/L1 */
WMI_SERVICE_EM_DCVS_SUPPORT = 454, /* Indicates support for Dynamic clock and voltage scaling */
WMI_SERVICE_EM_EDPS_SUPPORT = 455, /* Indicates support for Dynamic AP power save */
WMI_SERVICE_EM_PUO_SUPPORT = 456, /* Indicates support for TWT based periodic unavailability operation. */
WMI_SERVICE_EM_ECO_MODE_SUPPORT = 457, /* Indicates support for ECO mode config (LP BBF+ADC+SYNCT) */
WMI_SERVICE_11BN = 458, /* Indicates FW supports 802.11bn */
WMI_SERVICE_HOST_AWARE_POWERSAVE = 459, /* FW supports indicating the powerstate of FW to host */
WMI_SERVICE_PDEV_DIV_STATES_REPORT = 460, /* FW supports reporting antenna diversity states */
WMI_SERVICE_EAPOL_OVER_RAW = 461, /* FW supports sending EAPOL frames in raw mode even when the vdev is brought up in nwifi/ethernet mode */
WMI_SERVICE_MLO_SAP_LINK_REMOVAL_SUPPORT = 462, /* Indicates FW supports MLO SAP link removal operation */
WMI_MAX_EXT2_SERVICE

View file

@ -1476,6 +1476,29 @@ typedef enum {
WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_sn_info,
WMITLV_TAG_STRUC_wmi_vdev_vbss_config_event_fixed_param,
WMITLV_TAG_STRUC_wmi_stats_ext_event_vdev_ext2_t,
WMITLV_TAG_STRUC_wmi_ndp_set_latency_tput_fixed_param,
WMITLV_TAG_STRUC_wmi_roam_partner_link_param,
WMITLV_TAG_STRUC_wmi_mlo_link_ttlm_complete_fixed_param,
WMITLV_TAG_STRUC_wmi_ctrl_path_sta_dar_stats_struct,
WMITLV_TAG_STRUC_wmi_bpf_set_supported_offload_bitmap_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_hw_blacklist_chan_fixed_param,
WMITLV_TAG_STRUC_wmi_hw_blacklist_chan_data,
WMITLV_TAG_STRUC_wmi_pdev_suspend_event_fixed_param,
WMITLV_TAG_STRUC_wmi_bpf_set_apf_mode_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_peer_assoc_operating_mode_params,
WMITLV_TAG_STRUC_wmi_recv_bcn_stats,
WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_dyn_info,
WMITLV_TAG_STRUC_wmi_energy_mgmt_pcie_config_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_energy_mgmt_pcie_lpm_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_energy_mgmt_dcvs_config_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_energy_mgmt_edps_config_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_energy_mgmt_puo_config_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_energy_mgmt_eco_mode_config_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_peer_assoc_mgmt_mpduq_params,
WMITLV_TAG_STRUC_wmi_peer_assoc_mgmt_msduq_params,
WMITLV_TAG_STRUC_wmi_peer_assoc_hol_mdsuq_params,
WMITLV_TAG_STRUC_wmi_peer_tid_rate_custom_cmd_fixed_param,
WMITLV_TAG_STRUC_wmi_co_located_chan_info,
} WMITLV_TAG_ID;
/*
* IMPORTANT: Please add _ALL_ WMI Commands Here.
@ -2037,6 +2060,17 @@ typedef enum {
OP(WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID) \
OP(WMI_SAWF_EZMESH_HOP_COUNT_CMDID) \
OP(WMI_VDEV_VBSS_CONFIG_CMDID) \
OP(WMI_NDP_SET_LATENCY_TPUT_CMDID) \
OP(WMI_MLO_LINK_TTLM_COMPLETE_CMDID) \
OP(WMI_BPF_SET_SUPPORTED_OFFLOAD_BITMAP_CMDID) \
OP(WMI_BPF_SET_APF_MODE_CMDID) \
OP(WMI_ENERGY_MGMT_PCIE_CONFIG_CMDID) \
OP(WMI_ENERGY_MGMT_PCIE_LPM_CMDID) \
OP(WMI_ENERGY_MGMT_DCVS_CONFIG_CMDID) \
OP(WMI_ENERGY_MGMT_EDPS_CONFIG_CMDID) \
OP(WMI_ENERGY_MGMT_PUO_CONFIG_CMDID) \
OP(WMI_ENERGY_MGMT_ECO_MODE_CONFIG_CMDID) \
OP(WMI_PEER_TID_RATE_CUSTOM_CMDID) \
/* add new CMD_LIST elements above this line */
@ -2372,6 +2406,8 @@ typedef enum {
OP(WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID) \
OP(WMI_VDEV_VBSS_CONFIG_EVENTID) \
OP(WMI_OPT_DP_DIAG_EVENTID) \
OP(WMI_HW_BLACKLIST_CHAN_EVENTID) \
OP(WMI_PDEV_SUSPEND_EVENTID) \
/* add new EVT_LIST elements above this line */
@ -2867,7 +2903,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_mlo_params, mlo_params, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_eht_rate_set, peer_eht_rates, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_mlo_partner_link_params, partner_link_params, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_tid_to_link_map, peer_tid_to_link_map, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_tid_to_link_map, peer_tid_to_link_map, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_operating_mode_params, operating_mode_params, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_mgmt_mpduq_params, mgmt_mpduq_params, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_mgmt_msduq_params, mgmt_msduq_params, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_assoc_hol_mdsuq_params, hol_mdsuq_params, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ASSOC_CMDID);
@ -3611,7 +3651,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_DELETE_CMDID);
/* Vdev up Cmd */
#define WMITLV_TABLE_WMI_VDEV_UP_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, wmi_vdev_up_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, wmi_vdev_up_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_co_located_chan_info, co_located_chan_info, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_UP_CMDID);
@ -3643,7 +3684,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_UPDATE_MAC_ADDR_CMDID);
#define WMITLV_TABLE_WMI_VDEV_VBSS_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_vbss_config_cmd_fixed_param, wmi_vdev_vbss_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_pn_info, vbss_peer_pn_info, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_sn_info, vbss_peer_sn_info, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_sn_info, vbss_peer_sn_info, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_dyn_info, vbss_peer_dyn_info, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_VBSS_CONFIG_CMDID);
/* Pdev suspend Cmd */
@ -4099,6 +4141,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_NDP_END_REQ_CMDID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ndp_cmd_param, wmi_ndp_cmd_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_NDP_CMDID);
/* NDP Set Latency Tput Cmd */
#define WMITLV_TABLE_WMI_NDP_SET_LATENCY_TPUT_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ndp_set_latency_tput_fixed_param, wmi_ndp_set_latency_tput_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_NDP_SET_LATENCY_TPUT_CMDID);
/* RCPI Info Request Cmd */
#define WMITLV_TABLE_WMI_REQUEST_RCPI_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, wmi_request_rcpi_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
@ -5384,6 +5431,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECONFIG_CMDID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_complete_fixed_param, wmi_mlo_link_reconfig_complete_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID);
/** WMI cmd to notify fw completion of link TTLM negotiation */
#define WMITLV_TABLE_WMI_MLO_LINK_TTLM_COMPLETE_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_link_ttlm_complete_fixed_param, wmi_mlo_link_ttlm_complete_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_TTLM_COMPLETE_CMDID);
/* Mcast ipv4 address filter list cmd */
#define WMITLV_TABLE_WMI_VDEV_IGMP_OFFLOAD_CMDID(id,op,buf,len) \
WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_igmp_offload_fixed_param, wmi_igmp_offload_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
@ -5745,6 +5797,50 @@ WMITLV_CREATE_PARAM_STRUC(WMI_GET_SCAN_CACHE_RESULT_CMDID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sawf_ezmesh_hop_count_cmd_fixed_param, wmi_sawf_ezmesh_hop_count_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_SAWF_EZMESH_HOP_COUNT_CMDID);
#define WMITLV_TABLE_WMI_BPF_SET_SUPPORTED_OFFLOAD_BITMAP_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bpf_set_supported_offload_bitmap_cmd_fixed_param, wmi_bpf_set_supported_offload_bitmap_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_BPF_SET_SUPPORTED_OFFLOAD_BITMAP_CMDID);
#define WMITLV_TABLE_WMI_BPF_SET_APF_MODE_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bpf_set_apf_mode_cmd_fixed_param, wmi_bpf_set_apf_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_BPF_SET_APF_MODE_CMDID);
/* WMI cmd used to control PCIe config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_PCIE_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_pcie_config_cmd_fixed_param, wmi_energy_mgmt_pcie_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_PCIE_CONFIG_CMDID);
/* WMI cmd used for PCIe LPM config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_PCIE_LPM_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_pcie_lpm_cmd_fixed_param, wmi_energy_mgmt_pcie_lpm_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_PCIE_LPM_CMDID);
/* WMI cmd used to control DCVS config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_DCVS_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_dcvs_config_cmd_fixed_param, wmi_energy_mgmt_dcvs_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_DCVS_CONFIG_CMDID);
/* WMI cmd used to control Dynamic AP Power Save config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_EDPS_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_edps_config_cmd_fixed_param, wmi_energy_mgmt_edps_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_EDPS_CONFIG_CMDID);
/* WMI cmd used to control Scheduled AP Power Save config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_PUO_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_puo_config_cmd_fixed_param, wmi_energy_mgmt_puo_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_PUO_CONFIG_CMDID);
/* WMI cmd used to control Un-scheduled AP Power Save config */
#define WMITLV_TABLE_WMI_ENERGY_MGMT_ECO_MODE_CONFIG_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_energy_mgmt_eco_mode_config_cmd_fixed_param, wmi_energy_mgmt_eco_mode_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_ENERGY_MGMT_ECO_MODE_CONFIG_CMDID);
/* peer tid rate customization cmd */
#define WMITLV_TABLE_WMI_PEER_TID_RATE_CUSTOM_CMDID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_tid_rate_custom_cmd_fixed_param, wmi_peer_tid_rate_custom_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, rate_code, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_PEER_TID_RATE_CUSTOM_CMDID);
/************************** TLV definitions of WMI events *******************************/
@ -6092,7 +6188,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_AGGR_STATE_TRIG_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, deauth_disassoc_frame, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_hw_mode_transition_event_fixed_param, hw_mode_transition_fixed_param, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_set_hw_mode_response_vdev_mac_entry, wmi_pdev_set_hw_mode_response_vdev_mac_mapping, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_bss_info_param, bss_info_param, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_bss_info_param, bss_info_param, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_partner_link_param, partner_link_param, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_EVENTID);
/* Roam Synch Event */
@ -6365,7 +6462,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_HOST_SWFDA_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pmf_bcn_protect_stats, pmf_bcn_protect_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_extd_stats, vdev_extd_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_extd_stats, pdev_extd_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_telemetry_stats, pdev_telemetry_stats, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_telemetry_stats, pdev_telemetry_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_recv_bcn_stats, recv_bcn_stats, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_STATS_EVENTID);
/* Update PN response Event */
@ -6801,6 +6899,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_STATS_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_resume_event_fixed_param, wmi_pdev_resume_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_RESUME_EVENTID);
/* pdev suspend event */
#define WMITLV_TABLE_WMI_PDEV_SUSPEND_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_suspend_event_fixed_param, wmi_pdev_suspend_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SUSPEND_EVENTID);
/* SAP Authentication offload event */
#define WMITLV_TABLE_WMI_SAP_OFL_ADD_STA_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sap_ofl_add_sta_event_fixed_param, wmi_sap_ofl_add_sta_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \
@ -6954,7 +7057,9 @@ WMITLV_CREATE_PARAM_STRUC(WMI_REG_CHAN_LIST_CC_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_regulatory_chan_priority_struct, reg_chan_priority, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_regulatory_fcc_rule_struct, reg_fcc_rule, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_reg_chan_list_cc_ext_additional_params, reg_more_data, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_regulatory_rule_meta_data, reg_meta_data, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_regulatory_rule_meta_data, reg_meta_data, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hw_blacklist_chan_fixed_param, hw_blacklist_chan_fixed_param, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hw_blacklist_chan_data, hw_blacklist_chan_data, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_REG_CHAN_LIST_CC_EXT_EVENTID);
/* WMI AFC info event */
@ -6964,9 +7069,17 @@ WMITLV_CREATE_PARAM_STRUC(WMI_REG_CHAN_LIST_CC_EXT_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_afc_power_event_param, wmi_afc_power_event_param, afc_power_event_param, WMITLV_SIZE_FIX)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_6g_afc_frequency_info, freq_info_array, WMITLV_SIZE_VAR)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_6g_afc_channel_info, channel_info_array, WMITLV_SIZE_VAR)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_afc_chan_eirp_power_info, chan_eirp_power_info_array, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_afc_chan_eirp_power_info, chan_eirp_power_info_array, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hw_blacklist_chan_fixed_param, hw_blacklist_chan_fixed_param, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hw_blacklist_chan_data, hw_blacklist_chan_data, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_AFC_EVENTID);
/* HW blacklist channels for the current country code */
#define WMITLV_TABLE_WMI_HW_BLACKLIST_CHAN_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hw_blacklist_chan_fixed_param, wmi_hw_blacklist_chan_fixed_param, hw_blacklist_chan_fixed_param, WMITLV_SIZE_FIX) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hw_blacklist_chan_data, hw_blacklist_chan_data, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_HW_BLACKLIST_CHAN_EVENTID);
/* Indicate LPI AP detect or not to Host */
#define WMITLV_TABLE_WMI_C2C_DETECT_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_c2c_detect_event_fixed_param, wmi_c2c_detect_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)
@ -7257,7 +7370,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PEER_STATS_INFO_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_vdev_bcn_tx_stats_struct, ctrl_path_vdev_bcn_tx_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_bcn_tx_stats_struct, ctrl_path_pdev_bcn_tx_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_conn_stats_struct, ctrl_path_pdev_conn_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_ml_rcfg_stats_struct, ctrl_path_ml_rcfg_stats, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_ml_rcfg_stats_struct, ctrl_path_ml_rcfg_stats, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_sta_dar_stats_struct, ctrl_path_sta_dar_stats, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_CTRL_PATH_STATS_EVENTID);
/*
@ -7775,7 +7889,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VENDOR_PEER_EVENTID);
#define WMITLV_TABLE_WMI_VDEV_VBSS_CONFIG_EVENTID(id,op,buf,len) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_vbss_config_event_fixed_param, wmi_vdev_vbss_config_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)\
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_pn_info, vbss_peer_pn_info, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_sn_info, vbss_peer_sn_info, WMITLV_SIZE_VAR)
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_sn_info, vbss_peer_sn_info, WMITLV_SIZE_VAR) \
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_vbss_peer_dyn_info, vbss_peer_dyn_info, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_VBSS_CONFIG_EVENTID);
/* link switch event */

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@
#define __WMI_VER_MINOR_ 0
/** WMI revision number has to be incremented when there is a
* change that may or may not break compatibility. */
#define __WMI_REVISION_ 1575
#define __WMI_REVISION_ 1637
/** The Version Namespace should not be normally changed. Only
* host and firmware of the same WMI namespace will work

View file

@ -411,10 +411,19 @@ void qdf_mtrace_log(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
uint16_t message_id, uint8_t vdev_id)
{
uint32_t trace_log, payload;
static uint16_t counter;
static __qdf_atomic_t counter;
static bool initialized = false;
// Initialize counter only once
if (!initialized) {
qdf_atomic_init(&counter);
initialized = true;
}
trace_log = (src_module << 23) | (dst_module << 15) | message_id;
payload = (vdev_id << 16) | counter++;
qdf_atomic_add(1, &counter);
payload = ((uint32_t)vdev_id << 16) | (qdf_atomic_read(&counter) & 0xFFFF);
QDF_TRACE(src_module, QDF_TRACE_LEVEL_TRACE, "%x %x",
trace_log, payload);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -2089,6 +2089,11 @@ QDF_STATUS reg_process_master_chan_list_ext(
reg_store_regulatory_ext_info_to_socpriv(soc_reg, regulat_info, phy_id);
if (this_mchan_params->client_type >= REG_MAX_CLIENT_TYPE) {
reg_err("6 GHz reg client type invalid");
return QDF_STATUS_E_FAILURE;
}
status = reg_fill_master_channels(regulat_info,
&this_mchan_params->reg_rules,
this_mchan_params->client_type,

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -5113,7 +5113,7 @@ QDF_STATUS reg_get_6g_chan_ap_power(struct wlan_objmgr_pdev *pdev,
QDF_STATUS reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd,
bool is_psd,
uint16_t *tx_power,
uint16_t *eirp_psd_power)
{
@ -5136,8 +5136,7 @@ QDF_STATUS reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
reg_find_txpower_from_6g_list(chan_freq, master_chan_list,
tx_power);
*is_psd = reg_is_6g_psd_power(pdev);
if (*is_psd)
if (is_psd)
status = reg_get_6g_chan_psd_eirp_power(chan_freq,
master_chan_list,
eirp_psd_power);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
*
* Permission to use, copy, modify, and/or distribute this software for
@ -1484,7 +1484,7 @@ QDF_STATUS reg_get_6g_chan_ap_power(struct wlan_objmgr_pdev *pdev,
*
* This function is meant to be called to find the channel frequency power
* information for a client when the device is operating as a client. It will
* fill in the parameter is_psd, tx_power, and eirp_psd_power. eirp_psd_power
* fill in the parameters tx_power and eirp_psd_power. eirp_psd_power
* will only be filled if the channel is PSD.
*
* Return: QDF_STATUS
@ -1492,7 +1492,7 @@ QDF_STATUS reg_get_6g_chan_ap_power(struct wlan_objmgr_pdev *pdev,
QDF_STATUS reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd,
bool is_psd,
uint16_t *tx_power,
uint16_t *eirp_psd_power);
@ -1582,11 +1582,10 @@ static inline
QDF_STATUS reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd,
bool is_psd,
uint16_t *tx_power,
uint16_t *eirp_psd_power)
{
*is_psd = false;
*tx_power = 0;
*eirp_psd_power = 0;
return QDF_STATUS_E_NOSUPPORT;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1869,8 +1869,8 @@ QDF_STATUS wlan_reg_get_6g_chan_ap_power(struct wlan_objmgr_pdev *pdev,
*
* This function is meant to be called to find the channel frequency power
* information for a client when the device is operating as a client. It will
* fill in the parameter is_psd, tx_power, and eirp_psd_power. eirp_psd_power
* will only be filled if the channel is PSD.
* fill in the parameters tx_power and eirp_psd_power. eirp_psd_power will
* only be filled if the channel is PSD.
*
* Return: QDF_STATUS
*/
@ -1878,7 +1878,7 @@ QDF_STATUS
wlan_reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd, uint16_t *tx_power,
bool is_psd, uint16_t *tx_power,
uint16_t *eirp_psd_power);
/**
@ -1985,10 +1985,9 @@ static inline QDF_STATUS
wlan_reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd, uint16_t *tx_power,
bool is_psd, uint16_t *tx_power,
uint16_t *eirp_psd_power)
{
*is_psd = false;
*tx_power = 0;
*eirp_psd_power = 0;
return QDF_STATUS_E_NOSUPPORT;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
*
* Permission to use, copy, modify, and/or distribute this software for
@ -1443,7 +1443,7 @@ QDF_STATUS
wlan_reg_get_client_power_for_connecting_ap(struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type ap_type,
qdf_freq_t chan_freq,
bool *is_psd, uint16_t *tx_power,
bool is_psd, uint16_t *tx_power,
uint16_t *eirp_psd_power)
{
return reg_get_client_power_for_connecting_ap(pdev, ap_type, chan_freq,

View file

@ -14208,9 +14208,14 @@ extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
return QDF_STATUS_E_FAILURE;
}
if (ap_idx >= param_buf->num_roam_ap_info) {
wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d",
ap_idx, param_buf->num_roam_ap_info);
/*
* Check to validate that the requested number of APs do not exceed the
* remaining APs in param_buf after ap_idx to prevent out of bounds
* access.
*/
if ((ap_idx + num_cand) > param_buf->num_roam_ap_info) {
wmi_err("Invalid roam scan AP tlv ap_idx:%d, num_cand:%d, total_ap:%d",
ap_idx, num_cand, param_buf->num_roam_ap_info);
return QDF_STATUS_E_FAILURE;
}
@ -14724,6 +14729,12 @@ static QDF_STATUS extract_pdev_csa_switch_count_status_tlv(
wmi_handle,
csa_status->pdev_id);
param->current_switch_count = csa_status->current_switch_count;
if (param_buf->num_vdev_ids != csa_status->num_vdevs) {
wmi_err("Invalid number of vdevs: received = %d, expected = %d",
csa_status->num_vdevs, param_buf->num_vdev_ids);
return QDF_STATUS_E_INVAL;
}
param->num_vdevs = csa_status->num_vdevs;
param->vdev_ids = param_buf->vdev_ids;

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1846,6 +1847,8 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_LFR3_ROAM_PREAUTH_RETRY_COUNT);
lfr->roam_rssi_diff = cfg_get(psoc, CFG_LFR_ROAM_RSSI_DIFF);
lfr->roam_rssi_diff_6ghz = cfg_get(psoc, CFG_LFR_ROAM_RSSI_DIFF_6GHZ);
lfr->roam_rssi_delta_6ghz_to_non_6ghz =
cfg_get(psoc, CFG_LFR_ROAM_RSSI_DELTA_6GHZ_TO_NON_6GHZ);
lfr->bg_rssi_threshold = cfg_get(psoc, CFG_LFR_ROAM_BG_RSSI_TH);
lfr->roam_scan_offload_enabled =
cfg_get(psoc, CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED);

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1280,6 +1281,38 @@
CFG_VALUE_OR_DEFAULT, \
"Enable 6 GHz roam based on rssi")
/*
* <ini>
* roam_rssi_delta_from_6ghz_to_non_6ghz - Enable roam to Non 6 GHz AP based
* on rssi
* @Min: 0
* @Max: 100
* @Default: 0
*
* This INI is used to decide whether to roam to Non 6 GHz AP or not based on
* RSSI. AP1 is the currently associated AP(6 GHz) and AP2(2.4 GHz / 5 GHz) is
* chosen for roaming. The Roaming will happen only if AP2 has better Signal
* Quality and it has a RSSI better than AP1.
* roam_rssi_delta_from_6ghz_to_non_6ghz is the number of dB units AP2 is
* better than AP1.
*
*
* Related: None
*
* Supported Feature: Roaming
*
* Usage: External
*
* </ini>
*/
#define CFG_LFR_ROAM_RSSI_DELTA_6GHZ_TO_NON_6GHZ CFG_INI_UINT( \
"roam_rssi_delta_from_6ghz_to_non_6ghz", \
0, \
100, \
0, \
CFG_VALUE_OR_DEFAULT, \
"Enable 6 GHz to non 6 GHz roam based on rssi")
/*
* <ini>
* bg_rssi_threshold - To set RSSI Threshold for BG scan roaming
@ -2930,6 +2963,7 @@
CFG(CFG_LFR_FAST_TRANSITION_ENABLED) \
CFG(CFG_LFR_ROAM_RSSI_DIFF) \
CFG(CFG_LFR_ROAM_RSSI_DIFF_6GHZ) \
CFG(CFG_LFR_ROAM_RSSI_DELTA_6GHZ_TO_NON_6GHZ) \
CFG(CFG_LFR_ROAM_BG_RSSI_TH) \
CFG(CFG_LFR_ENABLE_WES_MODE) \
CFG(CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED) \

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1680,8 +1681,10 @@ struct fw_scan_channels {
* @roam_preauth_no_ack_timeout: Configure the no ack timeout period
* @roam_rssi_diff: Enable roam based on rssi
* @roam_rssi_diff_6ghz: RSSI diff value to be used for roaming to 6 GHz AP.
* @roam_scan_offload_enabled: Enable Roam Scan Offload
* @neighbor_scan_timer_period: Neighbor scan timer period
* @roam_rssi_delta_6ghz_to_non_6ghz: RSSI diff value to be used for
* roaming from 6 GHz to Non 6GHz AP.
* @roam_scan_offload_enabled: Enable Roam Scan Offload
* @neighbor_scan_timer_period: Neighbor scan timer period
* @neighbor_scan_min_timer_period: Min neighbor scan timer period
* @neighbor_lookup_rssi_threshold: Neighbor lookup rssi threshold
* @opportunistic_scan_threshold_diff: Set oppurtunistic threshold diff
@ -1804,6 +1807,7 @@ struct wlan_mlme_lfr_cfg {
uint32_t roam_preauth_no_ack_timeout;
uint8_t roam_rssi_diff;
uint8_t roam_rssi_diff_6ghz;
uint8_t roam_rssi_delta_6ghz_to_non_6ghz;
uint8_t bg_rssi_threshold;
bool roam_scan_offload_enabled;
uint32_t neighbor_scan_timer_period;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -211,7 +211,7 @@ static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx)
struct p2p_soc_priv_obj *p2p_soc_obj;
struct p2p_roc_context *curr_roc_ctx;
if (!tx_ctx || tx_ctx->chan) {
if (!tx_ctx || tx_ctx->chan_freq) {
p2p_err("NULL tx ctx or channel valid");
return QDF_STATUS_E_INVAL;
}
@ -232,7 +232,7 @@ static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx)
(mode == QDF_P2P_DEVICE_MODE ||
mode == QDF_P2P_CLIENT_MODE ||
mode == QDF_P2P_GO_MODE))
tx_ctx->chan = curr_roc_ctx->chan;
tx_ctx->chan_freq = curr_roc_ctx->chan_freq;
wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
@ -1068,16 +1068,13 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
void *mac_addr;
uint8_t pdev_id;
struct wlan_objmgr_vdev *vdev;
uint16_t chanfreq = 0;
psoc = tx_ctx->p2p_soc_obj->soc;
mgmt_param.tx_frame = packet;
mgmt_param.frm_len = buf_len;
mgmt_param.vdev_id = tx_ctx->vdev_id;
mgmt_param.pdata = frame;
if (tx_ctx->chan)
chanfreq = (uint16_t)wlan_chan_to_freq(tx_ctx->chan);
mgmt_param.chanfreq = chanfreq;
mgmt_param.chanfreq = tx_ctx->chan_freq;
mgmt_param.qdf_ctx = wlan_psoc_get_qdf_dev(psoc);
if (!(mgmt_param.qdf_ctx)) {
@ -1161,7 +1158,7 @@ static QDF_STATUS p2p_roc_req_for_tx_action(
p2p_soc_obj = tx_ctx->p2p_soc_obj;
roc_ctx->p2p_soc_obj = p2p_soc_obj;
roc_ctx->vdev_id = tx_ctx->vdev_id;
roc_ctx->chan = tx_ctx->chan;
roc_ctx->chan_freq = tx_ctx->chan_freq;
roc_ctx->duration = tx_ctx->duration;
roc_ctx->roc_state = ROC_STATE_IDLE;
roc_ctx->roc_type = OFF_CHANNEL_TX;
@ -1804,13 +1801,15 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj)
while (QDF_IS_STATUS_SUCCESS(status)) {
tx_ctx = qdf_container_of(p_node,
struct tx_action_context, node);
p2p_debug("p2p soc object:%pK, tx ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj, tx_ctx,
tx_ctx->vdev_id, tx_ctx->scan_id,
tx_ctx->roc_cookie, tx_ctx->chan,
tx_ctx->buf, tx_ctx->buf_len,
tx_ctx->off_chan, tx_ctx->no_cck,
tx_ctx->no_ack, tx_ctx->duration);
p2p_debug("p2p soc object:%pK, tx ctx:%pK, vdev_id:%d, "
"scan_id:%d, roc_cookie:%llx, freq:%d, buf:%pK, "
"len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj, tx_ctx,
tx_ctx->vdev_id, tx_ctx->scan_id,
tx_ctx->roc_cookie, tx_ctx->chan_freq,
tx_ctx->buf, tx_ctx->buf_len,
tx_ctx->off_chan, tx_ctx->no_cck,
tx_ctx->no_ack, tx_ctx->duration);
status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc,
p_node, &p_node);
@ -1822,13 +1821,15 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj)
while (QDF_IS_STATUS_SUCCESS(status)) {
tx_ctx = qdf_container_of(p_node,
struct tx_action_context, node);
p2p_debug("p2p soc object:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj, tx_ctx,
tx_ctx->vdev_id, tx_ctx->scan_id,
tx_ctx->roc_cookie, tx_ctx->chan,
tx_ctx->buf, tx_ctx->buf_len,
tx_ctx->off_chan, tx_ctx->no_cck,
tx_ctx->no_ack, tx_ctx->duration);
p2p_debug("p2p soc object:%pK, tx_ctx:%pK, vdev_id:%d, "
"scan_id:%d, roc_cookie:%llx, freq:%d, buf:%pK, "
"len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj, tx_ctx,
tx_ctx->vdev_id, tx_ctx->scan_id,
tx_ctx->roc_cookie, tx_ctx->chan_freq,
tx_ctx->buf, tx_ctx->buf_len,
tx_ctx->off_chan, tx_ctx->no_cck,
tx_ctx->no_ack, tx_ctx->duration);
status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
p_node, &p_node);
@ -2918,17 +2919,17 @@ void p2p_rand_mac_tx(struct tx_action_context *tx_action)
return;
soc = tx_action->p2p_soc_obj->soc;
if (!tx_action->no_ack && tx_action->chan &&
if (!tx_action->no_ack && tx_action->chan_freq &&
tx_action->buf_len > MIN_MAC_HEADER_LEN &&
p2p_is_vdev_support_rand_mac_by_id(soc, tx_action->vdev_id) &&
p2p_is_random_mac(soc, tx_action->vdev_id,
&tx_action->buf[SRC_MAC_ADDR_OFFSET])) {
status = p2p_request_random_mac(
soc, tx_action->vdev_id,
&tx_action->buf[SRC_MAC_ADDR_OFFSET],
wlan_chan_to_freq(tx_action->chan),
tx_action->id,
tx_action->duration);
soc, tx_action->vdev_id,
&tx_action->buf[SRC_MAC_ADDR_OFFSET],
tx_action->chan_freq,
tx_action->id,
tx_action->duration);
if (status == QDF_STATUS_SUCCESS)
tx_action->rand_mac_tx = true;
else
@ -2998,11 +2999,13 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
p2p_soc_obj = tx_ctx->p2p_soc_obj;
p2p_debug("soc:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj->soc, tx_ctx, tx_ctx->vdev_id,
tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan,
tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan,
tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration);
p2p_debug("soc:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, "
"roc_cookie:%llx, freq:%d, buf:%pK, len:%d, "
"off_chan:%d, cck:%d, ack:%d, duration:%d",
p2p_soc_obj->soc, tx_ctx, tx_ctx->vdev_id,
tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan_freq,
tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan,
tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration);
status = p2p_get_frame_info(tx_ctx->buf, tx_ctx->buf_len,
&(tx_ctx->frame_info));
@ -3031,8 +3034,8 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
tx_ctx->no_ack = 1;
}
if (!tx_ctx->off_chan || !tx_ctx->chan) {
if (!tx_ctx->chan)
if (!tx_ctx->off_chan || !tx_ctx->chan_freq) {
if (!tx_ctx->chan_freq)
p2p_check_and_update_channel(tx_ctx);
status = p2p_execute_tx_action_frame(tx_ctx);
if (status != QDF_STATUS_SUCCESS) {
@ -3044,7 +3047,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
/* For off channel tx case */
curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
if (curr_roc_ctx && (curr_roc_ctx->chan == tx_ctx->chan)) {
if (curr_roc_ctx && (curr_roc_ctx->chan_freq == tx_ctx->chan_freq)) {
if ((curr_roc_ctx->roc_state == ROC_STATE_REQUESTED) ||
(curr_roc_ctx->roc_state == ROC_STATE_STARTED)) {
tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx;
@ -3075,7 +3078,8 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
}
}
curr_roc_ctx = p2p_find_roc_by_chan(p2p_soc_obj, tx_ctx->chan);
curr_roc_ctx = p2p_find_roc_by_chan_freq(p2p_soc_obj,
tx_ctx->chan_freq);
if (curr_roc_ctx && (curr_roc_ctx->roc_state == ROC_STATE_IDLE)) {
tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx;
status = qdf_list_insert_back(

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -157,7 +157,7 @@ struct p2p_frame_info {
* @scan_id: Scan id given by scan component for this roc req
* @roc_cookie: Cookie for remain on channel request
* @id: Identifier of this tx context
* @chan: Chan for which this tx has been requested
* @chan_freq: Chan frequency for which this tx has been requested
* @buf: tx buffer
* @buf_len: Length of tx buffer
* @off_chan: Is this off channel tx
@ -174,7 +174,7 @@ struct tx_action_context {
int scan_id;
uint64_t roc_cookie;
int32_t id;
uint8_t chan;
qdf_freq_t chan_freq;
uint8_t *buf;
int buf_len;
bool off_chan;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -114,7 +114,7 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx)
req->scan_req.scan_type = SCAN_TYPE_P2P_LISTEN;
req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id;
req->scan_req.chan_list.num_chan = 1;
req->scan_req.chan_list.chan[0].freq = wlan_chan_to_freq(roc_ctx->chan);
req->scan_req.chan_list.chan[0].freq = roc_ctx->chan_freq;
req->scan_req.dwell_time_passive = roc_ctx->duration;
req->scan_req.dwell_time_active = 0;
req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
@ -278,7 +278,7 @@ static QDF_STATUS p2p_send_roc_event(
p2p_evt.vdev_id = roc_ctx->vdev_id;
p2p_evt.roc_event = evt;
p2p_evt.cookie = (uint64_t)roc_ctx->id;
p2p_evt.chan = roc_ctx->chan;
p2p_evt.chan_freq = roc_ctx->chan_freq;
p2p_evt.duration = roc_ctx->duration;
p2p_debug("roc_event: %d, cookie:%llx", p2p_evt.roc_event,
@ -305,9 +305,10 @@ static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx,
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj;
p2p_debug("p2p_soc_obj:%pK, roc_ctx:%pK, up_layer_event:%d, in_roc_queue:%d vdev_id:%d chan:%d duration:%d",
p2p_soc_obj, roc_ctx, up_layer_event, in_roc_queue,
roc_ctx->vdev_id, roc_ctx->chan, roc_ctx->duration);
p2p_debug("p2p_soc_obj:%pK, roc_ctx:%pK, up_layer_event:%d,"
" in_roc_queue:%d vdev_id:%d freq:%d duration:%d",
p2p_soc_obj, roc_ctx, up_layer_event, in_roc_queue,
roc_ctx->vdev_id, roc_ctx->chan_freq, roc_ctx->duration);
if (up_layer_event) {
if (roc_ctx->roc_state < ROC_STATE_ON_CHAN)
@ -391,11 +392,13 @@ static void p2p_roc_timeout(void *pdata)
return;
}
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d,"
" tx ctx:%pK, freq:%d, phy_mode:%d, duration:%d,"
" roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
if (roc_ctx->roc_state == ROC_STATE_CANCEL_IN_PROG) {
p2p_err("Cancellation already in progress");
@ -418,11 +421,13 @@ static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx)
QDF_STATUS status;
struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj;
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d,"
" tx ctx:%pK, freq:%d, phy_mode:%d, duration:%d,"
" roc_type:%d, roc_state:%d",
p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
/* prevent runtime suspend */
qdf_runtime_pm_prevent_suspend(&p2p_soc_obj->roc_runtime_lock);
@ -645,14 +650,14 @@ struct p2p_roc_context *p2p_find_current_roc_ctx(
struct p2p_roc_context, node);
if (roc_ctx->roc_state != ROC_STATE_IDLE) {
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id"
":%d, scan_id:%d, tx ctx:%pK, chan:"
"%d, phy_mode:%d, duration:%d, "
"roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx,
roc_ctx->vdev_id, roc_ctx->scan_id,
roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
":%d, scan_id:%d, tx ctx:%pK, freq:"
"%d, phy_mode:%d, duration:%d, "
"roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx,
roc_ctx->vdev_id, roc_ctx->scan_id,
roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
return roc_ctx;
}
@ -685,8 +690,8 @@ struct p2p_roc_context *p2p_find_roc_by_tx_ctx(
return NULL;
}
struct p2p_roc_context *p2p_find_roc_by_chan(
struct p2p_soc_priv_obj *p2p_soc_obj, uint8_t chan)
struct p2p_roc_context *p2p_find_roc_by_chan_freq(
struct p2p_soc_priv_obj *p2p_soc_obj, qdf_freq_t chan_freq)
{
struct p2p_roc_context *roc_ctx;
qdf_list_node_t *p_node;
@ -697,11 +702,14 @@ struct p2p_roc_context *p2p_find_roc_by_chan(
roc_ctx = qdf_container_of(p_node,
struct p2p_roc_context,
node);
if (roc_ctx->chan == chan) {
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
if (roc_ctx->chan_freq == chan_freq) {
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d,"
" scan_id:%d, tx ctx:%pK, freq:%d,"
" phy_mode:%d, duration:%d,"
" roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx,
roc_ctx->vdev_id, roc_ctx->scan_id,
roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
@ -808,10 +816,12 @@ QDF_STATUS p2p_process_cleanup_roc_queue(
roc_ctx = qdf_container_of(p_node,
struct p2p_roc_context, node);
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, "
"scan_id:%d, tx ctx:%pK, freq:%d, phy_mode:%d, "
"duration:%d, roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx,
roc_ctx->vdev_id, roc_ctx->scan_id,
roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
status = qdf_list_peek_next(&p2p_soc_obj->roc_q,
@ -836,9 +846,11 @@ QDF_STATUS p2p_process_cleanup_roc_queue(
roc_ctx = qdf_container_of(p_node,
struct p2p_roc_context, node);
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, "
"scan_id:%d, tx ctx:%pK, freq:%d, phy_mode:%d, "
"duration:%d, roc_type:%d, roc_state:%d",
roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
@ -871,11 +883,13 @@ QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx)
p2p_soc_obj = roc_ctx->p2p_soc_obj;
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d",
p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, "
"tx_ctx:%pK, freq:%d, phy_mode:%d, duration:%d, "
"roc_type:%d, roc_state:%d",
p2p_soc_obj, roc_ctx, roc_ctx->vdev_id,
roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan_freq,
roc_ctx->phy_mode, roc_ctx->duration,
roc_ctx->roc_type, roc_ctx->roc_state);
status = qdf_list_insert_back(&p2p_soc_obj->roc_q,
&roc_ctx->node);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -81,7 +81,7 @@ enum roc_state {
* @vdev_id: Vdev id on which this request has come
* @scan_id: Scan id given by scan component for this roc req
* @tx_ctx: TX context if this ROC is for tx MGMT
* @chan: Chan for which this RoC has been requested
* @chan_freq: Chan frequency for which this RoC has been requested
* @phy_mode: PHY mode
* @duration: Duration for the RoC
* @roc_type: RoC type User requested or internal
@ -95,7 +95,7 @@ struct p2p_roc_context {
uint32_t vdev_id;
uint32_t scan_id;
void *tx_ctx;
uint8_t chan;
qdf_freq_t chan_freq;
uint8_t phy_mode;
uint32_t duration;
enum roc_type roc_type;
@ -165,9 +165,9 @@ struct p2p_roc_context *p2p_find_roc_by_tx_ctx(
struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie);
/**
* p2p_find_roc_by_chan() - Find out roc context by channel
* p2p_find_roc_by_chan_freq() - Find out roc context by channel
* @p2p_soc_obj: p2p psoc private object
* @chan: channel of the ROC
* @chan_freq: channel frequency of the ROC
*
* This function finds out roc context by channel from p2p psoc
* private object
@ -175,8 +175,8 @@ struct p2p_roc_context *p2p_find_roc_by_tx_ctx(
* Return: Pointer to roc context - success
* NULL - failure
*/
struct p2p_roc_context *p2p_find_roc_by_chan(
struct p2p_soc_priv_obj *p2p_soc_obj, uint8_t chan);
struct p2p_roc_context *p2p_find_roc_by_chan_freq(
struct p2p_soc_priv_obj *p2p_soc_obj, qdf_freq_t chan_freq);
/**
* p2p_restart_roc_timer() - Restarts roc timer

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -61,13 +62,13 @@ struct p2p_ps_params {
/**
* struct p2p_roc_req - P2P roc request
* @vdev_id: Vdev id on which this request has come
* @chan: Chan for which this RoC has been requested
* @chan_freq: Chan frequency for which this RoC has been requested
* @phy_mode: PHY mode
* @duration: Duration for the RoC
*/
struct p2p_roc_req {
uint32_t vdev_id;
uint32_t chan;
qdf_freq_t chan_freq;
uint32_t phy_mode;
uint32_t duration;
};
@ -89,14 +90,14 @@ enum p2p_roc_event {
* @vdev_id: Vdev id
* @roc_event: RoC event
* @cookie: Cookie which is given to supplicant for this roc req
* @chan: Chan for which this RoC has been requested
* @chan_freq: Chan frequency for which this RoC has been requested
* @duration: Duration for the RoC
*/
struct p2p_event {
uint32_t vdev_id;
enum p2p_roc_event roc_event;
uint64_t cookie;
uint32_t chan;
qdf_freq_t chan_freq;
uint32_t duration;
};
@ -137,7 +138,7 @@ struct p2p_tx_cnf {
/**
* struct p2p_mgmt_tx - p2p mgmt tx structure
* @vdev_id: Vdev id
* @chan: Chan for which this RoC has been requested
* @chan_freq: Chan frequency for which this RoC has been requested
* @wait: Duration for the RoC
* @len: Length of tx buffer
* @no_cck: Required cck or not
@ -147,7 +148,7 @@ struct p2p_tx_cnf {
*/
struct p2p_mgmt_tx {
uint32_t vdev_id;
uint32_t chan;
qdf_freq_t chan_freq;
uint32_t wait;
uint32_t len;
uint32_t no_cck;

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -118,9 +119,9 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc,
QDF_STATUS status;
int32_t id;
p2p_debug("soc:%pK, vdev_id:%d, chan:%d, phy_mode:%d, duration:%d",
soc, roc_req->vdev_id, roc_req->chan,
roc_req->phy_mode, roc_req->duration);
p2p_debug("soc:%pK, vdev_id:%d, chanfreq:%d, phy_mode:%d, duration:%d",
soc, roc_req->vdev_id, roc_req->chan_freq,
roc_req->phy_mode, roc_req->duration);
if (!soc) {
p2p_err("psoc context passed is NULL");
@ -148,7 +149,7 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc,
*cookie = (uint64_t)id;
roc_ctx->p2p_soc_obj = p2p_soc_obj;
roc_ctx->vdev_id = roc_req->vdev_id;
roc_ctx->chan = roc_req->chan;
roc_ctx->chan_freq = roc_req->chan_freq;
roc_ctx->phy_mode = roc_req->phy_mode;
roc_ctx->duration = roc_req->duration;
roc_ctx->roc_state = ROC_STATE_IDLE;
@ -324,10 +325,11 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc,
QDF_STATUS status;
int32_t id;
p2p_debug("soc:%pK, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d",
soc, mgmt_frm->vdev_id, mgmt_frm->chan,
mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck,
mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan);
p2p_debug("soc:%pK, vdev_id:%d, freq:%d, wait:%d, buf_len:%d,"
" cck:%d, no ack:%d, off chan:%d",
soc, mgmt_frm->vdev_id, mgmt_frm->chan_freq,
mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck,
mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan);
if (!soc) {
p2p_err("psoc context passed is NULL");
@ -361,7 +363,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc,
*cookie = (uint64_t)id;
tx_action->p2p_soc_obj = p2p_soc_obj;
tx_action->vdev_id = mgmt_frm->vdev_id;
tx_action->chan = mgmt_frm->chan;
tx_action->chan_freq = mgmt_frm->chan_freq;
tx_action->duration = mgmt_frm->wait;
tx_action->buf_len = mgmt_frm->len;
tx_action->no_cck = mgmt_frm->no_cck;

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -264,6 +265,41 @@ target_if_cm_roam_rssi_diff_6ghz(struct wlan_objmgr_vdev *vdev,
return status;
}
/**
* target_if_cm_roam_rssi_delta_6ghz_to_non_6ghz() - Sends the roam RSSI
* diff value to the FW. This value is used to determine how much better
* the RSSI of the new/roamable non-6 GHz AP must be for roaming.
*
* @vdev: vdev object
* @roam_rssi_delta_6ghz_to_non_6ghz: RSSI diff value to be used for roaming to
* Non 6 GHz AP
*
* Return: QDF_STATUS
*/
static QDF_STATUS
target_if_cm_roam_rssi_delta_6ghz_to_non_6ghz(struct wlan_objmgr_vdev *vdev,
uint8_t roam_rssi_delta_6ghz_to_non_6ghz)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
uint8_t vdev_id;
wmi_unified_t wmi_handle;
wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev);
if (!wmi_handle)
return status;
vdev_id = wlan_vdev_get_id(vdev);
status = target_if_roam_set_param(
wmi_handle, vdev_id,
WMI_ROAM_PARAM_ROAM_RSSI_PENALTY_FOR_NON_6GHZ_CAND_AP,
roam_rssi_delta_6ghz_to_non_6ghz);
if (QDF_IS_STATUS_ERROR(status))
target_if_err("Failed to set WMI_ROAM_PARAM_ROAM_RSSI_PENALTY_FOR_NON_6GHZ_CAND_AP");
return status;
}
static QDF_STATUS
target_if_cm_roam_scan_offload_rssi_thresh(
wmi_unified_t wmi_handle,
@ -367,6 +403,13 @@ target_if_cm_roam_rssi_diff_6ghz(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_E_NOSUPPORT;
}
static QDF_STATUS
target_if_cm_roam_rssi_delta_6ghz_to_non_6ghz(struct wlan_objmgr_vdev *vdev,
uint8_t roam_rssi_diff_6ghz)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline void
target_if_check_hi_rssi_5ghz_support(
wmi_unified_t wmi_handle,
@ -1276,6 +1319,9 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev,
if (req->wlan_roam_rssi_diff_6ghz)
target_if_cm_roam_rssi_diff_6ghz(vdev,
req->wlan_roam_rssi_diff_6ghz);
if (req->wlan_roam_rssi_delta_6ghz_to_non_6ghz)
target_if_cm_roam_rssi_delta_6ghz_to_non_6ghz(
vdev, req->wlan_roam_rssi_delta_6ghz_to_non_6ghz);
/* add other wmi commands */
end:
@ -1516,6 +1562,10 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev,
if (req->wlan_roam_rssi_diff_6ghz)
target_if_cm_roam_rssi_diff_6ghz(
vdev, req->wlan_roam_rssi_diff_6ghz);
if (req->wlan_roam_rssi_delta_6ghz_to_non_6ghz)
target_if_cm_roam_rssi_delta_6ghz_to_non_6ghz(
vdev, req->wlan_roam_rssi_delta_6ghz_to_non_6ghz);
}
end:
return status;

View file

@ -629,6 +629,10 @@ cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp);
start_req->wlan_roam_rssi_diff_6ghz = temp.uint_value;
wlan_cm_roam_cfg_get_value(psoc, vdev_id,
ROAM_RSSI_DELTA_6GHZ_TO_NON_6GHZ, &temp);
start_req->wlan_roam_rssi_delta_6ghz_to_non_6ghz = temp.uint_value;
status = wlan_cm_tgt_send_roam_start_req(psoc, vdev_id, start_req);
if (QDF_IS_STATUS_ERROR(status))
mlme_debug("fail to send roam start");
@ -691,6 +695,10 @@ cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp);
update_req->wlan_roam_rssi_diff_6ghz = temp.uint_value;
wlan_cm_roam_cfg_get_value(psoc, vdev_id,
ROAM_RSSI_DELTA_6GHZ_TO_NON_6GHZ, &temp);
update_req->wlan_roam_rssi_delta_6ghz_to_non_6ghz = temp.uint_value;
status = wlan_cm_tgt_send_roam_update_req(psoc, vdev_id, update_req);
if (QDF_IS_STATUS_ERROR(status))
mlme_debug("fail to send update config");

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