aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/include
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linuxkpi/common/include')
-rw-r--r--sys/compat/linuxkpi/common/include/acpi/acpi.h88
-rw-r--r--sys/compat/linuxkpi/common/include/acpi/acpi_bus.h25
-rw-r--r--sys/compat/linuxkpi/common/include/acpi/actbl.h1
-rw-r--r--sys/compat/linuxkpi/common/include/acpi/video.h30
-rw-r--r--sys/compat/linuxkpi/common/include/asm-generic/io.h40
-rw-r--r--sys/compat/linuxkpi/common/include/asm/atomic-long.h10
-rw-r--r--sys/compat/linuxkpi/common/include/asm/atomic.h36
-rw-r--r--sys/compat/linuxkpi/common/include/asm/atomic64.h5
-rw-r--r--sys/compat/linuxkpi/common/include/asm/barrier.h8
-rw-r--r--sys/compat/linuxkpi/common/include/asm/byteorder.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/fcntl.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/fpu/api.h4
-rw-r--r--sys/compat/linuxkpi/common/include/asm/hypervisor.h19
-rw-r--r--sys/compat/linuxkpi/common/include/asm/intel-family.h6
-rw-r--r--sys/compat/linuxkpi/common/include/asm/io.h9
-rw-r--r--sys/compat/linuxkpi/common/include/asm/memtype.h18
-rw-r--r--sys/compat/linuxkpi/common/include/asm/msr.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/neon.h4
-rw-r--r--sys/compat/linuxkpi/common/include/asm/pgtable.h17
-rw-r--r--sys/compat/linuxkpi/common/include/asm/processor.h63
-rw-r--r--sys/compat/linuxkpi/common/include/asm/set_memory.h27
-rw-r--r--sys/compat/linuxkpi/common/include/asm/smp.h6
-rw-r--r--sys/compat/linuxkpi/common/include/asm/topology.h54
-rw-r--r--sys/compat/linuxkpi/common/include/asm/types.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/uaccess.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/unaligned.h20
-rw-r--r--sys/compat/linuxkpi/common/include/crypto/hash.h94
-rw-r--r--sys/compat/linuxkpi/common/include/kunit/static_stub.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/acpi.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/acpi_amd_wbrf.h97
-rw-r--r--sys/compat/linuxkpi/common/include/linux/agp_backend.h28
-rw-r--r--sys/compat/linuxkpi/common/include/linux/anon_inodes.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/aperture.h64
-rw-r--r--sys/compat/linuxkpi/common/include/linux/apple-gmux.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/atomic.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/average.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/backlight.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bcd.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitfield.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitmap.h100
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitops.h20
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bottom_half.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bsearch.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/build_bug.h65
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cache.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/capability.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cc_platform.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cdev.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cec.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cgroup.h34
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cleanup.h93
-rw-r--r--sys/compat/linuxkpi/common/include/linux/clocksource.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compat.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler.h35
-rw-r--r--sys/compat/linuxkpi/common/include/linux/completion.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/container_of.h54
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cpu.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/cpufeature.h43
-rw-r--r--sys/compat/linuxkpi/common/include/linux/crc32.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dcache.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/debugfs.h91
-rw-r--r--sys/compat/linuxkpi/common/include/linux/delay.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/devcoredump.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h145
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device/driver.h33
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dma-attrs.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dma-buf-map.h91
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dma-mapping.h113
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dmapool.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dmi.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dynamic_debug.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/efi.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/err.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/errno.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/etherdevice.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ethtool.h22
-rw-r--r--sys/compat/linuxkpi/common/include/linux/eventpoll.h45
-rw-r--r--sys/compat/linuxkpi/common/include/linux/export.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/file.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/firmware.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fs.h110
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fwnode.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/gcd.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/gfp.h62
-rw-r--r--sys/compat/linuxkpi/common/include/linux/gpf.h33
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hardirq.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hashtable.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hdmi.h447
-rw-r--r--sys/compat/linuxkpi/common/include/linux/highmem.h70
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hrtimer.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/i2c.h29
-rw-r--r--sys/compat/linuxkpi/common/include/linux/idr.h18
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ieee80211.h789
-rw-r--r--sys/compat/linuxkpi/common/include/linux/if_arp.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/if_ether.h19
-rw-r--r--sys/compat/linuxkpi/common/include/linux/if_vlan.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/in.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/in6.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/interrupt.h47
-rw-r--r--sys/compat/linuxkpi/common/include/linux/interval_tree.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h65
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io-mapping.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io.h95
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ioctl.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/iommu.h29
-rw-r--r--sys/compat/linuxkpi/common/include/linux/iopoll.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ioport.h58
-rw-r--r--sys/compat/linuxkpi/common/include/linux/iosys-map.h161
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ip.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/irq_work.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/irqdomain.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/irqreturn.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/jhash.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/jiffies.h58
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kconfig.h76
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kdev_t.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kernel.h488
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kernel_stat.h34
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kfifo.h89
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kmod.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kobject.h58
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kref.h22
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kstrtox.h324
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kthread.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ktime.h25
-rw-r--r--sys/compat/linuxkpi/common/include/linux/leds.h41
-rw-r--r--sys/compat/linuxkpi/common/include/linux/limits.h47
-rw-r--r--sys/compat/linuxkpi/common/include/linux/list.h45
-rw-r--r--sys/compat/linuxkpi/common/include/linux/lockdep.h38
-rw-r--r--sys/compat/linuxkpi/common/include/linux/log2.h98
-rw-r--r--sys/compat/linuxkpi/common/include/linux/math.h76
-rw-r--r--sys/compat/linuxkpi/common/include/linux/math64.h78
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mhi.h222
-rw-r--r--sys/compat/linuxkpi/common/include/linux/minmax.h74
-rw-r--r--sys/compat/linuxkpi/common/include/linux/miscdevice.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm.h213
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm_types.h14
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mman.h38
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mmu_context.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mmu_notifier.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mmzone.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mod_devicetable.h14
-rw-r--r--sys/compat/linuxkpi/common/include/linux/module.h24
-rw-r--r--sys/compat/linuxkpi/common/include/linux/moduleparam.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mutex.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/net.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/net_dim.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdev_features.h27
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdevice.h209
-rw-r--r--sys/compat/linuxkpi/common/include/linux/nl80211.h109
-rw-r--r--sys/compat/linuxkpi/common/include/linux/nodemask.h46
-rw-r--r--sys/compat/linuxkpi/common/include/linux/nospec.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/notifier.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/numa.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/of.h33
-rw-r--r--sys/compat/linuxkpi/common/include/linux/overflow.h520
-rw-r--r--sys/compat/linuxkpi/common/include/linux/page-flags.h41
-rw-r--r--sys/compat/linuxkpi/common/include/linux/page.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pagemap.h18
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pagevec.h137
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci.h741
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci_ids.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/perf_event.h34
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pfn.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pfn_t.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pid.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/platform_device.h97
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pm.h62
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pm_qos.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pm_runtime.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/poll.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/power_supply.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/preempt.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/prefetch.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/printk.h69
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h75
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pwm.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/qrtr.h41
-rw-r--r--sys/compat/linuxkpi/common/include/linux/radix-tree.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/random.h56
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rbtree.h52
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rculist.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rcupdate.h62
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ref_tracker.h93
-rw-r--r--sys/compat/linuxkpi/common/include/linux/refcount.h27
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rhashtable.h87
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rwlock.h23
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rwsem.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/scatterlist.h88
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched/mm.h43
-rw-r--r--sys/compat/linuxkpi/common/include/linux/semaphore.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seq_file.h55
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seqlock.h57
-rw-r--r--sys/compat/linuxkpi/common/include/linux/shmem_fs.h30
-rw-r--r--sys/compat/linuxkpi/common/include/linux/shrinker.h27
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sizes.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/skbuff.h522
-rw-r--r--sys/compat/linuxkpi/common/include/linux/slab.h161
-rw-r--r--sys/compat/linuxkpi/common/include/linux/smp.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h62
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h173
-rw-r--r--sys/compat/linuxkpi/common/include/linux/socket.h13
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sort.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/spinlock.h45
-rw-r--r--sys/compat/linuxkpi/common/include/linux/srcu.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stackdepot.h32
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stdarg.h33
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stddef.h31
-rw-r--r--sys/compat/linuxkpi/common/include/linux/string.h136
-rw-r--r--sys/compat/linuxkpi/common/include/linux/string_choices.h71
-rw-r--r--sys/compat/linuxkpi/common/include/linux/string_helpers.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stringify.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/suspend.h23
-rw-r--r--sys/compat/linuxkpi/common/include/linux/swap.h23
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sysfs.h252
-rw-r--r--sys/compat/linuxkpi/common/include/linux/tcp.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/time.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/timer.h31
-rw-r--r--sys/compat/linuxkpi/common/include/linux/topology.h35
-rw-r--r--sys/compat/linuxkpi/common/include/linux/tracepoint.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/types.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/uaccess.h27
-rw-r--r--sys/compat/linuxkpi/common/include/linux/udp.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/units.h40
-rw-r--r--sys/compat/linuxkpi/common/include/linux/usb.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/utsname.h51
-rw-r--r--sys/compat/linuxkpi/common/include/linux/uuid.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/vgaarb.h281
-rw-r--r--sys/compat/linuxkpi/common/include/linux/vmalloc.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait.h32
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait_bit.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/workqueue.h16
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ww_mutex.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/xarray.h40
-rw-r--r--sys/compat/linuxkpi/common/include/net/addrconf.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/cfg80211.h1268
-rw-r--r--sys/compat/linuxkpi/common/include/net/ieee80211_radiotap.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/if_inet6.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/ip.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/ipv6.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/mac80211.h1679
-rw-r--r--sys/compat/linuxkpi/common/include/net/netevent.h2
-rw-r--r--sys/compat/linuxkpi/common/include/net/netlink.h53
-rw-r--r--sys/compat/linuxkpi/common/include/net/page_pool.h119
-rw-r--r--sys/compat/linuxkpi/common/include/net/regulatory.h6
-rw-r--r--sys/compat/linuxkpi/common/include/net/tcp.h2
-rw-r--r--sys/compat/linuxkpi/common/include/stdarg.h4
-rw-r--r--sys/compat/linuxkpi/common/include/video/cmdline.h44
-rw-r--r--sys/compat/linuxkpi/common/include/video/mipi_display.h64
-rw-r--r--sys/compat/linuxkpi/common/include/video/vga.h19
-rw-r--r--sys/compat/linuxkpi/common/include/xen/xen.h37
253 files changed, 12111 insertions, 2897 deletions
diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi.h b/sys/compat/linuxkpi/common/include/acpi/acpi.h
index e996301e27f0..9bb435591daa 100644
--- a/sys/compat/linuxkpi/common/include/acpi/acpi.h
+++ b/sys/compat/linuxkpi/common/include/acpi/acpi.h
@@ -1,8 +1,12 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org>
* Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -25,14 +29,19 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ACPI_ACPI_H_
#define _LINUXKPI_ACPI_ACPI_H_
/*
+ * LINUXKPI_WANT_LINUX_ACPI is a temporary workaround to allow drm-kmod
+ * to update all needed branches without breaking builds.
+ * Once that happened and checks are implemented based on __FreeBSD_version
+ * we will remove these conditions again.
+ */
+
+/*
* FreeBSD import of ACPICA has a typedef for BOOLEAN which conflicts with
* amdgpu driver. Workaround it on preprocessor level.
*/
@@ -48,8 +57,8 @@ typedef int64_t INT64;
#include <contrib/dev/acpica/include/acpi.h>
#undef BOOLEAN
+typedef ACPI_IO_ADDRESS acpi_io_address;
typedef ACPI_HANDLE acpi_handle;
-typedef ACPI_OBJECT acpi_object;
typedef ACPI_OBJECT_HANDLER acpi_object_handler;
typedef ACPI_OBJECT_TYPE acpi_object_type;
typedef ACPI_STATUS acpi_status;
@@ -57,12 +66,62 @@ typedef ACPI_STRING acpi_string;
typedef ACPI_SIZE acpi_size;
typedef ACPI_WALK_CALLBACK acpi_walk_callback;
+union linuxkpi_acpi_object {
+ acpi_object_type type;
+ struct {
+ acpi_object_type type;
+ UINT64 value;
+ } integer;
+ struct {
+ acpi_object_type type;
+ UINT32 length;
+ char *pointer;
+ } string;
+ struct {
+ acpi_object_type type;
+ UINT32 length;
+ UINT8 *pointer;
+ } buffer;
+ struct {
+ acpi_object_type type;
+ UINT32 count;
+ union linuxkpi_acpi_object *elements;
+ } package;
+ struct {
+ acpi_object_type type;
+ acpi_object_type actual_type;
+ acpi_handle handle;
+ } reference;
+ struct {
+ acpi_object_type type;
+ UINT32 proc_id;
+ acpi_io_address pblk_address;
+ UINT32 pblk_length;
+ } processor;
+ struct {
+ acpi_object_type type;
+ UINT32 system_level;
+ UINT32 resource_order;
+ } power_resource;
+};
+
+#ifdef LINUXKPI_WANT_LINUX_ACPI
+struct linuxkpi_acpi_buffer {
+ acpi_size length; /* Length in bytes of the buffer */
+ void *pointer; /* pointer to buffer */
+};
+
+typedef struct linuxkpi_acpi_buffer lkpi_acpi_buffer_t;
+#else
+typedef ACPI_BUFFER lkpi_acpi_buffer_t;
+#endif
+
static inline ACPI_STATUS
acpi_evaluate_object(ACPI_HANDLE Object, ACPI_STRING Pathname,
- ACPI_OBJECT_LIST *ParameterObjects, ACPI_BUFFER *ReturnObjectBuffer)
+ ACPI_OBJECT_LIST *ParameterObjects, lkpi_acpi_buffer_t *ReturnObjectBuffer)
{
return (AcpiEvaluateObject(
- Object, Pathname, ParameterObjects, ReturnObjectBuffer));
+ Object, Pathname, ParameterObjects, (ACPI_BUFFER *)ReturnObjectBuffer));
}
static inline const char *
@@ -72,7 +131,7 @@ acpi_format_exception(ACPI_STATUS Exception)
}
static inline ACPI_STATUS
-acpi_get_handle(ACPI_HANDLE Parent, ACPI_STRING Pathname,
+acpi_get_handle(ACPI_HANDLE Parent, const char *Pathname,
ACPI_HANDLE *RetHandle)
{
return (AcpiGetHandle(Parent, Pathname, RetHandle));
@@ -85,9 +144,9 @@ acpi_get_data(ACPI_HANDLE ObjHandle, ACPI_OBJECT_HANDLER Handler, void **Data)
}
static inline ACPI_STATUS
-acpi_get_name(ACPI_HANDLE Object, UINT32 NameType, ACPI_BUFFER *RetPathPtr)
+acpi_get_name(ACPI_HANDLE Object, UINT32 NameType, lkpi_acpi_buffer_t *RetPathPtr)
{
- return (AcpiGetName(Object, NameType, RetPathPtr));
+ return (AcpiGetName(Object, NameType, (ACPI_BUFFER *)RetPathPtr));
}
static inline ACPI_STATUS
@@ -97,4 +156,15 @@ acpi_get_table(ACPI_STRING Signature, UINT32 Instance,
return (AcpiGetTable(Signature, Instance, OutTable));
}
+static inline void
+acpi_put_table(ACPI_TABLE_HEADER *Table)
+{
+ AcpiPutTable(Table);
+}
+
+#ifdef LINUXKPI_WANT_LINUX_ACPI
+#define acpi_object linuxkpi_acpi_object
+#define acpi_buffer linuxkpi_acpi_buffer
+#endif
+
#endif /* _LINUXKPI_ACPI_ACPI_H_ */
diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
index c8a6385f26b2..da50d25a63bb 100644
--- a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
+++ b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -24,13 +24,14 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ACPI_ACPI_BUS_H_
#define _LINUXKPI_ACPI_ACPI_BUS_H_
+/* Aliase struct acpi_device to device_t */
+#define acpi_device _device
+
typedef char acpi_device_class[20];
struct acpi_bus_event {
@@ -39,14 +40,28 @@ struct acpi_bus_event {
uint32_t data;
};
+#define acpi_dev_present(...) lkpi_acpi_dev_present(__VA_ARGS__)
+#define acpi_dev_get_first_match_dev(...) \
+ lkpi_acpi_dev_get_first_match_dev(__VA_ARGS__)
+
ACPI_HANDLE bsd_acpi_get_handle(device_t bsddev);
-bool acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev,
+bool acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev,
uint64_t funcs);
-ACPI_OBJECT * acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const char *uuid,
+ACPI_OBJECT * acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid,
int rev, int func, ACPI_OBJECT *argv4,
ACPI_OBJECT_TYPE type);
int register_acpi_notifier(struct notifier_block *nb);
int unregister_acpi_notifier(struct notifier_block *nb);
uint32_t acpi_target_system_state(void);
+bool lkpi_acpi_dev_present(const char *hid, const char *uid,
+ int64_t hrv);
+struct acpi_device *lkpi_acpi_dev_get_first_match_dev(const char *hid,
+ const char *uid, int64_t hrv);
+
+union linuxkpi_acpi_object;
+
+union linuxkpi_acpi_object *
+acpi_evaluate_dsm(ACPI_HANDLE ObjHandle, const guid_t *guid,
+ UINT64 rev, UINT64 func, union linuxkpi_acpi_object *arg);
#endif /* _LINUXKPI_ACPI_ACPI_BUS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/acpi/actbl.h b/sys/compat/linuxkpi/common/include/acpi/actbl.h
new file mode 100644
index 000000000000..dbb7db41bb66
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/acpi/actbl.h
@@ -0,0 +1 @@
+#include <contrib/dev/acpica/include/actbl.h>
diff --git a/sys/compat/linuxkpi/common/include/acpi/video.h b/sys/compat/linuxkpi/common/include/acpi/video.h
index 63f876e78b57..fd2ffd6764d0 100644
--- a/sys/compat/linuxkpi/common/include/acpi/video.h
+++ b/sys/compat/linuxkpi/common/include/acpi/video.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -24,15 +24,39 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ACPI_VIDEO_H_
#define _LINUXKPI_ACPI_VIDEO_H_
+#include <sys/types.h>
+#include <sys/errno.h>
+
#define ACPI_VIDEO_CLASS "video"
#define ACPI_VIDEO_NOTIFY_PROBE 0x81
+static inline int
+acpi_video_register(void)
+{
+
+ return (-ENODEV);
+}
+
+static inline void
+acpi_video_unregister(void)
+{
+}
+
+static inline void
+acpi_video_register_backlight(void)
+{
+}
+
+static inline bool
+acpi_video_backlight_use_native(void)
+{
+ return (true);
+}
+
#endif /* _LINUXKPI_ACPI_VIDEO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm-generic/io.h b/sys/compat/linuxkpi/common/include/asm-generic/io.h
new file mode 100644
index 000000000000..8dc7eb6cf453
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm-generic/io.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _LINUXKPI_ASMGENERIC_IO_H_
+#define _LINUXKPI_ASMGENERIC_IO_H_
+
+#if defined(__i386__) || defined(__amd64__)
+
+#include <machine/cpufunc.h>
+
+#define outb(a,b) outb(b,a)
+#define outw(a,b) outw(b,a)
+#define outl(a,b) outl(b,a)
+
+#endif
+
+#endif /* _LINUXKPI_ASMGENERIC_IO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/atomic-long.h b/sys/compat/linuxkpi/common/include/asm/atomic-long.h
index f8bd9edfccf9..db3a94c539e5 100644
--- a/sys/compat/linuxkpi/common/include/asm/atomic-long.h
+++ b/sys/compat/linuxkpi/common/include/asm/atomic-long.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_ATOMIC_LONG_H_
#define _LINUXKPI_ASM_ATOMIC_LONG_H_
@@ -41,7 +39,7 @@ typedef struct {
} atomic_long_t;
#define atomic_long_add(i, v) atomic_long_add_return((i), (v))
-#define atomic_long_sub(i, v) atomic_long_add_return(-(i), (v))
+#define atomic_long_sub(i, v) atomic_long_sub_return((i), (v))
#define atomic_long_inc_return(v) atomic_long_add_return(1, (v))
#define atomic_long_inc_not_zero(v) atomic_long_add_unless((v), 1, 0)
@@ -51,6 +49,12 @@ atomic_long_add_return(long i, atomic_long_t *v)
return i + atomic_fetchadd_long(&v->counter, i);
}
+static inline long
+atomic_long_sub_return(long i, atomic_long_t *v)
+{
+ return atomic_fetchadd_long(&v->counter, -i) - i;
+}
+
static inline void
atomic_long_set(atomic_long_t *v, long i)
{
diff --git a/sys/compat/linuxkpi/common/include/asm/atomic.h b/sys/compat/linuxkpi/common/include/asm/atomic.h
index 8c201ad6a101..edb478af8c82 100644
--- a/sys/compat/linuxkpi/common/include/asm/atomic.h
+++ b/sys/compat/linuxkpi/common/include/asm/atomic.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_ATOMIC_H_
@@ -166,9 +164,7 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
#define LINUXKPI_ATOMIC_16(...)
#endif
-#if !(defined(i386) || (defined(__mips__) && !(defined(__mips_n32) || \
- defined(__mips_n64))) || (defined(__powerpc__) && \
- !defined(__powerpc64__)))
+#if !(defined(i386) || (defined(__powerpc__) && !defined(__powerpc64__)))
#define LINUXKPI_ATOMIC_64(...) __VA_ARGS__
#else
#define LINUXKPI_ATOMIC_64(...)
@@ -220,6 +216,7 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
__ret.val; \
})
+#define cmpxchg64(...) cmpxchg(__VA_ARGS__)
#define cmpxchg_relaxed(...) cmpxchg(__VA_ARGS__)
#define xchg(ptr, new) ({ \
@@ -268,6 +265,28 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
__ret.val; \
})
+#define try_cmpxchg(p, op, n) \
+({ \
+ __typeof(p) __op = (__typeof((p)))(op); \
+ __typeof(*(p)) __o = *__op; \
+ __typeof(*(p)) __p = __sync_val_compare_and_swap((p), (__o), (n)); \
+ if (__p != __o) \
+ *__op = __p; \
+ (__p == __o); \
+})
+
+#define __atomic_try_cmpxchg(type, _p, _po, _n) \
+({ \
+ __typeof(_po) __po = (_po); \
+ __typeof(*(_po)) __r, __o = *__po; \
+ __r = atomic_cmpxchg##type((_p), __o, (_n)); \
+ if (unlikely(__r != __o)) \
+ *__po = __r; \
+ likely(__r == __o); \
+})
+
+#define atomic_try_cmpxchg(_p, _po, _n) __atomic_try_cmpxchg(, _p, _po, _n)
+
static inline int
atomic_dec_if_positive(atomic_t *v)
{
@@ -307,6 +326,13 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \
return (c); \
}
+static inline int
+atomic_fetch_inc(atomic_t *v)
+{
+
+ return ((atomic_inc_return(v) - 1));
+}
+
LINUX_ATOMIC_OP(or, |)
LINUX_ATOMIC_OP(and, &)
LINUX_ATOMIC_OP(andnot, &~)
diff --git a/sys/compat/linuxkpi/common/include/asm/atomic64.h b/sys/compat/linuxkpi/common/include/asm/atomic64.h
index 4ee0fa5ecf84..fbfb9254b64c 100644
--- a/sys/compat/linuxkpi/common/include/asm/atomic64.h
+++ b/sys/compat/linuxkpi/common/include/asm/atomic64.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_ATOMIC64_H_
#define _LINUXKPI_ASM_ATOMIC64_H_
@@ -125,8 +123,7 @@ atomic64_fetch_add_unless(atomic64_t *v, int64_t a, int64_t u)
static inline int64_t
atomic64_xchg(atomic64_t *v, int64_t i)
{
-#if !((defined(__mips__) && !(defined(__mips_n32) || defined(__mips_n64))) || \
- (defined(__powerpc__) && !defined(__powerpc64__)))
+#if !(defined(__powerpc__) && !defined(__powerpc64__))
return (atomic_swap_64(&v->counter, i));
#else
int64_t ret = atomic64_read(v);
diff --git a/sys/compat/linuxkpi/common/include/asm/barrier.h b/sys/compat/linuxkpi/common/include/asm/barrier.h
index 12b4736e1939..39c5139cb322 100644
--- a/sys/compat/linuxkpi/common/include/asm/barrier.h
+++ b/sys/compat/linuxkpi/common/include/asm/barrier.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -55,4 +55,10 @@
#define smp_store_mb(x, v) do { WRITE_ONCE(x, v); smp_mb(); } while (0)
#endif
+#define smp_mb__before_atomic() barrier()
+#define smp_mb__after_atomic() barrier()
+
+#define smp_store_release(p, v) do { smp_mb(); WRITE_ONCE(*p, v); } while (0)
+#define smp_load_acquire(p) ({ typeof(*p) _v = READ_ONCE(*p); smp_mb(); _v; })
+
#endif /* _LINUXKPI_ASM_BARRIER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/byteorder.h b/sys/compat/linuxkpi/common/include/asm/byteorder.h
index 19961303596e..ad7a923ca143 100644
--- a/sys/compat/linuxkpi/common/include/asm/byteorder.h
+++ b/sys/compat/linuxkpi/common/include/asm/byteorder.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_BYTEORDER_H_
#define _LINUXKPI_ASM_BYTEORDER_H_
diff --git a/sys/compat/linuxkpi/common/include/asm/fcntl.h b/sys/compat/linuxkpi/common/include/asm/fcntl.h
index 2d0285e977e0..3820e15039f2 100644
--- a/sys/compat/linuxkpi/common/include/asm/fcntl.h
+++ b/sys/compat/linuxkpi/common/include/asm/fcntl.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_FCNTL_H_
#define _LINUXKPI_ASM_FCNTL_H_
diff --git a/sys/compat/linuxkpi/common/include/asm/fpu/api.h b/sys/compat/linuxkpi/common/include/asm/fpu/api.h
index 133754abdc4b..a4803bde461f 100644
--- a/sys/compat/linuxkpi/common/include/asm/fpu/api.h
+++ b/sys/compat/linuxkpi/common/include/asm/fpu/api.h
@@ -1,7 +1,7 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020 Greg V <greg@unrelenting.technology>
+ * Copyright (c) 2020 Val Packett <val@packett.cool>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/sys/compat/linuxkpi/common/include/asm/hypervisor.h b/sys/compat/linuxkpi/common/include/asm/hypervisor.h
new file mode 100644
index 000000000000..f344a2929359
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm/hypervisor.h
@@ -0,0 +1,19 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_ASM_HYPERVISOR_H
+#define _LINUXKPI_ASM_HYPERVISOR_H
+
+#if defined(__i386__) || defined(__amd64__)
+
+#define X86_HYPER_NATIVE 1
+#define X86_HYPER_MS_HYPERV 2
+
+static inline bool
+hypervisor_is_type(int type)
+{
+ return (type == X86_HYPER_NATIVE);
+}
+
+#endif
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/asm/intel-family.h b/sys/compat/linuxkpi/common/include/asm/intel-family.h
new file mode 100644
index 000000000000..91ad1d1a8ff3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm/intel-family.h
@@ -0,0 +1,6 @@
+/* Public domain. */
+
+#define INTEL_FAM6_ALDERLAKE 0x97
+#define INTEL_FAM6_ALDERLAKE_L 0x9A
+
+#define INTEL_FAM6_ROCKETLAKE 0xA7
diff --git a/sys/compat/linuxkpi/common/include/asm/io.h b/sys/compat/linuxkpi/common/include/asm/io.h
index 49eca70a38eb..63d1c8f72f8e 100644
--- a/sys/compat/linuxkpi/common/include/asm/io.h
+++ b/sys/compat/linuxkpi/common/include/asm/io.h
@@ -25,12 +25,17 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_IO_H_
#define _LINUXKPI_ASM_IO_H_
+#include <sys/param.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
#include <linux/io.h>
+#define virt_to_phys(x) vtophys(x)
+
#endif /* _LINUXKPI_ASM_IO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/memtype.h b/sys/compat/linuxkpi/common/include/asm/memtype.h
new file mode 100644
index 000000000000..c433e54fd7bf
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm/memtype.h
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_ASM_MEMTYPE_H_
+#define _LINUXKPI_ASM_MEMTYPE_H_
+
+#if defined(__amd64__) || defined(__i386__)
+
+#include <asm/cpufeature.h>
+
+static inline bool
+pat_enabled(void)
+{
+ return (boot_cpu_has(X86_FEATURE_PAT));
+}
+
+#endif
+
+#endif /* _LINUXKPI_ASM_MEMTYPE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/msr.h b/sys/compat/linuxkpi/common/include/asm/msr.h
index 9d23e6b1bbc7..6f7c10f2860b 100644
--- a/sys/compat/linuxkpi/common/include/asm/msr.h
+++ b/sys/compat/linuxkpi/common/include/asm/msr.h
@@ -22,8 +22,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_MSR_H_
diff --git a/sys/compat/linuxkpi/common/include/asm/neon.h b/sys/compat/linuxkpi/common/include/asm/neon.h
index 2547fa9304d5..0488a90d6664 100644
--- a/sys/compat/linuxkpi/common/include/asm/neon.h
+++ b/sys/compat/linuxkpi/common/include/asm/neon.h
@@ -1,7 +1,7 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2022 Greg V <greg@unrelenting.technology>
+ * Copyright (c) 2022 Val Packett <val@packett.cool>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/sys/compat/linuxkpi/common/include/asm/pgtable.h b/sys/compat/linuxkpi/common/include/asm/pgtable.h
index 9e66fab8eae4..865662d587db 100644
--- a/sys/compat/linuxkpi/common/include/asm/pgtable.h
+++ b/sys/compat/linuxkpi/common/include/asm/pgtable.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_PGTABLE_H_
#define _LINUXKPI_ASM_PGTABLE_H_
@@ -42,4 +40,19 @@ typedef struct page *pgtable_t;
#define pgprot_decrypted(prot) (prot)
+#if defined(__i386__) || defined(__amd64__)
+#define _PAGE_BIT_PRESENT 0
+#define _PAGE_BIT_RW 1
+#define _PAGE_BIT_USER 2
+#define _PAGE_BIT_PWT 3
+#define _PAGE_BIT_PCD 4
+#define _PAGE_BIT_PAT 7
+
+#define _PAGE_PRESENT (((pteval_t) 1) << _PAGE_BIT_PRESENT)
+#define _PAGE_RW (((pteval_t) 1) << _PAGE_BIT_RW)
+#define _PAGE_PWT (((pteval_t) 1) << _PAGE_BIT_PWT)
+#define _PAGE_PCD (((pteval_t) 1) << _PAGE_BIT_PCD)
+#define _PAGE_PAT (((pteval_t) 1) << _PAGE_BIT_PAT)
+#endif
+
#endif /* _LINUXKPI_ASM_PGTABLE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/processor.h b/sys/compat/linuxkpi/common/include/asm/processor.h
new file mode 100644
index 000000000000..2bc4b6532544
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm/processor.h
@@ -0,0 +1,63 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_ASM_PROCESSOR_H_
+#define _LINUXKPI_ASM_PROCESSOR_H_
+
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#include <machine/cpu.h>
+
+#if defined(__i386__) || defined(__amd64__)
+#define X86_VENDOR_INTEL 0
+#define X86_VENDOR_CYRIX 1
+#define X86_VENDOR_AMD 2
+#define X86_VENDOR_UMC 3
+#define X86_VENDOR_CENTAUR 5
+#define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_NSC 8
+#define X86_VENDOR_HYGON 9
+#define X86_VENDOR_NUM 12
+
+#define X86_VENDOR_UNKNOWN 0xff
+
+struct cpuinfo_x86 {
+ uint8_t x86;
+ uint8_t x86_model;
+ uint16_t x86_clflush_size;
+ uint16_t x86_max_cores;
+ uint8_t x86_vendor;
+};
+
+extern struct cpuinfo_x86 boot_cpu_data;
+extern struct cpuinfo_x86 *__cpu_data;
+#define cpu_data(cpu) __cpu_data[cpu]
+#endif
+
+#define cpu_relax() cpu_spinwait()
+
+#endif /* _LINUXKPI_ASM_PROCESSOR_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h
index cdb7ad912acc..1019aaf264a0 100644
--- a/sys/compat/linuxkpi/common/include/asm/set_memory.h
+++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h
@@ -34,14 +34,20 @@
static inline int
set_memory_uc(unsigned long addr, int numpages)
{
- return (pmap_change_attr(addr, numpages, VM_MEMATTR_UNCACHEABLE));
+ vm_size_t len;
+
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_UNCACHEABLE));
}
static inline int
set_memory_wc(unsigned long addr, int numpages)
{
#ifdef VM_MEMATTR_WRITE_COMBINING
- return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_COMBINING));
+ vm_size_t len;
+
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_COMBINING));
#else
return (set_memory_uc(addr, numpages));
#endif
@@ -50,11 +56,14 @@ set_memory_wc(unsigned long addr, int numpages)
static inline int
set_memory_wb(unsigned long addr, int numpages)
{
- return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_BACK));
+ vm_size_t len;
+
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_BACK));
}
static inline int
-set_pages_uc(vm_page_t page, int numpages)
+set_pages_uc(struct page *page, int numpages)
{
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
@@ -63,7 +72,7 @@ set_pages_uc(vm_page_t page, int numpages)
}
static inline int
-set_pages_wc(vm_page_t page, int numpages)
+set_pages_wc(struct page *page, int numpages)
{
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
@@ -76,7 +85,7 @@ set_pages_wc(vm_page_t page, int numpages)
}
static inline int
-set_pages_wb(vm_page_t page, int numpages)
+set_pages_wb(struct page *page, int numpages)
{
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
@@ -85,7 +94,7 @@ set_pages_wb(vm_page_t page, int numpages)
}
static inline int
-set_pages_array_wb(vm_page_t *pages, int addrinarray)
+set_pages_array_wb(struct page **pages, int addrinarray)
{
int i;
@@ -95,7 +104,7 @@ set_pages_array_wb(vm_page_t *pages, int addrinarray)
}
static inline int
-set_pages_array_wc(vm_page_t *pages, int addrinarray)
+set_pages_array_wc(struct page **pages, int addrinarray)
{
int i;
@@ -105,7 +114,7 @@ set_pages_array_wc(vm_page_t *pages, int addrinarray)
}
static inline int
-set_pages_array_uc(vm_page_t *pages, int addrinarray)
+set_pages_array_uc(struct page **pages, int addrinarray)
{
int i;
diff --git a/sys/compat/linuxkpi/common/include/asm/smp.h b/sys/compat/linuxkpi/common/include/asm/smp.h
index c349edb16bf4..27c3a81ef101 100644
--- a/sys/compat/linuxkpi/common/include/asm/smp.h
+++ b/sys/compat/linuxkpi/common/include/asm/smp.h
@@ -22,13 +22,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_SMP_H_
#define _LINUXKPI_ASM_SMP_H_
+#include <linux/jump_label.h>
+#include <linux/preempt.h>
+#include <asm/fpu/api.h>
+
#if defined(__i386__) || defined(__amd64__)
#define wbinvd_on_all_cpus() linux_wbinvd_on_all_cpus()
diff --git a/sys/compat/linuxkpi/common/include/asm/topology.h b/sys/compat/linuxkpi/common/include/asm/topology.h
new file mode 100644
index 000000000000..f334d3253cfb
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/asm/topology.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_ASM_TOPOLOGY_H_
+#define _LINUXKPI_ASM_TOPOLOGY_H_
+
+#if defined(__i386__) || defined(__amd64__)
+#include <sys/smp.h>
+
+/*
+ * The following functions are defined in `arch/x86/include/asm/topology.h`
+ * and thus are specific to i386 and amd64.
+ */
+
+static inline unsigned int
+topology_num_cores_per_package(void)
+{
+ return (mp_ncores);
+}
+
+static inline unsigned int
+topology_num_threads_per_package(void)
+{
+ return (mp_ncpus);
+}
+#endif
+
+#endif /* _LINUXKPI_ASM_TOPOLOGY_H_ */
diff --git a/sys/compat/linuxkpi/common/include/asm/types.h b/sys/compat/linuxkpi/common/include/asm/types.h
index e7d3de60e987..2e61bcfdb5e6 100644
--- a/sys/compat/linuxkpi/common/include/asm/types.h
+++ b/sys/compat/linuxkpi/common/include/asm/types.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_TYPES_H_
#define _LINUXKPI_ASM_TYPES_H_
diff --git a/sys/compat/linuxkpi/common/include/asm/uaccess.h b/sys/compat/linuxkpi/common/include/asm/uaccess.h
index b3b2cb53d22a..94354f8ddeee 100644
--- a/sys/compat/linuxkpi/common/include/asm/uaccess.h
+++ b/sys/compat/linuxkpi/common/include/asm/uaccess.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_UACCESS_H_
#define _LINUXKPI_ASM_UACCESS_H_
diff --git a/sys/compat/linuxkpi/common/include/asm/unaligned.h b/sys/compat/linuxkpi/common/include/asm/unaligned.h
index 8a001ec38c3d..e45846a3b543 100644
--- a/sys/compat/linuxkpi/common/include/asm/unaligned.h
+++ b/sys/compat/linuxkpi/common/include/asm/unaligned.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020 The FreeBSD Foundation
+ * Copyright (c) 2020,2023 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_ASM_UNALIGNED_H
@@ -51,6 +49,15 @@ get_unaligned_le32(const void *p)
}
static __inline void
+put_unaligned_le16(__le16 v, void *p)
+{
+ __le16 x;
+
+ x = cpu_to_le16(v);
+ memcpy(p, &x, sizeof(x));
+}
+
+static __inline void
put_unaligned_le32(__le32 v, void *p)
{
__le32 x;
@@ -82,4 +89,11 @@ get_unaligned_be32(const void *p)
return (be32_to_cpup((const __be32 *)p));
}
+static __inline uint64_t
+get_unaligned_be64(const void *p)
+{
+
+ return (be64_to_cpup((const __be64 *)p));
+}
+
#endif /* _LINUXKPI_ASM_UNALIGNED_H */
diff --git a/sys/compat/linuxkpi/common/include/crypto/hash.h b/sys/compat/linuxkpi/common/include/crypto/hash.h
new file mode 100644
index 000000000000..bf401691722a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/crypto/hash.h
@@ -0,0 +1,94 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_CRYPTO_HASH_H
+#define _LINUXKPI_CRYPTO_HASH_H
+
+#include <linux/kernel.h> /* for pr_debug */
+
+struct crypto_shash {
+};
+
+struct shash_desc {
+ struct crypto_shash *tfm;
+};
+
+static inline struct crypto_shash *
+crypto_alloc_shash(const char *algostr, int x, int y)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline void
+crypto_free_shash(struct crypto_shash *csh)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline int
+crypto_shash_init(struct shash_desc *desc)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENXIO);
+}
+
+static inline int
+crypto_shash_final(struct shash_desc *desc, uint8_t *mic)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENXIO);
+}
+
+static inline int
+crypto_shash_setkey(struct crypto_shash *csh, const uint8_t *key, size_t keylen)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENXIO);
+}
+
+static inline int
+crypto_shash_update(struct shash_desc *desc, uint8_t *data, size_t datalen)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENXIO);
+}
+
+static inline void
+shash_desc_zero(struct shash_desc *desc)
+{
+
+ explicit_bzero(desc, sizeof(*desc));
+}
+
+/* XXX review this. */
+#define SHASH_DESC_ON_STACK(desc, tfm) \
+ uint8_t ___ ## desc ## _desc[sizeof(struct shash_desc)]; \
+ struct shash_desc *desc = (struct shash_desc *)___ ## desc ## _desc
+
+#endif /* _LINUXKPI_CRYPTO_HASH_H */
diff --git a/sys/compat/linuxkpi/common/include/kunit/static_stub.h b/sys/compat/linuxkpi/common/include/kunit/static_stub.h
new file mode 100644
index 000000000000..9d425d46dbb0
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/kunit/static_stub.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_KUNIT_STATIC_STUB_H
+#define _LINUXKPI_KUNIT_STATIC_STUB_H
+
+#define KUNIT_STATIC_STUB_REDIRECT(_fn, ...) do { } while(0)
+
+#endif /* _LINUXKPI_KUNIT_STATIC_STUB_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/acpi.h b/sys/compat/linuxkpi/common/include/linux/acpi.h
index 1a9d25e7a7ff..3e1ec1b20626 100644
--- a/sys/compat/linuxkpi/common/include/linux/acpi.h
+++ b/sys/compat/linuxkpi/common/include/linux/acpi.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ACPI_H_
@@ -41,6 +39,10 @@
#define ACPI_HANDLE(dev) \
((dev)->bsddev != NULL ? bsd_acpi_get_handle((dev)->bsddev) : NULL)
+#define acpi_device_handle(dev) \
+ ((dev) != NULL ? bsd_acpi_get_handle(dev) : NULL)
+static inline void acpi_dev_put(struct acpi_device *adev) {}
+#define acpi_handle_debug(handle, fmt, ...)
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/acpi_amd_wbrf.h b/sys/compat/linuxkpi/common/include/linux/acpi_amd_wbrf.h
new file mode 100644
index 000000000000..92c2ead41c45
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/acpi_amd_wbrf.h
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_ACPI_AMD_WBRF_H_
+#define _LINUXKPI_LINUX_ACPI_AMD_WBRF_H_
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+#define MAX_NUM_OF_WBRF_RANGES 11
+
+#define WBRF_RECORD_ADD 0x0
+#define WBRF_RECORD_REMOVE 0x1
+
+struct freq_band_range {
+ uint64_t start;
+ uint64_t end;
+};
+
+struct wbrf_ranges_in_out {
+ uint64_t num_of_ranges;
+ struct freq_band_range band_list[MAX_NUM_OF_WBRF_RANGES];
+};
+
+enum wbrf_notifier_actions {
+ WBRF_CHANGED,
+};
+
+/*
+ * The following functions currently have dummy implementations that, on Linux,
+ * are used when CONFIG_AMD_WBRF is not set at compile time.
+ */
+
+static inline bool
+acpi_amd_wbrf_supported_consumer(struct device *dev)
+{
+ return (false);
+}
+
+static inline int
+acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action,
+ struct wbrf_ranges_in_out *in)
+{
+ return (-ENODEV);
+}
+
+static inline bool
+acpi_amd_wbrf_supported_producer(struct device *dev)
+{
+ return (false);
+}
+
+static inline int
+amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out)
+{
+ return (-ENODEV);
+}
+
+static inline int
+amd_wbrf_register_notifier(struct notifier_block *nb)
+{
+ return (-ENODEV);
+}
+
+static inline int
+amd_wbrf_unregister_notifier(struct notifier_block *nb)
+{
+ return (-ENODEV);
+}
+
+#endif /* _LINUXKPI_LINUX_ACPI_AMD_WBRF_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/agp_backend.h b/sys/compat/linuxkpi/common/include/linux/agp_backend.h
new file mode 100644
index 000000000000..c855fd842970
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/agp_backend.h
@@ -0,0 +1,28 @@
+/* Public domain */
+
+#ifndef _LINUXKPI_LINUX_AGP_BACKEND_H_
+#define _LINUXKPI_LINUX_AGP_BACKEND_H_
+
+#include <sys/types.h>
+
+struct agp_version {
+ uint16_t major;
+ uint16_t minor;
+};
+
+struct agp_kern_info {
+ struct agp_version version;
+ uint16_t vendor;
+ uint16_t device;
+ unsigned long mode;
+ unsigned long aper_base;
+ size_t aper_size;
+ int max_memory;
+ int current_memory;
+ bool cant_use_aperture;
+ unsigned long page_mask;
+};
+
+struct agp_memory;
+
+#endif /* _LINUXKPI_LINUX_AGP_BACKEND_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/anon_inodes.h b/sys/compat/linuxkpi/common/include/linux/anon_inodes.h
index cab5cbd4d67e..c69f6e152b17 100644
--- a/sys/compat/linuxkpi/common/include/linux/anon_inodes.h
+++ b/sys/compat/linuxkpi/common/include/linux/anon_inodes.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
diff --git a/sys/compat/linuxkpi/common/include/linux/aperture.h b/sys/compat/linuxkpi/common/include/linux/aperture.h
new file mode 100644
index 000000000000..7eced3cc3cb1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/aperture.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef _LINUX_APERTURE_H_
+#define _LINUX_APERTURE_H_
+
+#include <linux/types.h>
+
+#define CONFIG_APERTURE_HELPERS
+
+struct pci_dev;
+struct platform_device;
+
+#if defined(CONFIG_APERTURE_HELPERS)
+int devm_aperture_acquire_for_platform_device(struct platform_device *pdev,
+ resource_size_t base,
+ resource_size_t size);
+
+int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
+ const char *name);
+
+int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev);
+
+int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name);
+#else
+static inline int devm_aperture_acquire_for_platform_device(struct platform_device *pdev,
+ resource_size_t base,
+ resource_size_t size)
+{
+ return 0;
+}
+
+static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
+ const char *name)
+{
+ return 0;
+}
+
+static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev)
+{
+ return 0;
+}
+
+static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name)
+{
+ return 0;
+}
+#endif
+
+/**
+ * aperture_remove_all_conflicting_devices - remove all existing framebuffers
+ * @name: a descriptive name of the requesting driver
+ *
+ * This function removes all graphics device drivers. Use this function on systems
+ * that can have their framebuffer located anywhere in memory.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise
+ */
+static inline int aperture_remove_all_conflicting_devices(const char *name)
+{
+ return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name);
+}
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/apple-gmux.h b/sys/compat/linuxkpi/common/include/linux/apple-gmux.h
new file mode 100644
index 000000000000..812a782c57d4
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/apple-gmux.h
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_APPLE_GMUX_H
+#define _LINUXKPI_LINUX_APPLE_GMUX_H
+
+static inline bool
+apple_gmux_detect(void *a, void *b)
+{
+ return false;
+}
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/atomic.h b/sys/compat/linuxkpi/common/include/linux/atomic.h
index e491283ae6e5..bc76928a7d67 100644
--- a/sys/compat/linuxkpi/common/include/linux/atomic.h
+++ b/sys/compat/linuxkpi/common/include/linux/atomic.h
@@ -22,8 +22,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ATOMIC_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/average.h b/sys/compat/linuxkpi/common/include/linux/average.h
index 61b2010d6509..4191a351c5c6 100644
--- a/sys/compat/linuxkpi/common/include/linux/average.h
+++ b/sys/compat/linuxkpi/common/include/linux/average.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_AVERAGE_H
diff --git a/sys/compat/linuxkpi/common/include/linux/backlight.h b/sys/compat/linuxkpi/common/include/linux/backlight.h
index 9591a4b671ab..4f8f7440925a 100644
--- a/sys/compat/linuxkpi/common/include/linux/backlight.h
+++ b/sys/compat/linuxkpi/common/include/linux/backlight.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BACKLIGHT_H_
@@ -92,6 +90,13 @@ backlight_force_update(struct backlight_device *bd, int reason)
}
static inline int
+backlight_get_brightness(struct backlight_device *bd)
+{
+
+ return (bd->props.brightness);
+}
+
+static inline int
backlight_device_set_brightness(struct backlight_device *bd, int brightness)
{
@@ -119,4 +124,11 @@ backlight_disable(struct backlight_device *bd)
return (backlight_update_status(bd));
}
+static inline bool
+backlight_is_blank(struct backlight_device *bd)
+{
+
+ return (bd->props.power != 0/* FB_BLANK_UNBLANK */);
+}
+
#endif /* _LINUXKPI_LINUX_BACKLIGHT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcd.h b/sys/compat/linuxkpi/common/include/linux/bcd.h
index 8a40da1a330b..385819910454 100644
--- a/sys/compat/linuxkpi/common/include/linux/bcd.h
+++ b/sys/compat/linuxkpi/common/include/linux/bcd.h
@@ -23,8 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BCD_H
diff --git a/sys/compat/linuxkpi/common/include/linux/bitfield.h b/sys/compat/linuxkpi/common/include/linux/bitfield.h
index c22757d54290..8a91b0663f37 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitfield.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitfield.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BITFIELD_H
@@ -127,9 +125,16 @@ _uX_replace_bits(8)
#define __bf_shf(x) (__builtin_ffsll(x) - 1)
+#define FIELD_FIT(_mask, _value) \
+ (!(((typeof(_mask))(_value) << __bf_shf(_mask)) & ~(_mask)))
+
#define FIELD_PREP(_mask, _value) \
(((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask))
+/* Likely would need extra sanity checks compared to FIELD_PREP()? */
+#define FIELD_PREP_CONST(_mask, _value) \
+ (((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask))
+
#define FIELD_GET(_mask, _value) \
((typeof(_mask))(((_value) & (_mask)) >> __bf_shf(_mask)))
diff --git a/sys/compat/linuxkpi/common/include/linux/bitmap.h b/sys/compat/linuxkpi/common/include/linux/bitmap.h
index 1ae6078966a4..f26a0f99dc03 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitmap.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitmap.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BITMAP_H_
@@ -266,6 +264,27 @@ bitmap_subset(const unsigned long *pa,
return (1);
}
+static inline bool
+bitmap_intersects(const unsigned long *pa, const unsigned long *pb,
+ unsigned size)
+{
+ const unsigned end = BIT_WORD(size);
+ const unsigned tail = size & (BITS_PER_LONG - 1);
+ unsigned i;
+
+ for (i = 0; i != end; i++)
+ if (pa[i] & pb[i])
+ return (true);
+
+ if (tail) {
+ const unsigned long mask = BITMAP_LAST_WORD_MASK(tail);
+
+ if (pa[end] & pb[end] & mask)
+ return (true);
+ }
+ return (false);
+}
+
static inline void
bitmap_complement(unsigned long *dst, const unsigned long *src,
const unsigned int size)
@@ -289,6 +308,49 @@ bitmap_copy(unsigned long *dst, const unsigned long *src,
}
static inline void
+bitmap_to_arr32(uint32_t *dst, const unsigned long *src, unsigned int size)
+{
+ const unsigned int end = howmany(size, 32);
+
+#ifdef __LP64__
+ unsigned int i = 0;
+ while (i < end) {
+ dst[i++] = (uint32_t)(*src & UINT_MAX);
+ if (i < end)
+ dst[i++] = (uint32_t)(*src >> 32);
+ src++;
+ }
+#else
+ bitmap_copy((unsigned long *)dst, src, size);
+#endif
+ if ((size % 32) != 0) /* Linux uses BITS_PER_LONG. Seems to be a bug */
+ dst[end - 1] &= (uint32_t)(UINT_MAX >> (32 - (size % 32)));
+}
+
+static inline void
+bitmap_from_arr32(unsigned long *dst, const uint32_t *src,
+ unsigned int size)
+{
+ const unsigned int end = BIT_WORD(size);
+ const unsigned int tail = size & (BITS_PER_LONG - 1);
+
+#ifdef __LP64__
+ const unsigned int end32 = howmany(size, 32);
+ unsigned int i = 0;
+
+ while (i < end32) {
+ dst[i++/2] = (unsigned long) *(src++);
+ if (i < end32)
+ dst[i++/2] |= ((unsigned long) *(src++)) << 32;
+ }
+#else
+ bitmap_copy(dst, (const unsigned long *)src, size);
+#endif
+ if ((size % BITS_PER_LONG) != 0)
+ dst[end] &= BITMAP_LAST_WORD_MASK(tail);
+}
+
+static inline void
bitmap_or(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, const unsigned int size)
{
@@ -332,6 +394,40 @@ bitmap_xor(unsigned long *dst, const unsigned long *src1,
dst[i] = src1[i] ^ src2[i];
}
+static inline void
+bitmap_shift_right(unsigned long *dst, const unsigned long *src,
+ unsigned int shift, unsigned int size)
+{
+ const unsigned int end = BITS_TO_LONGS(size);
+ const unsigned int tail = size & (BITS_PER_LONG - 1);
+ const unsigned long mask = BITMAP_LAST_WORD_MASK(tail);
+ const unsigned int off = BIT_WORD(shift);
+ const unsigned int rem = shift & (BITS_PER_LONG - 1);
+ unsigned long left, right;
+ unsigned int i, srcpos;
+
+ for (i = 0, srcpos = off; srcpos < end; i++, srcpos++) {
+ right = src[srcpos];
+ left = 0;
+
+ if (srcpos == end - 1)
+ right &= mask;
+
+ if (rem != 0) {
+ right >>= rem;
+ if (srcpos + 1 < end) {
+ left = src[srcpos + 1];
+ if (srcpos + 1 == end - 1)
+ left &= mask;
+ left <<= (BITS_PER_LONG - rem);
+ }
+ }
+ dst[i] = left | right;
+ }
+ if (off != 0)
+ memset(dst + end - off, 0, off * sizeof(unsigned long));
+}
+
static inline unsigned long *
bitmap_alloc(unsigned int size, gfp_t flags)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h
index b6c54b2e6858..00dd1f9a1ec0 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitops.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitops.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BITOPS_H_
#define _LINUXKPI_LINUX_BITOPS_H_
@@ -56,6 +54,7 @@
#define GENMASK_ULL(h, l) (((~0ULL) >> (BITS_PER_LONG_LONG - (h) - 1)) & ((~0ULL) << (l)))
#define BITS_PER_BYTE 8
#define BITS_PER_TYPE(t) (sizeof(t) * BITS_PER_BYTE)
+#define BITS_TO_BYTES(n) howmany((n), BITS_PER_BYTE)
#define hweight8(x) bitcount((uint8_t)(x))
#define hweight16(x) bitcount16(x)
@@ -63,10 +62,10 @@
#define hweight64(x) bitcount64(x)
#define hweight_long(x) bitcountl(x)
-#define HWEIGHT8(x) (bitcount8((uint8_t)(x)) + 1)
-#define HWEIGHT16(x) (bitcount16(x) + 1)
-#define HWEIGHT32(x) (bitcount32(x) + 1)
-#define HWEIGHT64(x) (bitcount64(x) + 1)
+#define HWEIGHT8(x) (__builtin_popcountg((uint8_t)(x)))
+#define HWEIGHT16(x) (__builtin_popcountg((uint16_t)(x)))
+#define HWEIGHT32(x) (__builtin_popcountg((uint32_t)(x)))
+#define HWEIGHT64(x) (__builtin_popcountg((uint64_t)(x)))
static inline int
__ffs(int mask)
@@ -289,6 +288,15 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size,
#define test_bit(i, a) \
!!(READ_ONCE(((volatile const unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i))
+static inline void
+__assign_bit(long bit, volatile unsigned long *addr, bool value)
+{
+ if (value)
+ __set_bit(bit, addr);
+ else
+ __clear_bit(bit, addr);
+}
+
static inline int
test_and_clear_bit(long bit, volatile unsigned long *var)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/bottom_half.h b/sys/compat/linuxkpi/common/include/linux/bottom_half.h
index 1b139c481283..12b170845cbc 100644
--- a/sys/compat/linuxkpi/common/include/linux/bottom_half.h
+++ b/sys/compat/linuxkpi/common/include/linux/bottom_half.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BOTTOM_HALF_H_
#define _LINUXKPI_LINUX_BOTTOM_HALF_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/bsearch.h b/sys/compat/linuxkpi/common/include/linux/bsearch.h
index 8cc329aa855c..fb67109e4bba 100644
--- a/sys/compat/linuxkpi/common/include/linux/bsearch.h
+++ b/sys/compat/linuxkpi/common/include/linux/bsearch.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_BSEARCH_H
diff --git a/sys/compat/linuxkpi/common/include/linux/build_bug.h b/sys/compat/linuxkpi/common/include/linux/build_bug.h
new file mode 100644
index 000000000000..6a026376cfc8
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/build_bug.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org>
+ * Copyright (c) 2018 Johannes Lundberg <johalun0@gmail.com>
+ * Copyright (c) 2021 The FreeBSD Foundation
+ * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2023 Serenity Cyber Security, LLC
+ *
+ * Portions of this software were developed by Bjoern A. Zeeb
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_BUILD_BUG_H_
+#define _LINUXKPI_LINUX_BUILD_BUG_H_
+
+#include <sys/param.h>
+
+#include <linux/compiler.h>
+
+/*
+ * BUILD_BUG_ON() can happen inside functions where _Static_assert() does not
+ * seem to work. Use old-schoold-ish CTASSERT from before commit
+ * a3085588a88fa58eb5b1eaae471999e1995a29cf but also make sure we do not
+ * end up with an unused typedef or variable. The compiler should optimise
+ * it away entirely.
+ */
+#define _O_CTASSERT(x) _O__CTASSERT(x, __LINE__)
+#define _O__CTASSERT(x, y) _O___CTASSERT(x, y)
+#define _O___CTASSERT(x, y) while (0) { \
+ typedef char __assert_line_ ## y[(x) ? 1 : -1]; \
+ __assert_line_ ## y _x __unused; \
+ _x[0] = '\0'; \
+}
+
+#define BUILD_BUG() do { CTASSERT(0); } while (0)
+#define BUILD_BUG_ON(x) do { _O_CTASSERT(!(x)) } while (0)
+#define BUILD_BUG_ON_MSG(x, msg) BUILD_BUG_ON(x)
+#define BUILD_BUG_ON_NOT_POWER_OF_2(x) BUILD_BUG_ON(!powerof2(x))
+#define BUILD_BUG_ON_INVALID(expr) while (0) { (void)(expr); }
+#define BUILD_BUG_ON_ZERO(x) ((int)sizeof(struct { int:-((x) != 0); }))
+
+#define static_assert(x, ...) __static_assert(x, ##__VA_ARGS__, #x)
+#define __static_assert(x, msg, ...) _Static_assert(x, msg)
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/cache.h b/sys/compat/linuxkpi/common/include/linux/cache.h
index 6479d5d04d3a..b02b28d08ea9 100644
--- a/sys/compat/linuxkpi/common/include/linux/cache.h
+++ b/sys/compat/linuxkpi/common/include/linux/cache.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_CACHE_H_
#define _LINUXKPI_LINUX_CACHE_H_
@@ -35,6 +33,7 @@
#define cache_line_size() CACHE_LINE_SIZE
#define L1_CACHE_BYTES CACHE_LINE_SIZE
+#define L1_CACHE_ALIGN(x) ALIGN(x, CACHE_LINE_SIZE)
#define SMP_CACHE_BYTES L1_CACHE_BYTES
diff --git a/sys/compat/linuxkpi/common/include/linux/capability.h b/sys/compat/linuxkpi/common/include/linux/capability.h
index 547ee586ad8e..e3dacd4e9f15 100644
--- a/sys/compat/linuxkpi/common/include/linux/capability.h
+++ b/sys/compat/linuxkpi/common/include/linux/capability.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2015 Rimvydas Jasinskas
* All rights reserved.
diff --git a/sys/compat/linuxkpi/common/include/linux/cc_platform.h b/sys/compat/linuxkpi/common/include/linux/cc_platform.h
new file mode 100644
index 000000000000..1544c141614b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cc_platform.h
@@ -0,0 +1,21 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_CC_PLATFORM_H_
+#define _LINUXKPI_LINUX_CC_PLATFORM_H_
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+
+enum cc_attr {
+ CC_ATTR_MEM_ENCRYPT,
+ CC_ATTR_GUEST_MEM_ENCRYPT,
+};
+
+static inline bool
+cc_platform_has(enum cc_attr attr __unused)
+{
+
+ return (false);
+}
+
+#endif /* _LINUXKPI_LINUX_CC_PLATFORM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cdev.h b/sys/compat/linuxkpi/common/include/linux/cdev.h
index 2befe9b259cb..d989db14c2f8 100644
--- a/sys/compat/linuxkpi/common/include/linux/cdev.h
+++ b/sys/compat/linuxkpi/common/include/linux/cdev.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_CDEV_H_
#define _LINUXKPI_LINUX_CDEV_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/cec.h b/sys/compat/linuxkpi/common/include/linux/cec.h
new file mode 100644
index 000000000000..e0854d87d85c
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cec.h
@@ -0,0 +1,8 @@
+/* Public domain */
+
+#ifndef _LINUXKPI_LINUX_CEC_H_
+#define _LINUXKPI_LINUX_CEC_H_
+
+#define CEC_PHYS_ADDR_INVALID 0xffff
+
+#endif /* _LINUXKPI_LINUX_CEC_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cgroup.h b/sys/compat/linuxkpi/common/include/linux/cgroup.h
new file mode 100644
index 000000000000..a9dd22fd0f4c
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cgroup.h
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_CGROUP_H_
+#define _LINUXKPI_LINUX_CGROUP_H_
+
+#include <linux/kernel_stat.h>
+
+#endif /* _LINUXKPI_LINUX_CGROUP_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/cleanup.h b/sys/compat/linuxkpi/common/include/linux/cleanup.h
new file mode 100644
index 000000000000..5bb146f082ed
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cleanup.h
@@ -0,0 +1,93 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024-2025 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ */
+
+#ifndef _LINUXKPI_LINUX_CLEANUP_H
+#define _LINUXKPI_LINUX_CLEANUP_H
+
+#define __cleanup(_f) __attribute__((__cleanup__(_f)))
+
+/*
+ * Note: "_T" are special as they are exposed into common code for
+ * statements. Extra care should be taken when changing the code.
+ */
+#define DEFINE_GUARD(_n, _dt, _lock, _unlock) \
+ \
+ typedef _dt guard_ ## _n ## _t; \
+ \
+ static inline _dt \
+ guard_ ## _n ## _create( _dt _T) \
+ { \
+ _dt c; \
+ \
+ c = ({ _lock; _T; }); \
+ return (c); \
+ } \
+ \
+ static inline void \
+ guard_ ## _n ## _destroy(_dt *t) \
+ { \
+ _dt _T; \
+ \
+ _T = *t; \
+ if (_T) { _unlock; }; \
+ }
+
+/* We need to keep these calls unique. */
+#define guard(_n) \
+ guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__ \
+ __cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create
+
+#define DEFINE_FREE(_n, _t, _f) \
+ static inline void \
+ __free_ ## _n(void *p) \
+ { \
+ _t _T; \
+ \
+ _T = *(_t *)p; \
+ _f; \
+ }
+
+#define __free(_n) __cleanup(__free_##_n)
+
+/*
+ * Given this is a _0 version it should likely be broken up into parts.
+ * But we have no idead what a _1, _2, ... version would do different
+ * until we see a call.
+ * This is used for a not-real-type (rcu). We use a bool to "simulate"
+ * the lock held. Also _T still special, may not always be used, so tag
+ * with __unused (or better the LinuxKPI __maybe_unused).
+ */
+#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \
+ \
+ typedef struct { \
+ bool lock; \
+ __VA_ARGS__; \
+ } guard_ ## _n ## _t; \
+ \
+ static inline void \
+ guard_ ## _n ## _destroy(guard_ ## _n ## _t *_T) \
+ { \
+ if (_T->lock) { \
+ _unlock; \
+ } \
+ } \
+ \
+ static inline guard_ ## _n ## _t \
+ guard_ ## _n ## _create(void) \
+ { \
+ guard_ ## _n ## _t _tmp; \
+ guard_ ## _n ## _t *_T __maybe_unused; \
+ \
+ _tmp.lock = true; \
+ _T = &_tmp; \
+ _lock; \
+ return (_tmp); \
+ }
+
+#endif /* _LINUXKPI_LINUX_CLEANUP_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/clocksource.h b/sys/compat/linuxkpi/common/include/linux/clocksource.h
index 8027ed76ec0f..3e7664c3e57e 100644
--- a/sys/compat/linuxkpi/common/include/linux/clocksource.h
+++ b/sys/compat/linuxkpi/common/include/linux/clocksource.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_CLOCKSOURCE_H
#define _LINUXKPI_LINUX_CLOCKSOURCE_H
diff --git a/sys/compat/linuxkpi/common/include/linux/compat.h b/sys/compat/linuxkpi/common/include/linux/compat.h
index 5e4dd1daf67d..8a5a6918bb7c 100644
--- a/sys/compat/linuxkpi/common/include/linux/compat.h
+++ b/sys/compat/linuxkpi/common/include/linux/compat.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_COMPAT_H_
#define _LINUXKPI_LINUX_COMPAT_H_
@@ -43,19 +41,28 @@ extern int linux_alloc_current(struct thread *, int flags);
extern void linux_free_current(struct task_struct *);
extern struct domainset *linux_get_vm_domain_set(int node);
+#define __current_unallocated(td) \
+ __predict_false((td)->td_lkpi_task == NULL)
+
static inline void
linux_set_current(struct thread *td)
{
- if (__predict_false(td->td_lkpi_task == NULL))
+ if (__current_unallocated(td))
lkpi_alloc_current(td, M_WAITOK);
}
static inline int
linux_set_current_flags(struct thread *td, int flags)
{
- if (__predict_false(td->td_lkpi_task == NULL))
+ if (__current_unallocated(td))
return (lkpi_alloc_current(td, flags));
return (0);
}
+#define compat_ptr(x) ((void *)(uintptr_t)x)
+#define ptr_to_compat(x) ((uintptr_t)x)
+
+typedef void fpu_safe_exec_cb_t(void *ctx);
+void lkpi_fpu_safe_exec(fpu_safe_exec_cb_t func, void *ctx);
+
#endif /* _LINUXKPI_LINUX_COMPAT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler.h b/sys/compat/linuxkpi/common/include/linux/compiler.h
index 87a37228736f..948396144ad6 100644
--- a/sys/compat/linuxkpi/common/include/linux/compiler.h
+++ b/sys/compat/linuxkpi/common/include/linux/compiler.h
@@ -26,8 +26,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_COMPILER_H_
#define _LINUXKPI_LINUX_COMPILER_H_
@@ -50,7 +48,9 @@
#define __cond_lock(x,c) (c)
#define __bitwise
#define __devinitdata
+#ifndef __deprecated
#define __deprecated
+#endif
#define __init
#define __initconst
#define __devinit
@@ -64,10 +64,22 @@
#undef __always_inline
#define __always_inline inline
#define noinline __noinline
+#define noinline_for_stack __noinline
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
#define ____cacheline_aligned_in_smp __aligned(CACHE_LINE_SIZE)
#define fallthrough /* FALLTHROUGH */ do { } while(0)
+#if __has_attribute(__nonstring__)
+#define __nonstring __attribute__((__nonstring__))
+#else
+#define __nonstring
+#endif
+#if __has_attribute(__counted_by__)
+#define __counted_by(_x) __attribute__((__counted_by__(_x)))
+#else
+#define __counted_by(_x)
+#endif
+
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define typeof(x) __typeof(x)
@@ -79,6 +91,10 @@
#define __printf(a,b) __printflike(a,b)
+#define __diag_push()
+#define __diag_pop()
+#define __diag_ignore_all(...)
+
#define barrier() __asm__ __volatile__("": : :"memory")
#define lower_32_bits(n) ((u32)(n))
@@ -87,18 +103,16 @@
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
-#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))
-
#define WRITE_ONCE(x,v) do { \
barrier(); \
- ACCESS_ONCE(x) = (v); \
+ (*(volatile __typeof(x) *)(uintptr_t)&(x)) = (v); \
barrier(); \
} while (0)
#define READ_ONCE(x) ({ \
__typeof(x) __var = ({ \
barrier(); \
- ACCESS_ONCE(x); \
+ (*(const volatile __typeof(x) *)&(x)); \
}); \
barrier(); \
__var; \
@@ -113,4 +127,13 @@
#define sizeof_field(_s, _m) sizeof(((_s *)0)->_m)
+#define is_signed_type(t) ((t)-1 < (t)1)
+#define is_unsigned_type(t) ((t)-1 > (t)1)
+
+#if __has_builtin(__builtin_dynamic_object_size)
+#define __struct_size(_s) __builtin_dynamic_object_size(_s, 0)
+#else
+#define __struct_size(_s) __builtin_object_size(_s, 0)
+#endif
+
#endif /* _LINUXKPI_LINUX_COMPILER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/completion.h b/sys/compat/linuxkpi/common/include/linux/completion.h
index 2f58bd5c03e6..9f8bebb4cf82 100644
--- a/sys/compat/linuxkpi/common/include/linux/completion.h
+++ b/sys/compat/linuxkpi/common/include/linux/completion.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_COMPLETION_H_
#define _LINUXKPI_LINUX_COMPLETION_H_
@@ -62,7 +60,8 @@ struct completion {
extern void linux_complete_common(struct completion *, int);
extern int linux_wait_for_common(struct completion *, int);
-extern int linux_wait_for_timeout_common(struct completion *, int, int);
+extern unsigned long linux_wait_for_timeout_common(struct completion *,
+ unsigned long, int);
extern int linux_try_wait_for_completion(struct completion *);
extern int linux_completion_done(struct completion *);
diff --git a/sys/compat/linuxkpi/common/include/linux/container_of.h b/sys/compat/linuxkpi/common/include/linux/container_of.h
new file mode 100644
index 000000000000..7210d531b055
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/container_of.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2010 Isilon Systems, Inc.
+ * Copyright (c) 2010 iX Systems, Inc.
+ * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2017 Matt Macy <mmacy@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_CONTAINER_OF_H
+#define _LINUXKPI_LINUX_CONTAINER_OF_H
+
+#include <sys/stdint.h>
+
+#include <linux/build_bug.h>
+#include <linux/stddef.h>
+
+#define container_of(ptr, type, member) \
+({ \
+ const __typeof(((type *)0)->member) *__p = (ptr); \
+ (type *)((uintptr_t)__p - offsetof(type, member)); \
+})
+
+#define container_of_const(ptr, type, member) \
+ _Generic(ptr, \
+ const typeof(*(ptr)) *: \
+ (const type *)container_of(ptr, type, member), \
+ default: \
+ container_of(ptr, type, member) \
+ )
+
+#define typeof_member(type, member) __typeof(((type *)0)->member)
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/cpu.h b/sys/compat/linuxkpi/common/include/linux/cpu.h
index 53fa9db424c2..43ec3d66a2e3 100644
--- a/sys/compat/linuxkpi/common/include/linux/cpu.h
+++ b/sys/compat/linuxkpi/common/include/linux/cpu.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_CPU_H
@@ -44,6 +42,8 @@ typedef cpuset_t cpumask_t;
extern cpumask_t cpu_online_mask;
+cpumask_t *lkpi_get_static_single_cpu_mask(int);
+
static __inline int
cpumask_next(int cpuid, cpumask_t mask)
{
@@ -73,4 +73,6 @@ cpumask_set_cpu(int cpu, cpumask_t *mask)
CPU_SET(cpu, mask);
}
+#define cpumask_of(_cpu) (lkpi_get_static_single_cpu_mask(_cpu))
+
#endif /* _LINUXKPI_LINUX_CPU_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/cpufeature.h b/sys/compat/linuxkpi/common/include/linux/cpufeature.h
new file mode 100644
index 000000000000..746d1a7164a8
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/cpufeature.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_CPUFEATURE_H_
+#define _LINUXKPI_LINUX_CPUFEATURE_H_
+
+/*
+ * Linux includes the following header. We don't have it on FreeBSD yet, so
+ * let's comment this include for now. It is still referenced here because
+ * sometimes, consumers of headers rely voluntarily or not on the namespace
+ * pollution.
+ */
+/* #include <linux/init.h> */
+#include <linux/mod_devicetable.h>
+#include <asm/cpufeature.h>
+
+#endif /* _LINUXKPI_LINUX_CPUFEATURE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/crc32.h b/sys/compat/linuxkpi/common/include/linux/crc32.h
index a93be642fb1a..e6d39fa7c5ff 100644
--- a/sys/compat/linuxkpi/common/include/linux/crc32.h
+++ b/sys/compat/linuxkpi/common/include/linux/crc32.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_CRC32_H
diff --git a/sys/compat/linuxkpi/common/include/linux/dcache.h b/sys/compat/linuxkpi/common/include/linux/dcache.h
index 9f9943a18dc6..992d6f7c2720 100644
--- a/sys/compat/linuxkpi/common/include/linux/dcache.h
+++ b/sys/compat/linuxkpi/common/include/linux/dcache.h
@@ -22,15 +22,14 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DCACHE_H
#define _LINUXKPI_LINUX_DCACHE_H
-struct vnode;
-struct pfs_node;
+#include <sys/vnode.h>
+
+#include <fs/pseudofs/pseudofs.h>
struct dentry {
struct vnode *d_inode;
diff --git a/sys/compat/linuxkpi/common/include/linux/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h
index 6a3273cbbf3c..4d146e085a7b 100644
--- a/sys/compat/linuxkpi/common/include/linux/debugfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2016-2018, Matthew Macy <mmacy@freebsd.org>
*
@@ -23,29 +23,102 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DEBUGFS_H_
#define _LINUXKPI_LINUX_DEBUGFS_H_
#include <linux/fs.h>
+#include <linux/module.h>
#include <linux/seq_file.h>
-
#include <linux/types.h>
-void debugfs_remove(struct dentry *dentry);
+MALLOC_DECLARE(M_DFSINT);
+
+struct debugfs_reg32 {
+ char *name;
+ unsigned long offset;
+};
+
+struct debugfs_regset32 {
+ const struct debugfs_reg32 *regs;
+ int nregs;
+};
+
+struct debugfs_blob_wrapper {
+ void *data;
+ size_t size;
+};
+
+static inline bool
+debugfs_initialized(void)
+{
+
+ return (true);
+}
struct dentry *debugfs_create_file(const char *name, umode_t mode,
- struct dentry *parent, void *data,
- const struct file_operations *fops);
+ struct dentry *parent, void *data,
+ const struct file_operations *fops);
+
+/* TODO: We currently ignore the `file_size` argument. */
+struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ loff_t file_size);
+
+struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
+struct dentry *parent, void *data,
+ const struct file_operations *fops);
+
+struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ const struct file_operations *fops_ro,
+ const struct file_operations *fops_wo);
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
- const char *dest);
+ const char *dest);
+
+struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
+
+void debugfs_remove(struct dentry *dentry);
void debugfs_remove_recursive(struct dentry *dentry);
-#endif
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
+ DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)
+#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \
+ DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)
+
+void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
+ bool *value);
+void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
+ uint8_t *value);
+void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent,
+ uint16_t *value);
+void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent,
+ uint32_t *value);
+void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent,
+ uint64_t *value);
+void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent,
+ uint8_t *value);
+void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent,
+ uint16_t *value);
+void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent,
+ uint32_t *value);
+void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent,
+ uint64_t *value);
+void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent,
+ unsigned long *value);
+void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent,
+ atomic_t *value);
+void debugfs_create_str(const char *name, umode_t mode, struct dentry *parent,
+ char **value);
+
+struct dentry *debugfs_create_blob(const char *name, umode_t mode,
+ struct dentry *parent, struct debugfs_blob_wrapper *value);
+
+#endif /* _LINUXKPI_LINUX_DEBUGFS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/delay.h b/sys/compat/linuxkpi/common/include/linux/delay.h
index ea0a8253b09f..f19d1a759c26 100644
--- a/sys/compat/linuxkpi/common/include/linux/delay.h
+++ b/sys/compat/linuxkpi/common/include/linux/delay.h
@@ -26,8 +26,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DELAY_H_
#define _LINUXKPI_LINUX_DELAY_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/devcoredump.h b/sys/compat/linuxkpi/common/include/linux/devcoredump.h
index eecf5380bfc3..5fa06c6595a8 100644
--- a/sys/compat/linuxkpi/common/include/linux/devcoredump.h
+++ b/sys/compat/linuxkpi/common/include/linux/devcoredump.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DEVCOREDUMP_H
@@ -73,4 +71,11 @@ dev_coredumpsg(struct device *dev __unused, struct scatterlist *table,
_lkpi_dev_coredumpsg_free(table);
}
+static inline void
+_devcd_free_sgtable(struct scatterlist *table)
+{
+ /* UNIMPLEMENTED */
+ _lkpi_dev_coredumpsg_free(table);
+}
+
#endif /* _LINUXKPI_LINUX_DEVCOREDUMP_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index e39b3f95ca0d..7dd6340746d2 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -4,6 +4,10 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
* All rights reserved.
+ * Copyright (c) 2021-2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,8 +29,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DEVICE_H_
#define _LINUXKPI_LINUX_DEVICE_H_
@@ -37,25 +39,24 @@
#include <linux/sysfs.h>
#include <linux/list.h>
#include <linux/compiler.h>
-#include <linux/types.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
#include <linux/backlight.h>
#include <linux/pm.h>
#include <linux/idr.h>
+#include <linux/overflow.h>
#include <linux/ratelimit.h> /* via linux/dev_printk.h */
+#include <linux/fwnode.h>
#include <asm/atomic.h>
#include <sys/bus.h>
#include <sys/backlight.h>
struct device;
-struct fwnode_handle;
struct class {
const char *name;
- struct module *owner;
struct kobject kobj;
devclass_t bsdclass;
const struct dev_pm_ops *pm;
@@ -67,6 +68,7 @@ struct class {
struct dev_pm_ops {
int (*prepare)(struct device *dev);
+ void (*complete)(struct device *dev);
int (*suspend)(struct device *dev);
int (*suspend_late)(struct device *dev);
int (*resume)(struct device *dev);
@@ -79,6 +81,7 @@ struct dev_pm_ops {
int (*poweroff_late)(struct device *dev);
int (*restore)(struct device *dev);
int (*restore_early)(struct device *dev);
+ int (*suspend_noirq)(struct device *dev);
int (*runtime_suspend)(struct device *dev);
int (*runtime_resume)(struct device *dev);
int (*runtime_idle)(struct device *dev);
@@ -87,6 +90,8 @@ struct dev_pm_ops {
struct device_driver {
const char *name;
const struct dev_pm_ops *pm;
+
+ void (*shutdown) (struct device *);
};
struct device_type {
@@ -124,6 +129,8 @@ struct device {
spinlock_t devres_lock;
struct list_head devres_head;
+
+ struct dev_pm_info power;
};
extern struct device linux_root_device;
@@ -183,15 +190,47 @@ show_class_attr_string(struct class *class,
struct class_attribute_string class_attr_##_name = \
_CLASS_ATTR_STRING(_name, _mode, _str)
-#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_crit(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_emerg(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
-#define dev_dbg(dev, fmt, ...) do { } while (0)
#define dev_printk(lvl, dev, fmt, ...) \
- device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+ device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+
+#define dev_emerg(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_alert(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_crit(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
+#define dev_dbg(dev, fmt, ...) do { } while (0)
+
+#define dev_WARN(dev, fmt, ...) \
+ device_printf((dev)->bsddev, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#define dev_WARN_ONCE(dev, condition, fmt, ...) do { \
+ static bool __dev_WARN_ONCE; \
+ bool __ret_warn_on = (condition); \
+ if (unlikely(__ret_warn_on)) { \
+ if (!__dev_WARN_ONCE) { \
+ __dev_WARN_ONCE = true; \
+ device_printf((dev)->bsddev, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__); \
+ } \
+ } \
+} while (0)
+
+#define dev_info_once(dev, ...) do { \
+ static bool __dev_info_once; \
+ if (!__dev_info_once) { \
+ __dev_info_once = true; \
+ dev_info(dev, __VA_ARGS__); \
+ } \
+} while (0)
+
+#define dev_warn_once(dev, ...) do { \
+ static bool __dev_warn_once; \
+ if (!__dev_warn_once) { \
+ __dev_warn_once = 1; \
+ dev_warn(dev, __VA_ARGS__); \
+ } \
+} while (0)
#define dev_err_once(dev, ...) do { \
static bool __dev_err_once; \
@@ -201,6 +240,14 @@ show_class_attr_string(struct class *class,
} \
} while (0)
+#define dev_dbg_once(dev, ...) do { \
+ static bool __dev_dbg_once; \
+ if (!__dev_dbg_once) { \
+ __dev_dbg_once = 1; \
+ dev_dbg(dev, __VA_ARGS__); \
+ } \
+} while (0)
+
#define dev_err_ratelimited(dev, ...) do { \
static linux_ratelimit_t __ratelimited; \
if (linux_ratelimited(&__ratelimited)) \
@@ -213,6 +260,12 @@ show_class_attr_string(struct class *class,
dev_warn(dev, __VA_ARGS__); \
} while (0)
+#define dev_dbg_ratelimited(dev, ...) do { \
+ static linux_ratelimit_t __ratelimited; \
+ if (linux_ratelimited(&__ratelimited)) \
+ dev_dbg(dev, __VA_ARGS__); \
+} while (0)
+
/* Public and LinuxKPI internal devres functions. */
void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
void lkpi_devres_add(struct device *, void *);
@@ -231,6 +284,8 @@ int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *)
void lkpi_devres_release_free_list(struct device *);
void lkpi_devres_unlink(struct device *, void *);
void lkpi_devm_kmalloc_release(struct device *, void *);
+void lkpi_devm_kfree(struct device *, const void *);
+#define devm_kfree(_d, _p) lkpi_devm_kfree(_d, _p)
static inline const char *
dev_driver_string(const struct device *dev)
@@ -278,6 +333,13 @@ dev_name(const struct device *dev)
return kobject_name(&dev->kobj);
}
+static inline bool
+dev_is_removable(struct device *dev)
+{
+
+ return (false);
+}
+
#define dev_set_name(_dev, _fmt, ...) \
kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__)
@@ -289,7 +351,12 @@ put_device(struct device *dev)
kobject_put(&dev->kobj);
}
-struct class *class_create(struct module *owner, const char *name);
+struct class *lkpi_class_create(const char *name);
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60400
+#define class_create(name) lkpi_class_create(name)
+#else
+#define class_create(owner, name) lkpi_class_create(name)
+#endif
static inline int
class_register(struct class *class)
@@ -517,6 +584,30 @@ device_reprobe(struct device *dev)
return (-error);
}
+static inline void
+device_set_wakeup_enable(struct device *dev __unused, bool enable __unused)
+{
+
+ /*
+ * XXX-BZ TODO This is used by wireless drivers supporting WoWLAN which
+ * we currently do not support.
+ */
+}
+
+static inline int
+device_wakeup_enable(struct device *dev)
+{
+
+ device_set_wakeup_enable(dev, true);
+ return (0);
+}
+
+static inline bool
+device_iommu_mapped(struct device *dev __unused)
+{
+ return (false);
+}
+
#define dev_pm_set_driver_flags(dev, flags) do { \
} while (0)
@@ -593,10 +684,36 @@ devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
return (p);
}
+static inline void *
+devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp)
+{
+ void *dst;
+
+ if (len == 0)
+ return (NULL);
+
+ dst = devm_kmalloc(dev, len, gfp);
+ if (dst != NULL)
+ memcpy(dst, src, len);
+
+ return (dst);
+}
+
#define devm_kzalloc(_dev, _size, _gfp) \
devm_kmalloc((_dev), (_size), (_gfp) | __GFP_ZERO)
#define devm_kcalloc(_dev, _sizen, _size, _gfp) \
devm_kmalloc((_dev), ((_sizen) * (_size)), (_gfp) | __GFP_ZERO)
+int lkpi_devm_add_action(struct device *dev, void (*action)(void *), void *data);
+#define devm_add_action(dev, action, data) \
+ lkpi_devm_add_action(dev, action, data);
+int lkpi_devm_add_action_or_reset(struct device *dev, void (*action)(void *), void *data);
+#define devm_add_action_or_reset(dev, action, data) \
+ lkpi_devm_add_action_or_reset(dev, action, data)
+
+int lkpi_devm_device_add_group(struct device *dev, const struct attribute_group *group);
+#define devm_device_add_group(dev, group) \
+ lkpi_devm_device_add_group(dev, group)
+
#endif /* _LINUXKPI_LINUX_DEVICE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/device/driver.h b/sys/compat/linuxkpi/common/include/linux/device/driver.h
new file mode 100644
index 000000000000..03b510c9c8b7
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/device/driver.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 Bjoern A. Zeeb
+ * Copyright (c) 2024 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#ifndef LINUXKPI_LINUX_DEVICE_DRIVER_H
+#define LINUXKPI_LINUX_DEVICE_DRIVER_H
+
+#include <sys/cdefs.h>
+#include <linux/module.h>
+
+#define module_driver(_drv, _regf, _unregf) \
+static inline int \
+__CONCAT(__CONCAT(_, _drv), _init)(void) \
+{ \
+ return (_regf(&(_drv))); \
+} \
+ \
+static inline void \
+__CONCAT(__CONCAT(_, _drv), _exit)(void) \
+{ \
+ _unregf(&(_drv)); \
+} \
+ \
+module_init(__CONCAT(__CONCAT(_, _drv), _init)); \
+module_exit(__CONCAT(__CONCAT(_, _drv), _exit))
+
+#endif /* LINUXKPI_LINUX_DEVICE_DRIVER_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/dma-attrs.h b/sys/compat/linuxkpi/common/include/linux/dma-attrs.h
index 741e1aa15d67..c9cfa9b621d5 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-attrs.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-attrs.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DMA_ATTR_H_
#define _LINUXKPI_LINUX_DMA_ATTR_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h b/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h
new file mode 100644
index 000000000000..567ce3b072b3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/dma-buf-map.h
@@ -0,0 +1,91 @@
+/* Public domain. */
+
+#ifndef _LINUX_DMA_BUF_MAP_H
+#define _LINUX_DMA_BUF_MAP_H
+
+#include <linux/io.h>
+#include <linux/string.h>
+
+struct dma_buf_map {
+ union {
+ void *vaddr_iomem;
+ void *vaddr;
+ };
+ bool is_iomem;
+};
+
+static inline void
+dma_buf_map_incr(struct dma_buf_map *dbm, size_t n)
+{
+ if (dbm->is_iomem)
+ dbm->vaddr_iomem += n;
+ else
+ dbm->vaddr += n;
+}
+
+static inline void
+dma_buf_map_memcpy_to(struct dma_buf_map *dbm, const void *src, size_t len)
+{
+ if (dbm->is_iomem)
+ memcpy_toio(dbm->vaddr_iomem, src, len);
+ else
+ memcpy(dbm->vaddr, src, len);
+}
+
+static inline bool
+dma_buf_map_is_null(const struct dma_buf_map *dbm)
+{
+ if (dbm->is_iomem)
+ return (dbm->vaddr_iomem == NULL);
+ else
+ return (dbm->vaddr == NULL);
+}
+
+static inline bool
+dma_buf_map_is_set(const struct dma_buf_map *dbm)
+{
+ if (dbm->is_iomem)
+ return (dbm->vaddr_iomem != NULL);
+ else
+ return (dbm->vaddr != NULL);
+}
+
+static inline bool
+dma_buf_map_is_equal(
+ const struct dma_buf_map *dbm_a, const struct dma_buf_map *dbm_b)
+{
+ if (dbm_a->is_iomem != dbm_b->is_iomem)
+ return (false);
+
+ if (dbm_a->is_iomem)
+ return (dbm_a->vaddr_iomem == dbm_b->vaddr_iomem);
+ else
+ return (dbm_a->vaddr == dbm_b->vaddr);
+}
+
+static inline void
+dma_buf_map_clear(struct dma_buf_map *dbm)
+{
+ if (dbm->is_iomem) {
+ dbm->vaddr_iomem = NULL;
+ dbm->is_iomem = false;
+ } else {
+ dbm->vaddr = NULL;
+ }
+}
+
+static inline void
+dma_buf_map_set_vaddr_iomem(struct dma_buf_map *dbm, void *addr)
+{
+ dbm->vaddr_iomem = addr;
+ dbm->is_iomem = true;
+}
+
+static inline void
+dma_buf_map_set_vaddr(struct dma_buf_map *dbm, void *addr)
+{
+ dbm->vaddr = addr;
+ dbm->is_iomem = false;
+}
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
index dd3bbc094dfb..2d8e1196d3d3 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DMA_MAPPING_H_
#define _LINUXKPI_LINUX_DMA_MAPPING_H_
@@ -45,6 +43,7 @@
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <vm/uma_align_mask.h>
#include <vm/pmap.h>
#include <machine/bus.h>
@@ -95,13 +94,19 @@ int linux_dma_tag_init(struct device *, u64);
int linux_dma_tag_init_coherent(struct device *, u64);
void *linux_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
-dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len);
-void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size);
+void *linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len); /* backward compat */
+dma_addr_t lkpi_dma_map_phys(struct device *, vm_paddr_t, size_t,
+ enum dma_data_direction, unsigned long);
+void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size); /* backward compat */
+void lkpi_dma_unmap(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction, unsigned long);
int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir __unused,
+ int nents, enum dma_data_direction direction,
unsigned long attrs __unused);
void linux_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
- int nents __unused, enum dma_data_direction dir __unused,
+ int nents __unused, enum dma_data_direction direction,
unsigned long attrs __unused);
void linuxkpi_dma_sync(struct device *, dma_addr_t, size_t, bus_dmasync_op_t);
@@ -159,21 +164,30 @@ dma_zalloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
return (dma_alloc_coherent(dev, size, dma_handle, flag | __GFP_ZERO));
}
+static inline void *
+dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t flag)
+{
+
+ return (linuxkpi_dmam_alloc_coherent(dev, size, dma_handle, flag));
+}
+
static inline void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr)
{
- linux_dma_unmap(dev, dma_addr, size);
- kmem_free((vm_offset_t)cpu_addr, size);
+ lkpi_dma_unmap(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0);
+ kmem_free(cpu_addr, size);
}
static inline dma_addr_t
dma_map_page_attrs(struct device *dev, struct page *page, size_t offset,
- size_t size, enum dma_data_direction dir, unsigned long attrs)
+ size_t size, enum dma_data_direction direction, unsigned long attrs)
{
- return (linux_dma_map_phys(dev, VM_PAGE_TO_PHYS(page) + offset, size));
+ return (lkpi_dma_map_phys(dev, page_to_phys(page) + offset, size,
+ direction, attrs));
}
/* linux_dma_(un)map_sg_attrs does not support attrs yet */
@@ -188,7 +202,8 @@ dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- return (linux_dma_map_phys(dev, VM_PAGE_TO_PHYS(page) + offset, size));
+ return (lkpi_dma_map_phys(dev, page_to_phys(page) + offset, size,
+ direction, 0));
}
static inline void
@@ -196,7 +211,21 @@ dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
enum dma_data_direction direction)
{
- linux_dma_unmap(dev, dma_address, size);
+ lkpi_dma_unmap(dev, dma_address, size, direction, 0);
+}
+
+static inline dma_addr_t
+dma_map_resource(struct device *dev, phys_addr_t paddr, size_t size,
+ enum dma_data_direction direction, unsigned long attrs)
+{
+ return (lkpi_dma_map_phys(dev, paddr, size, direction, attrs));
+}
+
+static inline void
+dma_unmap_resource(struct device *dev, dma_addr_t dma, size_t size,
+ enum dma_data_direction direction, unsigned long attrs)
+{
+ lkpi_dma_unmap(dev, dma, size, direction, attrs);
}
static inline void
@@ -254,35 +283,44 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma,
linuxkpi_dma_sync(dev, dma, size, op);
}
+/* (20250329) These four seem to be unused code. */
static inline void
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
{
+ pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction);
}
static inline void
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
{
+ pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction);
}
static inline void
dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size, int direction)
+ unsigned long offset, size_t size, enum dma_data_direction direction)
{
+ pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction);
}
static inline void
dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size, int direction)
+ unsigned long offset, size_t size, enum dma_data_direction direction)
{
+ pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction);
}
+#define DMA_MAPPING_ERROR (~(dma_addr_t)0)
+
static inline int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- return (dma_addr == 0);
+ if (dma_addr == 0 || dma_addr == DMA_MAPPING_ERROR)
+ return (-ENOMEM);
+ return (0);
}
static inline unsigned int dma_set_max_seg_size(struct device *dev,
@@ -293,24 +331,17 @@ static inline unsigned int dma_set_max_seg_size(struct device *dev,
static inline dma_addr_t
_dma_map_single_attrs(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction, unsigned long attrs __unused)
+ enum dma_data_direction direction, unsigned long attrs)
{
- dma_addr_t dma;
-
- dma = linux_dma_map_phys(dev, vtophys(ptr), size);
- if (!dma_mapping_error(dev, dma))
- dma_sync_single_for_device(dev, dma, size, direction);
-
- return (dma);
+ return (lkpi_dma_map_phys(dev, vtophys(ptr), size,
+ direction, attrs));
}
static inline void
_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma, size_t size,
- enum dma_data_direction direction, unsigned long attrs __unused)
+ enum dma_data_direction direction, unsigned long attrs)
{
-
- dma_sync_single_for_cpu(dev, dma, size, direction);
- linux_dma_unmap(dev, dma, size);
+ lkpi_dma_unmap(dev, dma, size, direction, attrs);
}
static inline size_t
@@ -338,7 +369,31 @@ dma_max_mapping_size(struct device *dev)
#define dma_unmap_len(p, name) ((p)->name)
#define dma_unmap_len_set(p, name, v) (((p)->name) = (v))
-extern int uma_align_cache;
-#define dma_get_cache_alignment() uma_align_cache
+#define dma_get_cache_alignment() (uma_get_cache_align_mask() + 1)
+
+
+static inline int
+dma_map_sgtable(struct device *dev, struct sg_table *sgt,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ int nents;
+
+ nents = dma_map_sg_attrs(dev, sgt->sgl, sgt->nents, dir, attrs);
+ if (nents < 0)
+ return (nents);
+ sgt->nents = nents;
+ return (0);
+}
+
+static inline void
+dma_unmap_sgtable(struct device *dev, struct sg_table *sgt,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+
+ dma_unmap_sg_attrs(dev, sgt->sgl, sgt->nents, dir, attrs);
+}
+
#endif /* _LINUXKPI_LINUX_DMA_MAPPING_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/dmapool.h b/sys/compat/linuxkpi/common/include/linux/dmapool.h
index e45472dabc60..8501a32e30b7 100644
--- a/sys/compat/linuxkpi/common/include/linux/dmapool.h
+++ b/sys/compat/linuxkpi/common/include/linux/dmapool.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_DMAPOOL_H_
#define _LINUXKPI_LINUX_DMAPOOL_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/dmi.h b/sys/compat/linuxkpi/common/include/linux/dmi.h
index 339f622f89b2..d9760ee0324f 100644
--- a/sys/compat/linuxkpi/common/include/linux/dmi.h
+++ b/sys/compat/linuxkpi/common/include/linux/dmi.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef __LINUXKPI_LINUX_DMI_H__
@@ -34,6 +32,12 @@
#include <sys/types.h>
#include <linux/mod_devicetable.h>
+struct dmi_header {
+ uint8_t type;
+ uint8_t length;
+ uint16_t handle;
+};
+
int linux_dmi_check_system(const struct dmi_system_id *);
bool linux_dmi_match(enum dmi_field, const char *);
const struct dmi_system_id *linux_dmi_first_match(const struct dmi_system_id *);
@@ -44,4 +48,11 @@ const char *linux_dmi_get_system_info(int);
#define dmi_first_match(sysid) linux_dmi_first_match(sysid)
#define dmi_get_system_info(sysid) linux_dmi_get_system_info(sysid)
+static inline int
+dmi_walk(void (*callbackf)(const struct dmi_header *, void *), void *arg)
+{
+
+ return (-ENXIO);
+}
+
#endif /* __LINUXKPI_LINUX_DMI_H__ */
diff --git a/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h b/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h
new file mode 100644
index 000000000000..12915eec3b68
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/dynamic_debug.h
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_DYNAMIC_DEBUG_H
+#define _LINUXKPI_LINUX_DYNAMIC_DEBUG_H
+
+#define DECLARE_DYNDBG_CLASSMAP(a, b, c, ...)
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/efi.h b/sys/compat/linuxkpi/common/include/linux/efi.h
index 03702bba557a..aa33371bd0e8 100644
--- a/sys/compat/linuxkpi/common/include/linux/efi.h
+++ b/sys/compat/linuxkpi/common/include/linux/efi.h
@@ -29,6 +29,7 @@
#define _LINUXKPI_LINUX_EFI_H_
#include <sys/param.h>
+#include <sys/queue.h>
#include <sys/linker.h>
#include <sys/systm.h>
@@ -40,9 +41,6 @@
static inline bool
__efi_enabled(int feature)
{
-#if defined(MODINFOMD_EFI_MAP) && !defined(__amd64__)
- caddr_t kmdp;
-#endif
bool enabled = false;
switch (feature) {
@@ -51,10 +49,7 @@ __efi_enabled(int feature)
/* Use cached value on amd64 */
enabled = efi_boot;
#elif defined(MODINFOMD_EFI_MAP)
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp == NULL)
- kmdp = preload_search_by_type("elf64 kernel");
- enabled = preload_search_info(kmdp,
+ enabled = preload_search_info(preload_kmdp,
MODINFO_METADATA | MODINFOMD_EFI_MAP) != NULL;
#endif
break;
diff --git a/sys/compat/linuxkpi/common/include/linux/err.h b/sys/compat/linuxkpi/common/include/linux/err.h
index 693f7962df65..3d19949e641e 100644
--- a/sys/compat/linuxkpi/common/include/linux/err.h
+++ b/sys/compat/linuxkpi/common/include/linux/err.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ERR_H_
#define _LINUXKPI_LINUX_ERR_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/errno.h b/sys/compat/linuxkpi/common/include/linux/errno.h
index f9c0ceeac5e2..d634675d43d0 100644
--- a/sys/compat/linuxkpi/common/include/linux/errno.h
+++ b/sys/compat/linuxkpi/common/include/linux/errno.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ERRNO_H_
#define _LINUXKPI_LINUX_ERRNO_H_
@@ -34,6 +32,8 @@
#include <sys/errno.h>
#define EBADRQC 56 /* Bad request code */
+#define EBADSLT 57 /* Invalid slot */
+#define ENOKEY 126 /* Required key not available */
#define ECHRNG EDOM
#define ETIME ETIMEDOUT
@@ -44,6 +44,7 @@
#define ERESTARTSYS 512
#define ENOTSUPP EOPNOTSUPP
#define ENONET EHOSTDOWN
+#define EHWPOISON 133 /* Memory page hardware error */
/*
* The error numbers below are arbitrary and do not resemble the numbers
@@ -67,5 +68,6 @@
#define ENOMEDIUM 532
#define ENOSR 533
#define ELNRNG 534
+#define ENAVAIL 535
#endif /* _LINUXKPI_LINUX_ERRNO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/etherdevice.h b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
index 219ed55a880d..1f2d6cf22d7e 100644
--- a/sys/compat/linuxkpi/common/include/linux/etherdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ETHERDEVICE_H_
#define _LINUXKPI_LINUX_ETHERDEVICE_H_
@@ -55,19 +53,27 @@ struct ethtool_modinfo {
static inline bool
is_zero_ether_addr(const u8 * addr)
{
- return ((addr[0] + addr[1] + addr[2] + addr[3] + addr[4] + addr[5]) == 0x00);
+ return ((addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) ==
+ 0x00);
+}
+
+static inline bool
+is_unicast_ether_addr(const u8 * addr)
+{
+ return ((addr[0] & 0x01) == 0x00);
}
static inline bool
is_multicast_ether_addr(const u8 * addr)
{
- return (0x01 & addr[0]);
+ return ((addr[0] & 0x01) == 0x01);
}
static inline bool
is_broadcast_ether_addr(const u8 * addr)
{
- return ((addr[0] + addr[1] + addr[2] + addr[3] + addr[4] + addr[5]) == (6 * 0xff));
+ return ((addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
+ 0xff);
}
static inline bool
diff --git a/sys/compat/linuxkpi/common/include/linux/ethtool.h b/sys/compat/linuxkpi/common/include/linux/ethtool.h
index 9195766f752d..f5567cd7ea40 100644
--- a/sys/compat/linuxkpi/common/include/linux/ethtool.h
+++ b/sys/compat/linuxkpi/common/include/linux/ethtool.h
@@ -23,8 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_ETHTOOL_H_
@@ -32,10 +30,28 @@
#include <linux/types.h>
-#define ETHTOOL_FWVERS_LEN 64
+#define ETH_GSTRING_LEN (2 * IF_NAMESIZE) /* Increase if not large enough */
+
+#define ETHTOOL_FWVERS_LEN 32
struct ethtool_stats {
uint8_t __dummy[0];
};
+enum ethtool_ss {
+ ETH_SS_STATS,
+};
+
+struct ethtool_drvinfo {
+ char driver[32];
+ char version[32];
+ char fw_version[ETHTOOL_FWVERS_LEN];
+ char bus_info[32];
+};
+
+struct net_device;
+struct ethtool_ops {
+ void(*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
+};
+
#endif /* _LINUXKPI_LINUX_ETHTOOL_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/eventpoll.h b/sys/compat/linuxkpi/common/include/linux/eventpoll.h
new file mode 100644
index 000000000000..e77e6d689f86
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/eventpoll.h
@@ -0,0 +1,45 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022, Jake Freeland <jfree@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_EVENTPOLL_H_
+#define _LINUXKPI_LINUX_EVENTPOLL_H_
+
+#include <sys/poll.h>
+
+#define EPOLLIN POLLIN
+#define EPOLLPRI POLLPRI
+#define EPOLLOUT POLLOUT
+#define EPOLLERR POLLERR
+#define EPOLLHUP POLLHUP
+#define EPOLLNVAL POLLNVAL
+#define EPOLLRDNORM POLLRDNORM
+#define EPOLLRDBAND POLLRDBAND
+#define EPOLLWRNORM POLLWRNORM
+#define EPOLLWRBAND POLLWRBAND
+#define EPOLLRDHUP POLLRDHUP
+
+#endif /* _LINUXKPI_LINUX_EVENTPOLL_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/export.h b/sys/compat/linuxkpi/common/include/linux/export.h
index e9ac669a535f..f48bd6af45d3 100644
--- a/sys/compat/linuxkpi/common/include/linux/export.h
+++ b/sys/compat/linuxkpi/common/include/linux/export.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_EXPORT_H
#define _LINUXKPI_LINUX_EXPORT_H
diff --git a/sys/compat/linuxkpi/common/include/linux/file.h b/sys/compat/linuxkpi/common/include/linux/file.h
index 32db72d771fc..f6e988c2d88e 100644
--- a/sys/compat/linuxkpi/common/include/linux/file.h
+++ b/sys/compat/linuxkpi/common/include/linux/file.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_FILE_H_
#define _LINUXKPI_LINUX_FILE_H_
@@ -45,7 +43,7 @@ struct linux_file;
#undef file
-extern struct fileops linuxfileops;
+extern const struct fileops linuxfileops;
static inline struct linux_file *
linux_fget(unsigned int fd)
diff --git a/sys/compat/linuxkpi/common/include/linux/firmware.h b/sys/compat/linuxkpi/common/include/linux/firmware.h
index ada7d0d73edf..a6330ddafb55 100644
--- a/sys/compat/linuxkpi/common/include/linux/firmware.h
+++ b/sys/compat/linuxkpi/common/include/linux/firmware.h
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2022 Bjoern A. Zeeb
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,8 +27,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_FIRMWARE_H
@@ -56,6 +55,8 @@ int linuxkpi_request_firmware(const struct linuxkpi_firmware **,
int linuxkpi_firmware_request_nowarn(const struct linuxkpi_firmware **,
const char *, struct device *);
void linuxkpi_release_firmware(const struct linuxkpi_firmware *);
+int linuxkpi_request_partial_firmware_into_buf(const struct linuxkpi_firmware **,
+ const char *, struct device *, uint8_t *, size_t, size_t);
static __inline int
@@ -100,6 +101,16 @@ release_firmware(const struct linuxkpi_firmware *fw)
linuxkpi_release_firmware(fw);
}
+static inline int
+request_partial_firmware_into_buf(const struct linuxkpi_firmware **fw,
+ const char *fw_name, struct device *dev, void *buf, size_t buflen,
+ size_t offset)
+{
+
+ return (linuxkpi_request_partial_firmware_into_buf(fw, fw_name,
+ dev, buf, buflen, offset));
+}
+
#define firmware linuxkpi_firmware
#endif /* _LINUXKPI_LINUX_FIRMWARE_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
index a21c140d5a9b..f1568ad6282d 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -25,13 +25,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_FS_H_
#define _LINUXKPI_LINUX_FS_H_
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
@@ -45,6 +42,8 @@
#include <linux/dcache.h>
#include <linux/capability.h>
#include <linux/wait_bit.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
struct module;
struct kiocb;
@@ -151,6 +150,11 @@ struct file_operations {
* an illegal seek error
*/
off_t (*llseek)(struct linux_file *, off_t, int);
+/*
+ * Not supported in FreeBSD. That's ok, we never call it and it allows some
+ * drivers like DRM drivers to compile without changes.
+ */
+ void (*show_fdinfo)(struct seq_file *, struct file *);
#if 0
/* We do not support these methods. Don't permit them to compile. */
loff_t (*llseek)(struct file *, loff_t, int);
@@ -250,6 +254,7 @@ nonseekable_open(struct inode *inode, struct file *filp)
static inline int
simple_open(struct inode *inode, struct file *filp)
{
+ filp->private_data = inode->i_private;
return 0;
}
@@ -264,12 +269,18 @@ get_file(struct linux_file *f)
return (f);
}
+struct linux_file * linux_get_file_rcu(struct linux_file **f);
+struct linux_file * get_file_active(struct linux_file **f);
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION < 60700
static inline bool
get_file_rcu(struct linux_file *f)
{
return (refcount_acquire_if_not_zero(
f->_file == NULL ? &f->f_count : &f->_file->f_count));
}
+#else
+#define get_file_rcu(f) linux_get_file_rcu(f)
+#endif
static inline struct inode *
igrab(struct inode *inode)
@@ -298,6 +309,18 @@ no_llseek(struct file *file, loff_t offset, int whence)
}
static inline loff_t
+default_llseek(struct file *file, loff_t offset, int whence)
+{
+ return (no_llseek(file, offset, whence));
+}
+
+static inline loff_t
+generic_file_llseek(struct file *file, loff_t offset, int whence)
+{
+ return (no_llseek(file, offset, whence));
+}
+
+static inline loff_t
noop_llseek(struct linux_file *file, loff_t offset, int whence)
{
@@ -318,4 +341,85 @@ call_mmap(struct linux_file *file, struct vm_area_struct *vma)
return (file->f_op->mmap(file, vma));
}
+static inline void
+i_size_write(struct inode *inode, loff_t i_size)
+{
+}
+
+/*
+ * simple_read_from_buffer: copy data from kernel-space origin
+ * buffer into user-space destination buffer
+ *
+ * @dest: destination buffer
+ * @read_size: number of bytes to be transferred
+ * @ppos: starting transfer position pointer
+ * @orig: origin buffer
+ * @buf_size: size of destination and origin buffers
+ *
+ * Return value:
+ * On success, total bytes copied with *ppos incremented accordingly.
+ * On failure, negative value.
+ */
+static inline ssize_t
+simple_read_from_buffer(void __user *dest, size_t read_size, loff_t *ppos,
+ void *orig, size_t buf_size)
+{
+ void *p, *read_pos = ((char *) orig) + *ppos;
+ size_t buf_remain = buf_size - *ppos;
+
+ if (buf_remain < 0 || buf_remain > buf_size)
+ return -EINVAL;
+
+ if (read_size > buf_remain)
+ read_size = buf_remain;
+
+ /*
+ * XXX At time of commit only debugfs consumers could be
+ * identified. If others will use this function we may
+ * have to revise this: normally we would call copy_to_user()
+ * here but lindebugfs will return the result and the
+ * copyout is done elsewhere for us.
+ */
+ p = memcpy(dest, read_pos, read_size);
+ if (p != NULL)
+ *ppos += read_size;
+
+ return (read_size);
+}
+
+MALLOC_DECLARE(M_LSATTR);
+
+#define __DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt, __wrfunc)\
+static inline int \
+__fops ## _open(struct inode *inode, struct file *filp) \
+{ \
+ return (simple_attr_open(inode, filp, __get, __set, __fmt)); \
+} \
+static const struct file_operations __fops = { \
+ .owner = THIS_MODULE, \
+ .open = __fops ## _open, \
+ .release = simple_attr_release, \
+ .read = simple_attr_read, \
+ .write = __wrfunc, \
+ .llseek = no_llseek \
+}
+
+#define DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt) \
+ __DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt, simple_attr_write)
+#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(fops, get, set, fmt) \
+ __DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt, simple_attr_write_signed)
+
+int simple_attr_open(struct inode *inode, struct file *filp,
+ int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t),
+ const char *fmt);
+
+int simple_attr_release(struct inode *inode, struct file *filp);
+
+ssize_t simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos);
+
+ssize_t simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos);
+
+ssize_t simple_attr_write_signed(struct file *filp, const char *buf,
+ size_t write_size, loff_t *ppos);
+
#endif /* _LINUXKPI_LINUX_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/fwnode.h b/sys/compat/linuxkpi/common/include/linux/fwnode.h
new file mode 100644
index 000000000000..a1fbc1b6d6a3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/fwnode.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_FWNODE_H_
+#define _LINUXKPI_LINUX_FWNODE_H_
+
+struct fwnode_handle {
+ struct fwnode_handle *secondary;
+};
+
+#endif /* _LINUXKPI_LINUX_FWNODE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/gcd.h b/sys/compat/linuxkpi/common/include/linux/gcd.h
index 40523bd6cba6..5ca0540e5102 100644
--- a/sys/compat/linuxkpi/common/include/linux/gcd.h
+++ b/sys/compat/linuxkpi/common/include/linux/gcd.h
@@ -25,8 +25,6 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_GCD_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h
index 6273fa969db8..7a32e7862338 100644
--- a/sys/compat/linuxkpi/common/include/linux/gfp.h
+++ b/sys/compat/linuxkpi/common/include/linux/gfp.h
@@ -25,18 +25,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_GFP_H_
#define _LINUXKPI_LINUX_GFP_H_
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <linux/page.h>
+#include <linux/topology.h>
#include <vm/vm_param.h>
#include <vm/vm_object.h>
@@ -46,7 +44,7 @@
#define __GFP_NOWARN 0
#define __GFP_HIGHMEM 0
#define __GFP_ZERO M_ZERO
-#define __GFP_NORETRY 0
+#define __GFP_NOMEMALLOC 0
#define __GFP_RECLAIM 0
#define __GFP_RECLAIMABLE 0
#define __GFP_RETRY_MAYFAIL 0
@@ -59,7 +57,8 @@
#define __GFP_KSWAPD_RECLAIM 0
#define __GFP_WAIT M_WAITOK
#define __GFP_DMA32 (1U << 24) /* LinuxKPI only */
-#define __GFP_BITS_SHIFT 25
+#define __GFP_NORETRY (1U << 25) /* LinuxKPI only */
+#define __GFP_BITS_SHIFT 26
#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
#define __GFP_NOFAIL M_WAITOK
@@ -71,6 +70,7 @@
#define GFP_HIGHUSER_MOVABLE M_WAITOK
#define GFP_IOFS M_NOWAIT
#define GFP_NOIO M_NOWAIT
+#define GFP_NOFS M_NOWAIT
#define GFP_DMA32 __GFP_DMA32
#define GFP_TEMPORARY M_NOWAIT
#define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO)
@@ -80,20 +80,19 @@
CTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0);
CTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK);
-/*
- * Resolve a page into a virtual address:
- *
- * NOTE: This function only works for pages allocated by the kernel.
- */
-extern void *linux_page_address(struct page *);
-
-#define page_address(page) linux_page_address(page)
+struct page_frag_cache {
+ void *va;
+ int pagecnt_bias;
+};
/*
* Page management for unmapped pages:
*/
-extern vm_page_t linux_alloc_pages(gfp_t flags, unsigned int order);
-extern void linux_free_pages(vm_page_t page, unsigned int order);
+struct page *linux_alloc_pages(gfp_t flags, unsigned int order);
+void linux_free_pages(struct page *page, unsigned int order);
+void *linuxkpi_page_frag_alloc(struct page_frag_cache *, size_t, gfp_t);
+void linuxkpi_page_frag_free(void *);
+void linuxkpi__page_frag_cache_drain(struct page *, size_t);
static inline struct page *
alloc_page(gfp_t flags)
@@ -130,11 +129,19 @@ __free_page(struct page *page)
linux_free_pages(page, 0);
}
+static inline struct page *
+dev_alloc_pages(unsigned int order)
+{
+ return (linux_alloc_pages(GFP_ATOMIC, order));
+}
+
+struct folio *folio_alloc(gfp_t gfp, unsigned int order);
+
/*
* Page management for mapped pages:
*/
-extern vm_offset_t linux_alloc_kmem(gfp_t flags, unsigned int order);
-extern void linux_free_kmem(vm_offset_t, unsigned int order);
+vm_offset_t linux_alloc_kmem(gfp_t flags, unsigned int order);
+void linux_free_kmem(vm_offset_t, unsigned int order);
static inline vm_offset_t
get_zeroed_page(gfp_t flags)
@@ -175,6 +182,27 @@ free_page(uintptr_t addr)
linux_free_kmem(addr, 0);
}
+static inline void *
+page_frag_alloc(struct page_frag_cache *pfc, size_t fragsz, gfp_t gfp)
+{
+
+ return (linuxkpi_page_frag_alloc(pfc, fragsz, gfp));
+}
+
+static inline void
+page_frag_free(void *addr)
+{
+
+ linuxkpi_page_frag_free(addr);
+}
+
+static inline void
+__page_frag_cache_drain(struct page *page, size_t count)
+{
+
+ linuxkpi__page_frag_cache_drain(page, count);
+}
+
static inline bool
gfpflags_allow_blocking(const gfp_t gfp_flags)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/gpf.h b/sys/compat/linuxkpi/common/include/linux/gpf.h
new file mode 100644
index 000000000000..01e883a94728
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/gpf.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_GPF_H_
+#define _LINUXKPI_LINUX_GPF_H_
+
+#include <linux/mmzone.h>
+
+#endif /* _LINUXKPI_LINUX_GPF_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/hardirq.h b/sys/compat/linuxkpi/common/include/linux/hardirq.h
index 07f00f076860..f79451dd0d35 100644
--- a/sys/compat/linuxkpi/common/include/linux/hardirq.h
+++ b/sys/compat/linuxkpi/common/include/linux/hardirq.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_HARDIRQ_H_
#define _LINUXKPI_LINUX_HARDIRQ_H_
@@ -40,4 +38,14 @@
#define synchronize_irq(irq) _intr_drain((irq))
+/*
+ * FIXME: In the i915 driver's `intel_engine_cs.c` file,
+ * `synchronize_hardirq()` was replaced by `synchronize_rcu()` with the
+ * following comment:
+ * "Is it enough to wait that all cpu have context-switched?"
+ *
+ * See commit f6d50b7af554e21c380486d6f41c8537b265c777 in drm-kmod.
+ */
+#define synchronize_hardirq(irq) _intr_drain((irq))
+
#endif /* _LINUXKPI_LINUX_HARDIRQ_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/hashtable.h b/sys/compat/linuxkpi/common/include/linux/hashtable.h
index a7a30143a58e..55755c354959 100644
--- a/sys/compat/linuxkpi/common/include/linux/hashtable.h
+++ b/sys/compat/linuxkpi/common/include/linux/hashtable.h
@@ -23,8 +23,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_HASHTABLE_H
@@ -94,8 +92,6 @@ __hash_node_type_assert(struct hlist_node *node)
#define hash_add_rcu(ht, node, key) do { \
struct lkpi_hash_head *__head = &(ht)[hash_min(key, HASH_BITS(ht))]; \
__hash_node_type_assert(node); \
- KASSERT(((struct lkpi_hash_entry *)(node))->entry.cle_prev == NULL, \
- ("node is already on list or was not zeroed")); \
CK_LIST_INSERT_HEAD(&__head->head, \
(struct lkpi_hash_entry *)(node), entry); \
} while (0)
diff --git a/sys/compat/linuxkpi/common/include/linux/hdmi.h b/sys/compat/linuxkpi/common/include/linux/hdmi.h
new file mode 100644
index 000000000000..e07578167d69
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/hdmi.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_HDMI_H_
+#define __LINUX_HDMI_H_
+
+#include <linux/types.h>
+#include <linux/device.h>
+
+enum hdmi_packet_type {
+ HDMI_PACKET_TYPE_NULL = 0x00,
+ HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01,
+ HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02,
+ HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03,
+ HDMI_PACKET_TYPE_ACP = 0x04,
+ HDMI_PACKET_TYPE_ISRC1 = 0x05,
+ HDMI_PACKET_TYPE_ISRC2 = 0x06,
+ HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07,
+ HDMI_PACKET_TYPE_DST_AUDIO = 0x08,
+ HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09,
+ HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a,
+ /* + enum hdmi_infoframe_type */
+};
+
+enum hdmi_infoframe_type {
+ HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
+ HDMI_INFOFRAME_TYPE_AVI = 0x82,
+ HDMI_INFOFRAME_TYPE_SPD = 0x83,
+ HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
+ HDMI_INFOFRAME_TYPE_DRM = 0x87,
+};
+
+#define HDMI_IEEE_OUI 0x000c03
+#define HDMI_FORUM_IEEE_OUI 0xc45dd8
+#define HDMI_INFOFRAME_HEADER_SIZE 4
+#define HDMI_AVI_INFOFRAME_SIZE 13
+#define HDMI_SPD_INFOFRAME_SIZE 25
+#define HDMI_AUDIO_INFOFRAME_SIZE 10
+#define HDMI_DRM_INFOFRAME_SIZE 26
+#define HDMI_VENDOR_INFOFRAME_SIZE 4
+
+#define HDMI_INFOFRAME_SIZE(type) \
+ (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE)
+
+struct hdmi_any_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+};
+
+enum hdmi_colorspace {
+ HDMI_COLORSPACE_RGB,
+ HDMI_COLORSPACE_YUV422,
+ HDMI_COLORSPACE_YUV444,
+ HDMI_COLORSPACE_YUV420,
+ HDMI_COLORSPACE_RESERVED4,
+ HDMI_COLORSPACE_RESERVED5,
+ HDMI_COLORSPACE_RESERVED6,
+ HDMI_COLORSPACE_IDO_DEFINED,
+};
+
+enum hdmi_scan_mode {
+ HDMI_SCAN_MODE_NONE,
+ HDMI_SCAN_MODE_OVERSCAN,
+ HDMI_SCAN_MODE_UNDERSCAN,
+ HDMI_SCAN_MODE_RESERVED,
+};
+
+enum hdmi_colorimetry {
+ HDMI_COLORIMETRY_NONE,
+ HDMI_COLORIMETRY_ITU_601,
+ HDMI_COLORIMETRY_ITU_709,
+ HDMI_COLORIMETRY_EXTENDED,
+};
+
+enum hdmi_picture_aspect {
+ HDMI_PICTURE_ASPECT_NONE,
+ HDMI_PICTURE_ASPECT_4_3,
+ HDMI_PICTURE_ASPECT_16_9,
+ HDMI_PICTURE_ASPECT_64_27,
+ HDMI_PICTURE_ASPECT_256_135,
+ HDMI_PICTURE_ASPECT_RESERVED,
+};
+
+enum hdmi_active_aspect {
+ HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
+ HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
+ HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
+ HDMI_ACTIVE_ASPECT_PICTURE = 8,
+ HDMI_ACTIVE_ASPECT_4_3 = 9,
+ HDMI_ACTIVE_ASPECT_16_9 = 10,
+ HDMI_ACTIVE_ASPECT_14_9 = 11,
+ HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
+ HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
+ HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
+};
+
+enum hdmi_extended_colorimetry {
+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
+ HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
+ HDMI_EXTENDED_COLORIMETRY_OPYCC_601,
+ HDMI_EXTENDED_COLORIMETRY_OPRGB,
+
+ /* The following EC values are only defined in CEA-861-F. */
+ HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM,
+ HDMI_EXTENDED_COLORIMETRY_BT2020,
+ HDMI_EXTENDED_COLORIMETRY_RESERVED,
+};
+
+enum hdmi_quantization_range {
+ HDMI_QUANTIZATION_RANGE_DEFAULT,
+ HDMI_QUANTIZATION_RANGE_LIMITED,
+ HDMI_QUANTIZATION_RANGE_FULL,
+ HDMI_QUANTIZATION_RANGE_RESERVED,
+};
+
+/* non-uniform picture scaling */
+enum hdmi_nups {
+ HDMI_NUPS_UNKNOWN,
+ HDMI_NUPS_HORIZONTAL,
+ HDMI_NUPS_VERTICAL,
+ HDMI_NUPS_BOTH,
+};
+
+enum hdmi_ycc_quantization_range {
+ HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
+ HDMI_YCC_QUANTIZATION_RANGE_FULL,
+};
+
+enum hdmi_content_type {
+ HDMI_CONTENT_TYPE_GRAPHICS,
+ HDMI_CONTENT_TYPE_PHOTO,
+ HDMI_CONTENT_TYPE_CINEMA,
+ HDMI_CONTENT_TYPE_GAME,
+};
+
+enum hdmi_metadata_type {
+ HDMI_STATIC_METADATA_TYPE1 = 0,
+};
+
+enum hdmi_eotf {
+ HDMI_EOTF_TRADITIONAL_GAMMA_SDR,
+ HDMI_EOTF_TRADITIONAL_GAMMA_HDR,
+ HDMI_EOTF_SMPTE_ST2084,
+ HDMI_EOTF_BT_2100_HLG,
+};
+
+struct hdmi_avi_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ bool itc;
+ unsigned char pixel_repeat;
+ enum hdmi_colorspace colorspace;
+ enum hdmi_scan_mode scan_mode;
+ enum hdmi_colorimetry colorimetry;
+ enum hdmi_picture_aspect picture_aspect;
+ enum hdmi_active_aspect active_aspect;
+ enum hdmi_extended_colorimetry extended_colorimetry;
+ enum hdmi_quantization_range quantization_range;
+ enum hdmi_nups nups;
+ unsigned char video_code;
+ enum hdmi_ycc_quantization_range ycc_quantization_range;
+ enum hdmi_content_type content_type;
+ unsigned short top_bar;
+ unsigned short bottom_bar;
+ unsigned short left_bar;
+ unsigned short right_bar;
+};
+
+/* DRM Infoframe as per CTA 861.G spec */
+struct hdmi_drm_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ enum hdmi_eotf eotf;
+ enum hdmi_metadata_type metadata_type;
+ struct {
+ u16 x, y;
+ } display_primaries[3];
+ struct {
+ u16 x, y;
+ } white_point;
+ u16 max_display_mastering_luminance;
+ u16 min_display_mastering_luminance;
+ u16 max_cll;
+ u16 max_fall;
+};
+
+void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
+ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+ size_t size);
+ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame);
+int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame);
+ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer,
+ size_t size);
+ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame);
+int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
+ const void *buffer, size_t size);
+
+enum hdmi_spd_sdi {
+ HDMI_SPD_SDI_UNKNOWN,
+ HDMI_SPD_SDI_DSTB,
+ HDMI_SPD_SDI_DVDP,
+ HDMI_SPD_SDI_DVHS,
+ HDMI_SPD_SDI_HDDVR,
+ HDMI_SPD_SDI_DVC,
+ HDMI_SPD_SDI_DSC,
+ HDMI_SPD_SDI_VCD,
+ HDMI_SPD_SDI_GAME,
+ HDMI_SPD_SDI_PC,
+ HDMI_SPD_SDI_BD,
+ HDMI_SPD_SDI_SACD,
+ HDMI_SPD_SDI_HDDVD,
+ HDMI_SPD_SDI_PMP,
+};
+
+struct hdmi_spd_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ char vendor[8];
+ char product[16];
+ enum hdmi_spd_sdi sdi;
+};
+
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+ const char *vendor, const char *product);
+ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+ size_t size);
+ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame);
+
+enum hdmi_audio_coding_type {
+ HDMI_AUDIO_CODING_TYPE_STREAM,
+ HDMI_AUDIO_CODING_TYPE_PCM,
+ HDMI_AUDIO_CODING_TYPE_AC3,
+ HDMI_AUDIO_CODING_TYPE_MPEG1,
+ HDMI_AUDIO_CODING_TYPE_MP3,
+ HDMI_AUDIO_CODING_TYPE_MPEG2,
+ HDMI_AUDIO_CODING_TYPE_AAC_LC,
+ HDMI_AUDIO_CODING_TYPE_DTS,
+ HDMI_AUDIO_CODING_TYPE_ATRAC,
+ HDMI_AUDIO_CODING_TYPE_DSD,
+ HDMI_AUDIO_CODING_TYPE_EAC3,
+ HDMI_AUDIO_CODING_TYPE_DTS_HD,
+ HDMI_AUDIO_CODING_TYPE_MLP,
+ HDMI_AUDIO_CODING_TYPE_DST,
+ HDMI_AUDIO_CODING_TYPE_WMA_PRO,
+ HDMI_AUDIO_CODING_TYPE_CXT,
+};
+
+enum hdmi_audio_sample_size {
+ HDMI_AUDIO_SAMPLE_SIZE_STREAM,
+ HDMI_AUDIO_SAMPLE_SIZE_16,
+ HDMI_AUDIO_SAMPLE_SIZE_20,
+ HDMI_AUDIO_SAMPLE_SIZE_24,
+};
+
+enum hdmi_audio_sample_frequency {
+ HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
+};
+
+enum hdmi_audio_coding_type_ext {
+ /* Refer to Audio Coding Type (CT) field in Data Byte 1 */
+ HDMI_AUDIO_CODING_TYPE_EXT_CT,
+
+ /*
+ * The next three CXT values are defined in CEA-861-E only.
+ * They do not exist in older versions, and in CEA-861-F they are
+ * defined as 'Not in use'.
+ */
+ HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC,
+ HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2,
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND,
+
+ /* The following CXT values are only defined in CEA-861-F. */
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC,
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2,
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC,
+ HDMI_AUDIO_CODING_TYPE_EXT_DRA,
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND,
+ HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND = 10,
+};
+
+struct hdmi_audio_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ unsigned char channels;
+ enum hdmi_audio_coding_type coding_type;
+ enum hdmi_audio_sample_size sample_size;
+ enum hdmi_audio_sample_frequency sample_frequency;
+ enum hdmi_audio_coding_type_ext coding_type_ext;
+ unsigned char channel_allocation;
+ unsigned char level_shift_value;
+ bool downmix_inhibit;
+
+};
+
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
+ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+ void *buffer, size_t size);
+ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+#ifdef __linux__
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+ struct dp_sdp *sdp, u8 dp_version);
+#endif
+
+enum hdmi_3d_structure {
+ HDMI_3D_STRUCTURE_INVALID = -1,
+ HDMI_3D_STRUCTURE_FRAME_PACKING = 0,
+ HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE,
+ HDMI_3D_STRUCTURE_LINE_ALTERNATIVE,
+ HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL,
+ HDMI_3D_STRUCTURE_L_DEPTH,
+ HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH,
+ HDMI_3D_STRUCTURE_TOP_AND_BOTTOM,
+ HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8,
+};
+
+
+struct hdmi_vendor_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ unsigned int oui;
+ u8 vic;
+ enum hdmi_3d_structure s3d_struct;
+ unsigned int s3d_ext_data;
+};
+
+/* HDR Metadata as per 861.G spec */
+struct hdr_static_metadata {
+ __u8 eotf;
+ __u8 metadata_type;
+ __u16 max_cll;
+ __u16 max_fall;
+ __u16 min_cll;
+};
+
+/**
+ * struct hdr_sink_metadata - HDR sink metadata
+ *
+ * Metadata Information read from Sink's EDID
+ */
+struct hdr_sink_metadata {
+ /**
+ * @metadata_type: Static_Metadata_Descriptor_ID.
+ */
+ __u32 metadata_type;
+ /**
+ * @hdmi_type1: HDR Metadata Infoframe.
+ */
+ union {
+ struct hdr_static_metadata hdmi_type1;
+ };
+};
+
+int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame);
+ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+ void *buffer, size_t size);
+ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame);
+
+union hdmi_vendor_any_infoframe {
+ struct {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ unsigned int oui;
+ } any;
+ struct hdmi_vendor_infoframe hdmi;
+};
+
+/**
+ * union hdmi_infoframe - overall union of all abstract infoframe representations
+ * @any: generic infoframe
+ * @avi: avi infoframe
+ * @spd: spd infoframe
+ * @vendor: union of all vendor infoframes
+ * @audio: audio infoframe
+ * @drm: Dynamic Range and Mastering infoframe
+ *
+ * This is used by the generic pack function. This works since all infoframes
+ * have the same header which also indicates which type of infoframe should be
+ * packed.
+ */
+union hdmi_infoframe {
+ struct hdmi_any_infoframe any;
+ struct hdmi_avi_infoframe avi;
+ struct hdmi_spd_infoframe spd;
+ union hdmi_vendor_any_infoframe vendor;
+ struct hdmi_audio_infoframe audio;
+ struct hdmi_drm_infoframe drm;
+};
+
+ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
+ size_t size);
+ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame,
+ void *buffer, size_t size);
+int hdmi_infoframe_check(union hdmi_infoframe *frame);
+int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
+ const void *buffer, size_t size);
+void hdmi_infoframe_log(const char *level, struct device *dev,
+ const union hdmi_infoframe *frame);
+
+#endif /* _DRM_HDMI_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/highmem.h b/sys/compat/linuxkpi/common/include/linux/highmem.h
index 53efbec06385..58a9cdcdf60f 100644
--- a/sys/compat/linuxkpi/common/include/linux/highmem.h
+++ b/sys/compat/linuxkpi/common/include/linux/highmem.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2016 Matthew Macy (mmacy@mattmacy.io)
@@ -43,23 +43,25 @@
#include <vm/vm_page.h>
#include <vm/pmap.h>
+#include <linux/mm.h>
#include <linux/page.h>
#define PageHighMem(p) (0)
-static inline vm_page_t
+static inline struct page *
kmap_to_page(void *addr)
{
+
return (virt_to_page(addr));
}
static inline void *
-kmap(vm_page_t page)
+kmap(struct page *page)
{
struct sf_buf *sf;
if (PMAP_HAS_DMAP) {
- return ((void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(page)));
+ return ((void *)PHYS_TO_DMAP(page_to_phys(page)));
} else {
sched_pin();
sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE);
@@ -72,27 +74,39 @@ kmap(vm_page_t page)
}
static inline void *
-kmap_atomic_prot(vm_page_t page, pgprot_t prot)
+kmap_atomic_prot(struct page *page, pgprot_t prot)
{
vm_memattr_t attr = pgprot2cachemode(prot);
if (attr != VM_MEMATTR_DEFAULT) {
- vm_page_lock(page);
page->flags |= PG_FICTITIOUS;
- vm_page_unlock(page);
pmap_page_set_memattr(page, attr);
}
return (kmap(page));
}
static inline void *
-kmap_atomic(vm_page_t page)
+kmap_atomic(struct page *page)
{
+
return (kmap_atomic_prot(page, VM_PROT_ALL));
}
+static inline void *
+kmap_local_page(struct page *page)
+{
+ return (kmap(page));
+}
+
+static inline void *
+kmap_local_page_prot(struct page *page, pgprot_t prot)
+{
+
+ return (kmap_atomic_prot(page, prot));
+}
+
static inline void
-kunmap(vm_page_t page)
+kunmap(struct page *page)
{
struct sf_buf *sf;
@@ -111,8 +125,46 @@ kunmap(vm_page_t page)
static inline void
kunmap_atomic(void *vaddr)
{
+
if (!PMAP_HAS_DMAP)
kunmap(virt_to_page(vaddr));
}
+static inline void
+kunmap_local(void *addr)
+{
+
+ kunmap_atomic(addr);
+}
+
+static inline void
+memcpy_from_page(char *to, struct page *page, size_t offset, size_t len)
+{
+ char *from;
+
+ KASSERT(offset + len <= PAGE_SIZE,
+ ("%s: memcpy from page %p to address %p: "
+ "offset+len (%zu+%zu) would go beyond page end",
+ __func__, page, to, offset, len));
+
+ from = kmap_local_page(page);
+ memcpy(to, from + offset, len);
+ kunmap_local(from);
+}
+
+static inline void
+memcpy_to_page(struct page *page, size_t offset, const char *from, size_t len)
+{
+ char *to;
+
+ KASSERT(offset + len <= PAGE_SIZE,
+ ("%s: memcpy from address %p to page %p: "
+ "offset+len (%zu+%zu) would go beyond page end",
+ __func__, from, page, offset, len));
+
+ to = kmap_local_page(page);
+ memcpy(to + offset, from, len);
+ kunmap_local(to);
+}
+
#endif /* _LINUXKPI_LINUX_HIGHMEM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/hrtimer.h b/sys/compat/linuxkpi/common/include/linux/hrtimer.h
index 23e707d906b4..88f9487d0b85 100644
--- a/sys/compat/linuxkpi/common/include/linux/hrtimer.h
+++ b/sys/compat/linuxkpi/common/include/linux/hrtimer.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_HRTIMER_H_
@@ -32,6 +30,7 @@
#include <sys/_mutex.h>
#include <linux/ktime.h>
+#include <linux/rbtree.h>
#include <linux/timer.h>
enum hrtimer_mode {
@@ -53,6 +52,7 @@ struct hrtimer {
};
#define hrtimer_active(hrtimer) linux_hrtimer_active(hrtimer)
+#define hrtimer_try_to_cancel(hrtimer) linux_hrtimer_try_to_cancel(hrtimer)
#define hrtimer_cancel(hrtimer) linux_hrtimer_cancel(hrtimer)
#define hrtimer_init(hrtimer, clock, mode) do { \
@@ -79,6 +79,7 @@ struct hrtimer {
} while (0)
bool linux_hrtimer_active(struct hrtimer *);
+int linux_hrtimer_try_to_cancel(struct hrtimer *);
int linux_hrtimer_cancel(struct hrtimer *);
void linux_hrtimer_init(struct hrtimer *);
void linux_hrtimer_set_expires(struct hrtimer *, ktime_t);
diff --git a/sys/compat/linuxkpi/common/include/linux/i2c.h b/sys/compat/linuxkpi/common/include/linux/i2c.h
index 0bb8b470edd7..f24d282586f6 100644
--- a/sys/compat/linuxkpi/common/include/linux/i2c.h
+++ b/sys/compat/linuxkpi/common/include/linux/i2c.h
@@ -46,6 +46,7 @@
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0
#define I2C_FUNC_10BIT_ADDR 0
+#define I2C_CLASS_HWMON 0x1
#define I2C_CLASS_DDC 0x8
#define I2C_CLASS_SPD 0x80
@@ -58,6 +59,7 @@ struct i2c_adapter {
const struct i2c_lock_operations *lock_ops;
const struct i2c_algorithm *algo;
+ const struct i2c_adapter_quirks *quirks;
void *algo_data;
int retries;
@@ -82,6 +84,29 @@ struct i2c_lock_operations {
void (*unlock_bus)(struct i2c_adapter *, unsigned int);
};
+struct i2c_adapter_quirks {
+ uint64_t flags;
+ int max_num_msgs;
+ uint16_t max_write_len;
+ uint16_t max_read_len;
+ uint16_t max_comb_1st_msg_len;
+ uint16_t max_comb_2nd_msg_len;
+};
+
+#define I2C_AQ_COMB BIT(0)
+#define I2C_AQ_COMB_WRITE_FIRST BIT(1)
+#define I2C_AQ_COMB_READ_SECOND BIT(2)
+#define I2C_AQ_COMB_SAME_ADDR BIT(3)
+#define I2C_AQ_COMB_WRITE_THEN_READ \
+ (I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | \
+ I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR)
+#define I2C_AQ_NO_CLK_STRETCH BIT(4)
+#define I2C_AQ_NO_ZERO_LEN_READ BIT(5)
+#define I2C_AQ_NO_ZERO_LEN_WRITE BIT(6)
+#define I2C_AQ_NO_ZERO_LEN \
+ (I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_NO_ZERO_LEN_WRITE)
+#define I2C_AQ_NO_REP_START BIT(7)
+
int lkpi_i2c_add_adapter(struct i2c_adapter *adapter);
int lkpi_i2c_del_adapter(struct i2c_adapter *adapter);
@@ -100,7 +125,7 @@ do_i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs)
retries = adapter->retries == 0 ? 1 : adapter->retries;
for (; retries != 0; retries--) {
- if (adapter->algo->master_xfer != NULL)
+ if (adapter->algo != NULL && adapter->algo->master_xfer != NULL)
ret = adapter->algo->master_xfer(adapter, msgs, nmsgs);
else
ret = lkpi_i2cbb_transfer(adapter, msgs, nmsgs);
@@ -116,7 +141,7 @@ i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs)
{
int ret;
- if (!adapter->algo)
+ if (adapter->algo == NULL && adapter->algo_data == NULL)
return (-EOPNOTSUPP);
if (adapter->lock_ops)
diff --git a/sys/compat/linuxkpi/common/include/linux/idr.h b/sys/compat/linuxkpi/common/include/linux/idr.h
index 5310fcf9950c..06850c94a5e9 100644
--- a/sys/compat/linuxkpi/common/include/linux/idr.h
+++ b/sys/compat/linuxkpi/common/include/linux/idr.h
@@ -25,16 +25,17 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IDR_H_
#define _LINUXKPI_LINUX_IDR_H_
#include <sys/param.h>
#include <sys/lock.h>
+#include <sys/limits.h>
#include <sys/mutex.h>
+#include <linux/radix-tree.h>
+#include <linux/gpf.h>
#include <linux/types.h>
#define IDR_BITS 5
@@ -134,12 +135,25 @@ ida_get_new(struct ida *ida, int *p_id)
}
static inline int
+ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp)
+{
+ return (ida_simple_get(ida, min, UINT_MAX, gfp));
+}
+
+static inline int
ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)
{
return (ida_simple_get(ida, 0, max, gfp));
}
+static inline int
+ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, gfp_t gfp)
+{
+
+ return (ida_simple_get(ida, min, max, gfp));
+}
+
static inline int ida_alloc(struct ida *ida, gfp_t gfp)
{
return (ida_alloc_max(ida, ~0u, gfp));
diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index dee8c385464c..17041bb03ce8 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IEEE80211_H
@@ -35,9 +33,19 @@
#include <net80211/ieee80211.h>
#include <asm/unaligned.h>
+#include <linux/kernel.h>
#include <linux/bitops.h>
+#include <linux/bitfield.h>
#include <linux/if_ether.h>
+/* linux_80211.c */
+extern int linuxkpi_debug_80211;
+#ifndef D80211_TODO
+#define D80211_TODO 0x1
+#endif
+#define TODO(fmt, ...) if (linuxkpi_debug_80211 & D80211_TODO) \
+ printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
+
/* 9.4.2.55 Management MIC element (CMAC-256, GMAC-128, and GMAC-256). */
struct ieee80211_mmie_16 {
@@ -57,20 +65,22 @@ struct ieee80211_mmie_16 {
#define IEEE80211_GCMP_MIC_LEN 16
#define IEEE80211_GCMP_PN_LEN 6
#define IEEE80211_GMAC_PN_LEN 6
+#define IEEE80211_CMAC_PN_LEN 6
#define IEEE80211_MAX_PN_LEN 16
#define IEEE80211_INVAL_HW_QUEUE ((uint8_t)-1)
-#define IEEE80211_MAX_AMPDU_BUF_HT 0x40
-#define IEEE80211_MAX_AMPDU_BUF 256 /* for HE? */
+#define IEEE80211_MAX_AMPDU_BUF_HT IEEE80211_AGGR_BAWMAX
#define IEEE80211_MAX_AMPDU_BUF_HE 256
+#define IEEE80211_MAX_AMPDU_BUF_EHT 1024
#define IEEE80211_MAX_FRAME_LEN 2352
#define IEEE80211_MAX_DATA_LEN (2300 + IEEE80211_CRC_LEN)
#define IEEE80211_MAX_MPDU_LEN_HT_BA 4095 /* 9.3.2.1 Format of Data frames; non-VHT non-DMG STA */
#define IEEE80211_MAX_MPDU_LEN_HT_3839 3839
+#define IEEE80211_MAX_MPDU_LEN_HT_7935 7935
#define IEEE80211_MAX_MPDU_LEN_VHT_3895 3895
#define IEEE80211_MAX_MPDU_LEN_VHT_7991 7991
#define IEEE80211_MAX_MPDU_LEN_VHT_11454 11454
@@ -83,12 +93,18 @@ struct ieee80211_mmie_16 {
#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7f
#define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7)
+/* 802.11-2016, 9.2.4.5.1, Table 9-6 QoS Control Field */
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
#define IEEE80211_QOS_CTL_TID_MASK IEEE80211_QOS_TID
#define IEEE80211_QOS_CTL_EOSP 0x0010
-#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080 /* 9.2.4.5.1, Table 9-6 QoS Control Field */
+#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080
+#define IEEE80211_QOS_CTL_ACK_POLICY_MASK 0x0060
+#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020
+#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
-#define IEEE80211_RATE_SHORT_PREAMBLE BIT(0)
+enum ieee80211_rate_flags {
+ IEEE80211_RATE_SHORT_PREAMBLE = BIT(0),
+};
enum ieee80211_rate_control_changed_flags {
IEEE80211_RC_BW_CHANGED = BIT(0),
@@ -103,9 +119,23 @@ enum ieee80211_rate_control_changed_flags {
#define IEEE80211_TKIP_ICV_LEN 4
#define IEEE80211_TKIP_IV_LEN 8 /* WEP + KID + EXT */
-#define IEEE80211_VHT_EXT_NSS_BW_CAPABLE (1 << 13) /* assigned to tx_highest */
+/* 802.11-2016, 9.4.2.158.3 Supported VHT-MCS and NSS Set field. */
+#define IEEE80211_VHT_EXT_NSS_BW_CAPABLE (1 << 13) /* part of tx_highest */
-#define IEEE80211_VHT_MAX_AMPDU_1024K 7 /* 9.4.2.56.3 A-MPDU Parameters field, Table 9-163 */
+/*
+ * 802.11-2020, 9.4.2.157.2 VHT Capabilities Information field,
+ * Table 9-271-Subfields of the VHT Capabilities Information field (continued).
+ */
+enum ieee80211_vht_max_ampdu_len_exp {
+ IEEE80211_VHT_MAX_AMPDU_8K = 0,
+ IEEE80211_VHT_MAX_AMPDU_16K = 1,
+ IEEE80211_VHT_MAX_AMPDU_32K = 2,
+ IEEE80211_VHT_MAX_AMPDU_64K = 3,
+ IEEE80211_VHT_MAX_AMPDU_128K = 4,
+ IEEE80211_VHT_MAX_AMPDU_256K = 5,
+ IEEE80211_VHT_MAX_AMPDU_512K = 6,
+ IEEE80211_VHT_MAX_AMPDU_1024K = 7,
+};
#define IEEE80211_WEP_IV_LEN 3 /* net80211: IEEE80211_WEP_IVLEN */
#define IEEE80211_WEP_ICV_LEN 4
@@ -117,26 +147,36 @@ enum ieee80211_rate_control_changed_flags {
enum wlan_ht_cap_sm_ps {
WLAN_HT_CAP_SM_PS_STATIC = 0,
- WLAN_HT_CAP_SM_PS_DYNAMIC,
- WLAN_HT_CAP_SM_PS_INVALID,
- WLAN_HT_CAP_SM_PS_DISABLED,
+ WLAN_HT_CAP_SM_PS_DYNAMIC = 1,
+ WLAN_HT_CAP_SM_PS_INVALID = 2,
+ WLAN_HT_CAP_SM_PS_DISABLED = 3
};
-#define WLAN_MAX_KEY_LEN 32 /* TODO FIXME brcmfmac */
-#define WLAN_PMKID_LEN 16 /* TODO FIXME brcmfmac */
-
-#define WLAN_KEY_LEN_WEP40 5
-#define WLAN_KEY_LEN_WEP104 13
-#define WLAN_KEY_LEN_CCMP 16
-#define WLAN_KEY_LEN_GCMP_256 32
+#define WLAN_MAX_KEY_LEN 32
+#define WLAN_PMKID_LEN 16
+#define WLAN_PMK_LEN_SUITE_B_192 48
+
+enum ieee80211_key_len {
+ WLAN_KEY_LEN_WEP40 = 5,
+ WLAN_KEY_LEN_WEP104 = 13,
+ WLAN_KEY_LEN_TKIP = 32,
+ WLAN_KEY_LEN_CCMP = 16,
+ WLAN_KEY_LEN_CCMP_256 = 32,
+ WLAN_KEY_LEN_GCMP = 16,
+ WLAN_KEY_LEN_AES_CMAC = 16,
+ WLAN_KEY_LEN_GCMP_256 = 32,
+ WLAN_KEY_LEN_BIP_CMAC_256 = 32,
+ WLAN_KEY_LEN_BIP_GMAC_128 = 16,
+ WLAN_KEY_LEN_BIP_GMAC_256 = 32,
+};
/* 802.11-2020, 9.4.2.55.3, Table 9-185 Subfields of the A-MPDU Parameters field */
enum ieee80211_min_mpdu_start_spacing {
IEEE80211_HT_MPDU_DENSITY_NONE = 0,
#if 0
IEEE80211_HT_MPDU_DENSITY_XXX = 1, /* 1/4 us */
- IEEE80211_HT_MPDU_DENSITY_YYY = 2, /* 1/2 us */
#endif
+ IEEE80211_HT_MPDU_DENSITY_0_5 = 2, /* 1/2 us */
IEEE80211_HT_MPDU_DENSITY_1 = 3, /* 1 us */
IEEE80211_HT_MPDU_DENSITY_2 = 4, /* 2 us */
IEEE80211_HT_MPDU_DENSITY_4 = 5, /* 4us */
@@ -151,6 +191,14 @@ enum ieee80211_min_mpdu_start_spacing {
#define IEEE80211_FCTL_STYPE IEEE80211_FC0_SUBTYPE_MASK
#define IEEE80211_FCTL_ORDER (IEEE80211_FC1_ORDER << 8)
#define IEEE80211_FCTL_PROTECTED (IEEE80211_FC1_PROTECTED << 8)
+#define IEEE80211_FCTL_FROMDS (IEEE80211_FC1_DIR_FROMDS << 8)
+#define IEEE80211_FCTL_TODS (IEEE80211_FC1_DIR_TODS << 8)
+#define IEEE80211_FCTL_MOREFRAGS (IEEE80211_FC1_MORE_FRAG << 8)
+#define IEEE80211_FCTL_PM (IEEE80211_FC1_PWR_MGT << 8)
+
+#define IEEE80211_FTYPE_MGMT IEEE80211_FC0_TYPE_MGT
+#define IEEE80211_FTYPE_CTL IEEE80211_FC0_TYPE_CTL
+#define IEEE80211_FTYPE_DATA IEEE80211_FC0_TYPE_DATA
#define IEEE80211_STYPE_ASSOC_REQ IEEE80211_FC0_SUBTYPE_ASSOC_REQ
#define IEEE80211_STYPE_REASSOC_REQ IEEE80211_FC0_SUBTYPE_REASSOC_REQ
@@ -158,8 +206,13 @@ enum ieee80211_min_mpdu_start_spacing {
#define IEEE80211_STYPE_DISASSOC IEEE80211_FC0_SUBTYPE_DISASSOC
#define IEEE80211_STYPE_AUTH IEEE80211_FC0_SUBTYPE_AUTH
#define IEEE80211_STYPE_DEAUTH IEEE80211_FC0_SUBTYPE_DEAUTH
+#define IEEE80211_STYPE_CTS IEEE80211_FC0_SUBTYPE_CTS
+#define IEEE80211_STYPE_RTS IEEE80211_FC0_SUBTYPE_RTS
#define IEEE80211_STYPE_ACTION IEEE80211_FC0_SUBTYPE_ACTION
-#define IEEE80211_STYPE_QOS_DATA IEEE80211_FC0_SUBTYPE_QOS
+#define IEEE80211_STYPE_DATA IEEE80211_FC0_SUBTYPE_DATA
+#define IEEE80211_STYPE_QOS_DATA IEEE80211_FC0_SUBTYPE_QOS_DATA
+#define IEEE80211_STYPE_QOS_NULLFUNC IEEE80211_FC0_SUBTYPE_QOS_NULL
+#define IEEE80211_STYPE_QOS_CFACK 0xd0 /* XXX-BZ reserved? */
#define IEEE80211_NUM_ACS 4 /* net8021::WME_NUM_AC */
@@ -176,11 +229,12 @@ enum ieee80211_min_mpdu_start_spacing {
#define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK 8 /* TODO FIXME ax? */
#define IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE 16 /* TODO FIXME ax? */
-#define IEEE80211_HT_OP_MODE_PROTECTION 0x03 /* MASK */
-#define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0x00
-#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 0x01
-#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 0x02
-#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 0x03
+/* 802.11-2012, Table 8-130-HT Operation element fields and subfields, HT Protection */
+#define IEEE80211_HT_OP_MODE_PROTECTION IEEE80211_HTINFO_OPMODE /* Mask. */
+#define IEEE80211_HT_OP_MODE_PROTECTION_NONE IEEE80211_HTINFO_OPMODE_PURE /* No protection */
+#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER IEEE80211_HTINFO_OPMODE_PROTOPT /* Nonmember protection */
+#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ IEEE80211_HTINFO_OPMODE_HT20PR /* 20 MHz protection */
+#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED IEEE80211_HTINFO_OPMODE_MIXED /* Non-HT mixed */
/* 9.6.13.1, Table 9-342 TDLS Action field values. */
@@ -199,13 +253,19 @@ enum ieee80211_tdls_action_code {
/* 11-255 reserved */
};
-/* 9.4.2.27, Table 9-135. Extended Capabilities field. */
+/* 802.11-2020 9.4.2.26, Table 9-153. Extended Capabilities field. */
/* This is split up into octets CAPA1 = octet 1, ... */
#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2 % 8)
#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(22 % 8)
+#define WLAN_EXT_CAPA3_TIMING_MEASUREMENT_SUPPORT BIT(23 % 8)
#define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(62 % 8)
-#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5) /* XXX */
-#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7) /* XXX */
+#define WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB BIT(63 % 8)
+#define WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB BIT(64 % 8)
+#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(77 % 8)
+#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(78 % 8)
+#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(79 % 8)
+
+#define WLAN_EXT_CAPA11_EMA_SUPPORT 0x00 /* XXX TODO FIXME */
/* iwlwifi/mvm/utils:: for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_VI; ac++) */
@@ -225,19 +285,55 @@ enum ieee80211_ac_numbers {
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE 8
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL 0xf
-struct vht_mcs {
- uint16_t rx_mcs_map;
- uint16_t rx_highest;
- uint16_t tx_mcs_map;
- uint16_t tx_highest;
-};
-struct ieee80211_vht_cap {
- struct vht_mcs supp_mcs;;
- __le32 vht_cap_info;
-};
+/* Define the LinuxKPI names directly to the net80211 ones. */
+#define IEEE80211_HT_CAP_LDPC_CODING IEEE80211_HTCAP_LDPC
+#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 IEEE80211_HTCAP_CHWIDTH40
+#define IEEE80211_HT_CAP_SM_PS IEEE80211_HTCAP_SMPS
+#define IEEE80211_HT_CAP_SM_PS_SHIFT 2
+#define IEEE80211_HT_CAP_GRN_FLD IEEE80211_HTCAP_GREENFIELD
+#define IEEE80211_HT_CAP_SGI_20 IEEE80211_HTCAP_SHORTGI20
+#define IEEE80211_HT_CAP_SGI_40 IEEE80211_HTCAP_SHORTGI40
+#define IEEE80211_HT_CAP_TX_STBC IEEE80211_HTCAP_TXSTBC
+#define IEEE80211_HT_CAP_RX_STBC IEEE80211_HTCAP_RXSTBC
+#define IEEE80211_HT_CAP_RX_STBC_SHIFT IEEE80211_HTCAP_RXSTBC_S
+#define IEEE80211_HT_CAP_MAX_AMSDU IEEE80211_HTCAP_MAXAMSDU
+#define IEEE80211_HT_CAP_DSSSCCK40 IEEE80211_HTCAP_DSSSCCK40
+#define IEEE80211_HT_CAP_LSIG_TXOP_PROT IEEE80211_HTCAP_LSIGTXOPPROT
+
+#define IEEE80211_HT_MCS_TX_DEFINED 0x0001
+#define IEEE80211_HT_MCS_TX_RX_DIFF 0x0002
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK 0x0c
+#define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff
+#define IEEE80211_HT_MCS_MASK_LEN 10
+
+#define IEEE80211_MLD_MAX_NUM_LINKS 15
+#define IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS 0xf
+#define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP 0x0060
+#define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME 1
+
+struct ieee80211_mcs_info {
+ uint8_t rx_mask[IEEE80211_HT_MCS_MASK_LEN];
+ uint16_t rx_highest;
+ uint8_t tx_params;
+ uint8_t __reserved[3];
+} __packed;
+
+/* 802.11-2020, 9.4.2.55.1 HT Capabilities element structure */
+struct ieee80211_ht_cap {
+ uint16_t cap_info;
+ uint8_t ampdu_params_info;
+ struct ieee80211_mcs_info mcs;
+ uint16_t extended_ht_cap_info;
+ uint32_t tx_BF_cap_info;
+ uint8_t antenna_selection_info;
+} __packed;
#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
+#define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16
+#define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20
+#define IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR 13
enum ieee80211_ht_max_ampdu_len {
IEEE80211_HT_MAX_AMPDU_64K
@@ -248,13 +344,14 @@ enum ieee80211_ampdu_mlme_action {
IEEE80211_AMPDU_RX_STOP,
IEEE80211_AMPDU_TX_OPERATIONAL,
IEEE80211_AMPDU_TX_START,
- IEEE80211_AMPDU_TX_START_DELAY_ADDBA,
- IEEE80211_AMPDU_TX_START_IMMEDIATE,
IEEE80211_AMPDU_TX_STOP_CONT,
IEEE80211_AMPDU_TX_STOP_FLUSH,
IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
};
+#define IEEE80211_AMPDU_TX_START_IMMEDIATE 1
+#define IEEE80211_AMPDU_TX_START_DELAY_ADDBA 2
+
enum ieee80211_chanctx_switch_mode {
CHANCTX_SWMODE_REASSIGN_VIF,
CHANCTX_SWMODE_SWAP_CONTEXTS,
@@ -266,6 +363,8 @@ enum ieee80211_chanctx_change_flags {
IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(2),
IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(3),
IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(4),
+ IEEE80211_CHANCTX_CHANGE_PUNCTURING = BIT(5),
+ IEEE80211_CHANCTX_CHANGE_MIN_DEF = BIT(6),
};
enum ieee80211_frame_release_type {
@@ -302,15 +401,15 @@ enum ieee80211_smps_mode {
/* net80211::IEEE80211_S_* different but represents the state machine. */
/* Note: order here is important! */
enum ieee80211_sta_state {
- IEEE80211_STA_NOTEXIST,
- IEEE80211_STA_NONE,
- IEEE80211_STA_AUTH,
- IEEE80211_STA_ASSOC,
- IEEE80211_STA_AUTHORIZED, /* 802.1x */
+ IEEE80211_STA_NOTEXIST = 0,
+ IEEE80211_STA_NONE = 1,
+ IEEE80211_STA_AUTH = 2,
+ IEEE80211_STA_ASSOC = 3,
+ IEEE80211_STA_AUTHORIZED = 4, /* 802.1x */
};
-enum ieee80211_sta_rx_bw {
- IEEE80211_STA_RX_BW_20,
+enum ieee80211_sta_rx_bandwidth {
+ IEEE80211_STA_RX_BW_20 = 0,
IEEE80211_STA_RX_BW_40,
IEEE80211_STA_RX_BW_80,
IEEE80211_STA_RX_BW_160,
@@ -335,11 +434,24 @@ enum ieee80211_tx_info_flags {
IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(13),
IEEE80211_TX_CTL_NO_CCK_RATE = BIT(14),
IEEE80211_TX_CTL_INJECTED = BIT(15),
+ IEEE80211_TX_CTL_HW_80211_ENCAP = BIT(16),
+ IEEE80211_TX_CTL_USE_MINRATE = BIT(17),
+ IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(18),
+ IEEE80211_TX_CTL_LDPC = BIT(19),
+ IEEE80211_TX_CTL_STBC = BIT(20),
+} __packed;
+
+enum ieee80211_tx_status_flags {
+ IEEE80211_TX_STATUS_ACK_SIGNAL_VALID = BIT(0),
};
enum ieee80211_tx_control_flags {
/* XXX TODO .. right shift numbers */
IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0),
+ IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1),
+ IEEE80211_TX_CTRL_RATE_INJECT = BIT(2),
+ IEEE80211_TX_CTRL_DONT_USE_RATE_MASK = BIT(3),
+ IEEE80211_TX_CTRL_MLO_LINK = 0xF0000000, /* This is IEEE80211_LINK_UNSPECIFIED on the high bits. */
};
enum ieee80211_tx_rate_flags {
@@ -354,6 +466,8 @@ enum ieee80211_tx_rate_flags {
IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(7),
};
+#define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128
+
#define IEEE80211_HT_CTL_LEN 4
struct ieee80211_hdr { /* net80211::ieee80211_frame_addr4 */
@@ -375,10 +489,35 @@ struct ieee80211_hdr_3addr { /* net80211::ieee80211_frame */
__le16 seq_ctrl;
};
+struct ieee80211_qos_hdr { /* net80211:ieee80211_qosframe */
+ __le16 frame_control;
+ __le16 duration_id;
+ uint8_t addr1[ETH_ALEN];
+ uint8_t addr2[ETH_ALEN];
+ uint8_t addr3[ETH_ALEN];
+ __le16 seq_ctrl;
+ __le16 qos_ctrl;
+};
+
struct ieee80211_vendor_ie {
};
-/* 9.3.3.2 Format of Management frames */
+/* 802.11-2020, Table 9-359-Block Ack Action field values */
+enum ieee80211_back {
+ WLAN_ACTION_ADDBA_REQ = 0,
+};
+
+enum ieee80211_sa_query {
+ WLAN_ACTION_SA_QUERY_RESPONSE = 1,
+};
+
+/* 802.11-2020, Table 9-51-Category values */
+enum ieee80211_category {
+ WLAN_CATEGORY_BACK = 3,
+ WLAN_CATEGORY_SA_QUERY = 8, /* net80211::IEEE80211_ACTION_CAT_SA_QUERY */
+};
+
+/* 80211-2020 9.3.3.2 Format of Management frames */
struct ieee80211_mgmt {
__le16 frame_control;
__le16 duration_id;
@@ -393,24 +532,40 @@ struct ieee80211_mgmt {
uint16_t beacon_int;
uint16_t capab_info;
uint8_t variable[0];
- } beacon;
+ } __packed beacon;
+ /* 9.3.3.5 Association Request frame format */
+ struct {
+ uint16_t capab_info;
+ uint16_t listen_interval;
+ uint8_t variable[0];
+ } __packed assoc_req;
/* 9.3.3.10 Probe Request frame format */
struct {
uint8_t variable[0];
- } probe_req;
+ } __packed probe_req;
/* 9.3.3.11 Probe Response frame format */
struct {
uint64_t timestamp;
uint16_t beacon_int;
uint16_t capab_info;
uint8_t variable[0];
- } probe_resp;
+ } __packed probe_resp;
/* 9.3.3.14 Action frame format */
struct {
/* 9.4.1.11 Action field */
uint8_t category;
/* 9.6.8 Public Action details */
union {
+ /* 9.6.2.5 TPC Report frame format */
+ struct {
+ uint8_t spec_mgmt;
+ uint8_t dialog_token;
+ /* uint32_t tpc_rep_elem:: */
+ uint8_t tpc_elem_id;
+ uint8_t tpc_elem_length;
+ uint8_t tpc_elem_tx_power;
+ uint8_t tpc_elem_link_margin;
+ } __packed tpc_report;
/* 9.6.8.33 Fine Timing Measurement frame format */
struct {
uint8_t dialog_token;
@@ -420,11 +575,39 @@ struct ieee80211_mgmt {
uint16_t tod_error;
uint16_t toa_error;
uint8_t variable[0];
- } ftm;
+ } __packed ftm;
+ /* 802.11-2016, 9.6.5.2 ADDBA Request frame format */
+ struct {
+ uint8_t action_code;
+ uint8_t dialog_token;
+ uint16_t capab;
+ uint16_t timeout;
+ uint16_t start_seq_num;
+ /* Optional follows... */
+ uint8_t variable[0];
+ } __packed addba_req;
+ /* XXX */
+ struct {
+ uint8_t dialog_token;
+ } __packed wnm_timing_msr;
} u;
- } action;
+ } __packed action;
+ DECLARE_FLEX_ARRAY(uint8_t, body);
} u;
-};
+} __packed __aligned(2);
+
+struct ieee80211_cts { /* net80211::ieee80211_frame_cts */
+ __le16 frame_control;
+ __le16 duration;
+ uint8_t ra[ETH_ALEN];
+} __packed;
+
+struct ieee80211_rts { /* net80211::ieee80211_frame_rts */
+ __le16 frame_control;
+ __le16 duration;
+ uint8_t ra[ETH_ALEN];
+ uint8_t ta[ETH_ALEN];
+} __packed;
#define MHZ_TO_KHZ(_f) ((_f) * 1000)
#define DBI_TO_MBI(_g) ((_g) * 100)
@@ -434,6 +617,8 @@ struct ieee80211_mgmt {
#define IEEE80211_SEQ_TO_SN(_seqn) (((_seqn) & IEEE80211_SEQ_SEQ_MASK) >> \
IEEE80211_SEQ_SEQ_SHIFT)
+#define IEEE80211_SN_TO_SEQ(_sn) (((_sn) << IEEE80211_SEQ_SEQ_SHIFT) & \
+ IEEE80211_SEQ_SEQ_MASK)
/* Time unit (TU) to .. See net80211: IEEE80211_DUR_TU */
#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies(_tu) * 1024)
@@ -449,17 +634,38 @@ enum ieee80211_eid {
WLAN_EID_SUPP_RATES = 1,
WLAN_EID_DS_PARAMS = 3,
WLAN_EID_TIM = 5,
- WLAN_EID_COUNTRY = 7, /* IEEE80211_ELEMID_COUNTRY */
+ WLAN_EID_COUNTRY = 7, /* IEEE80211_ELEMID_COUNTRY */
WLAN_EID_REQUEST = 10,
+ WLAN_EID_QBSS_LOAD = 11, /* IEEE80211_ELEMID_BSSLOAD */
WLAN_EID_CHANNEL_SWITCH = 37,
WLAN_EID_MEASURE_REPORT = 39,
- WLAN_EID_RSN = 48, /* IEEE80211_ELEMID_RSN */
+ WLAN_EID_HT_CAPABILITY = 45, /* IEEE80211_ELEMID_HTCAP */
+ WLAN_EID_RSN = 48, /* IEEE80211_ELEMID_RSN */
WLAN_EID_EXT_SUPP_RATES = 50,
+ WLAN_EID_EXT_NON_INHERITANCE = 56,
WLAN_EID_EXT_CHANSWITCH_ANN = 60,
+ WLAN_EID_MULTIPLE_BSSID = 71, /* IEEE80211_ELEMID_MULTIBSSID */
+ WLAN_EID_MULTI_BSSID_IDX = 85,
WLAN_EID_EXT_CAPABILITY = 127,
- WLAN_EID_VENDOR_SPECIFIC = 221,
+ WLAN_EID_VHT_CAPABILITY = 191, /* IEEE80211_ELEMID_VHT_CAP */
+ WLAN_EID_S1G_TWT = 216,
+ WLAN_EID_VENDOR_SPECIFIC = 221, /* IEEE80211_ELEMID_VENDOR */
};
+enum ieee80211_eid_ext {
+ WLAN_EID_EXT_HE_CAPABILITY = 35,
+};
+
+#define for_each_element(_elem, _data, _len) \
+ for (_elem = (const struct element *)(_data); \
+ (((const uint8_t *)(_data) + (_len) - (const uint8_t *)_elem) >= sizeof(*_elem)) && \
+ (((const uint8_t *)(_data) + (_len) - (const uint8_t *)_elem) >= (sizeof(*_elem) + _elem->datalen)); \
+ _elem = (const struct element *)(_elem->data + _elem->datalen))
+
+#define for_each_element_id(_elem, _eid, _data, _len) \
+ for_each_element(_elem, _data, _len) \
+ if (_elem->id == (_eid))
+
/* 9.4.1.7, Table 9-45. Reason codes. */
enum ieee80211_reason_code {
/* reserved = 0, */
@@ -488,10 +694,10 @@ struct ieee80211_trigger {
/* Table 9-29c-Trigger Type subfield encoding */
enum {
IEEE80211_TRIGGER_TYPE_BASIC = 0x0,
+ IEEE80211_TRIGGER_TYPE_MU_BAR = 0x2,
#if 0
/* Not seen yet. */
BFRP = 0x1,
- MU-BAR = 0x2,
MU-RTS = 0x3,
BSRP = 0x4,
GCR MU-BAR = 0x5,
@@ -502,6 +708,120 @@ enum {
IEEE80211_TRIGGER_TYPE_MASK = 0xf
};
+#define IEEE80211_TRIGGER_ULBW_MASK 0xc0000
+#define IEEE80211_TRIGGER_ULBW_20MHZ 0x0
+#define IEEE80211_TRIGGER_ULBW_40MHZ 0x1
+#define IEEE80211_TRIGGER_ULBW_80MHZ 0x2
+#define IEEE80211_TRIGGER_ULBW_160_80P80MHZ 0x3
+
+/* 802.11-2020, Figure 9-687-Control field format; 802.11ax-2021 */
+#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3)
+#define IEEE80211_TWT_CONTROL_RX_DISABLED BIT(4)
+#define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT BIT(5)
+
+/* 802.11-2020, Figure 9-688-Request Type field format; 802.11ax-2021 */
+#define IEEE80211_TWT_REQTYPE_SETUP_CMD (BIT(1) | BIT(2) | BIT(3))
+#define IEEE80211_TWT_REQTYPE_TRIGGER BIT(4)
+#define IEEE80211_TWT_REQTYPE_IMPLICIT BIT(5)
+#define IEEE80211_TWT_REQTYPE_FLOWTYPE BIT(6)
+#define IEEE80211_TWT_REQTYPE_FLOWID (BIT(7) | BIT(8) | BIT(9))
+#define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP (BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14))
+#define IEEE80211_TWT_REQTYPE_PROTECTION BIT(15)
+
+struct ieee80211_twt_params {
+ int mantissa, min_twt_dur, twt;
+ uint16_t req_type;
+};
+
+struct ieee80211_twt_setup {
+ int control;
+ struct ieee80211_twt_params *params;
+};
+
+/* 802.11-2020, Table 9-297-TWT Setup Command field values */
+enum ieee80211_twt_setup_cmd {
+ TWT_SETUP_CMD_REQUEST = 0,
+ TWT_SETUP_CMD_SUGGEST = 1,
+ /* DEMAND = 2, */
+ /* GROUPING = 3, */
+ TWT_SETUP_CMD_ACCEPT = 4,
+ /* ALTERNATE = 5 */
+ TWT_SETUP_CMD_DICTATE = 6,
+ TWT_SETUP_CMD_REJECT = 7,
+};
+
+struct ieee80211_bssid_index {
+ int bssid_index;
+};
+
+enum ieee80211_ap_reg_power {
+ IEEE80211_REG_UNSET_AP,
+ IEEE80211_REG_LPI_AP,
+ IEEE80211_REG_SP_AP,
+ IEEE80211_REG_VLP_AP,
+};
+
+/*
+ * 802.11ax-2021, Table 9-277-Meaning of Maximum Transmit Power Count subfield
+ * if Maximum Transmit Power Interpretation subfield is 1 or 3
+ */
+#define IEEE80211_MAX_NUM_PWR_LEVEL 8
+
+/*
+ * 802.11ax-2021, Table 9-275a-Maximum Transmit Power Interpretation subfield
+ * encoding (4) * Table E-12-Regulatory Info subfield encoding in the
+ * United States (2)
+ */
+#define IEEE80211_TPE_MAX_IE_NUM 8
+
+/* 802.11ax-2021, 9.4.2.161 Transmit Power Envelope element */
+struct ieee80211_tx_pwr_env {
+ uint8_t tx_power_info;
+ uint8_t tx_power[IEEE80211_MAX_NUM_PWR_LEVEL];
+};
+
+/* 802.11ax-2021, Figure 9-617-Transmit Power Information field format */
+/* These are field masks (3bit/3bit/2bit). */
+#define IEEE80211_TX_PWR_ENV_INFO_COUNT 0x07
+#define IEEE80211_TX_PWR_ENV_INFO_INTERPRET 0x38
+#define IEEE80211_TX_PWR_ENV_INFO_CATEGORY 0xc0
+
+/*
+ * 802.11ax-2021, Table 9-275a-Maximum Transmit Power Interpretation subfield
+ * encoding
+ */
+enum ieee80211_tx_pwr_interpretation_subfield_enc {
+ IEEE80211_TPE_LOCAL_EIRP,
+ IEEE80211_TPE_LOCAL_EIRP_PSD,
+ IEEE80211_TPE_REG_CLIENT_EIRP,
+ IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
+};
+
+enum ieee80211_tx_pwr_category_6ghz {
+ IEEE80211_TPE_CAT_6GHZ_DEFAULT,
+};
+
+/* 802.11-2020, 9.4.2.27 BSS Load element */
+struct ieee80211_bss_load_elem {
+ uint16_t sta_count;
+ uint8_t channel_util;
+ uint16_t avail_adm_capa;
+};
+
+struct ieee80211_p2p_noa_desc {
+ uint32_t count; /* uint8_t ? */
+ uint32_t duration;
+ uint32_t interval;
+ uint32_t start_time;
+};
+
+struct ieee80211_p2p_noa_attr {
+ uint8_t index;
+ uint8_t oppps_ctwindow;
+ struct ieee80211_p2p_noa_desc desc[4];
+};
+
+
/* net80211: IEEE80211_IS_CTL() */
static __inline bool
ieee80211_is_ctl(__le16 fc)
@@ -532,9 +852,8 @@ ieee80211_is_data_qos(__le16 fc)
{
__le16 v;
- fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS | IEEE80211_FC0_TYPE_MASK |
- IEEE80211_FC0_VERSION_MASK);
- v = htole16(IEEE80211_FC0_QOSDATA);
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_DATA);
return (fc == v);
}
@@ -574,9 +893,9 @@ ieee80211_hdrlen(__le16 fc)
if ((fc & htole16(IEEE80211_FC1_DIR_MASK << 8)) ==
htole16(IEEE80211_FC1_DIR_DSTODS << 8))
size += IEEE80211_ADDR_LEN;
- if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS |
+ if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA |
IEEE80211_FC0_TYPE_MASK)) ==
- htole16(IEEE80211_FC0_SUBTYPE_QOS |
+ htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA |
IEEE80211_FC0_TYPE_DATA))
size += sizeof(uint16_t);
}
@@ -603,4 +922,346 @@ ieee80211_is_trigger(__le16 fc)
return (fc == v);
}
+static __inline bool
+ieee80211_is_action(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_ACTION | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_probe_resp(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_RESP | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_auth(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_AUTH | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_assoc_req(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_assoc_resp(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_reassoc_req(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_reassoc_resp(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_disassoc(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_DISASSOC | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_data_present(__le16 fc)
+{
+ __le16 v;
+
+ /* If it is a data frame and NODATA is not present. */
+ fc &= htole16(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_NODATA);
+ v = htole16(IEEE80211_FC0_TYPE_DATA);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_deauth(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_DEAUTH | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_beacon(__le16 fc)
+{
+ __le16 v;
+
+ /*
+ * For as much as I get it this comes in LE and unlike FreeBSD
+ * where we get the entire frame header and u8[], here we get the
+ * 9.2.4.1 Frame Control field only. Mask and compare.
+ */
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_BEACON | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+
+static __inline bool
+ieee80211_is_probe_req(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_has_protected(__le16 fc)
+{
+
+ return (fc & htole16(IEEE80211_FC1_PROTECTED << 8));
+}
+
+static __inline bool
+ieee80211_is_back_req(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_BAR | IEEE80211_FC0_TYPE_CTL);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt;
+ __le16 fc;
+
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+ fc = mgmt->frame_control;
+
+ /* 11.2.2 Bufferable MMPDUs, 80211-2020. */
+ /* XXX we do not care about IBSS yet. */
+
+ if (!ieee80211_is_mgmt(fc))
+ return (false);
+ if (ieee80211_is_action(fc)) /* XXX FTM? */
+ return (true); /* XXX false? */
+ if (ieee80211_is_disassoc(fc))
+ return (true);
+ if (ieee80211_is_deauth(fc))
+ return (true);
+
+ TODO();
+
+ return (false);
+}
+
+static __inline bool
+ieee80211_is_nullfunc(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_qos_nullfunc(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_QOS_NULL | IEEE80211_FC0_TYPE_DATA);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_is_any_nullfunc(__le16 fc)
+{
+
+ return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
+}
+
+static inline bool
+ieee80211_is_pspoll(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
+ v = htole16(IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_has_a4(__le16 fc)
+{
+ __le16 v;
+
+ fc &= htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
+ v = htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
+
+ return (fc == v);
+}
+
+static __inline bool
+ieee80211_has_order(__le16 fc)
+{
+
+ return (fc & htole16(IEEE80211_FC1_ORDER << 8));
+}
+
+static __inline bool
+ieee80211_has_retry(__le16 fc)
+{
+
+ return (fc & htole16(IEEE80211_FC1_RETRY << 8));
+}
+
+
+static __inline bool
+ieee80211_has_fromds(__le16 fc)
+{
+
+ return (fc & htole16(IEEE80211_FC1_DIR_FROMDS << 8));
+}
+
+static __inline bool
+ieee80211_has_tods(__le16 fc)
+{
+
+ return (fc & htole16(IEEE80211_FC1_DIR_TODS << 8));
+}
+
+static __inline uint8_t *
+ieee80211_get_SA(struct ieee80211_hdr *hdr)
+{
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ return (hdr->addr4);
+ if (ieee80211_has_fromds(hdr->frame_control))
+ return (hdr->addr3);
+ return (hdr->addr2);
+}
+
+static __inline uint8_t *
+ieee80211_get_DA(struct ieee80211_hdr *hdr)
+{
+
+ if (ieee80211_has_tods(hdr->frame_control))
+ return (hdr->addr3);
+ return (hdr->addr1);
+}
+
+static __inline bool
+ieee80211_is_frag(struct ieee80211_hdr *hdr)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_is_first_frag(__le16 fc)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_is_ftm(struct sk_buff *skb)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_is_timing_measurement(struct sk_buff *skb)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_has_pm(__le16 fc)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+ieee80211_has_morefrags(__le16 fc)
+{
+
+ fc &= htole16(IEEE80211_FC1_MORE_FRAG << 8);
+ return (fc != 0);
+}
+
+static __inline u8 *
+ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
+{
+ if (ieee80211_has_a4(hdr->frame_control))
+ return (u8 *)hdr + 30;
+ else
+ return (u8 *)hdr + 24;
+}
+
#endif /* _LINUXKPI_LINUX_IEEE80211_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/if_arp.h b/sys/compat/linuxkpi/common/include/linux/if_arp.h
index abd30eac49c9..6201c3a1c284 100644
--- a/sys/compat/linuxkpi/common/include/linux/if_arp.h
+++ b/sys/compat/linuxkpi/common/include/linux/if_arp.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IF_ARP_H_
#define _LINUXKPI_LINUX_IF_ARP_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/if_ether.h b/sys/compat/linuxkpi/common/include/linux/if_ether.h
index 178b778ec736..6676e8fc142f 100644
--- a/sys/compat/linuxkpi/common/include/linux/if_ether.h
+++ b/sys/compat/linuxkpi/common/include/linux/if_ether.h
@@ -4,6 +4,10 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013 Mellanox Technologies, Ltd.
* All rights reserved.
+ * Copyright (c) 2021-2022 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,13 +29,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IF_ETHER_H_
#define _LINUXKPI_LINUX_IF_ETHER_H_
#include <linux/types.h>
+#include <linux/skbuff.h>
#include <net/ethernet.h>
@@ -55,6 +58,9 @@
#define ETH_P_8021AD ETHERTYPE_QINQ
#define ETH_P_PAE ETHERTYPE_PAE
#define ETH_P_802_2 ETHERTYPE_8023
+#define ETH_P_IPX ETHERTYPE_IPX
+#define ETH_P_AARP ETHERTYPE_AARP
+#define ETH_P_802_3_MIN 0x05DD /* See comment in sys/net/ethernet.h */
#define ETH_P_LINK_CTL 0x886C /* ITU-T G.989.2 */
#define ETH_P_TDLS 0x890D /* 802.11z-2010, see wpa. */
@@ -64,4 +70,13 @@ struct ethhdr {
uint16_t h_proto;
} __packed;
+static inline struct ethhdr *
+eth_hdr(const struct sk_buff *skb)
+{
+ struct ethhdr *hdr;
+
+ hdr = (struct ethhdr *)skb_mac_header(skb);
+ return (hdr);
+}
+
#endif /* _LINUXKPI_LINUX_IF_ETHER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/if_vlan.h b/sys/compat/linuxkpi/common/include/linux/if_vlan.h
index 7c5531f6ec11..3d1c61db1882 100644
--- a/sys/compat/linuxkpi/common/include/linux/if_vlan.h
+++ b/sys/compat/linuxkpi/common/include/linux/if_vlan.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IF_VLAN_H_
#define _LINUXKPI_LINUX_IF_VLAN_H_
@@ -44,7 +42,7 @@
static inline int
is_vlan_dev(struct ifnet *ifp)
{
- return (ifp->if_type == IFT_L2VLAN);
+ return (if_gettype(ifp) == IFT_L2VLAN);
}
static inline uint16_t
diff --git a/sys/compat/linuxkpi/common/include/linux/in.h b/sys/compat/linuxkpi/common/include/linux/in.h
index ae2be5be1799..5cc92416c7da 100644
--- a/sys/compat/linuxkpi/common/include/linux/in.h
+++ b/sys/compat/linuxkpi/common/include/linux/in.h
@@ -25,15 +25,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IN_H_
#define _LINUXKPI_LINUX_IN_H_
#include "opt_inet.h"
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <netinet/in.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/in6.h b/sys/compat/linuxkpi/common/include/linux/in6.h
index 5f5f548de06d..79be45b6819a 100644
--- a/sys/compat/linuxkpi/common/include/linux/in6.h
+++ b/sys/compat/linuxkpi/common/include/linux/in6.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IN6_H_
#define _LINUXKPI_LINUX_IN6_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h
index 905a29a77f91..dfd9816da8be 100644
--- a/sys/compat/linuxkpi/common/include/linux/interrupt.h
+++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_INTERRUPT_H_
#define _LINUXKPI_LINUX_INTERRUPT_H_
@@ -42,7 +40,12 @@
typedef irqreturn_t (*irq_handler_t)(int, void *);
-#define IRQF_SHARED RF_SHAREABLE
+#define IRQF_SHARED 0x0004 /* Historically */
+#define IRQF_NOBALANCING 0
+
+#define IRQ_DISABLE_UNLAZY 0
+
+#define IRQ_NOTCONNECTED (1U << 31)
int lkpi_request_irq(struct device *, unsigned int, irq_handler_t,
irq_handler_t, unsigned long, const char *, void *);
@@ -71,6 +74,14 @@ request_threaded_irq(int irq, irq_handler_t handler,
}
static inline int
+devm_request_irq(struct device *dev, int irq,
+ irq_handler_t handler, unsigned long flags, const char *name, void *arg)
+{
+
+ return (lkpi_request_irq(dev, irq, handler, NULL, flags, name, arg));
+}
+
+static inline int
devm_request_threaded_irq(struct device *dev, int irq,
irq_handler_t handler, irq_handler_t thread_handler,
unsigned long flags, const char *name, void *arg)
@@ -92,6 +103,12 @@ disable_irq(unsigned int irq)
lkpi_disable_irq(irq);
}
+static inline void
+disable_irq_nosync(unsigned int irq)
+{
+ lkpi_disable_irq(irq);
+}
+
static inline int
bind_irq_to_cpu(unsigned int irq, int cpu_id)
{
@@ -111,7 +128,7 @@ devm_free_irq(struct device *xdev, unsigned int irq, void *p)
}
static inline int
-irq_set_affinity_hint(int vector, cpumask_t *mask)
+irq_set_affinity_hint(int vector, const cpumask_t *mask)
{
int error;
@@ -123,10 +140,24 @@ irq_set_affinity_hint(int vector, cpumask_t *mask)
return (-error);
}
+static inline struct msi_desc *
+irq_get_msi_desc(unsigned int irq)
+{
+
+ return (lkpi_pci_msi_desc_alloc(irq));
+}
+
+static inline void
+irq_set_status_flags(unsigned int irq __unused, unsigned long flags __unused)
+{
+}
+
/*
* LinuxKPI tasklet support
*/
+struct tasklet_struct;
typedef void tasklet_func_t(unsigned long);
+typedef void tasklet_callback_t(struct tasklet_struct *);
struct tasklet_struct {
TAILQ_ENTRY(tasklet_struct) entry;
@@ -135,6 +166,8 @@ struct tasklet_struct {
volatile u_int tasklet_state;
atomic_t count;
unsigned long data;
+ tasklet_callback_t *callback;
+ bool use_callback;
};
#define DECLARE_TASKLET(_name, _func, _data) \
@@ -142,6 +175,11 @@ struct tasklet_struct _name = { .func = (_func), .data = (_data) }
#define tasklet_hi_schedule(t) tasklet_schedule(t)
+/* Some other compat code in the tree has this defined as well. */
+#define from_tasklet(_dev, _t, _field) \
+ container_of(_t, typeof(*(_dev)), _field)
+
+void tasklet_setup(struct tasklet_struct *, tasklet_callback_t *);
extern void tasklet_schedule(struct tasklet_struct *);
extern void tasklet_kill(struct tasklet_struct *);
extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *,
@@ -152,5 +190,6 @@ extern void tasklet_disable_nosync(struct tasklet_struct *);
extern int tasklet_trylock(struct tasklet_struct *);
extern void tasklet_unlock(struct tasklet_struct *);
extern void tasklet_unlock_wait(struct tasklet_struct *ts);
+#define tasklet_unlock_spin_wait(ts) tasklet_unlock_wait(ts)
#endif /* _LINUXKPI_LINUX_INTERRUPT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/interval_tree.h b/sys/compat/linuxkpi/common/include/linux/interval_tree.h
index 3f8e0cb743d9..1eb8a2fb9181 100644
--- a/sys/compat/linuxkpi/common/include/linux/interval_tree.h
+++ b/sys/compat/linuxkpi/common/include/linux/interval_tree.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
diff --git a/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h b/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h
index 2ee615fda159..3ed6e105cbda 100644
--- a/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h
+++ b/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Mark Kettenis <kettenis@OpenBSD.org>
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
diff --git a/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h b/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h
new file mode 100644
index 000000000000..844b3ef171d5
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/io-64-nonatomic-lo-hi.h
@@ -0,0 +1,65 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Felix Palmen
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _LINUXKPI_LINUX_IO_64_NONATOMIC_LO_HI_H_
+#define _LINUXKPI_LINUX_IO_64_NONATOMIC_LO_HI_H_
+
+#include <linux/io.h>
+
+static inline uint64_t
+lo_hi_readq(const volatile void *addr)
+{
+ const volatile uint32_t *p = addr;
+ uint32_t l, h;
+
+ __io_br();
+ l = le32toh(__raw_readl(p));
+ h = le32toh(__raw_readl(p + 1));
+ __io_ar();
+
+ return (l + ((uint64_t)h << 32));
+}
+
+static inline void
+lo_hi_writeq(uint64_t v, volatile void *addr)
+{
+ volatile uint32_t *p = addr;
+
+ __io_bw();
+ __raw_writel(htole32(v), p);
+ __raw_writel(htole32(v >> 32), p + 1);
+ __io_aw();
+}
+
+#ifndef readq
+#define readq(addr) lo_hi_readq(addr)
+#endif
+
+#ifndef writeq
+#define writeq(v, addr) lo_hi_writeq(v, addr)
+#endif
+
+#endif /* _LINUXKPI_LINUX_IO_64_NONATOMIC_LO_HI_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/io-mapping.h b/sys/compat/linuxkpi/common/include/linux/io-mapping.h
index 5c24f1ff8659..f5f2fbc5c2cb 100644
--- a/sys/compat/linuxkpi/common/include/linux/io-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/io-mapping.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IO_MAPPING_H_
@@ -37,6 +35,7 @@
#include <linux/types.h>
#include <linux/io.h>
+#include <linux/mm.h>
#include <linux/slab.h>
struct io_mapping {
@@ -93,6 +92,18 @@ io_mapping_unmap_atomic(void *vaddr)
}
static inline void *
+io_mapping_map_local_wc(struct io_mapping *mapping, unsigned long offset)
+{
+
+ return (io_mapping_map_atomic_wc(mapping, offset));
+}
+
+static inline void
+io_mapping_unmap_local(void *vaddr __unused)
+{
+}
+
+static inline void *
io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset,
unsigned long size)
{
@@ -100,6 +111,17 @@ io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset,
return ((char *)mapping->mem + offset);
}
+int lkpi_io_mapping_map_user(struct io_mapping *iomap,
+ struct vm_area_struct *vma, unsigned long addr, unsigned long pfn,
+ unsigned long size);
+
+static inline int
+io_mapping_map_user(struct io_mapping *iomap, struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn, unsigned long size)
+{
+ return (lkpi_io_mapping_map_user(iomap, vma, addr, pfn, size));
+}
+
static inline void
io_mapping_unmap(void *vaddr)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h
index 0790e518a1a3..2d6fef4e7c52 100644
--- a/sys/compat/linuxkpi/common/include/linux/io.h
+++ b/sys/compat/linuxkpi/common/include/linux/io.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IO_H_
#define _LINUXKPI_LINUX_IO_H_
@@ -37,7 +35,12 @@
#include <machine/vm.h>
#include <linux/compiler.h>
+#include <linux/err.h>
+#include <asm-generic/io.h>
#include <linux/types.h>
+#if !defined(__arm__)
+#include <asm/set_memory.h>
+#endif
/*
* XXX This is all x86 specific. It should be bus space access.
@@ -348,6 +351,16 @@ ioread32be(const volatile void *addr)
}
#define ioread32be(addr) ioread32be(addr)
+#ifdef __LP64__
+#undef ioread64
+static inline uint64_t
+ioread64(const volatile void *addr)
+{
+ return (readq(addr));
+}
+#define ioread64(addr) ioread64(addr)
+#endif
+
#undef iowrite8
static inline void
iowrite8(uint8_t v, volatile void *addr)
@@ -383,11 +396,7 @@ iowrite32be(uint32_t v, volatile void *addr)
#define iowrite32be(v, addr) iowrite32be(v, addr)
#if defined(__i386__) || defined(__amd64__)
-static inline void
-_outb(u_char data, u_int port)
-{
- __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
-}
+#define _outb(data, port) outb((data), (port))
#endif
#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv)
@@ -400,6 +409,13 @@ _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr)
}
#endif
+struct device;
+static inline void *
+devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size)
+{
+ return (NULL);
+}
+
#ifdef VM_MEMATTR_DEVICE
#define ioremap_nocache(addr, size) \
_ioremap_attr((addr), (size), VM_MEMATTR_DEVICE)
@@ -421,7 +437,7 @@ _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr)
#else
#define ioremap_wc(addr, size) ioremap_nocache(addr, size)
#endif
-#define ioremap_wb(addr, size) \
+#define ioremap_cache(addr, size) \
_ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK)
void iounmap(void *addr);
@@ -430,9 +446,9 @@ void iounmap(void *addr);
#define memcpy_toio(a, b, c) memcpy((a), (b), (c))
static inline void
-__iowrite32_copy(void *to, void *from, size_t count)
+__iowrite32_copy(void *to, const void *from, size_t count)
{
- uint32_t *src;
+ const uint32_t *src;
uint32_t *dst;
int i;
@@ -441,10 +457,10 @@ __iowrite32_copy(void *to, void *from, size_t count)
}
static inline void
-__iowrite64_copy(void *to, void *from, size_t count)
+__iowrite64_copy(void *to, const void *from, size_t count)
{
#ifdef __LP64__
- uint64_t *src;
+ const uint64_t *src;
uint64_t *dst;
int i;
@@ -455,6 +471,32 @@ __iowrite64_copy(void *to, void *from, size_t count)
#endif
}
+static inline void
+__ioread32_copy(void *to, const void *from, size_t count)
+{
+ const uint32_t *src;
+ uint32_t *dst;
+ int i;
+
+ for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
+ *dst = __raw_readl(src);
+}
+
+static inline void
+__ioread64_copy(void *to, const void *from, size_t count)
+{
+#ifdef __LP64__
+ const uint64_t *src;
+ uint64_t *dst;
+ int i;
+
+ for (i = 0, src = from, dst = to; i < count; i++, src++, dst++)
+ *dst = __raw_readq(src);
+#else
+ __ioread32_copy(to, from, count * 2);
+#endif
+}
+
enum {
MEMREMAP_WB = 1 << 0,
MEMREMAP_WT = 1 << 1,
@@ -467,7 +509,7 @@ memremap(resource_size_t offset, size_t size, unsigned long flags)
void *addr = NULL;
if ((flags & MEMREMAP_WB) &&
- (addr = ioremap_wb(offset, size)) != NULL)
+ (addr = ioremap_cache(offset, size)) != NULL)
goto done;
if ((flags & MEMREMAP_WT) &&
(addr = ioremap_wt(offset, size)) != NULL)
@@ -486,6 +528,8 @@ memunmap(void *addr)
iounmap(addr);
}
+#define IOMEM_ERR_PTR(err) (void __iomem *)ERR_PTR(err)
+
#define __MTRR_ID_BASE 1
int lkpi_arch_phys_wc_add(unsigned long, unsigned long);
void lkpi_arch_phys_wc_del(int);
@@ -494,4 +538,29 @@ void lkpi_arch_phys_wc_del(int);
#define arch_phys_wc_index(x) \
(((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE))
+static inline int
+arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
+{
+#if defined(__amd64__)
+ vm_offset_t va;
+
+ va = PHYS_TO_DMAP(start);
+ return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
+#else
+ return (0);
+#endif
+}
+
+static inline void
+arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
+{
+#if defined(__amd64__)
+ vm_offset_t va;
+
+ va = PHYS_TO_DMAP(start);
+
+ pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
+#endif
+}
+
#endif /* _LINUXKPI_LINUX_IO_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ioctl.h b/sys/compat/linuxkpi/common/include/linux/ioctl.h
index b1b5443fa150..77c01224e6a5 100644
--- a/sys/compat/linuxkpi/common/include/linux/ioctl.h
+++ b/sys/compat/linuxkpi/common/include/linux/ioctl.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IOCTL_H_
#define _LINUXKPI_LINUX_IOCTL_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/iommu.h b/sys/compat/linuxkpi/common/include/linux/iommu.h
new file mode 100644
index 000000000000..391d9778a0c8
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/iommu.h
@@ -0,0 +1,29 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_IOMMU_H_
+#define _LINUXKPI_LINUX_IOMMU_H_
+
+#include <linux/device.h>
+
+#define __IOMMU_DOMAIN_PAGING (1U << 0)
+#define __IOMMU_DOMAIN_DMA_API (1U << 1)
+#define __IOMMU_DOMAIN_PT (1U << 2)
+#define __IOMMU_DOMAIN_DMA_FQ (1U << 3)
+
+#define IOMMU_DOMAIN_BLOCKED (0U)
+#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT)
+#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
+#define IOMMU_DOMAIN_DMA (__IOMMU_DOMAIN_PAGING | __IOMMU_DOMAIN_DMA_API)
+#define IOMMU_DOMAIN_DMA_FQ (__IOMMU_DOMAIN_PAGING | __IOMMU_DOMAIN_DMA_API | __IOMMU_DOMAIN_DMA_FQ)
+
+struct iommu_domain {
+ unsigned int type;
+};
+
+static inline struct iommu_domain *
+iommu_get_domain_for_dev(struct device *dev __unused)
+{
+ return (NULL);
+}
+
+#endif /* _LINUXKPI_LINUX_IOMMU_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/iopoll.h b/sys/compat/linuxkpi/common/include/linux/iopoll.h
index 478d875c846c..8d0498a26da1 100644
--- a/sys/compat/linuxkpi/common/include/linux/iopoll.h
+++ b/sys/compat/linuxkpi/common/include/linux/iopoll.h
@@ -23,8 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IOPOLL_H
diff --git a/sys/compat/linuxkpi/common/include/linux/ioport.h b/sys/compat/linuxkpi/common/include/linux/ioport.h
new file mode 100644
index 000000000000..763af2de7c4f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ioport.h
@@ -0,0 +1,58 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_IOPORT_H
+#define _LINUXKPI_LINUX_IOPORT_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#define DEFINE_RES_MEM(_start, _size) \
+ (struct resource) { \
+ .start = (_start), \
+ .end = (_start) + (_size) - 1, \
+ }
+
+struct resource {
+ resource_size_t start;
+ resource_size_t end;
+ const char *name;
+};
+
+static inline resource_size_t
+resource_size(const struct resource *r)
+{
+ return (r->end - r->start + 1);
+}
+
+static inline bool
+resource_contains(struct resource *a, struct resource *b)
+{
+ return (a->start <= b->start && a->end >= b->end);
+}
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/iosys-map.h b/sys/compat/linuxkpi/common/include/linux/iosys-map.h
new file mode 100644
index 000000000000..66c442b8668f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/iosys-map.h
@@ -0,0 +1,161 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_IOSYS_MAP_H
+#define _LINUXKPI_LINUX_IOSYS_MAP_H
+
+#include <linux/io.h>
+#include <linux/string.h>
+
+struct iosys_map {
+ union {
+ void *vaddr_iomem;
+ void *vaddr;
+ };
+ bool is_iomem;
+#ifdef __OpenBSD__
+ bus_space_handle_t bsh;
+ bus_size_t size;
+#endif
+};
+
+#define IOSYS_MAP_INIT_OFFSET(_ism_src_p, _off) ({ \
+ struct iosys_map ism_dst = *(_ism_src_p); \
+ iosys_map_incr(&ism_dst, _off); \
+ ism_dst; \
+})
+
+static inline void
+iosys_map_incr(struct iosys_map *ism, size_t n)
+{
+ if (ism->is_iomem)
+ ism->vaddr_iomem += n;
+ else
+ ism->vaddr += n;
+}
+
+static inline void
+iosys_map_memcpy_to(struct iosys_map *ism, size_t off, const void *src,
+ size_t len)
+{
+ if (ism->is_iomem)
+ memcpy_toio(ism->vaddr_iomem + off, src, len);
+ else
+ memcpy(ism->vaddr + off, src, len);
+}
+
+static inline bool
+iosys_map_is_null(const struct iosys_map *ism)
+{
+ if (ism->is_iomem)
+ return (ism->vaddr_iomem == NULL);
+ else
+ return (ism->vaddr == NULL);
+}
+
+static inline bool
+iosys_map_is_set(const struct iosys_map *ism)
+{
+ if (ism->is_iomem)
+ return (ism->vaddr_iomem != NULL);
+ else
+ return (ism->vaddr != NULL);
+}
+
+static inline bool
+iosys_map_is_equal(const struct iosys_map *ism_a,
+ const struct iosys_map *ism_b)
+{
+ if (ism_a->is_iomem != ism_b->is_iomem)
+ return (false);
+
+ if (ism_a->is_iomem)
+ return (ism_a->vaddr_iomem == ism_b->vaddr_iomem);
+ else
+ return (ism_a->vaddr == ism_b->vaddr);
+}
+
+static inline void
+iosys_map_clear(struct iosys_map *ism)
+{
+ if (ism->is_iomem) {
+ ism->vaddr_iomem = NULL;
+ ism->is_iomem = false;
+ } else {
+ ism->vaddr = NULL;
+ }
+}
+
+static inline void
+iosys_map_set_vaddr_iomem(struct iosys_map *ism, void *addr)
+{
+ ism->vaddr_iomem = addr;
+ ism->is_iomem = true;
+}
+
+static inline void
+iosys_map_set_vaddr(struct iosys_map *ism, void *addr)
+{
+ ism->vaddr = addr;
+ ism->is_iomem = false;
+}
+
+static inline void
+iosys_map_memset(struct iosys_map *ism, size_t off, int value, size_t len)
+{
+ if (ism->is_iomem)
+ memset_io(ism->vaddr_iomem + off, value, len);
+ else
+ memset(ism->vaddr + off, value, len);
+}
+
+#ifdef __LP64__
+#define _iosys_map_readq(_addr) readq(_addr)
+#define _iosys_map_writeq(_val, _addr) writeq(_val, _addr)
+#else
+#define _iosys_map_readq(_addr) ({ \
+ uint64_t val; \
+ memcpy_fromio(&val, _addr, sizeof(uint64_t)); \
+ val; \
+})
+#define _iosys_map_writeq(_val, _addr) \
+ memcpy_toio(_addr, &(_val), sizeof(uint64_t))
+#endif
+
+#define iosys_map_rd(_ism, _off, _type) ({ \
+ _type val; \
+ if ((_ism)->is_iomem) { \
+ void *addr = (_ism)->vaddr_iomem + (_off); \
+ val = _Generic(val, \
+ uint8_t : readb(addr), \
+ uint16_t: readw(addr), \
+ uint32_t: readl(addr), \
+ uint64_t: _iosys_map_readq(addr)); \
+ } else \
+ val = READ_ONCE(*(_type *)((_ism)->vaddr + (_off))); \
+ val; \
+})
+#define iosys_map_wr(_ism, _off, _type, _val) ({ \
+ _type val = (_val); \
+ if ((_ism)->is_iomem) { \
+ void *addr = (_ism)->vaddr_iomem + (_off); \
+ _Generic(val, \
+ uint8_t : writeb(val, addr), \
+ uint16_t: writew(val, addr), \
+ uint32_t: writel(val, addr), \
+ uint64_t: _iosys_map_writeq(val, addr)); \
+ } else \
+ WRITE_ONCE(*(_type *)((_ism)->vaddr + (_off)), val); \
+})
+
+#define iosys_map_rd_field(_ism, _off, _type, _field) ({ \
+ _type *s; \
+ iosys_map_rd(_ism, (_off) + offsetof(_type, _field), \
+ __typeof(s->_field)); \
+})
+#define iosys_map_wr_field(_ism, _off, _type, _field, _val) ({ \
+ _type *s; \
+ iosys_map_wr(_ism, (_off) + offsetof(_type, _field), \
+ __typeof(s->_field), _val); \
+})
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/ip.h b/sys/compat/linuxkpi/common/include/linux/ip.h
index 11f4aed180d1..137cf89e7dcb 100644
--- a/sys/compat/linuxkpi/common/include/linux/ip.h
+++ b/sys/compat/linuxkpi/common/include/linux/ip.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IP_H
diff --git a/sys/compat/linuxkpi/common/include/linux/irq_work.h b/sys/compat/linuxkpi/common/include/linux/irq_work.h
index ec71a7ee094f..7c4019bc0242 100644
--- a/sys/compat/linuxkpi/common/include/linux/irq_work.h
+++ b/sys/compat/linuxkpi/common/include/linux/irq_work.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IRQ_WORK_H_
@@ -51,7 +49,12 @@ typedef void (*irq_work_func_t)(struct irq_work *);
struct irq_work {
struct task irq_task;
- struct llist_node llnode;
+ union {
+ struct llist_node llnode;
+ struct {
+ struct llist_node llist;
+ } node;
+ };
irq_work_func_t func;
};
diff --git a/sys/compat/linuxkpi/common/include/linux/irqdomain.h b/sys/compat/linuxkpi/common/include/linux/irqdomain.h
new file mode 100644
index 000000000000..c7788e51cc89
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/irqdomain.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_IRQDOMAIN_H
+#define _LINUXKPI_LINUX_IRQDOMAIN_H
+
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/radix-tree.h>
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/irqreturn.h b/sys/compat/linuxkpi/common/include/linux/irqreturn.h
index 8fbb0217573d..ff2618449d5e 100644
--- a/sys/compat/linuxkpi/common/include/linux/irqreturn.h
+++ b/sys/compat/linuxkpi/common/include/linux/irqreturn.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_IRQRETURN_H
diff --git a/sys/compat/linuxkpi/common/include/linux/jhash.h b/sys/compat/linuxkpi/common/include/linux/jhash.h
index 1bab37f22b5d..25e2c04f1965 100644
--- a/sys/compat/linuxkpi/common/include/linux/jhash.h
+++ b/sys/compat/linuxkpi/common/include/linux/jhash.h
@@ -20,8 +20,6 @@
*
* I've modified Bob's hash to be useful in the Linux kernel, and
* any bugs present are surely my fault. -DaveM
- *
- * $FreeBSD$
*/
/* NOTE: Arguments are modified. */
diff --git a/sys/compat/linuxkpi/common/include/linux/jiffies.h b/sys/compat/linuxkpi/common/include/linux/jiffies.h
index 76c9c6a749c1..c2409726e874 100644
--- a/sys/compat/linuxkpi/common/include/linux/jiffies.h
+++ b/sys/compat/linuxkpi/common/include/linux/jiffies.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_JIFFIES_H_
#define _LINUXKPI_LINUX_JIFFIES_H_
@@ -34,26 +32,27 @@
#include <linux/types.h>
#include <linux/time.h>
-#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/limits.h>
+#include <sys/time.h>
-#define jiffies ticks
-#define jiffies_64 ticks
-#define jiffies_to_msecs(x) (((int64_t)(int)(x)) * 1000 / hz)
+extern unsigned long jiffies; /* defined in sys/kern/subr_ticks.S */
+#define jiffies_64 jiffies /* XXX-MJ wrong on 32-bit platforms */
+#define jiffies_to_msecs(x) ((unsigned int)(((int64_t)(int)(x)) * 1000 / hz))
-#define MAX_JIFFY_OFFSET ((INT_MAX >> 1) - 1)
+#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1) - 1)
-#define time_after(a, b) ((int)((b) - (a)) < 0)
+#define time_after(a, b) ((long)((b) - (a)) < 0)
#define time_after32(a, b) ((int32_t)((uint32_t)(b) - (uint32_t)(a)) < 0)
#define time_before(a, b) time_after(b,a)
#define time_before32(a, b) time_after32(b, a)
-#define time_after_eq(a, b) ((int)((a) - (b)) >= 0)
+#define time_after_eq(a, b) ((long)((a) - (b)) >= 0)
#define time_before_eq(a, b) time_after_eq(b, a)
#define time_in_range(a,b,c) \
(time_after_eq(a,b) && time_before_eq(a,c))
#define time_is_after_eq_jiffies(a) time_after_eq(a, jiffies)
#define time_is_after_jiffies(a) time_after(a, jiffies)
+#define time_is_before_jiffies(a) time_before(a, jiffies)
#define HZ hz
@@ -69,20 +68,7 @@ extern uint64_t lkpi_msec2hz_rem;
extern uint64_t lkpi_msec2hz_div;
extern uint64_t lkpi_msec2hz_max;
-static inline int
-timespec_to_jiffies(const struct timespec *ts)
-{
- u64 result;
-
- result = ((u64)hz * ts->tv_sec) +
- (((u64)hz * ts->tv_nsec + NSEC_PER_SEC - 1) / NSEC_PER_SEC);
- if (result > MAX_JIFFY_OFFSET)
- result = MAX_JIFFY_OFFSET;
-
- return ((int)result);
-}
-
-static inline int
+static inline unsigned long
msecs_to_jiffies(uint64_t msec)
{
uint64_t result;
@@ -93,10 +79,10 @@ msecs_to_jiffies(uint64_t msec)
if (result > MAX_JIFFY_OFFSET)
result = MAX_JIFFY_OFFSET;
- return ((int)result);
+ return ((unsigned long)result);
}
-static inline int
+static inline unsigned long
usecs_to_jiffies(uint64_t usec)
{
uint64_t result;
@@ -107,7 +93,7 @@ usecs_to_jiffies(uint64_t usec)
if (result > MAX_JIFFY_OFFSET)
result = MAX_JIFFY_OFFSET;
- return ((int)result);
+ return ((unsigned long)result);
}
static inline uint64_t
@@ -134,34 +120,24 @@ nsecs_to_jiffies(uint64_t nsec)
}
static inline uint64_t
-jiffies_to_nsecs(int j)
+jiffies_to_nsecs(unsigned long j)
{
- return ((1000000000ULL / hz) * (uint64_t)(unsigned int)j);
+ return ((1000000000ULL / hz) * (uint64_t)j);
}
static inline uint64_t
-jiffies_to_usecs(int j)
+jiffies_to_usecs(unsigned long j)
{
- return ((1000000ULL / hz) * (uint64_t)(unsigned int)j);
+ return ((1000000ULL / hz) * (uint64_t)j);
}
static inline uint64_t
get_jiffies_64(void)
{
- return ((uint64_t)(unsigned int)ticks);
-}
-
-static inline int
-linux_timer_jiffies_until(int expires)
-{
- int delta = expires - jiffies;
- /* guard against already expired values */
- if (delta < 1)
- delta = 1;
- return (delta);
+ return ((uint64_t)jiffies);
}
#endif /* _LINUXKPI_LINUX_JIFFIES_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kconfig.h b/sys/compat/linuxkpi/common/include/linux/kconfig.h
new file mode 100644
index 000000000000..c1d186b56e1f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/kconfig.h
@@ -0,0 +1,76 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_KCONFIG_H_
+#define _LINUXKPI_LINUX_KCONFIG_H_
+
+/*
+ * Checking if an option is defined would be easy if we could do CPP inside CPP.
+ * The defined case whether -Dxxx or -Dxxx=1 are easy to deal with. In either
+ * case the defined value is "1". A more general -Dxxx=<c> case will require
+ * more effort to deal with all possible "true" values. Hope we do not have
+ * to do this as well.
+ * The real problem is the undefined case. To avoid this problem we do the
+ * concat/varargs trick: "yyy" ## xxx can make two arguments if xxx is "1"
+ * by having a #define for yyy_1 which is "ignore,".
+ * Otherwise we will just get "yyy".
+ * Need to be careful about variable substitutions in macros though.
+ * This way we make a (true, false) problem a (don't care, true, false) or a
+ * (don't care true, false). Then we can use a variadic macro to only select
+ * the always well known and defined argument #2. And that seems to be
+ * exactly what we need. Use 1 for true and 0 for false to also allow
+ * #if IS_*() checks pre-compiler checks which do not like #if true.
+ */
+#define ___XAB_1 dontcare,
+#define ___IS_XAB(_ignore, _x, ...) (_x)
+#define __IS_XAB(_x) ___IS_XAB(_x 1, 0)
+#define _IS_XAB(_x) __IS_XAB(__CONCAT(___XAB_, _x))
+
+/* This is if CONFIG_ccc=y. */
+#define IS_BUILTIN(_x) _IS_XAB(_x)
+/* This is if CONFIG_ccc=m. */
+#define IS_MODULE(_x) _IS_XAB(_x ## _MODULE)
+/* This is if CONFIG_ccc is compiled in(=y) or a module(=m). */
+#define IS_ENABLED(_x) (IS_BUILTIN(_x) || IS_MODULE(_x))
+/*
+ * This is weird case. If the CONFIG_ccc is builtin (=y) this returns true;
+ * or if the CONFIG_ccc is a module (=m) and the caller is built as a module
+ * (-DMODULE defined) this returns true, but if the callers is not a module
+ * (-DMODULE not defined, which means caller is BUILTIN) then it returns
+ * false. In other words, a module can reach the kernel, a module can reach
+ * a module, but the kernel cannot reach a module, and code never compiled
+ * cannot be reached either.
+ * XXX -- I'd hope the module-to-module case would be handled by a proper
+ * module dependency definition (MODULE_DEPEND() in FreeBSD).
+ */
+#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \
+ (IS_MODULE(_x) && IS_BUILTIN(MODULE)))
+
+#endif /* _LINUXKPI_LINUX_KCONFIG_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kdev_t.h b/sys/compat/linuxkpi/common/include/linux/kdev_t.h
index f2a5b53effec..988dd771254a 100644
--- a/sys/compat/linuxkpi/common/include/linux/kdev_t.h
+++ b/sys/compat/linuxkpi/common/include/linux/kdev_t.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KDEV_T_H_
#define _LINUXKPI_LINUX_KDEV_T_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/kernel.h b/sys/compat/linuxkpi/common/include/linux/kernel.h
index 4987c582f0f3..11a13cbd49b4 100644
--- a/sys/compat/linuxkpi/common/include/linux/kernel.h
+++ b/sys/compat/linuxkpi/common/include/linux/kernel.h
@@ -26,13 +26,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KERNEL_H_
#define _LINUXKPI_LINUX_KERNEL_H_
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h>
@@ -44,18 +41,27 @@
#include <sys/time.h>
#include <linux/bitops.h>
+#include <linux/build_bug.h>
#include <linux/compiler.h>
+#include <linux/container_of.h>
+#include <linux/kstrtox.h>
+#include <linux/limits.h>
+#include <linux/math.h>
+#include <linux/minmax.h>
#include <linux/stringify.h>
#include <linux/errno.h>
-#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/typecheck.h>
#include <linux/jiffies.h>
#include <linux/log2.h>
+#include <linux/kconfig.h>
#include <asm/byteorder.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
#include <asm/uaccess.h>
-#include <machine/stdarg.h>
+#include <linux/stdarg.h>
#define KERN_CONT ""
#define KERN_EMERG "<0>"
@@ -67,19 +73,6 @@
#define KERN_INFO "<6>"
#define KERN_DEBUG "<7>"
-#define U8_MAX ((u8)~0U)
-#define S8_MAX ((s8)(U8_MAX >> 1))
-#define S8_MIN ((s8)(-S8_MAX - 1))
-#define U16_MAX ((u16)~0U)
-#define S16_MAX ((s16)(U16_MAX >> 1))
-#define S16_MIN ((s16)(-S16_MAX - 1))
-#define U32_MAX ((u32)~0U)
-#define S32_MAX ((s32)(U32_MAX >> 1))
-#define S32_MIN ((s32)(-S32_MAX - 1))
-#define U64_MAX ((u64)~0ULL)
-#define S64_MAX ((s64)(U64_MAX >> 1))
-#define S64_MIN ((s64)(-S64_MAX - 1))
-
#define S8_C(x) x
#define U8_C(x) x ## U
#define S16_C(x) x
@@ -89,28 +82,6 @@
#define S64_C(x) x ## LL
#define U64_C(x) x ## ULL
-/*
- * BUILD_BUG_ON() can happen inside functions where _Static_assert() does not
- * seem to work. Use old-schoold-ish CTASSERT from before commit
- * a3085588a88fa58eb5b1eaae471999e1995a29cf but also make sure we do not
- * end up with an unused typedef or variable. The compiler should optimise
- * it away entirely.
- */
-#define _O_CTASSERT(x) _O__CTASSERT(x, __LINE__)
-#define _O__CTASSERT(x, y) _O___CTASSERT(x, y)
-#define _O___CTASSERT(x, y) while (0) { \
- typedef char __assert_line_ ## y[(x) ? 1 : -1]; \
- __assert_line_ ## y _x; \
- _x[0] = '\0'; \
-}
-
-#define BUILD_BUG() do { CTASSERT(0); } while (0)
-#define BUILD_BUG_ON(x) do { _O_CTASSERT(!(x)) } while (0)
-#define BUILD_BUG_ON_MSG(x, msg) BUILD_BUG_ON(x)
-#define BUILD_BUG_ON_NOT_POWER_OF_2(x) BUILD_BUG_ON(!powerof2(x))
-#define BUILD_BUG_ON_INVALID(expr) while (0) { (void)(expr); }
-#define BUILD_BUG_ON_ZERO(x) ((int)sizeof(struct { int:-((x) != 0); }))
-
#define BUG() panic("BUG at %s:%d", __FILE__, __LINE__)
#define BUG_ON(cond) do { \
if (cond) { \
@@ -154,15 +125,14 @@ extern int linuxkpi_warn_dump_stack;
#undef PTR_ALIGN
#define PTR_ALIGN(p, a) ((__typeof(p))ALIGN((uintptr_t)(p), (a)))
#define IS_ALIGNED(x, a) (((x) & ((__typeof(x))(a) - 1)) == 0)
-#define DIV_ROUND_UP(x, n) howmany(x, n)
#define __KERNEL_DIV_ROUND_UP(x, n) howmany(x, n)
-#define DIV_ROUND_UP_ULL(x, n) DIV_ROUND_UP((unsigned long long)(x), (n))
-#define DIV_ROUND_DOWN_ULL(x, n) (((unsigned long long)(x) / (n)) * (n))
#define FIELD_SIZEOF(t, f) sizeof(((t *)0)->f)
#define printk(...) printf(__VA_ARGS__)
#define vprintk(f, a) vprintf(f, a)
+#define PTR_IF(x, p) ((x) ? (p) : NULL)
+
#define asm __asm
extern void linux_dump_stack(void);
@@ -293,301 +263,15 @@ extern int linuxkpi_debug;
})
#endif
-#define container_of(ptr, type, member) \
-({ \
- const __typeof(((type *)0)->member) *__p = (ptr); \
- (type *)((uintptr_t)__p - offsetof(type, member)); \
-})
-
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define u64_to_user_ptr(val) ((void *)(uintptr_t)(val))
#define _RET_IP_ __builtin_return_address(0)
-static inline unsigned long long
-simple_strtoull(const char *cp, char **endp, unsigned int base)
-{
- return (strtouq(cp, endp, base));
-}
-
-static inline long long
-simple_strtoll(const char *cp, char **endp, unsigned int base)
-{
- return (strtoq(cp, endp, base));
-}
-
-static inline unsigned long
-simple_strtoul(const char *cp, char **endp, unsigned int base)
-{
- return (strtoul(cp, endp, base));
-}
-
-static inline long
-simple_strtol(const char *cp, char **endp, unsigned int base)
-{
- return (strtol(cp, endp, base));
-}
-
-static inline int
-kstrtoul(const char *cp, unsigned int base, unsigned long *res)
-{
- char *end;
-
- *res = strtoul(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- return (0);
-}
-
-static inline int
-kstrtol(const char *cp, unsigned int base, long *res)
-{
- char *end;
-
- *res = strtol(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- return (0);
-}
-
-static inline int
-kstrtoint(const char *cp, unsigned int base, int *res)
-{
- char *end;
- long temp;
-
- *res = temp = strtol(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- if (temp != (int)temp)
- return (-ERANGE);
- return (0);
-}
-
-static inline int
-kstrtouint(const char *cp, unsigned int base, unsigned int *res)
-{
- char *end;
- unsigned long temp;
-
- *res = temp = strtoul(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- if (temp != (unsigned int)temp)
- return (-ERANGE);
- return (0);
-}
-
-static inline int
-kstrtou8(const char *cp, unsigned int base, u8 *res)
-{
- char *end;
- unsigned long temp;
-
- *res = temp = strtoul(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- if (temp != (u8)temp)
- return (-ERANGE);
- return (0);
-}
-
-static inline int
-kstrtou16(const char *cp, unsigned int base, u16 *res)
-{
- char *end;
- unsigned long temp;
-
- *res = temp = strtoul(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- if (temp != (u16)temp)
- return (-ERANGE);
- return (0);
-}
-
-static inline int
-kstrtou32(const char *cp, unsigned int base, u32 *res)
-{
- char *end;
- unsigned long temp;
-
- *res = temp = strtoul(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- if (temp != (u32)temp)
- return (-ERANGE);
- return (0);
-}
-
-static inline int
-kstrtou64(const char *cp, unsigned int base, u64 *res)
-{
- char *end;
-
- *res = strtouq(cp, &end, base);
-
- /* skip newline character, if any */
- if (*end == '\n')
- end++;
- if (*cp == 0 || *end != 0)
- return (-EINVAL);
- return (0);
-}
-
-static inline int
-kstrtoull(const char *cp, unsigned int base, unsigned long long *res)
-{
- return (kstrtou64(cp, base, (u64 *)res));
-}
-
-static inline int
-kstrtobool(const char *s, bool *res)
-{
- int len;
-
- if (s == NULL || (len = strlen(s)) == 0 || res == NULL)
- return (-EINVAL);
-
- /* skip newline character, if any */
- if (s[len - 1] == '\n')
- len--;
-
- if (len == 1 && strchr("yY1", s[0]) != NULL)
- *res = true;
- else if (len == 1 && strchr("nN0", s[0]) != NULL)
- *res = false;
- else if (strncasecmp("on", s, len) == 0)
- *res = true;
- else if (strncasecmp("off", s, len) == 0)
- *res = false;
- else
- return (-EINVAL);
-
- return (0);
-}
-
-static inline int
-kstrtobool_from_user(const char __user *s, size_t count, bool *res)
-{
- char buf[8] = {};
-
- if (count > (sizeof(buf) - 1))
- count = (sizeof(buf) - 1);
-
- if (copy_from_user(buf, s, count))
- return (-EFAULT);
-
- return (kstrtobool(buf, res));
-}
-
-static inline int
-kstrtoint_from_user(const char __user *s, size_t count, unsigned int base,
- int *p)
-{
- char buf[36] = {};
-
- if (count > (sizeof(buf) - 1))
- count = (sizeof(buf) - 1);
-
- if (copy_from_user(buf, s, count))
- return (-EFAULT);
-
- return (kstrtoint(buf, base, p));
-}
-
-static inline int
-kstrtouint_from_user(const char __user *s, size_t count, unsigned int base,
- int *p)
-{
- char buf[36] = {};
-
- if (count > (sizeof(buf) - 1))
- count = (sizeof(buf) - 1);
-
- if (copy_from_user(buf, s, count))
- return (-EFAULT);
-
- return (kstrtouint(buf, base, p));
-}
-
-static inline int
-kstrtou8_from_user(const char __user *s, size_t count, unsigned int base,
- u8 *p)
-{
- char buf[8] = {};
-
- if (count > (sizeof(buf) - 1))
- count = (sizeof(buf) - 1);
-
- if (copy_from_user(buf, s, count))
- return (-EFAULT);
-
- return (kstrtou8(buf, base, p));
-}
-
-#define min(x, y) ((x) < (y) ? (x) : (y))
-#define max(x, y) ((x) > (y) ? (x) : (y))
-
-#define min3(a, b, c) min(a, min(b,c))
-#define max3(a, b, c) max(a, max(b,c))
-
-#define min_t(type, x, y) ({ \
- type __min1 = (x); \
- type __min2 = (y); \
- __min1 < __min2 ? __min1 : __min2; })
-
-#define max_t(type, x, y) ({ \
- type __max1 = (x); \
- type __max2 = (y); \
- __max1 > __max2 ? __max1 : __max2; })
-
#define offsetofend(t, m) \
(offsetof(t, m) + sizeof((((t *)0)->m)))
-#define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max)
-#define clamp(x, lo, hi) min( max(x,lo), hi)
-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
-
-/*
- * This looks more complex than it should be. But we need to
- * get the type for the ~ right in round_down (it needs to be
- * as wide as the result!), and we want to evaluate the macro
- * arguments just once each.
- */
-#define __round_mask(x, y) ((__typeof__(x))((y)-1))
-#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
-#define round_down(x, y) ((x) & ~__round_mask(x, y))
-
#define smp_processor_id() PCPU_GET(cpuid)
#define num_possible_cpus() mp_ncpus
#define num_online_cpus() mp_ncpus
@@ -597,37 +281,6 @@ extern bool linux_cpu_has_clflush;
#define cpu_has_clflush linux_cpu_has_clflush
#endif
-/* Swap values of a and b */
-#define swap(a, b) do { \
- typeof(a) _swap_tmp = a; \
- a = b; \
- b = _swap_tmp; \
-} while (0)
-
-#define DIV_ROUND_CLOSEST(x, divisor) (((x) + ((divisor) / 2)) / (divisor))
-
-#define DIV_ROUND_CLOSEST_ULL(x, divisor) ({ \
- __typeof(divisor) __d = (divisor); \
- unsigned long long __ret = (x) + (__d) / 2; \
- __ret /= __d; \
- __ret; \
-})
-
-static inline uintmax_t
-mult_frac(uintmax_t x, uintmax_t multiplier, uintmax_t divisor)
-{
- uintmax_t q = (x / divisor);
- uintmax_t r = (x % divisor);
-
- return ((q * multiplier) + ((r * multiplier) / divisor));
-}
-
-static inline int64_t
-abs64(int64_t x)
-{
- return (x < 0 ? -x : x);
-}
-
typedef struct linux_ratelimit {
struct timeval lasttime;
int counter;
@@ -639,12 +292,6 @@ linux_ratelimited(linux_ratelimit_t *rl)
return (ppsratecheck(&rl->lasttime, &rl->counter, 1));
}
-#define struct_size(ptr, field, num) ({ \
- const size_t __size = offsetof(__typeof(*(ptr)), field); \
- const size_t __max = (SIZE_MAX - __size) / sizeof((ptr)->field[0]); \
- ((num) > __max) ? SIZE_MAX : (__size + sizeof((ptr)->field[0]) * (num)); \
-})
-
#define __is_constexpr(x) \
__builtin_constant_p(x)
@@ -654,31 +301,10 @@ linux_ratelimited(linux_ratelimit_t *rl)
*/
#define is_signed(datatype) (((datatype)-1 / (datatype)2) == (datatype)0)
-/*
- * The type_max() macro below returns the maxium positive value the
- * passed data type can hold.
- */
-#define type_max(datatype) ( \
- (sizeof(datatype) >= 8) ? (is_signed(datatype) ? INT64_MAX : UINT64_MAX) : \
- (sizeof(datatype) >= 4) ? (is_signed(datatype) ? INT32_MAX : UINT32_MAX) : \
- (sizeof(datatype) >= 2) ? (is_signed(datatype) ? INT16_MAX : UINT16_MAX) : \
- (is_signed(datatype) ? INT8_MAX : UINT8_MAX) \
-)
-
-/*
- * The type_min() macro below returns the minimum value the passed
- * data type can hold. For unsigned types the minimum value is always
- * zero. For signed types it may vary.
- */
-#define type_min(datatype) ( \
- (sizeof(datatype) >= 8) ? (is_signed(datatype) ? INT64_MIN : 0) : \
- (sizeof(datatype) >= 4) ? (is_signed(datatype) ? INT32_MIN : 0) : \
- (sizeof(datatype) >= 2) ? (is_signed(datatype) ? INT16_MIN : 0) : \
- (is_signed(datatype) ? INT8_MIN : 0) \
-)
-
#define TAINT_WARN 0
#define test_taint(x) (0)
+#define add_taint(x,y) do { \
+ } while (0)
static inline int
_h2b(const char c)
@@ -711,49 +337,49 @@ hex2bin(uint8_t *bindst, const char *hexsrc, size_t binlen)
return (0);
}
+static inline bool
+mac_pton(const char *macin, uint8_t *macout)
+{
+ const char *s, *d;
+ uint8_t mac[6], hx, lx;
+ int i;
+
+ if (strlen(macin) < (3 * 6 - 1))
+ return (false);
+
+ i = 0;
+ s = macin;
+ do {
+ /* Should we also support '-'-delimiters? */
+ d = strchrnul(s, ':');
+ hx = lx = 0;
+ while (s < d) {
+ /* Fail on abc:123:xxx:... */
+ if ((d - s) > 2)
+ return (false);
+ /* We do support non-well-formed strings: 3:45:6:... */
+ if ((d - s) > 1) {
+ hx = _h2b(*s);
+ if (hx < 0)
+ return (false);
+ s++;
+ }
+ lx = _h2b(*s);
+ if (lx < 0)
+ return (false);
+ s++;
+ }
+ mac[i] = (hx << 4) | lx;
+ i++;
+ if (i >= 6)
+ return (false);
+ } while (d != NULL && *d != '\0');
+
+ memcpy(macout, mac, 6);
+ return (true);
+}
+
#define DECLARE_FLEX_ARRAY(_t, _n) \
struct { struct { } __dummy_ ## _n; _t _n[0]; }
-/*
- * Checking if an option is defined would be easy if we could do CPP inside CPP.
- * The defined case whether -Dxxx or -Dxxx=1 are easy to deal with. In either
- * case the defined value is "1". A more general -Dxxx=<c> case will require
- * more effort to deal with all possible "true" values. Hope we do not have
- * to do this as well.
- * The real problem is the undefined case. To avoid this problem we do the
- * concat/varargs trick: "yyy" ## xxx can make two arguments if xxx is "1"
- * by having a #define for yyy_1 which is "ignore,".
- * Otherwise we will just get "yyy".
- * Need to be careful about variable substitutions in macros though.
- * This way we make a (true, false) problem a (don't care, true, false) or a
- * (don't care true, false). Then we can use a variadic macro to only select
- * the always well known and defined argument #2. And that seems to be
- * exactly what we need. Use 1 for true and 0 for false to also allow
- * #if IS_*() checks pre-compiler checks which do not like #if true.
- */
-#define ___XAB_1 dontcare,
-#define ___IS_XAB(_ignore, _x, ...) (_x)
-#define __IS_XAB(_x) ___IS_XAB(_x 1, 0)
-#define _IS_XAB(_x) __IS_XAB(__CONCAT(___XAB_, _x))
-
-/* This is if CONFIG_ccc=y. */
-#define IS_BUILTIN(_x) _IS_XAB(_x)
-/* This is if CONFIG_ccc=m. */
-#define IS_MODULE(_x) _IS_XAB(_x ## _MODULE)
-/* This is if CONFIG_ccc is compiled in(=y) or a module(=m). */
-#define IS_ENABLED(_x) (IS_BUILTIN(_x) || IS_MODULE(_x))
-/*
- * This is weird case. If the CONFIG_ccc is builtin (=y) this returns true;
- * or if the CONFIG_ccc is a module (=m) and the caller is built as a module
- * (-DMODULE defined) this returns true, but if the callers is not a module
- * (-DMODULE not defined, which means caller is BUILTIN) then it returns
- * false. In other words, a module can reach the kernel, a module can reach
- * a module, but the kernel cannot reach a module, and code never compiled
- * cannot be reached either.
- * XXX -- I'd hope the module-to-module case would be handled by a proper
- * module dependency definition (MODULE_DEPEND() in FreeBSD).
- */
-#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \
- (IS_MODULE(_x) && IS_BUILTIN(MODULE)))
-
#endif /* _LINUXKPI_LINUX_KERNEL_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kernel_stat.h b/sys/compat/linuxkpi/common/include/linux/kernel_stat.h
new file mode 100644
index 000000000000..c960b4ad2cff
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/kernel_stat.h
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_KERNEL_STAT_H_
+#define _LINUXKPI_LINUX_KERNEL_STAT_H_
+
+#include <linux/interrupt.h>
+
+#endif /* _LINUXKPI_LINUX_KERNEL_STAT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kfifo.h b/sys/compat/linuxkpi/common/include/linux/kfifo.h
index 6ba1528d965c..d2f570781661 100644
--- a/sys/compat/linuxkpi/common/include/linux/kfifo.h
+++ b/sys/compat/linuxkpi/common/include/linux/kfifo.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Copyright (c) 2022 Bjoern A. Zeeb
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,7 +28,95 @@
#ifndef _LINUXKPI_LINUX_KFIFO_H_
#define _LINUXKPI_LINUX_KFIFO_H_
+#include <sys/types.h>
+
+#include <linux/slab.h>
+#include <linux/gfp.h>
+
#define INIT_KFIFO(x) 0
#define DECLARE_KFIFO(x, y, z)
+#define DECLARE_KFIFO_PTR(_name, _type) \
+ struct kfifo_ ## _name { \
+ size_t total; \
+ size_t count; \
+ size_t first; \
+ size_t last; \
+ _type *head; \
+ } _name
+
+#define kfifo_len(_kf) \
+({ \
+ (_kf)->count; \
+})
+
+#define kfifo_is_empty(_kf) \
+({ \
+ ((_kf)->count == 0) ? true : false; \
+})
+
+#define kfifo_is_full(_kf) \
+({ \
+ ((_kf)->count == (_kf)->total) ? true : false; \
+})
+
+#define kfifo_put(_kf, _e) \
+({ \
+ bool _rc; \
+ \
+ /* Would overflow. */ \
+ if (kfifo_is_full(_kf)) { \
+ _rc = false; \
+ } else { \
+ (_kf)->head[(_kf)->last] = (_e); \
+ (_kf)->count++; \
+ (_kf)->last++; \
+ if ((_kf)->last > (_kf)->total) \
+ (_kf)->last = 0; \
+ _rc = true; \
+ } \
+ \
+ _rc; \
+})
+
+#define kfifo_get(_kf, _e) \
+({ \
+ bool _rc; \
+ \
+ if (kfifo_is_empty(_kf)) { \
+ _rc = false; \
+ } else { \
+ *(_e) = (_kf)->head[(_kf)->first]; \
+ (_kf)->count--; \
+ (_kf)->first++; \
+ if ((_kf)->first > (_kf)->total) \
+ (_kf)->first = 0; \
+ _rc = true; \
+ } \
+ \
+ _rc; \
+})
+
+#define kfifo_alloc(_kf, _s, _gfp) \
+({ \
+ int _error; \
+ \
+ (_kf)->head = kmalloc(sizeof(__typeof(*(_kf)->head)) * (_s), _gfp); \
+ if ((_kf)->head == NULL) \
+ _error = ENOMEM; \
+ else { \
+ (_kf)->total = (_s); \
+ _error = 0; \
+ } \
+ \
+ _error; \
+})
+
+#define kfifo_free(_kf) \
+({ \
+ kfree((_kf)->head); \
+ (_kf)->head = NULL; \
+ (_kf)->total = (_kf)->count = (_kf)->first = (_kf)->last = 0; \
+})
+
#endif /* _LINUXKPI_LINUX_KFIFO_H_*/
diff --git a/sys/compat/linuxkpi/common/include/linux/kmod.h b/sys/compat/linuxkpi/common/include/linux/kmod.h
index b8e8a483210f..8f9f034aabd8 100644
--- a/sys/compat/linuxkpi/common/include/linux/kmod.h
+++ b/sys/compat/linuxkpi/common/include/linux/kmod.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KMOD_H_
#define _LINUXKPI_LINUX_KMOD_H_
@@ -35,15 +33,14 @@
#include <sys/syscallsubr.h>
#include <sys/refcount.h>
#include <sys/sbuf.h>
-#include <machine/stdarg.h>
+#include <sys/stdarg.h>
#include <sys/proc.h>
#define request_module(...) \
({\
char modname[128]; \
- int fileid; \
snprintf(modname, sizeof(modname), __VA_ARGS__); \
- kern_kldload(curthread, modname, &fileid); \
+ kern_kldload(curthread, modname, NULL); \
})
#define request_module_nowait request_module
diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h
index ad25058028fc..98f55d1234c4 100644
--- a/sys/compat/linuxkpi/common/include/linux/kobject.h
+++ b/sys/compat/linuxkpi/common/include/linux/kobject.h
@@ -25,20 +25,22 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KOBJECT_H_
#define _LINUXKPI_LINUX_KOBJECT_H_
-#include <machine/stdarg.h>
+#include <sys/stdarg.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
struct kobject;
+struct kset;
struct sysctl_oid;
#define KOBJ_CHANGE 0x01
@@ -47,6 +49,7 @@ struct kobj_type {
void (*release)(struct kobject *kobj);
const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
+ const struct attribute_group **default_groups;
};
extern const struct kobj_type linux_kfree_type;
@@ -58,6 +61,7 @@ struct kobject {
const struct kobj_type *ktype;
struct list_head entry;
struct sysctl_oid *oidp;
+ struct kset *kset;
};
extern struct kobject *mm_kobj;
@@ -78,6 +82,17 @@ struct kobj_attribute {
const char *buf, size_t count);
};
+struct kset_uevent_ops {
+ /* TODO */
+};
+
+struct kset {
+ struct list_head list;
+ spinlock_t list_lock;
+ struct kobject kobj;
+ const struct kset_uevent_ops *uevent_ops;
+};
+
static inline void
kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
{
@@ -155,4 +170,41 @@ kobject_uevent_env(struct kobject *kobj, int action, char *envp[])
*/
}
+void kset_init(struct kset *kset);
+int kset_register(struct kset *kset);
+void kset_unregister(struct kset *kset);
+struct kset * kset_create_and_add(const char *name,
+ const struct kset_uevent_ops *u, struct kobject *parent_kobj);
+
+static inline struct kset *
+to_kset(struct kobject *kobj)
+{
+ if (kobj != NULL)
+ return container_of(kobj, struct kset, kobj);
+ else
+ return NULL;
+}
+
+static inline struct kset *
+kset_get(struct kset *kset)
+{
+ if (kset != NULL) {
+ struct kobject *kobj;
+
+ kobj = kobject_get(&kset->kobj);
+ return to_kset(kobj);
+ } else {
+ return NULL;
+ }
+}
+
+static inline void
+kset_put(struct kset *kset)
+{
+ if (kset != NULL)
+ kobject_put(&kset->kobj);
+}
+
+void linux_kobject_kfree_name(struct kobject *kobj);
+
#endif /* _LINUXKPI_LINUX_KOBJECT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kref.h b/sys/compat/linuxkpi/common/include/linux/kref.h
index 2c59794f4ddc..b2fba468f7df 100644
--- a/sys/compat/linuxkpi/common/include/linux/kref.h
+++ b/sys/compat/linuxkpi/common/include/linux/kref.h
@@ -26,8 +26,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KREF_H_
#define _LINUXKPI_LINUX_KREF_H_
@@ -43,35 +41,35 @@
#include <asm/atomic.h>
struct kref {
- atomic_t refcount;
+ refcount_t refcount;
};
static inline void
kref_init(struct kref *kref)
{
- refcount_init(&kref->refcount.counter, 1);
+ refcount_init((uint32_t *)&kref->refcount, 1);
}
static inline unsigned int
kref_read(const struct kref *kref)
{
- return (atomic_read(&kref->refcount));
+ return (refcount_load(__DECONST(u_int32_t *, &kref->refcount)));
}
static inline void
kref_get(struct kref *kref)
{
- refcount_acquire(&kref->refcount.counter);
+ refcount_acquire((uint32_t *)&kref->refcount);
}
static inline int
kref_put(struct kref *kref, void (*rel)(struct kref *kref))
{
- if (refcount_release(&kref->refcount.counter)) {
+ if (refcount_release((uint32_t *)&kref->refcount)) {
rel(kref);
return 1;
}
@@ -83,7 +81,7 @@ kref_put_lock(struct kref *kref, void (*rel)(struct kref *kref),
spinlock_t *lock)
{
- if (refcount_release(&kref->refcount.counter)) {
+ if (refcount_release((uint32_t *)&kref->refcount)) {
spin_lock(lock);
rel(kref);
return (1);
@@ -97,7 +95,7 @@ kref_sub(struct kref *kref, unsigned int count,
{
while (count--) {
- if (refcount_release(&kref->refcount.counter)) {
+ if (refcount_release((uint32_t *)&kref->refcount)) {
rel(kref);
return 1;
}
@@ -109,16 +107,16 @@ static inline int __must_check
kref_get_unless_zero(struct kref *kref)
{
- return atomic_add_unless(&kref->refcount, 1, 0);
+ return refcount_acquire_if_not_zero((uint32_t *)&kref->refcount);
}
static inline int kref_put_mutex(struct kref *kref,
void (*release)(struct kref *kref), struct mutex *lock)
{
WARN_ON(release == NULL);
- if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
+ if (unlikely(!refcount_release_if_not_last((uint32_t *)&kref->refcount))) {
mutex_lock(lock);
- if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
+ if (unlikely(!refcount_release((uint32_t *)&kref->refcount))) {
mutex_unlock(lock);
return 0;
}
diff --git a/sys/compat/linuxkpi/common/include/linux/kstrtox.h b/sys/compat/linuxkpi/common/include/linux/kstrtox.h
new file mode 100644
index 000000000000..5da99de24197
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/kstrtox.h
@@ -0,0 +1,324 @@
+/*-
+ * Copyright (c) 2010 Isilon Systems, Inc.
+ * Copyright (c) 2010 iX Systems, Inc.
+ * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2017-2018 Mellanox Technologies, Ltd.
+ * All rights reserved.
+ * Copyright (c) 2018 Johannes Lundberg <johalun0@gmail.com>
+ * Copyright (c) 2020-2022 The FreeBSD Foundation
+ * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
+ * Copyright (c) 2023 Serenity Cyber Security, LLC
+ *
+ * Portions of this software were developed by Bjoern A. Zeeb and
+ * Emmanuel Vadot under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_KSTRTOX_H_
+#define _LINUXKPI_LINUX_KSTRTOX_H_
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/libkern.h>
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#include <asm/uaccess.h>
+
+static inline unsigned long long
+simple_strtoull(const char *cp, char **endp, unsigned int base)
+{
+ return (strtouq(cp, endp, base));
+}
+
+static inline long long
+simple_strtoll(const char *cp, char **endp, unsigned int base)
+{
+ return (strtoq(cp, endp, base));
+}
+
+static inline unsigned long
+simple_strtoul(const char *cp, char **endp, unsigned int base)
+{
+ return (strtoul(cp, endp, base));
+}
+
+static inline long
+simple_strtol(const char *cp, char **endp, unsigned int base)
+{
+ return (strtol(cp, endp, base));
+}
+
+static inline int
+kstrtoul(const char *cp, unsigned int base, unsigned long *res)
+{
+ char *end;
+
+ *res = strtoul(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ return (0);
+}
+
+static inline int
+kstrtol(const char *cp, unsigned int base, long *res)
+{
+ char *end;
+
+ *res = strtol(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ return (0);
+}
+
+static inline int
+kstrtoint(const char *cp, unsigned int base, int *res)
+{
+ char *end;
+ long temp;
+
+ *res = temp = strtol(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ if (temp != (int)temp)
+ return (-ERANGE);
+ return (0);
+}
+
+static inline int
+kstrtouint(const char *cp, unsigned int base, unsigned int *res)
+{
+ char *end;
+ unsigned long temp;
+
+ *res = temp = strtoul(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ if (temp != (unsigned int)temp)
+ return (-ERANGE);
+ return (0);
+}
+
+static inline int
+kstrtou8(const char *cp, unsigned int base, uint8_t *res)
+{
+ char *end;
+ unsigned long temp;
+
+ *res = temp = strtoul(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ if (temp != (uint8_t)temp)
+ return (-ERANGE);
+ return (0);
+}
+
+static inline int
+kstrtou16(const char *cp, unsigned int base, uint16_t *res)
+{
+ char *end;
+ unsigned long temp;
+
+ *res = temp = strtoul(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ if (temp != (uint16_t)temp)
+ return (-ERANGE);
+ return (0);
+}
+
+static inline int
+kstrtou32(const char *cp, unsigned int base, uint32_t *res)
+{
+
+ return (kstrtouint(cp, base, res));
+}
+
+static inline int
+kstrtos32(const char *cp, unsigned int base, int32_t *res)
+{
+
+ return (kstrtoint(cp, base, res));
+}
+
+static inline int
+kstrtos64(const char *cp, unsigned int base, int64_t *res)
+{
+ char *end;
+
+ *res = strtoq(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ return (0);
+}
+
+static inline int
+kstrtoll(const char *cp, unsigned int base, long long *res)
+{
+ return (kstrtos64(cp, base, (int64_t *)res));
+}
+
+static inline int
+kstrtou64(const char *cp, unsigned int base, u64 *res)
+{
+ char *end;
+
+ *res = strtouq(cp, &end, base);
+
+ /* skip newline character, if any */
+ if (*end == '\n')
+ end++;
+ if (*cp == 0 || *end != 0)
+ return (-EINVAL);
+ return (0);
+}
+
+static inline int
+kstrtoull(const char *cp, unsigned int base, unsigned long long *res)
+{
+ return (kstrtou64(cp, base, (uint64_t *)res));
+}
+
+static inline int
+kstrtobool(const char *s, bool *res)
+{
+ int len;
+
+ if (s == NULL || (len = strlen(s)) == 0 || res == NULL)
+ return (-EINVAL);
+
+ /* skip newline character, if any */
+ if (s[len - 1] == '\n')
+ len--;
+
+ if (len == 1 && strchr("yY1", s[0]) != NULL)
+ *res = true;
+ else if (len == 1 && strchr("nN0", s[0]) != NULL)
+ *res = false;
+ else if (strncasecmp("on", s, len) == 0)
+ *res = true;
+ else if (strncasecmp("off", s, len) == 0)
+ *res = false;
+ else
+ return (-EINVAL);
+
+ return (0);
+}
+
+static inline int
+kstrtobool_from_user(const char __user *s, size_t count, bool *res)
+{
+ char buf[8] = {};
+
+ if (count > (sizeof(buf) - 1))
+ count = (sizeof(buf) - 1);
+
+ if (copy_from_user(buf, s, count))
+ return (-EFAULT);
+
+ return (kstrtobool(buf, res));
+}
+
+static inline int
+kstrtoint_from_user(const char __user *s, size_t count, unsigned int base,
+ int *p)
+{
+ char buf[36] = {};
+
+ if (count > (sizeof(buf) - 1))
+ count = (sizeof(buf) - 1);
+
+ if (copy_from_user(buf, s, count))
+ return (-EFAULT);
+
+ return (kstrtoint(buf, base, p));
+}
+
+static inline int
+kstrtouint_from_user(const char __user *s, size_t count, unsigned int base,
+ unsigned int *p)
+{
+ char buf[36] = {};
+
+ if (count > (sizeof(buf) - 1))
+ count = (sizeof(buf) - 1);
+
+ if (copy_from_user(buf, s, count))
+ return (-EFAULT);
+
+ return (kstrtouint(buf, base, p));
+}
+
+static inline int
+kstrtou32_from_user(const char __user *s, size_t count, unsigned int base,
+ unsigned int *p)
+{
+
+ return (kstrtouint_from_user(s, count, base, p));
+}
+
+static inline int
+kstrtou8_from_user(const char __user *s, size_t count, unsigned int base,
+ uint8_t *p)
+{
+ char buf[8] = {};
+
+ if (count > (sizeof(buf) - 1))
+ count = (sizeof(buf) - 1);
+
+ if (copy_from_user(buf, s, count))
+ return (-EFAULT);
+
+ return (kstrtou8(buf, base, p));
+}
+
+#endif /* _LINUXKPI_LINUX_KSTRTOX_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kthread.h b/sys/compat/linuxkpi/common/include/linux/kthread.h
index 49309cd47a40..1fde734fd767 100644
--- a/sys/compat/linuxkpi/common/include/linux/kthread.h
+++ b/sys/compat/linuxkpi/common/include/linux/kthread.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KTHREAD_H_
#define _LINUXKPI_LINUX_KTHREAD_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/ktime.h b/sys/compat/linuxkpi/common/include/linux/ktime.h
index e0722aa2589b..6a2f04f3d789 100644
--- a/sys/compat/linuxkpi/common/include/linux/ktime.h
+++ b/sys/compat/linuxkpi/common/include/linux/ktime.h
@@ -24,8 +24,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_KTIME_H
@@ -71,6 +69,12 @@ ktime_to_ms(ktime_t kt)
return (ktime_divns(kt, NSEC_PER_MSEC));
}
+static inline ktime_t
+ms_to_ktime(uint64_t ms)
+{
+ return (ms * NSEC_PER_MSEC);
+}
+
static inline struct timeval
ktime_to_timeval(ktime_t kt)
{
@@ -190,6 +194,7 @@ timespec64_to_ns(struct timespec64 *ts)
#define ktime_get_ts(ts) getnanouptime(ts)
#define ktime_get_ts64(ts) getnanouptime(ts)
#define ktime_get_raw_ts64(ts) getnanouptime(ts)
+#define ktime_get_real_ts64(ts) getnanotime(ts)
#define getrawmonotonic64(ts) getnanouptime(ts)
static inline int64_t
@@ -227,6 +232,13 @@ ktime_get_boottime_ns(void)
return (ktime_to_ns(ktime_get_boottime()));
}
+static inline uint64_t
+ktime_get_boottime_seconds(void)
+{
+
+ return (ktime_divns(ktime_get_boottime(), NSEC_PER_SEC));
+}
+
static inline ktime_t
ktime_get_real(void)
{
@@ -263,4 +275,13 @@ ktime_get_raw_ns(void)
return (ktime_to_ns(timespec_to_ktime(ts)));
}
+static inline uint64_t
+ktime_get_raw_fast_ns(void)
+{
+ struct timespec ts;
+
+ getnanouptime(&ts);
+ return (ktime_to_ns(timespec_to_ktime(ts)));
+}
+
#endif /* _LINUXKPI_LINUX_KTIME_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/leds.h b/sys/compat/linuxkpi/common/include/linux/leds.h
new file mode 100644
index 000000000000..89f7286f6800
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/leds.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2022 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_LEDS_H
+#define _LINUXKPI_LINUX_LEDS_H
+
+enum led_brightness {
+ LED_OFF,
+};
+
+struct led_classdev {
+ const char *name;
+ const char *default_trigger;
+ int (*blink_set)(struct led_classdev *, unsigned long *, unsigned long *);
+ void (*brightness_set)(struct led_classdev *, enum led_brightness);
+ void (*led_set)(struct led_classdev *, enum led_brightness);
+};
+
+#endif /* _LINUXKPI_LINUX_LEDS_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/limits.h b/sys/compat/linuxkpi/common/include/linux/limits.h
new file mode 100644
index 000000000000..716366033bb3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/limits.h
@@ -0,0 +1,47 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_LIMITS_H
+#define _LINUXKPI_LINUX_LIMITS_H
+
+#include <sys/types.h>
+#include <sys/stdint.h>
+
+#define U8_MAX UINT8_MAX
+#define S8_MAX INT8_MAX
+#define S8_MIN INT8_MIN
+#define U16_MAX UINT16_MAX
+#define S16_MAX INT16_MAX
+#define S16_MIN INT16_MIN
+#define U32_MAX UINT32_MAX
+#define S32_MAX INT32_MAX
+#define S32_MIN INT32_MIN
+#define U64_MAX UINT64_MAX
+#define S64_MAX INT64_MAX
+#define S64_MIN INT64_MIN
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/list.h b/sys/compat/linuxkpi/common/include/linux/list.h
index 80ac57fecf6d..a6c74a324dac 100644
--- a/sys/compat/linuxkpi/common/include/linux/list.h
+++ b/sys/compat/linuxkpi/common/include/linux/list.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_LIST_H_
#define _LINUXKPI_LINUX_LIST_H_
@@ -86,14 +84,6 @@
#define LINUX_LIST_HEAD(name) \
struct list_head name = LINUX_LIST_HEAD_INIT(name)
-#ifndef LIST_HEAD_DEF
-#define LIST_HEAD_DEF
-struct list_head {
- struct list_head *next;
- struct list_head *prev;
-};
-#endif
-
static inline void
INIT_LIST_HEAD(struct list_head *list)
{
@@ -154,7 +144,7 @@ list_replace_init(struct list_head *old, struct list_head *new)
}
static inline void
-linux_list_add(struct list_head *new, struct list_head *prev,
+__list_add(struct list_head *new, struct list_head *prev,
struct list_head *next)
{
@@ -235,22 +225,32 @@ list_del_init(struct list_head *entry)
#define list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = (p)->prev)
+#define list_for_each_prev_safe(p, n, h) \
+ for (p = (h)->prev, n = (p)->prev; \
+ p != (h); \
+ p = n, n = (p)->prev)
+
#define list_for_each_entry_from_reverse(p, h, field) \
for (; &p->field != (h); \
p = list_prev_entry(p, field))
+#define list_for_each_rcu(p, head) \
+ for (p = rcu_dereference((head)->next); \
+ p != (head); \
+ p = rcu_dereference((p)->next))
+
static inline void
list_add(struct list_head *new, struct list_head *head)
{
- linux_list_add(new, head, head->next);
+ __list_add(new, head, head->next);
}
static inline void
list_add_tail(struct list_head *new, struct list_head *head)
{
- linux_list_add(new, head->prev, head);
+ __list_add(new, head->prev, head);
}
static inline void
@@ -474,6 +474,20 @@ static inline int list_is_last(const struct list_head *list,
return list->next == head;
}
+static inline size_t
+list_count_nodes(const struct list_head *list)
+{
+ const struct list_head *lh;
+ size_t count;
+
+ count = 0;
+ list_for_each(lh, list) {
+ count++;
+ }
+
+ return (count);
+}
+
#define hlist_entry(ptr, type, field) container_of(ptr, type, field)
#define hlist_for_each(p, head) \
@@ -504,7 +518,12 @@ static inline int list_is_last(const struct list_head *list,
(pos) && ({ n = (pos)->member.next; 1; }); \
pos = hlist_entry_safe(n, typeof(*(pos)), member))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv,
+ const struct list_head *a, const struct list_head *b));
+#else
extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv,
struct list_head *a, struct list_head *b));
+#endif
#endif /* _LINUXKPI_LINUX_LIST_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/lockdep.h b/sys/compat/linuxkpi/common/include/linux/lockdep.h
index 2289db7756d4..93fe445f7057 100644
--- a/sys/compat/linuxkpi/common/include/linux/lockdep.h
+++ b/sys/compat/linuxkpi/common/include/linux/lockdep.h
@@ -25,13 +25,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_LOCKDEP_H_
#define _LINUXKPI_LINUX_LOCKDEP_H_
+#include <sys/systm.h>
#include <sys/types.h>
#include <sys/lock.h>
@@ -48,8 +47,13 @@ struct pin_cookie {
#define lockdep_set_current_reclaim_state(g) do { } while (0)
#define lockdep_clear_current_reclaim_state() do { } while (0)
#define lockdep_init_map(_map, _name, _key, _x) do { } while(0)
+#define lockdep_register_key(key) do { } while(0)
+#define lockdep_unregister_key(key) do { } while(0)
#ifdef INVARIANTS
+#define lockdep_assert(cond) do { WARN_ON(!(cond)); } while (0)
+#define lockdep_assert_once(cond) do { WARN_ON_ONCE(!(cond)); } while (0)
+
#define lockdep_assert_not_held(m) do { \
struct lock_object *__lock = (struct lock_object *)(m); \
LOCK_CLASS(__lock)->lc_assert(__lock, LA_UNLOCKED); \
@@ -65,26 +69,34 @@ struct pin_cookie {
LOCK_CLASS(__lock)->lc_assert(__lock, LA_LOCKED | LA_NOTRECURSED); \
} while (0)
+#define lockdep_assert_none_held_once() do { } while (0)
+
+#else
+#define lockdep_assert(cond) do { } while (0)
+#define lockdep_assert_once(cond) do { } while (0)
+
+#define lockdep_assert_not_held(m) do { (void)(m); } while (0)
+#define lockdep_assert_held(m) do { (void)(m); } while (0)
+#define lockdep_assert_none_held_once() do { } while (0)
+
+#define lockdep_assert_held_once(m) do { (void)(m); } while (0)
+
+#endif
+
static __inline bool
-lockdep_is_held(void *__m)
+lockdep_is_held(void *__m __diagused)
{
+#ifdef INVARIANTS
struct lock_object *__lock;
struct thread *__td;
__lock = __m;
return (LOCK_CLASS(__lock)->lc_owner(__lock, &__td) != 0);
-}
-#define lockdep_is_held_type(_m, _t) lockdep_is_held(_m)
-
#else
-#define lockdep_assert_not_held(m) do { (void)(m); } while (0)
-#define lockdep_assert_held(m) do { (void)(m); } while (0)
-
-#define lockdep_assert_held_once(m) do { (void)(m); } while (0)
-
-#define lockdep_is_held(m) 1
-#define lockdep_is_held_type(_m, _t) 1
+ return (true);
#endif
+}
+#define lockdep_is_held_type(_m, _t) lockdep_is_held(_m)
#define might_lock(m) do { } while (0)
#define might_lock_read(m) do { } while (0)
diff --git a/sys/compat/linuxkpi/common/include/linux/log2.h b/sys/compat/linuxkpi/common/include/linux/log2.h
index 4c356136ca98..660e9adb6fa9 100644
--- a/sys/compat/linuxkpi/common/include/linux/log2.h
+++ b/sys/compat/linuxkpi/common/include/linux/log2.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_LOG2_H_
#define _LINUXKPI_LINUX_LOG2_H_
@@ -35,97 +33,9 @@
#include <sys/libkern.h>
-static inline unsigned long
-roundup_pow_of_two(unsigned long x)
-{
- return (1UL << flsl(x - 1));
-}
-
-static inline int
-is_power_of_2(unsigned long n)
-{
- return (n == roundup_pow_of_two(n));
-}
-
-static inline unsigned long
-rounddown_pow_of_two(unsigned long x)
-{
- return (1UL << (flsl(x) - 1));
-}
-
-#define ilog2(n) \
-( \
- __builtin_constant_p(n) ? ( \
- (n) < 1 ? -1 : \
- (n) & (1ULL << 63) ? 63 : \
- (n) & (1ULL << 62) ? 62 : \
- (n) & (1ULL << 61) ? 61 : \
- (n) & (1ULL << 60) ? 60 : \
- (n) & (1ULL << 59) ? 59 : \
- (n) & (1ULL << 58) ? 58 : \
- (n) & (1ULL << 57) ? 57 : \
- (n) & (1ULL << 56) ? 56 : \
- (n) & (1ULL << 55) ? 55 : \
- (n) & (1ULL << 54) ? 54 : \
- (n) & (1ULL << 53) ? 53 : \
- (n) & (1ULL << 52) ? 52 : \
- (n) & (1ULL << 51) ? 51 : \
- (n) & (1ULL << 50) ? 50 : \
- (n) & (1ULL << 49) ? 49 : \
- (n) & (1ULL << 48) ? 48 : \
- (n) & (1ULL << 47) ? 47 : \
- (n) & (1ULL << 46) ? 46 : \
- (n) & (1ULL << 45) ? 45 : \
- (n) & (1ULL << 44) ? 44 : \
- (n) & (1ULL << 43) ? 43 : \
- (n) & (1ULL << 42) ? 42 : \
- (n) & (1ULL << 41) ? 41 : \
- (n) & (1ULL << 40) ? 40 : \
- (n) & (1ULL << 39) ? 39 : \
- (n) & (1ULL << 38) ? 38 : \
- (n) & (1ULL << 37) ? 37 : \
- (n) & (1ULL << 36) ? 36 : \
- (n) & (1ULL << 35) ? 35 : \
- (n) & (1ULL << 34) ? 34 : \
- (n) & (1ULL << 33) ? 33 : \
- (n) & (1ULL << 32) ? 32 : \
- (n) & (1ULL << 31) ? 31 : \
- (n) & (1ULL << 30) ? 30 : \
- (n) & (1ULL << 29) ? 29 : \
- (n) & (1ULL << 28) ? 28 : \
- (n) & (1ULL << 27) ? 27 : \
- (n) & (1ULL << 26) ? 26 : \
- (n) & (1ULL << 25) ? 25 : \
- (n) & (1ULL << 24) ? 24 : \
- (n) & (1ULL << 23) ? 23 : \
- (n) & (1ULL << 22) ? 22 : \
- (n) & (1ULL << 21) ? 21 : \
- (n) & (1ULL << 20) ? 20 : \
- (n) & (1ULL << 19) ? 19 : \
- (n) & (1ULL << 18) ? 18 : \
- (n) & (1ULL << 17) ? 17 : \
- (n) & (1ULL << 16) ? 16 : \
- (n) & (1ULL << 15) ? 15 : \
- (n) & (1ULL << 14) ? 14 : \
- (n) & (1ULL << 13) ? 13 : \
- (n) & (1ULL << 12) ? 12 : \
- (n) & (1ULL << 11) ? 11 : \
- (n) & (1ULL << 10) ? 10 : \
- (n) & (1ULL << 9) ? 9 : \
- (n) & (1ULL << 8) ? 8 : \
- (n) & (1ULL << 7) ? 7 : \
- (n) & (1ULL << 6) ? 6 : \
- (n) & (1ULL << 5) ? 5 : \
- (n) & (1ULL << 4) ? 4 : \
- (n) & (1ULL << 3) ? 3 : \
- (n) & (1ULL << 2) ? 2 : \
- (n) & (1ULL << 1) ? 1 : \
- (n) & (1ULL << 0) ? 0 : \
- -1) : \
- (sizeof(n) <= 4) ? \
- fls((u32)(n)) - 1 : flsll((u64)(n)) - 1 \
-)
-
-#define order_base_2(x) ilog2(roundup_pow_of_two(x))
+#define is_power_of_2(n) ({ \
+ __typeof(n) _n = (n); \
+ _n != 0 && (_n & (_n - 1)) == 0; \
+})
#endif /* _LINUXKPI_LINUX_LOG2_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/math.h b/sys/compat/linuxkpi/common/include/linux/math.h
new file mode 100644
index 000000000000..1d50e011f66d
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/math.h
@@ -0,0 +1,76 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2013-2015 Mellanox Technologies, Ltd.
+ * Copyright (c) 2014-2015 François Tigeot
+ * Copyright (c) 2016 Matt Macy <mmacy@FreeBSD.org>
+ * Copyright (c) 2019 Johannes Lundberg <johalun@FreeBSD.org>
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_MATH_H_
+#define _LINUXKPI_LINUX_MATH_H_
+
+#include <linux/types.h>
+
+/*
+ * This looks more complex than it should be. But we need to
+ * get the type for the ~ right in round_down (it needs to be
+ * as wide as the result!), and we want to evaluate the macro
+ * arguments just once each.
+ */
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+#define DIV_ROUND_UP(x, n) howmany(x, n)
+#define DIV_ROUND_UP_ULL(x, n) DIV_ROUND_UP((unsigned long long)(x), (n))
+#define DIV_ROUND_DOWN_ULL(x, n) ((unsigned long long)(x) / (n))
+
+#define DIV_ROUND_CLOSEST(x, divisor) (((x) + ((divisor) / 2)) / (divisor))
+#define DIV_ROUND_CLOSEST_ULL(x, divisor) ({ \
+ __typeof(divisor) __d = (divisor); \
+ unsigned long long __ret = (x) + (__d) / 2; \
+ __ret /= __d; \
+ __ret; \
+})
+
+#if !defined(LINUXKPI_VERSION) || (LINUXKPI_VERSION >= 60600)
+#define abs_diff(x, y) ({ \
+ __typeof(x) _x = (x); \
+ __typeof(y) _y = (y); \
+ _x > _y ? _x - _y : _y - _x; \
+})
+#endif
+
+static inline uintmax_t
+mult_frac(uintmax_t x, uintmax_t multiplier, uintmax_t divisor)
+{
+ uintmax_t q = (x / divisor);
+ uintmax_t r = (x % divisor);
+
+ return ((q * multiplier) + ((r * multiplier) / divisor));
+}
+
+#endif /* _LINUXKPI_LINUX_MATH_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/math64.h b/sys/compat/linuxkpi/common/include/linux/math64.h
index da8b19d37efe..25ca9da1b622 100644
--- a/sys/compat/linuxkpi/common/include/linux/math64.h
+++ b/sys/compat/linuxkpi/common/include/linux/math64.h
@@ -23,14 +23,13 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MATH64_H
#define _LINUXKPI_LINUX_MATH64_H
#include <sys/stdint.h>
+#include <sys/systm.h>
#define do_div(n, base) ({ \
uint32_t __base = (base); \
@@ -62,6 +61,8 @@ div64_u64(uint64_t dividend, uint64_t divisor)
return (dividend / divisor);
}
+#define div64_ul(x, y) div64_u64((x), (y))
+
static inline uint64_t
div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
@@ -97,7 +98,80 @@ div64_u64_round_up(uint64_t dividend, uint64_t divisor)
return ((dividend + divisor - 1) / divisor);
}
+static inline uint64_t
+roundup_u64(uint64_t x1, uint32_t x2)
+{
+ return (div_u64(x1 + x2 - 1, x2) * x2);
+}
+
#define DIV64_U64_ROUND_UP(...) \
div64_u64_round_up(__VA_ARGS__)
+static inline uint64_t
+mul_u64_u32_div(uint64_t x, uint32_t y, uint32_t div)
+{
+ const uint64_t rem = x % div;
+
+ return ((x / div) * y + (rem * y) / div);
+}
+
+static inline uint64_t
+mul_u64_u64_div_u64(uint64_t x, uint64_t y, uint64_t z)
+{
+ uint64_t res, rem;
+ uint64_t x1, y1, y1z;
+
+ res = rem = 0;
+ x1 = x;
+ y1z = y / z;
+ y1 = y - y1z * z;
+
+ /*
+ * INVARIANT: x * y = res * z + rem + (y1 + y1z * z) * x1
+ * INVARIANT: y1 < z
+ * INVARIANT: rem < z
+ */
+ while (x1 > 0) {
+ /* Handle low bit. */
+ if (x1 & 1) {
+ x1 &= ~1;
+ res += y1z;
+ rem += y1;
+ if ((rem < y1) || (rem >= z)) {
+ res += 1;
+ rem -= z;
+ }
+ }
+
+ /* Shift x1 right and (y1 + y1z * z) left */
+ x1 >>= 1;
+ if ((y1 * 2 < y1) || (y1 * 2 >= z)) {
+ y1z = y1z * 2 + 1;
+ y1 = y1 * 2 - z;
+ } else {
+ y1z *= 2;
+ y1 *= 2;
+ }
+ }
+
+ KASSERT(res * z + rem == x * y, ("%s: res %ju * z %ju + rem %ju != "
+ "x %ju * y %ju", __func__, (uintmax_t)res, (uintmax_t)z,
+ (uintmax_t)rem, (uintmax_t)x, (uintmax_t)y));
+ KASSERT(rem < z, ("%s: rem %ju >= z %ju\n", __func__,
+ (uintmax_t)rem, (uintmax_t)z));
+
+ return (res);
+}
+
+static inline uint64_t
+mul_u64_u32_shr(uint64_t x, uint32_t y, unsigned int shift)
+{
+ uint32_t hi, lo;
+ hi = x >> 32;
+ lo = x & 0xffffffff;
+
+ return (mul_u32_u32(lo, y) >> shift) +
+ (mul_u32_u32(hi, y) << (32 - shift));
+}
+
#endif /* _LINUXKPI_LINUX_MATH64_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/mhi.h b/sys/compat/linuxkpi/common/include/linux/mhi.h
new file mode 100644
index 000000000000..24b3205d6f5a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/mhi.h
@@ -0,0 +1,222 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022-2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_MHI_H
+#define _LINUXKPI_LINUX_MHI_H
+
+#include <linux/types.h>
+
+/* Modem Host Interface (MHI) */
+
+/* XXX FIXME */
+#define MHI_DB_BRST_DISABLE 0
+#define MHI_ER_CTRL 0
+
+enum mhi_callback {
+ MHI_CB_SYS_ERROR,
+ MHI_CB_BW_REQ,
+ MHI_CB_EE_MISSION_MODE,
+ MHI_CB_EE_RDDM,
+ MHI_CB_FATAL_ERROR,
+ MHI_CB_IDLE,
+ MHI_CB_LPM_ENTER,
+ MHI_CB_LPM_EXIT,
+ MHI_CB_PENDING_DATA,
+};
+
+struct mhi_channel_config {
+ const char *name;
+ int auto_queue, dir, doorbell, doorbell_mode_switch, ee_mask, event_ring, lpm_notify, num, num_elements, offload_channel, pollcfg;
+};
+
+struct mhi_event_config {
+ int client_managed, data_type, hardware_event, irq, irq_moderation_ms, mode, num_elements, offload_channel, priority;
+};
+
+struct mhi_device {
+};
+
+struct mhi_controller_config {
+ const struct mhi_channel_config *ch_cfg;
+ struct mhi_event_config *event_cfg;
+
+ int buf_len, max_channels, num_channels, num_events, use_bounce_buf;
+
+ uint32_t timeout_ms;
+};
+
+struct mhi_controller {
+ struct device *cntrl_dev;
+ struct mhi_device *mhi_dev;
+ void *regs;
+ int *irq;
+ const char *fw_image;
+ const u8 *fw_data;
+ size_t fw_sz;
+
+ bool fbc_download;
+ size_t rddm_size;
+ size_t sbl_size;
+ size_t seg_len;
+ size_t reg_len;
+ int nr_irqs;
+ unsigned long irq_flags;
+ uint32_t timeout_ms;
+
+ dma_addr_t iova_start;
+ dma_addr_t iova_stop;
+
+ int (*runtime_get)(struct mhi_controller *);
+ void (*runtime_put)(struct mhi_controller *);
+ void (*status_cb)(struct mhi_controller *, enum mhi_callback);
+ int (*read_reg)(struct mhi_controller *, void __iomem *, uint32_t *);
+ void (*write_reg)(struct mhi_controller *, void __iomem *, uint32_t);
+};
+
+/* -------------------------------------------------------------------------- */
+
+struct mhi_controller *linuxkpi_mhi_alloc_controller(void);
+void linuxkpi_mhi_free_controller(struct mhi_controller *);
+int linuxkpi_mhi_register_controller(struct mhi_controller *,
+ const struct mhi_controller_config *);
+void linuxkpi_mhi_unregister_controller(struct mhi_controller *);
+
+/* -------------------------------------------------------------------------- */
+
+static inline struct mhi_controller *
+mhi_alloc_controller(void)
+{
+
+ /* Keep allocations internal to our implementation. */
+ return (linuxkpi_mhi_alloc_controller());
+}
+
+static inline void
+mhi_free_controller(struct mhi_controller *mhi_ctrl)
+{
+
+ linuxkpi_mhi_free_controller(mhi_ctrl);
+}
+
+static inline int
+mhi_register_controller(struct mhi_controller *mhi_ctrl,
+ const struct mhi_controller_config *cfg)
+{
+
+ return (linuxkpi_mhi_register_controller(mhi_ctrl, cfg));
+}
+
+static inline void
+mhi_unregister_controller(struct mhi_controller *mhi_ctrl)
+{
+
+ linuxkpi_mhi_unregister_controller(mhi_ctrl);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline int
+mhi_device_get_sync(struct mhi_device *mhi_dev)
+{
+ /* XXX TODO */
+ return (-1);
+}
+
+static __inline void
+mhi_device_put(struct mhi_device *mhi_dev)
+{
+ /* XXX TODO */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline int
+mhi_prepare_for_power_up(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline int
+mhi_sync_power_up(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline int
+mhi_async_power_up(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline void
+mhi_power_down(struct mhi_controller *mhi_ctrl, bool x)
+{
+ /* XXX TODO */
+}
+
+static __inline void
+mhi_unprepare_after_power_down(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline int
+mhi_pm_suspend(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline int
+mhi_pm_resume(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline int
+mhi_pm_resume_force(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline int
+mhi_force_rddm_mode(struct mhi_controller *mhi_ctrl)
+{
+ /* XXX TODO */
+ return (0);
+}
+
+#endif /* _LINUXKPI_LINUX_MHI_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/minmax.h b/sys/compat/linuxkpi/common/include/linux/minmax.h
new file mode 100644
index 000000000000..d48958f0899f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/minmax.h
@@ -0,0 +1,74 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2010 iX Systems, Inc.
+ * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2013-2015 Mellanox Technologies, Ltd.
+ * Copyright (c) 2014-2015 François Tigeot
+ * Copyright (c) 2015 Hans Petter Selasky <hselasky@FreeBSD.org>
+ * Copyright (c) 2016 Matt Macy <mmacy@FreeBSD.org>
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_MINMAX_H_
+#define _LINUXKPI_LINUX_MINMAX_H_
+
+#include <linux/build_bug.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
+#define min3(a, b, c) min(a, min(b, c))
+#define max3(a, b, c) max(a, max(b, c))
+
+#define min_not_zero(x, y) ({ \
+ __typeof(x) __min1 = (x); \
+ __typeof(y) __min2 = (y); \
+ __min1 == 0 ? __min2 : ((__min2 == 0) ? __min1 : min(__min1, __min2));\
+})
+
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1 : __min2; })
+
+#define max_t(type, x, y) ({ \
+ type __max1 = (x); \
+ type __max2 = (y); \
+ __max1 > __max2 ? __max1 : __max2; })
+
+#define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max)
+#define clamp(x, lo, hi) min(max(x, lo), hi)
+#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
+
+/* Swap values of a and b */
+#define swap(a, b) do { \
+ __typeof(a) _swap_tmp = a; \
+ a = b; \
+ b = _swap_tmp; \
+} while (0)
+
+#endif /* _LINUXKPI_LINUX_MINMAX_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/miscdevice.h b/sys/compat/linuxkpi/common/include/linux/miscdevice.h
index 1aa37454ffed..c66006a6b78e 100644
--- a/sys/compat/linuxkpi/common/include/linux/miscdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/miscdevice.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MISCDEVICE_H_
#define _LINUXKPI_LINUX_MISCDEVICE_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h
index 5a16cf0d0a58..156b00a0c0f0 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm.h
@@ -27,8 +27,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MM_H_
#define _LINUXKPI_LINUX_MM_H_
@@ -37,9 +35,13 @@
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/mm_types.h>
+#include <linux/mmzone.h>
#include <linux/pfn.h>
#include <linux/list.h>
#include <linux/mmap_lock.h>
+#include <linux/overflow.h>
+#include <linux/shrinker.h>
+#include <linux/page.h>
#include <asm/pgtable.h>
@@ -55,6 +57,8 @@ CTASSERT((VM_PROT_ALL & -(1 << 8)) == 0);
#define VM_WRITE VM_PROT_WRITE
#define VM_EXEC VM_PROT_EXECUTE
+#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
+
#define VM_PFNINTERNAL (1 << 8) /* FreeBSD private flag to vm_insert_pfn() */
#define VM_MIXEDMAP (1 << 9)
#define VM_NORESERVE (1 << 10)
@@ -143,11 +147,28 @@ struct vm_operations_struct {
};
struct sysinfo {
- uint64_t totalram;
- uint64_t totalhigh;
- uint32_t mem_unit;
+ uint64_t totalram; /* Total usable main memory size */
+ uint64_t freeram; /* Available memory size */
+ uint64_t totalhigh; /* Total high memory size */
+ uint64_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
};
+static inline struct page *
+virt_to_head_page(const void *p)
+{
+
+ return (virt_to_page(p));
+}
+
+static inline struct folio *
+virt_to_folio(const void *p)
+{
+ struct page *page = virt_to_page(p);
+
+ return (page_folio(page));
+}
+
/*
* Compute log2 of the power of two rounded up count of pages
* needed for size bytes.
@@ -166,6 +187,14 @@ get_order(unsigned long size)
return (order);
}
+/*
+ * Resolve a page into a virtual address:
+ *
+ * NOTE: This function only works for pages allocated by the kernel.
+ */
+void *linux_page_address(const struct page *);
+#define page_address(page) linux_page_address(page)
+
static inline void *
lowmem_page_address(struct page *page)
{
@@ -217,11 +246,15 @@ apply_to_page_range(struct mm_struct *mm, unsigned long address,
int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
unsigned long size);
+int lkpi_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long start_addr, unsigned long start_pfn, unsigned long size,
+ pgprot_t prot);
+
static inline int
remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
unsigned long pfn, unsigned long size, pgprot_t prot)
{
- return (-ENOTSUP);
+ return (lkpi_remap_pfn_range(vma, addr, pfn, size, prot));
}
static inline unsigned long
@@ -233,44 +266,114 @@ vma_pages(struct vm_area_struct *vma)
#define offset_in_page(off) ((unsigned long)(off) & (PAGE_SIZE - 1))
static inline void
-set_page_dirty(struct vm_page *page)
+set_page_dirty(struct page *page)
{
vm_page_dirty(page);
}
static inline void
-mark_page_accessed(struct vm_page *page)
+mark_page_accessed(struct page *page)
{
vm_page_reference(page);
}
static inline void
-get_page(struct vm_page *page)
+get_page(struct page *page)
{
vm_page_wire(page);
}
+static inline void
+put_page(struct page *page)
+{
+ /* `__free_page()` takes care of the refcounting (unwire). */
+ __free_page(page);
+}
+
+static inline void
+folio_get(struct folio *folio)
+{
+ get_page(&folio->page);
+}
+
+static inline void
+folio_put(struct folio *folio)
+{
+ put_page(&folio->page);
+}
+
+/*
+ * Linux uses the following "transparent" union so that `release_pages()`
+ * accepts both a list of `struct page` or a list of `struct folio`. This
+ * relies on the fact that a `struct folio` can be cast to a `struct page`.
+ */
+typedef union {
+ struct page **pages;
+ struct folio **folios;
+} release_pages_arg __attribute__ ((__transparent_union__));
+
+void linux_release_pages(release_pages_arg arg, int nr);
+#define release_pages(arg, nr) linux_release_pages((arg), (nr))
+
extern long
-get_user_pages(unsigned long start, unsigned long nr_pages,
- int gup_flags, struct page **,
- struct vm_area_struct **);
+lkpi_get_user_pages(unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **);
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60500
+#define get_user_pages(start, nr_pages, gup_flags, pages) \
+ lkpi_get_user_pages(start, nr_pages, gup_flags, pages)
+#else
+#define get_user_pages(start, nr_pages, gup_flags, pages, vmas) \
+ lkpi_get_user_pages(start, nr_pages, gup_flags, pages)
+#endif
+
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60500
+static inline long
+pin_user_pages(unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **pages)
+{
+ return (get_user_pages(start, nr_pages, gup_flags, pages));
+}
+#else
+static inline long
+pin_user_pages(unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas)
+{
+ return (get_user_pages(start, nr_pages, gup_flags, pages, vmas));
+}
+#endif
extern int
__get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **);
+static inline int
+pin_user_pages_fast(unsigned long start, int nr_pages,
+ unsigned int gup_flags, struct page **pages)
+{
+ return __get_user_pages_fast(
+ start, nr_pages, !!(gup_flags & FOLL_WRITE), pages);
+}
+
extern long
get_user_pages_remote(struct task_struct *, struct mm_struct *,
unsigned long start, unsigned long nr_pages,
- int gup_flags, struct page **,
+ unsigned int gup_flags, struct page **,
struct vm_area_struct **);
-static inline void
-put_page(struct vm_page *page)
+static inline long
+pin_user_pages_remote(struct task_struct *task, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas)
{
- vm_page_unwire(page, PQ_ACTIVE);
+ return get_user_pages_remote(
+ task, mm, start, nr_pages, gup_flags, pages, vmas);
}
+#define unpin_user_page(page) put_page(page)
+#define unpin_user_pages(pages, npages) release_pages(pages, npages)
+
#define copy_highpage(to, from) pmap_copy_page(from, to)
static inline pgprot_t
@@ -279,7 +382,19 @@ vm_get_page_prot(unsigned long vm_flags)
return (vm_flags & VM_PROT_ALL);
}
-static inline vm_page_t
+static inline void
+vm_flags_set(struct vm_area_struct *vma, unsigned long flags)
+{
+ vma->vm_flags |= flags;
+}
+
+static inline void
+vm_flags_clear(struct vm_area_struct *vma, unsigned long flags)
+{
+ vma->vm_flags &= ~flags;
+}
+
+static inline struct page *
vmalloc_to_page(const void *addr)
{
vm_paddr_t paddr;
@@ -288,13 +403,77 @@ vmalloc_to_page(const void *addr)
return (PHYS_TO_VM_PAGE(paddr));
}
+static inline int
+trylock_page(struct page *page)
+{
+ return (vm_page_tryxbusy(page));
+}
+
+static inline void
+unlock_page(struct page *page)
+{
+
+ vm_page_xunbusy(page);
+}
+
extern int is_vmalloc_addr(const void *addr);
void si_meminfo(struct sysinfo *si);
+static inline unsigned long
+totalram_pages(void)
+{
+ return ((unsigned long)physmem);
+}
+
#define unmap_mapping_range(...) lkpi_unmap_mapping_range(__VA_ARGS__)
void lkpi_unmap_mapping_range(void *obj, loff_t const holebegin __unused,
loff_t const holelen, int even_cows __unused);
#define PAGE_ALIGNED(p) __is_aligned(p, PAGE_SIZE)
+void vma_set_file(struct vm_area_struct *vma, struct linux_file *file);
+
+static inline void
+might_alloc(gfp_t gfp_mask __unused)
+{
+}
+
+#define is_cow_mapping(flags) (false)
+
+static inline bool
+want_init_on_free(void)
+{
+ return (false);
+}
+
+static inline unsigned long
+folio_pfn(struct folio *folio)
+{
+ return (page_to_pfn(&folio->page));
+}
+
+static inline long
+folio_nr_pages(struct folio *folio)
+{
+ return (1);
+}
+
+static inline size_t
+folio_size(struct folio *folio)
+{
+ return (PAGE_SIZE);
+}
+
+static inline void
+folio_mark_dirty(struct folio *folio)
+{
+ set_page_dirty(&folio->page);
+}
+
+static inline void *
+folio_address(const struct folio *folio)
+{
+ return (page_address(&folio->page));
+}
+
#endif /* _LINUXKPI_LINUX_MM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/mm_types.h b/sys/compat/linuxkpi/common/include/linux/mm_types.h
index 2a7b33d15054..3ea68e97004c 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm_types.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm_types.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MM_TYPES_H_
@@ -31,6 +29,7 @@
#include <linux/types.h>
#include <linux/page.h>
+#include <linux/rbtree.h>
#include <linux/rwsem.h>
#include <asm/atomic.h>
@@ -80,4 +79,15 @@ mmgrab(struct mm_struct *mm)
extern struct mm_struct *linux_get_task_mm(struct task_struct *);
#define get_task_mm(task) linux_get_task_mm(task)
+struct folio {
+ /*
+ * The page member must be at the beginning because `page_folio(p)`
+ * casts from a `struct page` to a `struct folio`.
+ *
+ * `release_pages()` also relies on this to be able to accept either a
+ * list of `struct page` or a list of `struct folio`.
+ */
+ struct page page;
+};
+
#endif /* _LINUXKPI_LINUX_MM_TYPES_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/mman.h b/sys/compat/linuxkpi/common/include/linux/mman.h
new file mode 100644
index 000000000000..eff80759b4cd
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/mman.h
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_MMAN_H
+#define _LINUX_MMAN_H
+
+/*
+ * In Linux, <linux/mman.h> includes <linux/percpu_counter.h>, which includes
+ * <linux/smp.h>.
+ */
+#include <linux/smp.h>
+
+#endif /* _LINUX_MMAN_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/mmu_context.h b/sys/compat/linuxkpi/common/include/linux/mmu_context.h
index afcc9cf07249..4c1bc61b3edb 100644
--- a/sys/compat/linuxkpi/common/include/linux/mmu_context.h
+++ b/sys/compat/linuxkpi/common/include/linux/mmu_context.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MMU_CONTEXT_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h b/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h
index 395f41c36a65..2492a6a3bd4f 100644
--- a/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h
+++ b/sys/compat/linuxkpi/common/include/linux/mmu_notifier.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MMU_NOTIFIER_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/mmzone.h b/sys/compat/linuxkpi/common/include/linux/mmzone.h
new file mode 100644
index 000000000000..57d3dcac9597
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/mmzone.h
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#ifndef _LINUX_MMZONE_H
+#define _LINUX_MMZONE_H
+
+#include <linux/mm_types.h>
+#include <linux/numa.h>
+#include <linux/page-flags.h>
+
+#define MAX_ORDER 11
+
+#define MAX_PAGE_ORDER 10
+#define NR_PAGE_ORDERS (MAX_PAGE_ORDER + 1)
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
index 441faab6df81..87bd6ec24bce 100644
--- a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
+++ b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h
@@ -24,23 +24,27 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef __LINUXKPI_LINUX_MOD_DEVICETABLE_H__
#define __LINUXKPI_LINUX_MOD_DEVICETABLE_H__
+#include <linux/types.h>
+
enum dmi_field {
DMI_NONE,
DMI_BIOS_VENDOR,
DMI_BIOS_VERSION,
DMI_BIOS_DATE,
+ DMI_BIOS_RELEASE,
+ DMI_EC_FIRMWARE_RELEASE,
DMI_SYS_VENDOR,
DMI_PRODUCT_NAME,
DMI_PRODUCT_VERSION,
DMI_PRODUCT_SERIAL,
DMI_PRODUCT_UUID,
+ DMI_PRODUCT_SKU,
+ DMI_PRODUCT_FAMILY,
DMI_BOARD_VENDOR,
DMI_BOARD_NAME,
DMI_BOARD_VERSION,
@@ -52,6 +56,7 @@ enum dmi_field {
DMI_CHASSIS_SERIAL,
DMI_CHASSIS_ASSET_TAG,
DMI_STRING_MAX,
+ DMI_OEM_STRING,
};
struct dmi_strmatch {
@@ -70,4 +75,9 @@ struct dmi_system_id {
#define DMI_MATCH(a, b) { .slot = a, .substr = b }
#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 }
+#define I2C_NAME_SIZE 20
+#define I2C_MODULE_PREFIX "i2c:"
+
+#define ACPI_ID_LEN 16
+
#endif /* __LINUXKPI_LINUX_MOD_DEVICETABLE_H__ */
diff --git a/sys/compat/linuxkpi/common/include/linux/module.h b/sys/compat/linuxkpi/common/include/linux/module.h
index ac7dfc07e468..079dacf8df6c 100644
--- a/sys/compat/linuxkpi/common/include/linux/module.h
+++ b/sys/compat/linuxkpi/common/include/linux/module.h
@@ -25,16 +25,15 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MODULE_H_
#define _LINUXKPI_LINUX_MODULE_H_
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/linker.h>
#include <linux/list.h>
#include <linux/compiler.h>
@@ -54,7 +53,26 @@
#define MODULE_SUPPORTED_DEVICE(name)
#define MODULE_IMPORT_NS(_name)
+/*
+ * THIS_MODULE is used to differentiate modules on Linux. We currently
+ * completely stub out any Linux struct module usage, but THIS_MODULE is still
+ * used to populate the "owner" fields of various drivers. Even though we
+ * don't actually dereference these "owner" fields they are still used by
+ * drivers to check if devices/dmabufs/etc come from different modules. For
+ * example, during DRM GEM import some drivers check if the dmabuf's owner
+ * matches the dev's owner. If they match because they are both NULL drivers
+ * may incorrectly think two resources come from the same module.
+ *
+ * To handle this we specify an undefined symbol __this_linker_file, which
+ * will get special treatment from the linker when resolving. This will
+ * populate the usages of __this_linker_file with the linker_file_t of the
+ * module.
+ */
+#ifdef KLD_MODULE
+#define THIS_MODULE ((struct module *)&__this_linker_file)
+#else
#define THIS_MODULE ((struct module *)0)
+#endif
#define __MODULE_STRING(x) __stringify(x)
diff --git a/sys/compat/linuxkpi/common/include/linux/moduleparam.h b/sys/compat/linuxkpi/common/include/linux/moduleparam.h
index d9485de88f56..b61bbce495ea 100644
--- a/sys/compat/linuxkpi/common/include/linux/moduleparam.h
+++ b/sys/compat/linuxkpi/common/include/linux/moduleparam.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MODULEPARAM_H_
#define _LINUXKPI_LINUX_MODULEPARAM_H_
@@ -90,6 +88,15 @@
LINUXKPI_PARAM_NAME(name), LINUXKPI_PARAM_PERM(perm), &(var), 0, \
LINUXKPI_PARAM_DESC(name)))
+#define LINUXKPI_PARAM_bint(name, var, perm) \
+ LINUXKPI_PARAM_int(name, var, perm)
+
+#define LINUXKPI_PARAM_hexint(name, var, perm) \
+ extern const char LINUXKPI_PARAM_DESC(name)[]; \
+ LINUXKPI_PARAM_PASS(SYSCTL_UINT(LINUXKPI_PARAM_PARENT, OID_AUTO, \
+ LINUXKPI_PARAM_NAME(name), LINUXKPI_PARAM_PERM(perm), &(var), 0, \
+ LINUXKPI_PARAM_DESC(name)))
+
#define LINUXKPI_PARAM_long(name, var, perm) \
extern const char LINUXKPI_PARAM_DESC(name)[]; \
LINUXKPI_PARAM_PASS(SYSCTL_LONG(LINUXKPI_PARAM_PARENT, OID_AUTO, \
diff --git a/sys/compat/linuxkpi/common/include/linux/mutex.h b/sys/compat/linuxkpi/common/include/linux/mutex.h
index 7af95e9d2dc5..6fb6a7744a89 100644
--- a/sys/compat/linuxkpi/common/include/linux/mutex.h
+++ b/sys/compat/linuxkpi/common/include/linux/mutex.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_MUTEX_H_
#define _LINUXKPI_LINUX_MUTEX_H_
@@ -36,6 +34,9 @@
#include <sys/lock.h>
#include <sys/sx.h>
+#include <linux/kernel.h>
+#include <linux/cleanup.h>
+#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/net.h b/sys/compat/linuxkpi/common/include/linux/net.h
index 5438fccb8512..a5172f3f31eb 100644
--- a/sys/compat/linuxkpi/common/include/linux/net.h
+++ b/sys/compat/linuxkpi/common/include/linux/net.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NET_H_
#define _LINUXKPI_LINUX_NET_H_
@@ -47,26 +45,27 @@ sock_create_kern(int family, int type, int proto, struct socket **res)
}
static inline int
-sock_getname(struct socket *so, struct sockaddr *addr, int *sockaddr_len,
+sock_getname(struct socket *so, struct sockaddr *sa, int *sockaddr_len,
int peer)
{
- struct sockaddr *nam;
int error;
- nam = NULL;
+ /*
+ * XXXGL: we can't use sopeeraddr()/sosockaddr() here since with
+ * INVARIANTS they would check if supplied sockaddr has enough
+ * length. Such notion doesn't even exist in Linux KPI.
+ */
if (peer) {
- if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
+ if ((so->so_state & SS_ISCONNECTED) == 0)
return (-ENOTCONN);
- error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &nam);
+ error = so->so_proto->pr_peeraddr(so, sa);
} else
- error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &nam);
+ error = so->so_proto->pr_sockaddr(so, sa);
if (error)
return (-error);
- *addr = *nam;
- *sockaddr_len = addr->sa_len;
+ *sockaddr_len = sa->sa_len;
- free(nam, M_SONAME);
return (0);
}
diff --git a/sys/compat/linuxkpi/common/include/linux/net_dim.h b/sys/compat/linuxkpi/common/include/linux/net_dim.h
index 08a8bb758c32..4fe3e39210e7 100644
--- a/sys/compat/linuxkpi/common/include/linux/net_dim.h
+++ b/sys/compat/linuxkpi/common/include/linux/net_dim.h
@@ -31,8 +31,6 @@
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
- *
- * $FreeBSD$
*/
/* This file implements Dynamic Interrupt Moderation, DIM */
diff --git a/sys/compat/linuxkpi/common/include/linux/netdev_features.h b/sys/compat/linuxkpi/common/include/linux/netdev_features.h
index e21d1965bec6..fae82776b071 100644
--- a/sys/compat/linuxkpi/common/include/linux/netdev_features.h
+++ b/sys/compat/linuxkpi/common/include/linux/netdev_features.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -24,8 +24,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NETDEV_FEATURES_H_
#define _LINUXKPI_LINUX_NETDEV_FEATURES_H_
@@ -35,15 +33,20 @@
typedef uint32_t netdev_features_t;
-#define NETIF_F_HIGHDMA BIT(0)
-#define NETIF_F_SG BIT(1)
-#define NETIF_F_IP_CSUM BIT(2)
-#define NETIF_F_IPV6_CSUM BIT(3)
-#define NETIF_F_TSO BIT(4)
-#define NETIF_F_TSO6 BIT(5)
-#define NETIF_F_RXCSUM BIT(6)
-#define NETIF_F_HW_CSUM BIT(7)
+#define NETIF_F_HIGHDMA BIT(0) /* Can DMA to high memory. */
+#define NETIF_F_SG BIT(1) /* Can do scatter/gather I/O. */
+#define NETIF_F_IP_CSUM BIT(2) /* Can csum TCP/UDP on IPv4. */
+#define NETIF_F_IPV6_CSUM BIT(3) /* Can csum TCP/UDP on IPv6. */
+#define NETIF_F_TSO BIT(4) /* Can do TCP over IPv4 segmentation. */
+#define NETIF_F_TSO6 BIT(5) /* Can do TCP over IPv6 segmentation. */
+#define NETIF_F_RXCSUM BIT(6) /* Can do receive csum offload. */
+#define NETIF_F_HW_CSUM BIT(7) /* Can csum packets (which?). */
+#define NETIF_F_HW_TC BIT(8) /* Can offload TC. */
+
+#define NETIF_F_CSUM_MASK (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)
-#define NETIF_F_CSUM_MASK (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)
+#define NETIF_F_BITS \
+ "\20\1HIGHDMA\2SG\3IP_CSUM\4IPV6_CSUM\5TSO\6TSO6\7RXCSUM" \
+ "\10HW_CSUM\11HW_TC"
#endif /* _LINUXKPI_LINUX_NETDEV_FEATURES_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h
index f8c03f92b025..3b808a4a1749 100644
--- a/sys/compat/linuxkpi/common/include/linux/netdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h
@@ -4,8 +4,8 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2019 Mellanox Technologies, Ltd.
* All rights reserved.
- * Copyright (c) 2020-2021 The FreeBSD Foundation
- * Copyright (c) 2020-2021 Bjoern A. Zeeb
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
+ * Copyright (c) 2020-2022 Bjoern A. Zeeb
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -30,8 +30,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NETDEVICE_H
#define _LINUXKPI_LINUX_NETDEVICE_H
@@ -53,6 +51,7 @@
#include <net/if_var.h>
#include <net/if_dl.h>
+#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/device.h>
@@ -76,6 +75,10 @@ struct wireless_dev; /* net/cfg80211.h */
#define NET_NAME_UNKNOWN 0
+enum net_addr_assign_type {
+ NET_ADDR_RANDOM,
+};
+
enum netdev_tx {
NETDEV_TX_OK = 0,
};
@@ -96,6 +99,10 @@ enum net_device_reg_state {
NETREG_REGISTERED,
};
+enum tc_setup_type {
+ TC_SETUP_MAX_DUMMY,
+};
+
struct net_device_ops {
int (*ndo_open)(struct net_device *);
int (*ndo_stop)(struct net_device *);
@@ -105,9 +112,6 @@ struct net_device_ops {
};
struct net_device {
- /* BSD specific for compat. */
- struct ifnet bsdifp;
-
/* net_device fields seen publicly. */
/* XXX can we later make some aliases to ifnet? */
char name[IFNAMSIZ];
@@ -126,6 +130,7 @@ struct net_device {
unsigned long tx_errors;
unsigned long tx_packets;
} stats;
+ enum net_addr_assign_type addr_assign_type;
enum net_device_reg_state reg_state;
const struct ethtool_ops *ethtool_ops;
const struct net_device_ops *netdev_ops;
@@ -134,6 +139,7 @@ struct net_device {
/* Not properly typed as-of now. */
int flags, type;
int name_assign_type, needed_headroom;
+ int threaded;
void (*priv_destructor)(struct net_device *);
@@ -182,6 +188,30 @@ int unregister_inetaddr_notifier(struct notifier_block *);
#define NAPI_POLL_WEIGHT 64 /* budget */
+/*
+ * There are drivers directly testing napi state bits, so we need to publicly
+ * expose them. If you ask me, those accesses should be hid behind an
+ * inline function and the bit flags not be directly exposed.
+ */
+enum napi_state_bits {
+ /*
+ * Official Linux flags encountered.
+ */
+ NAPI_STATE_SCHED = 1,
+
+ /*
+ * Our internal versions (for now).
+ */
+ /* Do not schedule new things while we are waiting to clear things. */
+ LKPI_NAPI_FLAG_DISABLE_PENDING = 0,
+ /* To synchronise that only one poll is ever running. */
+ LKPI_NAPI_FLAG_IS_SCHEDULED = 1,
+ /* If trying to schedule while poll is running. Need to re-schedule. */
+ LKPI_NAPI_FLAG_LOST_RACE_TRY_AGAIN = 2,
+ /* When shutting down forcefully prevent anything from running task/poll. */
+ LKPI_NAPI_FLAG_SHUTDOWN = 3,
+};
+
struct napi_struct {
TAILQ_ENTRY(napi_struct) entry;
@@ -191,11 +221,12 @@ struct napi_struct {
int budget;
int rx_count;
+
/*
* These flags mostly need to be checked/changed atomically
* (multiple together in some cases).
*/
- volatile unsigned long _flags;
+ volatile unsigned long state;
/* FreeBSD internal. */
/* Use task for now, so we can easily switch between direct and task. */
@@ -204,11 +235,11 @@ struct napi_struct {
void linuxkpi_init_dummy_netdev(struct net_device *);
void linuxkpi_netif_napi_add(struct net_device *, struct napi_struct *,
- int(*napi_poll)(struct napi_struct *, int), int);
+ int(*napi_poll)(struct napi_struct *, int));
void linuxkpi_netif_napi_del(struct napi_struct *);
bool linuxkpi_napi_schedule_prep(struct napi_struct *);
void linuxkpi___napi_schedule(struct napi_struct *);
-void linuxkpi_napi_schedule(struct napi_struct *);
+bool linuxkpi_napi_schedule(struct napi_struct *);
void linuxkpi_napi_reschedule(struct napi_struct *);
bool linuxkpi_napi_complete_done(struct napi_struct *, int);
bool linuxkpi_napi_complete(struct napi_struct *);
@@ -218,8 +249,8 @@ void linuxkpi_napi_synchronize(struct napi_struct *);
#define init_dummy_netdev(_n) \
linuxkpi_init_dummy_netdev(_n)
-#define netif_napi_add(_nd, _ns, _p, _b) \
- linuxkpi_netif_napi_add(_nd, _ns, _p, _b)
+#define netif_napi_add(_nd, _ns, _p) \
+ linuxkpi_netif_napi_add(_nd, _ns, _p)
#define netif_napi_del(_n) \
linuxkpi_netif_napi_del(_n)
#define napi_schedule_prep(_n) \
@@ -241,6 +272,22 @@ void linuxkpi_napi_synchronize(struct napi_struct *);
#define napi_synchronize(_n) \
linuxkpi_napi_synchronize(_n)
+
+static inline void
+netif_napi_add_tx(struct net_device *dev, struct napi_struct *napi,
+ int(*napi_poll)(struct napi_struct *, int))
+{
+
+ netif_napi_add(dev, napi, napi_poll);
+}
+
+static inline bool
+napi_is_scheduled(struct napi_struct *napi)
+{
+
+ return (test_bit(LKPI_NAPI_FLAG_IS_SCHEDULED, &napi->state));
+}
+
/* -------------------------------------------------------------------------- */
static inline void
@@ -255,6 +302,13 @@ netdev_rss_key_fill(uint32_t *buf, size_t len)
get_random_bytes(buf, len);
}
+static inline void
+__hw_addr_init(struct netdev_hw_addr_list *list)
+{
+ list->count = 0;
+ INIT_LIST_HEAD(&list->addr_list);
+}
+
static inline int
netdev_hw_addr_list_count(struct netdev_hw_addr_list *list)
{
@@ -283,6 +337,134 @@ synchronize_net(void)
synchronize_rcu();
}
+static __inline void
+netif_receive_skb_list(struct list_head *head)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline int
+napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-1);
+}
+
+static __inline void
+ether_setup(struct net_device *ndev)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+dev_net_set(struct net_device *ndev, void *p)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline int
+dev_set_threaded(struct net_device *ndev, bool threaded)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENODEV);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline bool
+netif_carrier_ok(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (false);
+}
+
+static __inline void
+netif_carrier_off(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+netif_carrier_on(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline bool
+netif_queue_stopped(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (false);
+}
+
+static __inline void
+netif_stop_queue(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+netif_wake_queue(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline int
+register_netdevice(struct net_device *ndev)
+{
+
+ /* assert rtnl_locked? */
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static __inline int
+register_netdev(struct net_device *ndev)
+{
+ int error;
+
+ /* lock */
+ error = register_netdevice(ndev);
+ /* unlock */
+ pr_debug("%s: TODO\n", __func__);
+ return (error);
+}
+
+static __inline void
+unregister_netdev(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+unregister_netdevice(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline void
+netif_rx(struct sk_buff *skb)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+netif_rx_ni(struct sk_buff *skb)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
/* -------------------------------------------------------------------------- */
struct net_device *linuxkpi_alloc_netdev(size_t, const char *, uint32_t,
@@ -291,6 +473,8 @@ void linuxkpi_free_netdev(struct net_device *);
#define alloc_netdev(_l, _n, _f, _func) \
linuxkpi_alloc_netdev(_l, _n, _f, _func)
+#define alloc_netdev_dummy(_l) \
+ linuxkpi_alloc_netdev(_l, "dummy", NET_NAME_UNKNOWN, NULL)
#define free_netdev(_n) \
linuxkpi_free_netdev(_n)
@@ -306,5 +490,6 @@ netdev_priv(const struct net_device *ndev)
#define rtnl_lock() do { } while(0)
#define rtnl_unlock() do { } while(0)
+#define rcu_dereference_rtnl(x) READ_ONCE(x)
#endif /* _LINUXKPI_LINUX_NETDEVICE_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index f6572cc8f6b8..f3979d3a2abc 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NL80211_H
@@ -51,6 +49,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_TX_POWER_INSERTION = BIT(14),
NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = BIT(15),
NL80211_FEATURE_AP_SCAN = BIT(16),
+ NL80211_FEATURE_ACTIVE_MONITOR = BIT(17),
};
enum nl80211_pmsr_ftm_failure_flags {
@@ -79,6 +78,13 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_160MHZ = BIT(8),
NL80211_RRF_NO_HE = BIT(9),
NL80211_RRF_NO_OFDM = BIT(10),
+ NL80211_RRF_NO_320MHZ = BIT(11),
+ NL80211_RRF_NO_EHT = BIT(12),
+ NL80211_RRF_DFS_CONCURRENT = BIT(13),
+ NL80211_RRF_NO_6GHZ_VLP_CLIENT = BIT(14),
+ NL80211_RRF_NO_6GHZ_AFC_CLIENT = BIT(15),
+ NL80211_RRF_PSD = BIT(16),
+ NL80211_RRF_ALLOW_6GHZ_VLP_AP = BIT(17),
};
#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS)
@@ -127,11 +133,13 @@ enum nl80211_band {
/* Keep this last. */
NUM_NL80211_BANDS
-};
+} __packed;
-enum nl80211_chan_flags {
- /* XXX TODO */
+enum nl80211_channel_type {
NL80211_CHAN_NO_HT,
+ NL80211_CHAN_HT20,
+ NL80211_CHAN_HT40PLUS,
+ NL80211_CHAN_HT40MINUS,
};
enum nl80211_chan_width {
@@ -144,6 +152,7 @@ enum nl80211_chan_width {
NL80211_CHAN_WIDTH_160,
NL80211_CHAN_WIDTH_5,
NL80211_CHAN_WIDTH_10,
+ NL80211_CHAN_WIDTH_320,
};
enum nl80211_iftype {
@@ -159,6 +168,8 @@ enum nl80211_iftype {
NL80211_IFTYPE_P2P_GO,
NL80211_IFTYPE_MESH_POINT,
NL80211_IFTYPE_WDS,
+ NL80211_IFTYPE_OCB,
+ NL80211_IFTYPE_NAN,
/* Keep this last. */
NUM_NL80211_IFTYPES
@@ -179,8 +190,6 @@ enum nl80211_tdls_operation {
NL80211_TDLS_ENABLE_LINK,
NL80211_TDLS_DISABLE_LINK,
NL80211_TDLS_DISCOVERY_REQ,
- NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
- NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
};
enum nl80211_cqm_rssi_threshold_event {
@@ -215,17 +224,37 @@ enum nl80211_ext_feature {
NL80211_EXT_FEATURE_AQL,
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
+ NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
+ NL80211_EXT_FEATURE_BEACON_RATE_HT,
+ NL80211_EXT_FEATURE_BEACON_RATE_VHT,
+ NL80211_EXT_FEATURE_BEACON_RATE_HE,
+ NL80211_EXT_FEATURE_BSS_COLOR,
+ NL80211_EXT_FEATURE_FILS_DISCOVERY,
+ NL80211_EXT_FEATURE_RADAR_BACKGROUND,
+ NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
+ NL80211_EXT_FEATURE_BEACON_PROTECTION,
+ NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
+ NL80211_EXT_FEATURE_PUNCT,
+ NL80211_EXT_FEATURE_DFS_CONCURRENT,
+ NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
+ NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
+ NL80211_EXT_FEATURE_SECURE_LTF,
+ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
+ NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
/* Keep this last. */
NUM_NL80211_EXT_FEATURES
};
+/* Keep in order with lkpi_nl80211_sta_info_to_str() */
enum nl80211_sta_info {
/* XXX TODO */
NL80211_STA_INFO_BEACON_RX,
NL80211_STA_INFO_BEACON_SIGNAL_AVG,
NL80211_STA_INFO_BSS_PARAM,
NL80211_STA_INFO_CHAIN_SIGNAL,
+ NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
NL80211_STA_INFO_CONNECTED_TIME,
NL80211_STA_INFO_INACTIVE_TIME,
NL80211_STA_INFO_SIGNAL,
@@ -238,9 +267,14 @@ enum nl80211_sta_info {
NL80211_STA_INFO_TX_BITRATE,
NL80211_STA_INFO_TX_PACKETS,
NL80211_STA_INFO_TX_BYTES,
+ NL80211_STA_INFO_TX_BYTES64,
+ NL80211_STA_INFO_RX_BYTES64,
NL80211_STA_INFO_TX_FAILED,
NL80211_STA_INFO_TX_RETRIES,
NL80211_STA_INFO_RX_DURATION,
+ NL80211_STA_INFO_TX_DURATION,
+ NL80211_STA_INFO_ACK_SIGNAL,
+ NL80211_STA_INFO_ACK_SIGNAL_AVG,
};
enum nl80211_ftm_stats {
@@ -294,7 +328,7 @@ enum nl80211_key_type {
NL80211_KEYTYPE_PAIRWISE,
};
-enum nl80211_rate_info_he_ru_alloc {
+enum nl80211_he_ru_alloc {
NL80211_RATE_INFO_HE_RU_ALLOC_26,
NL80211_RATE_INFO_HE_RU_ALLOC_52,
NL80211_RATE_INFO_HE_RU_ALLOC_106,
@@ -304,12 +338,43 @@ enum nl80211_rate_info_he_ru_alloc {
NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
};
-enum nl80211_rate_info_he_gi {
+enum nl80211_he_gi {
NL80211_RATE_INFO_HE_GI_0_8,
NL80211_RATE_INFO_HE_GI_1_6,
NL80211_RATE_INFO_HE_GI_3_2,
};
+enum nl80211_he_ltf {
+ NL80211_RATE_INFO_HE_1XLTF,
+ NL80211_RATE_INFO_HE_2XLTF,
+ NL80211_RATE_INFO_HE_4XLTF,
+};
+
+enum nl80211_eht_gi {
+ NL80211_RATE_INFO_EHT_GI_0_8,
+ NL80211_RATE_INFO_EHT_GI_1_6,
+ NL80211_RATE_INFO_EHT_GI_3_2,
+};
+
+enum nl80211_eht_ru_alloc {
+ NL80211_RATE_INFO_EHT_RU_ALLOC_26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_4x996,
+};
+
enum nl80211_dfs_regions {
NL80211_DFS_UNSET,
NL80211_DFS_FCC,
@@ -317,11 +382,16 @@ enum nl80211_dfs_regions {
NL80211_DFS_JP,
};
+enum nl80211_dfs_state {
+ NL80211_DFS_USABLE,
+};
+
enum nl80211_sar_type {
NL80211_SAR_TYPE_POWER,
};
#define NL80211_VHT_NSS_MAX 8
+#define NL80211_HE_NSS_MAX 8
enum nl80211_tid_cfg_attr {
NL80211_TID_CONFIG_ATTR_NOACK,
@@ -331,6 +401,7 @@ enum nl80211_tid_cfg_attr {
NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
NL80211_TID_CONFIG_ATTR_RETRY_LONG,
NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
+ NL80211_TID_CONFIG_ATTR_AMSDU_CTRL,
};
enum nl80211_tid_config {
@@ -344,6 +415,8 @@ enum nl80211_tx_rate_setting {
};
enum nl80211_txrate_gi {
+ NL80211_TXRATE_DEFAULT_GI,
+ NL80211_TXRATE_FORCE_SGI,
NL80211_TXRATE_FORCE_LGI,
};
@@ -353,4 +426,20 @@ enum nl80211_probe_resp_offload_support {
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
};
+enum nl80211_user_reg_hint_type {
+ NL80211_USER_REG_HINT_USER,
+};
+
+enum nl80211_hidden_ssid {
+ NL80211_HIDDEN_SSID_NOT_IN_USE,
+};
+
+#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
+#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
+
+#define NL80211_KCK_LEN 16
+#define NL80211_KCK_EXT_LEN 24
+#define NL80211_KEK_LEN 16
+#define NL80211_KEK_EXT_LEN 32
+#define NL80211_REPLAY_CTR_LEN 8
#endif /* _LINUXKPI_LINUX_NL80211_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/nodemask.h b/sys/compat/linuxkpi/common/include/linux/nodemask.h
new file mode 100644
index 000000000000..7a245cc6f256
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/nodemask.h
@@ -0,0 +1,46 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_NODEMASK_H_
+#define _LINUXKPI_LINUX_NODEMASK_H_
+
+#include <linux/kernel.h> /* pr_debug */
+
+static inline int
+num_online_nodes(void)
+{
+ return (1);
+}
+
+static inline int
+num_possible_nodes(void)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (1);
+}
+
+#endif /* _LINUXKPI_LINUX_NODEMASK_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/nospec.h b/sys/compat/linuxkpi/common/include/linux/nospec.h
new file mode 100644
index 000000000000..e8458ae8b371
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/nospec.h
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_NOSPEC_H_
+#define _LINUXKPI_LINUX_NOSPEC_H_
+
+#define array_index_nospec(a, b) (a)
+
+#endif /* _LINUXKPILINUX_NOSPEC_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/notifier.h b/sys/compat/linuxkpi/common/include/linux/notifier.h
index cafbb64f3f3e..9302a1ce4606 100644
--- a/sys/compat/linuxkpi/common/include/linux/notifier.h
+++ b/sys/compat/linuxkpi/common/include/linux/notifier.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NOTIFIER_H_
#define _LINUXKPI_LINUX_NOTIFIER_H_
@@ -34,7 +32,10 @@
#include <sys/types.h>
#include <sys/eventhandler.h>
-#define NOTIFY_DONE 0
+#define NOTIFY_DONE 0
+#define NOTIFY_OK 0x0001
+#define NOTIFY_STOP_MASK 0x8000
+#define NOTIFY_BAD (NOTIFY_STOP_MASK | 0x0002)
enum {
NETDEV_CHANGE,
diff --git a/sys/compat/linuxkpi/common/include/linux/numa.h b/sys/compat/linuxkpi/common/include/linux/numa.h
index b51a92951f3f..6b227e177a64 100644
--- a/sys/compat/linuxkpi/common/include/linux/numa.h
+++ b/sys/compat/linuxkpi/common/include/linux/numa.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NUMA_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/of.h b/sys/compat/linuxkpi/common/include/linux/of.h
new file mode 100644
index 000000000000..fb4554a8ddbc
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/of.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_OF_H
+#define _LINUXKPI_LINUX_OF_H
+
+#include <linux/kobject.h>
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/overflow.h b/sys/compat/linuxkpi/common/include/linux/overflow.h
index d2e15d8d2383..e811037b8ecc 100644
--- a/sys/compat/linuxkpi/common/include/linux/overflow.h
+++ b/sys/compat/linuxkpi/common/include/linux/overflow.h
@@ -1,53 +1,475 @@
-/*-
- * Copyright (c) 2020 The FreeBSD Foundation
- *
- * This software was developed by Emmanuel Vadot under sponsorship
- * from the FreeBSD Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef __LINUXKPI_LINUX_OVERFLOW_H__
-#define __LINUXKPI_LINUX_OVERFLOW_H__
-
-#include <sys/stdint.h>
-#include <sys/types.h>
-
-#define check_add_overflow(a, b, c) \
- __builtin_add_overflow(a, b, c)
-
-#define check_mul_overflow(a, b, c) \
- __builtin_mul_overflow(a, b, c)
-
-static inline size_t
-array_size(size_t x, size_t y)
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+#ifndef _LINUXKPI_LINUX_OVERFLOW_H
+#define _LINUXKPI_LINUX_OVERFLOW_H
+
+#include <linux/compiler.h>
+#include <linux/limits.h>
+#ifdef __linux__
+#include <linux/const.h>
+#endif
+
+/*
+ * We need to compute the minimum and maximum values representable in a given
+ * type. These macros may also be useful elsewhere. It would seem more obvious
+ * to do something like:
+ *
+ * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
+ * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
+ *
+ * Unfortunately, the middle expressions, strictly speaking, have
+ * undefined behaviour, and at least some versions of gcc warn about
+ * the type_max expression (but not if -fsanitize=undefined is in
+ * effect; in that case, the warning is deferred to runtime...).
+ *
+ * The slightly excessive casting in type_min is to make sure the
+ * macros also produce sensible values for the exotic type _Bool. [The
+ * overflow checkers only almost work for _Bool, but that's
+ * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
+ * _Bools. Besides, the gcc builtins don't allow _Bool* as third
+ * argument.]
+ *
+ * Idea stolen from
+ * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
+ * credit to Christian Biere.
+ */
+#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
+#define __type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
+#define type_max(t) __type_max(typeof(t))
+#define __type_min(T) ((T)((T)-type_max(T)-(T)1))
+#define type_min(t) __type_min(typeof(t))
+
+/*
+ * Avoids triggering -Wtype-limits compilation warning,
+ * while using unsigned data types to check a < 0.
+ */
+#define is_non_negative(a) ((a) > 0 || (a) == 0)
+#define is_negative(a) (!(is_non_negative(a)))
+
+/*
+ * Allows for effectively applying __must_check to a macro so we can have
+ * both the type-agnostic benefits of the macros while also being able to
+ * enforce that the return value is, in fact, checked.
+ */
+static inline bool __must_check __must_check_overflow(bool overflow)
+{
+ return unlikely(overflow);
+}
+
+/**
+ * check_add_overflow() - Calculate addition with overflow checking
+ * @a: first addend
+ * @b: second addend
+ * @d: pointer to store sum
+ *
+ * Returns true on wrap-around, false otherwise.
+ *
+ * *@d holds the results of the attempted addition, regardless of whether
+ * wrap-around occurred.
+ */
+#define check_add_overflow(a, b, d) \
+ __must_check_overflow(__builtin_add_overflow(a, b, d))
+
+/**
+ * wrapping_add() - Intentionally perform a wrapping addition
+ * @type: type for result of calculation
+ * @a: first addend
+ * @b: second addend
+ *
+ * Return the potentially wrapped-around addition without
+ * tripping any wrap-around sanitizers that may be enabled.
+ */
+#define wrapping_add(type, a, b) \
+ ({ \
+ type __val; \
+ __builtin_add_overflow(a, b, &__val); \
+ __val; \
+ })
+
+/**
+ * wrapping_assign_add() - Intentionally perform a wrapping increment assignment
+ * @var: variable to be incremented
+ * @offset: amount to add
+ *
+ * Increments @var by @offset with wrap-around. Returns the resulting
+ * value of @var. Will not trip any wrap-around sanitizers.
+ *
+ * Returns the new value of @var.
+ */
+#define wrapping_assign_add(var, offset) \
+ ({ \
+ typeof(var) *__ptr = &(var); \
+ *__ptr = wrapping_add(typeof(var), *__ptr, offset); \
+ })
+
+/**
+ * check_sub_overflow() - Calculate subtraction with overflow checking
+ * @a: minuend; value to subtract from
+ * @b: subtrahend; value to subtract from @a
+ * @d: pointer to store difference
+ *
+ * Returns true on wrap-around, false otherwise.
+ *
+ * *@d holds the results of the attempted subtraction, regardless of whether
+ * wrap-around occurred.
+ */
+#define check_sub_overflow(a, b, d) \
+ __must_check_overflow(__builtin_sub_overflow(a, b, d))
+
+/**
+ * wrapping_sub() - Intentionally perform a wrapping subtraction
+ * @type: type for result of calculation
+ * @a: minuend; value to subtract from
+ * @b: subtrahend; value to subtract from @a
+ *
+ * Return the potentially wrapped-around subtraction without
+ * tripping any wrap-around sanitizers that may be enabled.
+ */
+#define wrapping_sub(type, a, b) \
+ ({ \
+ type __val; \
+ __builtin_sub_overflow(a, b, &__val); \
+ __val; \
+ })
+
+/**
+ * wrapping_assign_sub() - Intentionally perform a wrapping decrement assign
+ * @var: variable to be decremented
+ * @offset: amount to subtract
+ *
+ * Decrements @var by @offset with wrap-around. Returns the resulting
+ * value of @var. Will not trip any wrap-around sanitizers.
+ *
+ * Returns the new value of @var.
+ */
+#define wrapping_assign_sub(var, offset) \
+ ({ \
+ typeof(var) *__ptr = &(var); \
+ *__ptr = wrapping_sub(typeof(var), *__ptr, offset); \
+ })
+
+/**
+ * check_mul_overflow() - Calculate multiplication with overflow checking
+ * @a: first factor
+ * @b: second factor
+ * @d: pointer to store product
+ *
+ * Returns true on wrap-around, false otherwise.
+ *
+ * *@d holds the results of the attempted multiplication, regardless of whether
+ * wrap-around occurred.
+ */
+#define check_mul_overflow(a, b, d) \
+ __must_check_overflow(__builtin_mul_overflow(a, b, d))
+
+/**
+ * wrapping_mul() - Intentionally perform a wrapping multiplication
+ * @type: type for result of calculation
+ * @a: first factor
+ * @b: second factor
+ *
+ * Return the potentially wrapped-around multiplication without
+ * tripping any wrap-around sanitizers that may be enabled.
+ */
+#define wrapping_mul(type, a, b) \
+ ({ \
+ type __val; \
+ __builtin_mul_overflow(a, b, &__val); \
+ __val; \
+ })
+
+/**
+ * check_shl_overflow() - Calculate a left-shifted value and check overflow
+ * @a: Value to be shifted
+ * @s: How many bits left to shift
+ * @d: Pointer to where to store the result
+ *
+ * Computes *@d = (@a << @s)
+ *
+ * Returns true if '*@d' cannot hold the result or when '@a << @s' doesn't
+ * make sense. Example conditions:
+ *
+ * - '@a << @s' causes bits to be lost when stored in *@d.
+ * - '@s' is garbage (e.g. negative) or so large that the result of
+ * '@a << @s' is guaranteed to be 0.
+ * - '@a' is negative.
+ * - '@a << @s' sets the sign bit, if any, in '*@d'.
+ *
+ * '*@d' will hold the results of the attempted shift, but is not
+ * considered "safe for use" if true is returned.
+ */
+#define check_shl_overflow(a, s, d) __must_check_overflow(({ \
+ typeof(a) _a = a; \
+ typeof(s) _s = s; \
+ typeof(d) _d = d; \
+ unsigned long long _a_full = _a; \
+ unsigned int _to_shift = \
+ is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \
+ *_d = (_a_full << _to_shift); \
+ (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \
+ (*_d >> _to_shift) != _a); \
+}))
+
+#define __overflows_type_constexpr(x, T) ( \
+ is_unsigned_type(typeof(x)) ? \
+ (x) > type_max(T) : \
+ is_unsigned_type(typeof(T)) ? \
+ (x) < 0 || (x) > type_max(T) : \
+ (x) < type_min(T) || (x) > type_max(T))
+
+#define __overflows_type(x, T) ({ \
+ typeof(T) v = 0; \
+ check_add_overflow((x), v, &v); \
+})
+
+/**
+ * overflows_type - helper for checking the overflows between value, variables,
+ * or data type
+ *
+ * @n: source constant value or variable to be checked
+ * @T: destination variable or data type proposed to store @x
+ *
+ * Compares the @x expression for whether or not it can safely fit in
+ * the storage of the type in @T. @x and @T can have different types.
+ * If @x is a constant expression, this will also resolve to a constant
+ * expression.
+ *
+ * Returns: true if overflow can occur, false otherwise.
+ */
+#define overflows_type(n, T) \
+ __builtin_choose_expr(__is_constexpr(n), \
+ __overflows_type_constexpr(n, T), \
+ __overflows_type(n, T))
+
+/**
+ * castable_to_type - like __same_type(), but also allows for casted literals
+ *
+ * @n: variable or constant value
+ * @T: variable or data type
+ *
+ * Unlike the __same_type() macro, this allows a constant value as the
+ * first argument. If this value would not overflow into an assignment
+ * of the second argument's type, it returns true. Otherwise, this falls
+ * back to __same_type().
+ */
+#define castable_to_type(n, T) \
+ __builtin_choose_expr(__is_constexpr(n), \
+ !__overflows_type_constexpr(n, T), \
+ __same_type(n, T))
+
+/**
+ * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
+ * @factor1: first factor
+ * @factor2: second factor
+ *
+ * Returns: calculate @factor1 * @factor2, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. The
+ * lvalue must be size_t to avoid implicit type conversion.
+ */
+static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
{
- size_t retval;
+ size_t bytes;
+
+ if (check_mul_overflow(factor1, factor2, &bytes))
+ return SIZE_MAX;
- if (__builtin_mul_overflow(x, y, &retval))
- retval = SIZE_MAX;
- return (retval);
+ return bytes;
}
-#endif /* __LINUXKPI_LINUX_OVERFLOW_H__ */
+/**
+ * size_add() - Calculate size_t addition with saturation at SIZE_MAX
+ * @addend1: first addend
+ * @addend2: second addend
+ *
+ * Returns: calculate @addend1 + @addend2, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. The
+ * lvalue must be size_t to avoid implicit type conversion.
+ */
+static inline size_t __must_check size_add(size_t addend1, size_t addend2)
+{
+ size_t bytes;
+
+ if (check_add_overflow(addend1, addend2, &bytes))
+ return SIZE_MAX;
+
+ return bytes;
+}
+
+/**
+ * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX
+ * @minuend: value to subtract from
+ * @subtrahend: value to subtract from @minuend
+ *
+ * Returns: calculate @minuend - @subtrahend, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. For
+ * composition with the size_add() and size_mul() helpers, neither
+ * argument may be SIZE_MAX (or the result with be forced to SIZE_MAX).
+ * The lvalue must be size_t to avoid implicit type conversion.
+ */
+static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
+{
+ size_t bytes;
+
+ if (minuend == SIZE_MAX || subtrahend == SIZE_MAX ||
+ check_sub_overflow(minuend, subtrahend, &bytes))
+ return SIZE_MAX;
+
+ return bytes;
+}
+
+/**
+ * array_size() - Calculate size of 2-dimensional array.
+ * @a: dimension one
+ * @b: dimension two
+ *
+ * Calculates size of 2-dimensional array: @a * @b.
+ *
+ * Returns: number of bytes needed to represent the array or SIZE_MAX on
+ * overflow.
+ */
+#define array_size(a, b) size_mul(a, b)
+
+/**
+ * array3_size() - Calculate size of 3-dimensional array.
+ * @a: dimension one
+ * @b: dimension two
+ * @c: dimension three
+ *
+ * Calculates size of 3-dimensional array: @a * @b * @c.
+ *
+ * Returns: number of bytes needed to represent the array or SIZE_MAX on
+ * overflow.
+ */
+#define array3_size(a, b, c) size_mul(size_mul(a, b), c)
+
+/**
+ * flex_array_size() - Calculate size of a flexible array member
+ * within an enclosing structure.
+ * @p: Pointer to the structure.
+ * @member: Name of the flexible array member.
+ * @count: Number of elements in the array.
+ *
+ * Calculates size of a flexible array of @count number of @member
+ * elements, at the end of structure @p.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define flex_array_size(p, member, count) \
+ __builtin_choose_expr(__is_constexpr(count), \
+ (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \
+ size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member)))
+
+/**
+ * struct_size() - Calculate size of structure with trailing flexible array.
+ * @p: Pointer to the structure.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array.
+ *
+ * Calculates size of memory needed for structure of @p followed by an
+ * array of @count number of @member elements.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define struct_size(p, member, count) \
+ __builtin_choose_expr(__is_constexpr(count), \
+ sizeof(*(p)) + flex_array_size(p, member, count), \
+ size_add(sizeof(*(p)), flex_array_size(p, member, count)))
+
+/**
+ * struct_size_t() - Calculate size of structure with trailing flexible array
+ * @type: structure type name.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array.
+ *
+ * Calculates size of memory needed for structure @type followed by an
+ * array of @count number of @member elements. Prefer using struct_size()
+ * when possible instead, to keep calculations associated with a specific
+ * instance variable of type @type.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define struct_size_t(type, member, count) \
+ struct_size((type *)NULL, member, count)
+
+/**
+ * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
+ * Enables caller macro to pass arbitrary trailing expressions
+ *
+ * @type: structure type name, including "struct" keyword.
+ * @name: Name for a variable to define.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ * @trailer: Trailing expressions for attributes and/or initializers.
+ */
+#define __DEFINE_FLEX(type, name, member, count, trailer...) \
+ _Static_assert(__builtin_constant_p(count), \
+ "onstack flex array members require compile-time const count"); \
+ union { \
+ u8 bytes[struct_size_t(type, member, count)]; \
+ type obj; \
+ } name##_u trailer; \
+ type *name = (type *)&name##_u
+
+/**
+ * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
+ * Enables caller macro to pass (different) initializer.
+ *
+ * @type: structure type name, including "struct" keyword.
+ * @name: Name for a variable to define.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ * @initializer: Initializer expression (e.g., pass `= { }` at minimum).
+ */
+#define _DEFINE_FLEX(type, name, member, count, initializer...) \
+ __DEFINE_FLEX(type, name, member, count, = { .obj initializer })
+
+/**
+ * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing
+ * flexible array member, when it does not have a __counted_by annotation.
+ *
+ * @type: structure type name, including "struct" keyword.
+ * @name: Name for a variable to define.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ *
+ * Define a zeroed, on-stack, instance of @type structure with a trailing
+ * flexible array member.
+ * Use __struct_size(@name) to get compile-time size of it afterwards.
+ * Use __member_size(@name->member) to get compile-time size of @name members.
+ * Use STACK_FLEX_ARRAY_SIZE(@name, @member) to get compile-time number of
+ * elements in array @member.
+ */
+#define DEFINE_RAW_FLEX(type, name, member, count) \
+ __DEFINE_FLEX(type, name, member, count, = { })
+
+/**
+ * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
+ * flexible array member.
+ *
+ * @TYPE: structure type name, including "struct" keyword.
+ * @NAME: Name for a variable to define.
+ * @MEMBER: Name of the array member.
+ * @COUNTER: Name of the __counted_by member.
+ * @COUNT: Number of elements in the array; must be compile-time const.
+ *
+ * Define a zeroed, on-stack, instance of @TYPE structure with a trailing
+ * flexible array member.
+ * Use __struct_size(@NAME) to get compile-time size of it afterwards.
+ * Use __member_size(@NAME->member) to get compile-time size of @NAME members.
+ * Use STACK_FLEX_ARRAY_SIZE(@name, @member) to get compile-time number of
+ * elements in array @member.
+ */
+#define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT) \
+ _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .COUNTER = COUNT, })
+
+/**
+ * STACK_FLEX_ARRAY_SIZE() - helper macro for DEFINE_FLEX() family.
+ * Returns the number of elements in @array.
+ *
+ * @name: Name for a variable defined in DEFINE_RAW_FLEX()/DEFINE_FLEX().
+ * @array: Name of the array member.
+ */
+#define STACK_FLEX_ARRAY_SIZE(name, array) \
+ (__member_size((name)->array) / sizeof(*(name)->array) + \
+ __must_be_array((name)->array))
+
+#endif /* _LINUXKPI_LINUX_OVERFLOW_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/page-flags.h b/sys/compat/linuxkpi/common/include/linux/page-flags.h
new file mode 100644
index 000000000000..a22b3a24c330
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/page-flags.h
@@ -0,0 +1,41 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_PAGEFLAGS_H_
+#define _LINUXKPI_LINUX_PAGEFLAGS_H_
+
+#include <linux/mm_types.h>
+
+#define PageHighMem(p) (0)
+
+#define page_folio(p) \
+ (_Generic((p), \
+ const struct page *: (const struct folio *)(p), \
+ struct page *: (struct folio *)(p)))
+
+#endif /* _LINUXKPI_LINUX_PAGEFLAGS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h
index b582966b49c3..37ab593a64e9 100644
--- a/sys/compat/linuxkpi/common/include/linux/page.h
+++ b/sys/compat/linuxkpi/common/include/linux/page.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PAGE_H_
#define _LINUXKPI_LINUX_PAGE_H_
@@ -74,6 +72,7 @@ pgprot2cachemode(pgprot_t prot)
return (VM_MEMATTR_DEFAULT);
}
+#define page_to_virt(page) linux_page_address(page)
#define virt_to_page(x) PHYS_TO_VM_PAGE(vtophys(x))
#define page_to_pfn(pp) (VM_PAGE_TO_PHYS(pp) >> PAGE_SHIFT)
#define pfn_to_page(pfn) (PHYS_TO_VM_PAGE((pfn) << PAGE_SHIFT))
diff --git a/sys/compat/linuxkpi/common/include/linux/pagemap.h b/sys/compat/linuxkpi/common/include/linux/pagemap.h
index e25fa743f9a7..cb6a1820ea8b 100644
--- a/sys/compat/linuxkpi/common/include/linux/pagemap.h
+++ b/sys/compat/linuxkpi/common/include/linux/pagemap.h
@@ -24,22 +24,26 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PAGEMAP_H_
#define _LINUXKPI_LINUX_PAGEMAP_H_
#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/vmalloc.h>
+
+struct folio_batch;
+
+#define invalidate_mapping_pages(...) \
+ linux_invalidate_mapping_pages(__VA_ARGS__)
+
+unsigned long linux_invalidate_mapping_pages(vm_object_t obj, pgoff_t start,
+ pgoff_t end);
static inline void
-release_pages(struct page **pages, int nr)
+mapping_clear_unevictable(vm_object_t mapping)
{
- int i;
-
- for (i = 0; i < nr; i++)
- put_page(pages[i]);
}
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/pagevec.h b/sys/compat/linuxkpi/common/include/linux/pagevec.h
new file mode 100644
index 000000000000..0a952e965b5a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/pagevec.h
@@ -0,0 +1,137 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_PAGEVEC_H_
+#define _LINUXKPI_LINUX_PAGEVEC_H_
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+
+#include <linux/pagemap.h>
+
+#define PAGEVEC_SIZE 15
+
+struct pagevec {
+ uint8_t nr;
+ struct page *pages[PAGEVEC_SIZE];
+};
+
+static inline unsigned int
+pagevec_space(struct pagevec *pvec)
+{
+ return PAGEVEC_SIZE - pvec->nr;
+}
+
+static inline void
+pagevec_init(struct pagevec *pvec)
+{
+ pvec->nr = 0;
+}
+
+static inline void
+pagevec_reinit(struct pagevec *pvec)
+{
+ pvec->nr = 0;
+}
+
+static inline unsigned int
+pagevec_count(struct pagevec *pvec)
+{
+ return pvec->nr;
+}
+
+static inline unsigned int
+pagevec_add(struct pagevec *pvec, struct page *page)
+{
+ pvec->pages[pvec->nr++] = page;
+ return PAGEVEC_SIZE - pvec->nr;
+}
+
+static inline void
+__pagevec_release(struct pagevec *pvec)
+{
+ release_pages(pvec->pages, pagevec_count(pvec));
+ pagevec_reinit(pvec);
+}
+
+static inline void
+pagevec_release(struct pagevec *pvec)
+{
+ if (pagevec_count(pvec))
+ __pagevec_release(pvec);
+}
+
+static inline void
+check_move_unevictable_pages(struct pagevec *pvec)
+{
+}
+
+/*
+ * struct folio
+ *
+ * On Linux, `struct folio` replaces `struct page`. To manage a list of folios,
+ * there is `struct folio_batch` on top of this, which replaces `struct
+ * pagevec` above.
+ *
+ * Here is the original description when `struct folio` was added to the Linux
+ * kernel:
+ * "A struct folio is a new abstraction to replace the venerable struct page.
+ * A function which takes a struct folio argument declares that it will
+ * operate on the entire (possibly compound) page, not just PAGE_SIZE bytes.
+ * In return, the caller guarantees that the pointer it is passing does not
+ * point to a tail page. No change to generated code."
+ */
+
+struct folio;
+
+struct folio_batch {
+ uint8_t nr;
+ struct folio *folios[PAGEVEC_SIZE];
+};
+
+static inline void
+folio_batch_init(struct folio_batch *fbatch)
+{
+ fbatch->nr = 0;
+}
+
+static inline void
+folio_batch_reinit(struct folio_batch *fbatch)
+{
+ fbatch->nr = 0;
+}
+
+static inline unsigned int
+folio_batch_count(struct folio_batch *fbatch)
+{
+ return (fbatch->nr);
+}
+
+static inline unsigned int
+folio_batch_space(struct folio_batch *fbatch)
+{
+ return (PAGEVEC_SIZE - fbatch->nr);
+}
+
+static inline unsigned int
+folio_batch_add(struct folio_batch *fbatch, struct folio *folio)
+{
+ KASSERT(
+ fbatch->nr < PAGEVEC_SIZE,
+ ("struct folio_batch %p is full", fbatch));
+
+ fbatch->folios[fbatch->nr++] = folio;
+
+ return (folio_batch_space(fbatch));
+}
+
+void __folio_batch_release(struct folio_batch *fbatch);
+
+static inline void
+folio_batch_release(struct folio_batch *fbatch)
+{
+ if (folio_batch_count(fbatch))
+ __folio_batch_release(fbatch);
+}
+
+#endif /* _LINUXKPI_LINUX_PAGEVEC_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index 695965673050..ffc2be600c22 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -4,7 +4,7 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
* All rights reserved.
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -29,8 +29,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PCI_H_
#define _LINUXKPI_LINUX_PCI_H_
@@ -38,13 +36,13 @@
#define CONFIG_PCI_MSI
#include <linux/types.h>
+#include <linux/device/driver.h>
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/nv.h>
#include <sys/pciio.h>
-#include <sys/rman.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pci_private.h>
@@ -57,10 +55,13 @@
#include <linux/compiler.h>
#include <linux/errno.h>
#include <asm/atomic.h>
+#include <asm/memtype.h>
#include <linux/device.h>
#include <linux/pci_ids.h>
#include <linux/pm.h>
+#include <linux/kernel.h> /* pr_debug */
+
struct pci_device_id {
uint32_t vendor;
uint32_t device;
@@ -71,6 +72,10 @@ struct pci_device_id {
uintptr_t driver_data;
};
+#define MODULE_DEVICE_TABLE_BUS_pci(_bus, _table) \
+MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
+ _bus, lkpi_ ## _table, _table, nitems(_table) - 1)
+
/* Linux has an empty element at the end of the ID table -> nitems() - 1. */
#define MODULE_DEVICE_TABLE(_bus, _table) \
\
@@ -84,11 +89,10 @@ static driver_t _ ## _bus ## _ ## _table ## _driver = { \
0 \
}; \
\
-DRIVER_MODULE(lkpi_ ## _table, pci, _ ## _bus ## _ ## _table ## _driver,\
+DRIVER_MODULE(lkpi_ ## _table, _bus, _ ## _bus ## _ ## _table ## _driver,\
0, 0); \
\
-MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
- _bus, lkpi_ ## _table, _table, nitems(_table) - 1)
+MODULE_DEVICE_TABLE_BUS_ ## _bus(_bus, _table)
#define PCI_ANY_ID -1U
@@ -96,6 +100,7 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07)
#define PCI_BUS_NUM(devfn) (((devfn) >> 8) & 0xff)
+#define PCI_DEVID(bus, devfn) ((((uint16_t)(bus)) << 8) | (devfn))
#define PCI_VDEVICE(_vendor, _device) \
.vendor = PCI_VENDOR_ID_##_vendor, .device = (_device), \
@@ -106,9 +111,18 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
-#define PCI_VENDOR_ID PCIR_DEVVENDOR
+#define PCI_STD_NUM_BARS 6
+#define PCI_BASE_ADDRESS_0 PCIR_BARS
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 PCIM_BAR_MEM_64
+#define PCI_VENDOR_ID PCIR_VENDOR
+#define PCI_DEVICE_ID PCIR_DEVICE
#define PCI_COMMAND PCIR_COMMAND
#define PCI_COMMAND_INTX_DISABLE PCIM_CMD_INTxDIS
+#define PCI_COMMAND_MEMORY PCIM_CMD_MEMEN
+#define PCI_PRIMARY_BUS PCIR_PRIBUS_1
+#define PCI_SECONDARY_BUS PCIR_SECBUS_1
+#define PCI_SUBORDINATE_BUS PCIR_SUBBUS_1
+#define PCI_SEC_LATENCY_TIMER PCIR_SECLAT_1
#define PCI_EXP_DEVCTL PCIER_DEVICE_CTL /* Device Control */
#define PCI_EXP_LNKCTL PCIER_LINK_CTL /* Link Control */
#define PCI_EXP_LNKCTL_ASPM_L0S PCIEM_LINK_CTL_ASPMC_L0S
@@ -142,24 +156,38 @@ MODULE_PNP_INFO("U32:vendor;U32:device;V32:subvendor;V32:subdevice", \
#define PCI_EXP_TYPE_DOWNSTREAM PCIEM_TYPE_DOWNSTREAM_PORT /* Downstream Port */
#define PCI_EXP_FLAGS_SLOT PCIEM_FLAGS_SLOT /* Slot implemented */
#define PCI_EXP_TYPE_RC_EC PCIEM_TYPE_ROOT_EC /* Root Complex Event Collector */
+#define PCI_EXP_LNKSTA_CLS PCIEM_LINK_STA_SPEED
+#define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */
#define PCI_EXP_LNKCAP_SLS_2_5GB 0x01 /* Supported Link Speed 2.5GT/s */
#define PCI_EXP_LNKCAP_SLS_5_0GB 0x02 /* Supported Link Speed 5.0GT/s */
-#define PCI_EXP_LNKCAP_SLS_8_0GB 0x04 /* Supported Link Speed 8.0GT/s */
-#define PCI_EXP_LNKCAP_SLS_16_0GB 0x08 /* Supported Link Speed 16.0GT/s */
+#define PCI_EXP_LNKCAP_SLS_8_0GB 0x03 /* Supported Link Speed 8.0GT/s */
+#define PCI_EXP_LNKCAP_SLS_16_0GB 0x04 /* Supported Link Speed 16.0GT/s */
+#define PCI_EXP_LNKCAP_SLS_32_0GB 0x05 /* Supported Link Speed 32.0GT/s */
+#define PCI_EXP_LNKCAP_SLS_64_0GB 0x06 /* Supported Link Speed 64.0GT/s */
#define PCI_EXP_LNKCAP_MLW 0x03f0 /* Maximum Link Width */
#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x02 /* Supported Link Speed 2.5GT/s */
#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x04 /* Supported Link Speed 5.0GT/s */
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x08 /* Supported Link Speed 8.0GT/s */
#define PCI_EXP_LNKCAP2_SLS_16_0GB 0x10 /* Supported Link Speed 16.0GT/s */
+#define PCI_EXP_LNKCAP2_SLS_32_0GB 0x20 /* Supported Link Speed 32.0GT/s */
+#define PCI_EXP_LNKCAP2_SLS_64_0GB 0x40 /* Supported Link Speed 64.0GT/s */
#define PCI_EXP_LNKCTL2_TLS 0x000f
#define PCI_EXP_LNKCTL2_TLS_2_5GT 0x0001 /* Supported Speed 2.5GT/s */
#define PCI_EXP_LNKCTL2_TLS_5_0GT 0x0002 /* Supported Speed 5GT/s */
#define PCI_EXP_LNKCTL2_TLS_8_0GT 0x0003 /* Supported Speed 8GT/s */
#define PCI_EXP_LNKCTL2_TLS_16_0GT 0x0004 /* Supported Speed 16GT/s */
#define PCI_EXP_LNKCTL2_TLS_32_0GT 0x0005 /* Supported Speed 32GT/s */
+#define PCI_EXP_LNKCTL2_TLS_64_0GT 0x0006 /* Supported Speed 64GT/s */
#define PCI_EXP_LNKCTL2_ENTER_COMP 0x0010 /* Enter Compliance */
#define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */
+#define PCI_MSI_ADDRESS_LO PCIR_MSI_ADDR
+#define PCI_MSI_ADDRESS_HI PCIR_MSI_ADDR_HIGH
+#define PCI_MSI_FLAGS PCIR_MSI_CTRL
+#define PCI_MSI_FLAGS_ENABLE PCIM_MSICTRL_MSI_ENABLE
+#define PCI_MSIX_FLAGS PCIR_MSIX_CTRL
+#define PCI_MSIX_FLAGS_ENABLE PCIM_MSIXCTRL_MSIX_ENABLE
+
#define PCI_EXP_LNKCAP_CLKPM 0x00040000
#define PCI_EXP_DEVSTA_TRPND 0x0020
@@ -173,6 +201,8 @@ enum pci_bus_speed {
PCIE_SPEED_5_0GT,
PCIE_SPEED_8_0GT,
PCIE_SPEED_16_0GT,
+ PCIE_SPEED_32_0GT,
+ PCIE_SPEED_64_0GT,
};
enum pcie_link_width {
@@ -193,14 +223,18 @@ enum pcie_link_width {
typedef int pci_power_t;
-#define PCI_D0 PCI_POWERSTATE_D0
-#define PCI_D1 PCI_POWERSTATE_D1
-#define PCI_D2 PCI_POWERSTATE_D2
-#define PCI_D3hot PCI_POWERSTATE_D3
-#define PCI_D3cold 4
+#define PCI_D0 PCI_POWERSTATE_D0
+#define PCI_D1 PCI_POWERSTATE_D1
+#define PCI_D2 PCI_POWERSTATE_D2
+#define PCI_D3hot PCI_POWERSTATE_D3_HOT
+#define PCI_D3cold PCI_POWERSTATE_D3_COLD
#define PCI_POWER_ERROR PCI_POWERSTATE_UNKNOWN
+extern const char *pci_power_names[6];
+
+#define PCI_ERR_UNCOR_STATUS PCIR_AER_UC_STATUS
+#define PCI_ERR_COR_STATUS PCIR_AER_COR_STATUS
#define PCI_ERR_ROOT_COMMAND PCIR_AER_ROOTERR_CMD
#define PCI_ERR_ROOT_ERR_SRC PCIR_AER_COR_SOURCE_ID
@@ -210,9 +244,14 @@ typedef int pci_power_t;
#define PCI_L1SS_CTL1 0x8
#define PCI_L1SS_CTL1_L1SS_MASK 0xf
-#define PCI_IRQ_LEGACY 0x01
+#define PCI_IRQ_INTX 0x01
#define PCI_IRQ_MSI 0x02
#define PCI_IRQ_MSIX 0x04
+#define PCI_IRQ_ALL_TYPES (PCI_IRQ_MSIX|PCI_IRQ_MSI|PCI_IRQ_INTX)
+
+#if defined(LINUXKPI_VERSION) && (LINUXKPI_VERSION <= 61000)
+#define PCI_IRQ_LEGACY PCI_IRQ_INTX
+#endif
struct pci_dev;
@@ -240,6 +279,7 @@ struct pci_driver {
struct pci_bus {
struct pci_dev *self;
+ /* struct pci_bus *parent */
int domain;
int number;
};
@@ -250,29 +290,34 @@ extern spinlock_t pci_lock;
#define __devexit_p(x) x
-#define module_pci_driver(_driver) \
- \
-static inline int \
-_pci_init(void) \
-{ \
- \
- return (linux_pci_register_driver(&_driver)); \
-} \
- \
-static inline void \
-_pci_exit(void) \
-{ \
- \
- linux_pci_unregister_driver(&_driver); \
-} \
- \
-module_init(_pci_init); \
-module_exit(_pci_exit)
+#define module_pci_driver(_drv) \
+ module_driver(_drv, linux_pci_register_driver, linux_pci_unregister_driver)
+
+struct msi_msg {
+ uint32_t data;
+};
+
+struct pci_msi_desc {
+ struct {
+ bool is_64;
+ } msi_attrib;
+};
+
+struct msi_desc {
+ struct msi_msg msg;
+ struct pci_msi_desc pci;
+};
+
+struct msix_entry {
+ int entry;
+ int vector;
+};
/*
* If we find drivers accessing this from multiple KPIs we may have to
* refcount objects of this structure.
*/
+struct resource;
struct pci_mmio_region {
TAILQ_ENTRY(pci_mmio_region) next;
struct resource *res;
@@ -286,6 +331,7 @@ struct pci_dev {
struct pci_driver *pdrv;
struct pci_bus *bus;
struct pci_dev *root;
+ pci_power_t current_state;
uint16_t device;
uint16_t vendor;
uint16_t subsystem_vendor;
@@ -294,39 +340,67 @@ struct pci_dev {
unsigned int devfn;
uint32_t class;
uint8_t revision;
+ uint8_t msi_cap;
+ uint8_t msix_cap;
bool managed; /* devres "pcim_*(). */
bool want_iomap_res;
bool msi_enabled;
bool msix_enabled;
phys_addr_t rom;
size_t romlen;
+ struct msi_desc **msi_desc;
+ char *path_name;
+ spinlock_t pcie_cap_lock;
TAILQ_HEAD(, pci_mmio_region) mmio;
};
-/* We need some meta-struct to keep track of these for devres. */
-struct pci_devres {
- bool enable_io;
- /* PCIR_MAX_BAR_0 + 1 = 6 => BIT(0..5). */
- uint8_t region_mask;
- struct resource *region_table[PCIR_MAX_BAR_0 + 1]; /* Not needed. */
-};
-struct pcim_iomap_devres {
- void *mmio_table[PCIR_MAX_BAR_0 + 1];
- struct resource *res_table[PCIR_MAX_BAR_0 + 1];
-};
-
-int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name);
int pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv,
unsigned int flags);
+bool pci_device_is_present(struct pci_dev *pdev);
+
+int linuxkpi_pcim_enable_device(struct pci_dev *pdev);
+void __iomem **linuxkpi_pcim_iomap_table(struct pci_dev *pdev);
+void *linuxkpi_pci_iomap_range(struct pci_dev *, int,
+ unsigned long, unsigned long);
+void *linuxkpi_pci_iomap(struct pci_dev *, int, unsigned long);
+void *linuxkpi_pcim_iomap(struct pci_dev *, int, unsigned long);
+void linuxkpi_pci_iounmap(struct pci_dev *pdev, void *res);
+int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask,
+ const char *name);
+int linuxkpi_pci_request_region(struct pci_dev *, int, const char *);
+int linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name);
+int linuxkpi_pcim_request_all_regions(struct pci_dev *, const char *);
+void linuxkpi_pci_release_region(struct pci_dev *pdev, int bar);
+void linuxkpi_pci_release_regions(struct pci_dev *pdev);
+int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries,
+ int nreq);
/* Internal helper function(s). */
struct pci_dev *lkpinew_pci_dev(device_t);
-struct pci_devres *lkpi_pci_devres_get_alloc(struct pci_dev *pdev);
void lkpi_pci_devres_release(struct device *, void *);
-struct resource *_lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size);
-struct pcim_iomap_devres *lkpi_pcim_iomap_devres_find(struct pci_dev *pdev);
-void lkpi_pcim_iomap_table_release(struct device *, void *);
+struct pci_dev *lkpi_pci_get_device(uint32_t, uint32_t, struct pci_dev *);
+struct msi_desc *lkpi_pci_msi_desc_alloc(int);
+struct device *lkpi_pci_find_irq_dev(unsigned int irq);
+int _lkpi_pci_enable_msi_range(struct pci_dev *pdev, int minvec, int maxvec);
+
+#define pci_err(pdev, fmt, ...) \
+ dev_err(&(pdev)->dev, fmt, ##__VA_ARGS__)
+#define pci_info(pdev, fmt, ...) \
+ dev_info(&(pdev)->dev, fmt, ##__VA_ARGS__)
+
+static inline bool
+dev_is_pci(struct device *dev)
+{
+
+ return (device_get_devclass(dev->bsddev) == devclass_find("pci"));
+}
+
+static inline uint16_t
+pci_dev_id(struct pci_dev *pdev)
+{
+ return (PCI_DEVID(pdev->bus->number, pdev->devfn));
+}
static inline int
pci_resource_type(struct pci_dev *pdev, int bar)
@@ -343,56 +417,6 @@ pci_resource_type(struct pci_dev *pdev, int bar)
return (SYS_RES_MEMORY);
}
-struct resource_list_entry *linux_pci_reserve_bar(struct pci_dev *pdev,
- struct resource_list *rl, int type, int rid);
-
-static inline struct resource_list_entry *
-linux_pci_get_rle(struct pci_dev *pdev, int type, int rid, bool reserve_bar)
-{
- struct pci_devinfo *dinfo;
- struct resource_list *rl;
- struct resource_list_entry *rle;
-
- dinfo = device_get_ivars(pdev->dev.bsddev);
- rl = &dinfo->resources;
- rle = resource_list_find(rl, type, rid);
- /* Reserve resources for this BAR if needed. */
- if (rle == NULL && reserve_bar)
- rle = linux_pci_reserve_bar(pdev, rl, type, rid);
- return (rle);
-}
-
-static inline struct resource_list_entry *
-linux_pci_get_bar(struct pci_dev *pdev, int bar, bool reserve)
-{
- int type;
-
- type = pci_resource_type(pdev, bar);
- if (type < 0)
- return (NULL);
- bar = PCIR_BAR(bar);
- return (linux_pci_get_rle(pdev, type, bar, reserve));
-}
-
-static inline struct device *
-linux_pci_find_irq_dev(unsigned int irq)
-{
- struct pci_dev *pdev;
- struct device *found;
-
- found = NULL;
- spin_lock(&pci_lock);
- list_for_each_entry(pdev, &pci_devices, links) {
- if (irq == pdev->dev.irq ||
- (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) {
- found = &pdev->dev;
- break;
- }
- }
- spin_unlock(&pci_lock);
- return (found);
-}
-
/*
* All drivers just seem to want to inspect the type not flags.
*/
@@ -410,8 +434,7 @@ pci_resource_flags(struct pci_dev *pdev, int bar)
static inline const char *
pci_name(struct pci_dev *d)
{
-
- return device_get_desc(d->dev.bsddev);
+ return d->path_name;
}
static inline void *
@@ -507,7 +530,20 @@ pci_upstream_bridge(struct pci_dev *pdev)
if (pdev == pdev->bus->self) {
device_t bridge;
- bridge = device_get_parent(pdev->dev.bsddev);
+ /*
+ * In the case of DRM drivers, the passed device is a child of
+ * `vgapci`. We want to start the lookup from `vgapci`, so the
+ * parent of the passed `drmn`.
+ *
+ * We can use the `isdrm` flag to determine this.
+ */
+ bridge = pdev->dev.bsddev;
+ if (pdev->pdrv != NULL && pdev->pdrv->isdrm)
+ bridge = device_get_parent(bridge);
+ if (bridge == NULL)
+ goto done;
+
+ bridge = device_get_parent(bridge);
if (bridge == NULL)
goto done;
bridge = device_get_parent(bridge);
@@ -527,73 +563,16 @@ done:
return (pdev->bus->self);
}
-static inline struct pci_devres *
-lkpi_pci_devres_find(struct pci_dev *pdev)
-{
-
- if (!pdev->managed)
- return (NULL);
-
- return (lkpi_pci_devres_get_alloc(pdev));
-}
-
-static inline void
-pci_release_region(struct pci_dev *pdev, int bar)
-{
- struct resource_list_entry *rle;
- struct pci_devres *dr;
- struct pci_mmio_region *mmio, *p;
-
- if ((rle = linux_pci_get_bar(pdev, bar, false)) == NULL)
- return;
-
- /*
- * As we implicitly track the requests we also need to clear them on
- * release. Do clear before resource release.
- */
- dr = lkpi_pci_devres_find(pdev);
- if (dr != NULL) {
- KASSERT(dr->region_table[bar] == rle->res, ("%s: pdev %p bar %d"
- " region_table res %p != rel->res %p\n", __func__, pdev,
- bar, dr->region_table[bar], rle->res));
- dr->region_table[bar] = NULL;
- dr->region_mask &= ~(1 << bar);
- }
-
- TAILQ_FOREACH_SAFE(mmio, &pdev->mmio, next, p) {
- if (rle->res != (void *)rman_get_bushandle(mmio->res))
- continue;
- TAILQ_REMOVE(&pdev->mmio, mmio, next);
- free(mmio, M_DEVBUF);
- }
-
- bus_release_resource(pdev->dev.bsddev, rle->type, rle->rid, rle->res);
-}
-
-static inline void
-pci_release_regions(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i <= PCIR_MAX_BAR_0; i++)
- pci_release_region(pdev, i);
-}
-
-static inline int
-pci_request_regions(struct pci_dev *pdev, const char *res_name)
-{
- int error;
- int i;
-
- for (i = 0; i <= PCIR_MAX_BAR_0; i++) {
- error = pci_request_region(pdev, i, res_name);
- if (error && error != -ENODEV) {
- pci_release_regions(pdev);
- return (error);
- }
- }
- return (0);
-}
+#define pci_request_region(pdev, bar, res_name) \
+ linuxkpi_pci_request_region(pdev, bar, res_name)
+#define pci_release_region(pdev, bar) \
+ linuxkpi_pci_release_region(pdev, bar)
+#define pci_request_regions(pdev, res_name) \
+ linuxkpi_pci_request_regions(pdev, res_name)
+#define pci_release_regions(pdev) \
+ linuxkpi_pci_release_regions(pdev)
+#define pcim_request_all_regions(pdev, name) \
+ linuxkpi_pcim_request_all_regions(pdev, name)
static inline void
lkpi_pci_disable_msix(struct pci_dev *pdev)
@@ -604,7 +583,7 @@ lkpi_pci_disable_msix(struct pci_dev *pdev)
/*
* The MSIX IRQ numbers associated with this PCI device are no
* longer valid and might be re-assigned. Make sure
- * linux_pci_find_irq_dev() does no longer see them by
+ * lkpi_pci_find_irq_dev() does no longer see them by
* resetting their references to zero:
*/
pdev->dev.irq_start = 0;
@@ -759,13 +738,10 @@ int linux_pci_register_drm_driver(struct pci_driver *pdrv);
void linux_pci_unregister_driver(struct pci_driver *pdrv);
void linux_pci_unregister_drm_driver(struct pci_driver *pdrv);
-#define pci_register_driver(pdrv) linux_pci_register_driver(pdrv)
-#define pci_unregister_driver(pdrv) linux_pci_unregister_driver(pdrv)
-
-struct msix_entry {
- int entry;
- int vector;
-};
+#define pci_register_driver(pdrv) \
+ linux_pci_register_driver(pdrv)
+#define pci_unregister_driver(pdrv) \
+ linux_pci_unregister_driver(pdrv)
/*
* Enable msix, positive errors indicate actual number of available
@@ -774,45 +750,11 @@ struct msix_entry {
* NB: define added to prevent this definition of pci_enable_msix from
* clashing with the native FreeBSD version.
*/
-#define pci_enable_msix(...) \
- linux_pci_enable_msix(__VA_ARGS__)
+#define pci_enable_msix(...) \
+ linuxkpi_pci_enable_msix(__VA_ARGS__)
-static inline int
-pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, int nreq)
-{
- struct resource_list_entry *rle;
- int error;
- int avail;
- int i;
-
- avail = pci_msix_count(pdev->dev.bsddev);
- if (avail < nreq) {
- if (avail == 0)
- return -EINVAL;
- return avail;
- }
- avail = nreq;
- if ((error = -pci_alloc_msix(pdev->dev.bsddev, &avail)) != 0)
- return error;
- /*
- * Handle case where "pci_alloc_msix()" may allocate less
- * interrupts than available and return with no error:
- */
- if (avail < nreq) {
- pci_release_msi(pdev->dev.bsddev);
- return avail;
- }
- rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false);
- pdev->dev.irq_start = rle->start;
- pdev->dev.irq_end = rle->start + avail;
- for (i = 0; i < nreq; i++)
- entries[i].vector = pdev->dev.irq_start + i;
- pdev->msix_enabled = true;
- return (0);
-}
-
-#define pci_enable_msix_range(...) \
- linux_pci_enable_msix_range(__VA_ARGS__)
+#define pci_enable_msix_range(...) \
+ linux_pci_enable_msix_range(__VA_ARGS__)
static inline int
pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
@@ -837,30 +779,14 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
return (nvec);
}
-#define pci_enable_msi(pdev) \
- linux_pci_enable_msi(pdev)
+#define pci_enable_msi(pdev) \
+ linux_pci_enable_msi(pdev)
static inline int
pci_enable_msi(struct pci_dev *pdev)
{
- struct resource_list_entry *rle;
- int error;
- int avail;
-
- avail = pci_msi_count(pdev->dev.bsddev);
- if (avail < 1)
- return -EINVAL;
-
- avail = 1; /* this function only enable one MSI IRQ */
- if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0)
- return error;
- rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1, false);
- pdev->dev.irq_start = rle->start;
- pdev->dev.irq_end = rle->start + avail;
- pdev->irq = rle->start;
- pdev->msi_enabled = true;
- return (0);
+ return (_lkpi_pci_enable_msi_range(pdev, 1, 1));
}
static inline int
@@ -879,35 +805,14 @@ static inline void pci_disable_sriov(struct pci_dev *dev)
{
}
-static inline void *
-pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size)
-{
- struct resource *res;
-
- res = _lkpi_pci_iomap(pdev, mmio_bar, mmio_size);
- if (res == NULL)
- return (NULL);
- /* This is a FreeBSD extension so we can use bus_*(). */
- if (pdev->want_iomap_res)
- return (res);
- return ((void *)rman_get_bushandle(res));
-}
-
-static inline void
-pci_iounmap(struct pci_dev *pdev, void *res)
-{
- struct pci_mmio_region *mmio, *p;
-
- TAILQ_FOREACH_SAFE(mmio, &pdev->mmio, next, p) {
- if (res != (void *)rman_get_bushandle(mmio->res))
- continue;
- bus_release_resource(pdev->dev.bsddev,
- mmio->type, mmio->rid, mmio->res);
- TAILQ_REMOVE(&pdev->mmio, mmio, next);
- free(mmio, M_DEVBUF);
- return;
- }
-}
+#define pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) \
+ linuxkpi_pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size)
+#define pci_iomap(pdev, mmio_bar, mmio_size) \
+ linuxkpi_pci_iomap(pdev, mmio_bar, mmio_size)
+#define pcim_iomap(pdev, bar, maxlen) \
+ linuxkpi_pcim_iomap(pdev, bar, maxlen)
+#define pci_iounmap(pdev, res) \
+ linuxkpi_pci_iounmap(pdev, res)
static inline void
lkpi_pci_save_state(struct pci_dev *pdev)
@@ -926,6 +831,13 @@ lkpi_pci_restore_state(struct pci_dev *pdev)
#define pci_save_state(dev) lkpi_pci_save_state(dev)
#define pci_restore_state(dev) lkpi_pci_restore_state(dev)
+static inline int
+pci_reset_function(struct pci_dev *pdev)
+{
+
+ return (-ENOSYS);
+}
+
#define DEFINE_PCI_DEVICE_TABLE(_table) \
const struct pci_device_id _table[] __devinitdata
@@ -1110,6 +1022,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
static inline int
pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *dst)
{
+ *dst = 0;
if (pos & 3)
return -EINVAL;
@@ -1122,6 +1035,7 @@ pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *dst)
static inline int
pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *dst)
{
+ *dst = 0;
if (pos & 3)
return -EINVAL;
@@ -1144,21 +1058,40 @@ pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
}
static inline int
-pcie_capability_set_word(struct pci_dev *dev, int pos, uint16_t val)
+pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+ uint16_t clear, uint16_t set)
{
int error;
uint16_t v;
+ if (pos == PCI_EXP_LNKCTL || pos == PCI_EXP_RTCTL)
+ spin_lock(&dev->pcie_cap_lock);
+
error = pcie_capability_read_word(dev, pos, &v);
- if (error != 0)
- return (error);
+ if (error == 0) {
+ v &= ~clear;
+ v |= set;
+ error = pcie_capability_write_word(dev, pos, v);
+ }
- v |= val;
+ if (pos == PCI_EXP_LNKCTL || pos == PCI_EXP_RTCTL)
+ spin_unlock(&dev->pcie_cap_lock);
- error = pcie_capability_write_word(dev, pos, v);
return (error);
}
+static inline int
+pcie_capability_set_word(struct pci_dev *dev, int pos, uint16_t val)
+{
+ return (pcie_capability_clear_and_set_word(dev, pos, 0, val));
+}
+
+static inline int
+pcie_capability_clear_word(struct pci_dev *dev, int pos, uint16_t val)
+{
+ return (pcie_capability_clear_and_set_word(dev, pos, val, 0));
+}
+
static inline int pcie_get_minimum_link(struct pci_dev *dev,
enum pci_bus_speed *speed, enum pcie_link_width *width)
{
@@ -1208,6 +1141,10 @@ pcie_get_speed_cap(struct pci_dev *dev)
return (PCIE_SPEED_8_0GT);
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB)
return (PCIE_SPEED_16_0GT);
+ if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_32_0GB)
+ return (PCIE_SPEED_32_0GT);
+ if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_64_0GB)
+ return (PCIE_SPEED_64_0GT);
} else { /* pre-r3.0 */
lnkcap = pci_read_config(root, pos + PCIER_LINK_CAP, 4);
if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
@@ -1218,6 +1155,10 @@ pcie_get_speed_cap(struct pci_dev *dev)
return (PCIE_SPEED_8_0GT);
if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB)
return (PCIE_SPEED_16_0GT);
+ if (lnkcap & PCI_EXP_LNKCAP_SLS_32_0GB)
+ return (PCIE_SPEED_32_0GT);
+ if (lnkcap & PCI_EXP_LNKCAP_SLS_64_0GB)
+ return (PCIE_SPEED_64_0GT);
}
return (PCI_SPEED_UNKNOWN);
}
@@ -1245,6 +1186,10 @@ PCIE_SPEED2MBS_ENC(enum pci_bus_speed spd)
{
switch(spd) {
+ case PCIE_SPEED_64_0GT:
+ return (64000 * 128 / 130);
+ case PCIE_SPEED_32_0GT:
+ return (32000 * 128 / 130);
case PCIE_SPEED_16_0GT:
return (16000 * 128 / 130);
case PCIE_SPEED_8_0GT:
@@ -1275,6 +1220,12 @@ pcie_bandwidth_available(struct pci_dev *pdev,
return (nwidth * PCIE_SPEED2MBS_ENC(nspeed));
}
+static inline bool
+pcie_aspm_enabled(struct pci_dev *pdev)
+{
+ return (false);
+}
+
static inline struct pci_dev *
pcie_find_root_port(struct pci_dev *pdev)
{
@@ -1307,6 +1258,29 @@ pci_stop_and_remove_bus_device(struct pci_dev *pdev)
{
}
+static inline int
+pci_rescan_bus(struct pci_bus *pbus)
+{
+ device_t *devlist, parent;
+ int devcount, error;
+
+ if (!device_is_attached(pbus->self->dev.bsddev))
+ return (0);
+ /* pci_rescan_method() will work on the pcib (parent). */
+ error = BUS_RESCAN(pbus->self->dev.bsddev);
+ if (error != 0)
+ return (0);
+
+ parent = device_get_parent(pbus->self->dev.bsddev);
+ error = device_get_children(parent, &devlist, &devcount);
+ if (error != 0)
+ return (0);
+ if (devcount != 0)
+ free(devlist, M_TEMP);
+
+ return (devcount);
+}
+
/*
* The following functions can be used to attach/detach the LinuxKPI's
* PCI device runtime. The pci_driver and pci_device_id pointer is
@@ -1330,11 +1304,40 @@ pci_dev_present(const struct pci_device_id *cur)
return (0);
}
+static inline const struct pci_device_id *
+pci_match_id(const struct pci_device_id *ids, struct pci_dev *pdev)
+{
+ if (ids == NULL)
+ return (NULL);
+
+ for (;
+ ids->vendor != 0 || ids->subvendor != 0 || ids->class_mask != 0;
+ ids++)
+ if ((ids->vendor == PCI_ANY_ID ||
+ ids->vendor == pdev->vendor) &&
+ (ids->device == PCI_ANY_ID ||
+ ids->device == pdev->device) &&
+ (ids->subvendor == PCI_ANY_ID ||
+ ids->subvendor == pdev->subsystem_vendor) &&
+ (ids->subdevice == PCI_ANY_ID ||
+ ids->subdevice == pdev->subsystem_device) &&
+ ((ids->class ^ pdev->class) & ids->class_mask) == 0)
+ return (ids);
+
+ return (NULL);
+}
+
struct pci_dev *lkpi_pci_get_domain_bus_and_slot(int domain,
unsigned int bus, unsigned int devfn);
#define pci_get_domain_bus_and_slot(domain, bus, devfn) \
lkpi_pci_get_domain_bus_and_slot(domain, bus, devfn)
+struct pci_dev *lkpi_pci_get_slot(struct pci_bus *, unsigned int);
+#ifndef WANT_NATIVE_PCI_GET_SLOT
+#define pci_get_slot(_pbus, _devfn) \
+ lkpi_pci_get_slot(_pbus, _devfn)
+#endif
+
static inline int
pci_domain_nr(struct pci_bus *pbus)
{
@@ -1398,66 +1401,25 @@ pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int pos,
struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from);
#define pci_get_class(class, from) lkpi_pci_get_class(class, from)
+struct pci_dev *lkpi_pci_get_base_class(unsigned int class,
+ struct pci_dev *from);
+#define pci_get_base_class(class, from) lkpi_pci_get_base_class(class, from)
/* -------------------------------------------------------------------------- */
-static inline int
-pcim_enable_device(struct pci_dev *pdev)
-{
- struct pci_devres *dr;
- int error;
-
- /* Here we cannot run through the pdev->managed check. */
- dr = lkpi_pci_devres_get_alloc(pdev);
- if (dr == NULL)
- return (-ENOMEM);
-
- /* If resources were enabled before do not do it again. */
- if (dr->enable_io)
- return (0);
-
- error = pci_enable_device(pdev);
- if (error == 0)
- dr->enable_io = true;
-
- /* This device is not managed. */
- pdev->managed = true;
-
- return (error);
-}
-
-static inline void __iomem **
-pcim_iomap_table(struct pci_dev *pdev)
-{
- struct pcim_iomap_devres *dr;
-
- dr = lkpi_pcim_iomap_devres_find(pdev);
- if (dr == NULL)
- return (NULL);
-
- /*
- * If the driver has manually set a flag to be able to request the
- * resource to use bus_read/write_<n>, return the shadow table.
- */
- if (pdev->want_iomap_res)
- return ((void **)dr->res_table);
-
- /* This is the Linux default. */
- return (dr->mmio_table);
-}
+#define pcim_enable_device(pdev) \
+ linuxkpi_pcim_enable_device(pdev)
+#define pcim_iomap_table(pdev) \
+ linuxkpi_pcim_iomap_table(pdev)
+#define pcim_iomap_regions(pdev, mask, name) \
+ linuxkpi_pcim_iomap_regions(pdev, mask, name)
static inline int
pcim_iomap_regions_request_all(struct pci_dev *pdev, uint32_t mask, char *name)
{
- struct pcim_iomap_devres *dr;
- void *res;
- uint32_t mappings, requests, req_mask;
+ uint32_t requests, req_mask;
int bar, error;
- dr = lkpi_pcim_iomap_devres_find(pdev);
- if (dr == NULL)
- return (-ENOMEM);
-
/* Request all the BARs ("regions") we do not iomap. */
req_mask = ((1 << (PCIR_MAX_BAR_0 + 1)) - 1) & ~mask;
for (bar = requests = 0; requests != req_mask; bar++) {
@@ -1469,44 +1431,37 @@ pcim_iomap_regions_request_all(struct pci_dev *pdev, uint32_t mask, char *name)
requests |= (1 << bar);
}
- /* Now iomap all the requested (by "mask") ones. */
- for (bar = mappings = 0; mappings != mask; bar++) {
- if ((mask & (1 << bar)) == 0)
- continue;
-
- /* Request double is not allowed. */
- if (dr->mmio_table[bar] != NULL) {
- device_printf(pdev->dev.bsddev, "%s: bar %d %p\n",
- __func__, bar, dr->mmio_table[bar]);
- goto err;
- }
-
- res = _lkpi_pci_iomap(pdev, bar, 0);
- if (res == NULL)
- goto err;
- dr->mmio_table[bar] = (void *)rman_get_bushandle(res);
- dr->res_table[bar] = res;
-
- mappings |= (1 << bar);
- }
+ error = pcim_iomap_regions(pdev, mask, name);
+ if (error != 0)
+ goto err;
return (0);
err:
for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) {
- if ((mappings & (1 << bar)) != 0) {
- res = dr->mmio_table[bar];
- if (res == NULL)
- continue;
- pci_iounmap(pdev, res);
- } else if ((requests & (1 << bar)) != 0) {
+ if ((requests & (1 << bar)) != 0)
pci_release_region(pdev, bar);
- }
}
return (-EINVAL);
}
+/*
+ * We cannot simply re-define pci_get_device() as we would normally do
+ * and then hide it in linux_pci.c as too many semi-native drivers still
+ * include linux/pci.h and run into the conflict with native PCI. Linux drivers
+ * using pci_get_device() need to be changed to call linuxkpi_pci_get_device().
+ */
+static inline struct pci_dev *
+linuxkpi_pci_get_device(uint32_t vendor, uint32_t device, struct pci_dev *odev)
+{
+
+ return (lkpi_pci_get_device(vendor, device, odev));
+}
+
+#define for_each_pci_dev(_pdev) \
+ while ((_pdev = linuxkpi_pci_get_device(PCI_ANY_ID, PCI_ANY_ID, _pdev)) != NULL)
+
/* This is a FreeBSD extension so we can use bus_*(). */
static inline void
linuxkpi_pcim_want_to_use_bus_functions(struct pci_dev *pdev)
@@ -1514,4 +1469,94 @@ linuxkpi_pcim_want_to_use_bus_functions(struct pci_dev *pdev)
pdev->want_iomap_res = true;
}
+static inline bool
+pci_is_thunderbolt_attached(struct pci_dev *pdev)
+{
+
+ return (false);
+}
+
+static inline void *
+pci_platform_rom(struct pci_dev *pdev, size_t *size)
+{
+
+ return (NULL);
+}
+
+static inline void
+pci_ignore_hotplug(struct pci_dev *pdev)
+{
+}
+
+static inline const char *
+pci_power_name(pci_power_t state)
+{
+ int pstate = state + 1;
+
+ if (pstate >= 0 && pstate < nitems(pci_power_names))
+ return (pci_power_names[pstate]);
+ else
+ return (pci_power_names[0]);
+}
+
+static inline int
+pcie_get_readrq(struct pci_dev *dev)
+{
+ u16 ctl;
+
+ if (pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl))
+ return (-EINVAL);
+
+ return (128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12));
+}
+
+static inline bool
+pci_is_enabled(struct pci_dev *pdev)
+{
+
+ return ((pci_read_config(pdev->dev.bsddev, PCIR_COMMAND, 2) &
+ PCIM_CMD_BUSMASTEREN) != 0);
+}
+
+static inline int
+pci_wait_for_pending_transaction(struct pci_dev *pdev)
+{
+
+ return (0);
+}
+
+static inline int
+pci_assign_resource(struct pci_dev *pdev, int bar)
+{
+
+ return (0);
+}
+
+static inline int
+pci_irq_vector(struct pci_dev *pdev, unsigned int vector)
+{
+
+ if (!pdev->msix_enabled && !pdev->msi_enabled) {
+ if (vector != 0)
+ return (-EINVAL);
+ return (pdev->irq);
+ }
+
+ if (pdev->msix_enabled || pdev->msi_enabled) {
+ if ((pdev->dev.irq_start + vector) >= pdev->dev.irq_end)
+ return (-EINVAL);
+ return (pdev->dev.irq_start + vector);
+ }
+
+ return (-ENXIO);
+}
+
+static inline int
+pci_wake_from_d3(struct pci_dev *pdev, bool enable)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
#endif /* _LINUXKPI_LINUX_PCI_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/pci_ids.h b/sys/compat/linuxkpi/common/include/linux/pci_ids.h
index 519d1b6eb663..e318f6f75ce7 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci_ids.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci_ids.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PCI_IDS_H
@@ -41,23 +39,31 @@
#define PCI_BASE_CLASS_BRIDGE 0x06
#define PCI_CLASS_BRIDGE_ISA 0x0601
+#define PCI_CLASS_ACCELERATOR_PROCESSING 0x1200
+
/* XXX We should really generate these and use them throughout the tree. */
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_VENDOR_ID_ASUSTEK 0x1043
+#define PCI_VENDOR_ID_ASMEDIA 0x1b21
+#define PCI_VENDOR_ID_ATHEROS 0x168c
#define PCI_VENDOR_ID_ATI 0x1002
#define PCI_VENDOR_ID_BROADCOM 0x14e4
#define PCI_VENDOR_ID_DELL 0x1028
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_VENDOR_ID_ITTIM 0x0b48
+#define PCI_VENDOR_ID_MEDIATEK 0x14c3
#define PCI_VENDOR_ID_MELLANOX 0x15b3
+#define PCI_VENDOR_ID_QCOM 0x17cb
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_VENDOR_ID_SERVERWORKS 0x1166
#define PCI_VENDOR_ID_SONY 0x104d
#define PCI_VENDOR_ID_TOPSPIN 0x1867
+#define PCI_VENDOR_ID_UBIQUITI 0x0777
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159
diff --git a/sys/compat/linuxkpi/common/include/linux/perf_event.h b/sys/compat/linuxkpi/common/include/linux/perf_event.h
new file mode 100644
index 000000000000..86b0d06cdc1f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/perf_event.h
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_PERF_EVENT_H_
+#define _LINUXKPI_LINUX_PERF_EVENT_H_
+
+#include <linux/cgroup.h>
+
+#endif /* _LINUXKPI_LINUX_PERF_EVENT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/pfn.h b/sys/compat/linuxkpi/common/include/linux/pfn.h
index 675f5d21364a..26d47b9bc3b1 100644
--- a/sys/compat/linuxkpi/common/include/linux/pfn.h
+++ b/sys/compat/linuxkpi/common/include/linux/pfn.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PFN_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/pfn_t.h b/sys/compat/linuxkpi/common/include/linux/pfn_t.h
index 48fb4f59a3c6..f22289802cb8 100644
--- a/sys/compat/linuxkpi/common/include/linux/pfn_t.h
+++ b/sys/compat/linuxkpi/common/include/linux/pfn_t.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PFN_T_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/pid.h b/sys/compat/linuxkpi/common/include/linux/pid.h
index be7c9384d4cf..60cb9f725b21 100644
--- a/sys/compat/linuxkpi/common/include/linux/pid.h
+++ b/sys/compat/linuxkpi/common/include/linux/pid.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PID_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/platform_device.h b/sys/compat/linuxkpi/common/include/linux/platform_device.h
new file mode 100644
index 000000000000..6853e709cb70
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/platform_device.h
@@ -0,0 +1,97 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020-2022 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_PLATFORM_DEVICE_H
+#define _LINUXKPI_LINUX_PLATFORM_DEVICE_H
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+
+struct platform_device {
+ const char *name;
+ int id;
+ bool id_auto;
+ struct device dev;
+};
+
+struct platform_driver {
+ int (*remove)(struct platform_device *);
+ struct device_driver driver;
+};
+
+#define dev_is_platform(dev) (false)
+#define to_platform_device(dev) (NULL)
+
+static __inline int
+platform_driver_register(struct platform_driver *pdrv)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENXIO);
+}
+
+static __inline void *
+dev_get_platdata(struct device *dev)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static __inline int
+platform_driver_probe(struct platform_driver *pdrv,
+ int(*pd_probe_f)(struct platform_device *))
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENODEV);
+}
+
+static __inline void
+platform_driver_unregister(struct platform_driver *pdrv)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return;
+}
+
+static __inline int
+platform_device_register(struct platform_device *pdev)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static __inline void
+platform_device_unregister(struct platform_device *pdev)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return;
+}
+
+#endif /* _LINUXKPI_LINUX_PLATFORM_DEVICE_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/pm.h b/sys/compat/linuxkpi/common/include/linux/pm.h
index 255c9bf0ea8b..c8d943027909 100644
--- a/sys/compat/linuxkpi/common/include/linux/pm.h
+++ b/sys/compat/linuxkpi/common/include/linux/pm.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2020 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,31 +26,75 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PM_H
#define _LINUXKPI_LINUX_PM_H
+#include <linux/kernel.h> /* pr_debug */
+#include <asm/atomic.h>
+
+/* Needed but breaks linux_usb.c */
+/* #include <linux/completion.h> */
+/* #include <linux/wait.h> */
+
+struct device;
+
typedef struct pm_message {
int event;
} pm_message_t;
+struct dev_pm_domain {
+};
+
+struct dev_pm_info {
+ atomic_t usage_count;
+};
+
+#define PM_EVENT_FREEZE 0x0001
+#define PM_EVENT_SUSPEND 0x0002
+
+#define pm_sleep_ptr(_p) \
+ IS_ENABLED(CONFIG_PM_SLEEP) ? (_p) : NULL
+
#ifdef CONFIG_PM_SLEEP
+#define __SET_PM_OPS(_suspendfunc, _resumefunc) \
+ .suspend = _suspendfunc, \
+ .resume = _resumefunc, \
+ .freeze = _suspendfunc, \
+ .thaw = _resumefunc, \
+ .poweroff = _suspendfunc, \
+ .restore = _resumefunc, \
+
#define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
const struct dev_pm_ops _name = { \
- .suspend = _suspendfunc, \
- .resume = _resumefunc, \
- .freeze = _suspendfunc, \
- .thaw = _resumefunc, \
- .poweroff = _suspendfunc, \
- .restore = _resumefunc, \
+ __SET_PM_OPS(_suspendfunc, _resumefunc) \
}
+
+#define DEFINE_SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
+const struct dev_pm_ops _name = { \
+ __SET_PM_OPS(_suspendfunc, _resumefunc) \
+}
+
+#define SET_SYSTEM_SLEEP_PM_OPS(_suspendfunc, _resumefunc) \
+ __SET_PM_OPS(_suspendfunc, _resumefunc)
#else
#define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
const struct dev_pm_ops _name = { \
}
+#define DEFINE_SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
+const struct dev_pm_ops _name = { \
+}
#endif
+bool linuxkpi_device_can_wakeup(struct device *);
+#define device_can_wakeup(_dev) linuxkpi_device_can_wakeup(_dev)
+
+static inline void
+pm_wakeup_event(struct device *dev __unused, unsigned int x __unused)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
#endif /* _LINUXKPI_LINUX_PM_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/pm_qos.h b/sys/compat/linuxkpi/common/include/linux/pm_qos.h
index 8a9b3bdbd1ef..47c41a819ba8 100644
--- a/sys/compat/linuxkpi/common/include/linux/pm_qos.h
+++ b/sys/compat/linuxkpi/common/include/linux/pm_qos.h
@@ -23,8 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PM_QOS_H
diff --git a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
index 42c96a92b1ad..6114b7b159d7 100644
--- a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
+++ b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
@@ -34,10 +34,21 @@ pm_runtime_get_if_in_use(struct device *dev)
return 1;
}
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION < 60900
static inline int
pm_runtime_get_if_active(struct device *dev, bool x)
+#else
+static inline int
+pm_runtime_get_if_active(struct device *dev)
+#endif
{
return 1;
}
+static inline int
+pm_runtime_suspended(struct device *dev)
+{
+ return 0;
+}
+
#endif /* _LINUXKPI_LINUX_PM_RUNTIME_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/poll.h b/sys/compat/linuxkpi/common/include/linux/poll.h
index ff83fb1959f6..3acb3c740954 100644
--- a/sys/compat/linuxkpi/common/include/linux/poll.h
+++ b/sys/compat/linuxkpi/common/include/linux/poll.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_POLL_H_
#define _LINUXKPI_LINUX_POLL_H_
@@ -34,6 +32,7 @@
#include <sys/poll.h>
#include <sys/fcntl.h>
+#include <linux/eventpoll.h>
#include <linux/wait.h>
#include <linux/file.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/power_supply.h b/sys/compat/linuxkpi/common/include/linux/power_supply.h
index cf8a937b04ad..8855cfff0539 100644
--- a/sys/compat/linuxkpi/common/include/linux/power_supply.h
+++ b/sys/compat/linuxkpi/common/include/linux/power_supply.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_POWER_SUPPLY_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/preempt.h b/sys/compat/linuxkpi/common/include/linux/preempt.h
index b8deb23d7089..32177d4a980c 100644
--- a/sys/compat/linuxkpi/common/include/linux/preempt.h
+++ b/sys/compat/linuxkpi/common/include/linux/preempt.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PREEMPT_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/prefetch.h b/sys/compat/linuxkpi/common/include/linux/prefetch.h
index aa997d50a3f3..71839f0ca191 100644
--- a/sys/compat/linuxkpi/common/include/linux/prefetch.h
+++ b/sys/compat/linuxkpi/common/include/linux/prefetch.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PREFETCH_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h
index 317c6232bbc5..d2d197682782 100644
--- a/sys/compat/linuxkpi/common/include/linux/printk.h
+++ b/sys/compat/linuxkpi/common/include/linux/printk.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_PRINTK_H_
#define _LINUXKPI_LINUX_PRINTK_H_
@@ -46,57 +44,19 @@ enum {
DUMP_PREFIX_OFFSET
};
+int __lkpi_hexdump_printf(void *, const char *, ...) __printflike(2, 3);
+
+void lkpi_hex_dump(int(*)(void *, const char *, ...), void *arg1,
+ const char *, const char *, const int, const int, const int,
+ const void *, size_t, const bool);
+
static inline void
print_hex_dump(const char *level, const char *prefix_str,
const int prefix_type, const int rowsize, const int groupsize,
const void *buf, size_t len, const bool ascii)
{
- typedef const struct { long long value; } __packed *print_64p_t;
- typedef const struct { uint32_t value; } __packed *print_32p_t;
- typedef const struct { uint16_t value; } __packed *print_16p_t;
- const void *buf_old = buf;
- int row;
-
- while (len > 0) {
- if (level != NULL)
- printf("%s", level);
- if (prefix_str != NULL)
- printf("%s ", prefix_str);
-
- switch (prefix_type) {
- case DUMP_PREFIX_ADDRESS:
- printf("[%p] ", buf);
- break;
- case DUMP_PREFIX_OFFSET:
- printf("[%#tx] ", ((const char *)buf -
- (const char *)buf_old));
- break;
- default:
- break;
- }
- for (row = 0; row != rowsize; row++) {
- if (groupsize == 8 && len > 7) {
- printf("%016llx ", ((print_64p_t)buf)->value);
- buf = (const uint8_t *)buf + 8;
- len -= 8;
- } else if (groupsize == 4 && len > 3) {
- printf("%08x ", ((print_32p_t)buf)->value);
- buf = (const uint8_t *)buf + 4;
- len -= 4;
- } else if (groupsize == 2 && len > 1) {
- printf("%04x ", ((print_16p_t)buf)->value);
- buf = (const uint8_t *)buf + 2;
- len -= 2;
- } else if (len > 0) {
- printf("%02x ", *(const uint8_t *)buf);
- buf = (const uint8_t *)buf + 1;
- len--;
- } else {
- break;
- }
- }
- printf("\n");
- }
+ lkpi_hex_dump(__lkpi_hexdump_printf, NULL, level, prefix_str, prefix_type,
+ rowsize, groupsize, buf, len, ascii);
}
static inline void
@@ -127,4 +87,17 @@ print_hex_dump_bytes(const char *prefix_str, const int prefix_type,
#define pr_info_ratelimited(fmt, ...) \
printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+#define no_printk(fmt, ...) \
+({ \
+ if (0) \
+ printk(pr_fmt(fmt), ##__VA_ARGS__); \
+ 0; \
+})
+
+#define FW_BUG "[Firmware Bug]: "
+#define FW_WARN "[Firmware Warn]: "
+#define FW_INFO "[Firmware Info]: "
+#define HW_ERR "[Hardware Error]: "
+#define DEPRECATED "[Deprecated]: "
+
#endif /* _LINUXKPI_LINUX_PRINTK_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h
new file mode 100644
index 000000000000..aad46cc25b1b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2023 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_PTP_CLOCK_KERNEL_H
+#define _LINUXKPI_LINUX_PTP_CLOCK_KERNEL_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/kernel.h> /* pr_debug */
+#include <linux/ktime.h> /* system_device_crosststamp */
+
+/* This very likely belongs elsewhere. */
+struct system_device_crosststamp {
+ ktime_t device;
+ ktime_t sys_realtime;
+ ktime_t sys_monotonic_raw; /* name guessed based on comment */
+};
+
+struct ptp_clock_info {
+ char name[32];
+ int max_adj;
+ void *owner; /* THIS_MODULE */
+ int (*adjfine)(struct ptp_clock_info *, long);
+ int (*adjtime)(struct ptp_clock_info *, s64);
+ int (*getcrosststamp)(struct ptp_clock_info *, struct system_device_crosststamp *);
+ int (*gettime64)(struct ptp_clock_info *, struct timespec *);
+};
+
+static inline struct ptp_clock *
+ptp_clock_register(struct ptp_clock_info *ptpci, struct device *dev)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline void
+ptp_clock_unregister(struct ptp_clock *ptpc)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline int
+ptp_clock_index(struct ptp_clock *ptpc)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+#endif /* _LINUXKPI_LINUX_PTP_CLOCK_KERNEL_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/pwm.h b/sys/compat/linuxkpi/common/include/linux/pwm.h
index 59a17f525c91..c0740db675e8 100644
--- a/sys/compat/linuxkpi/common/include/linux/pwm.h
+++ b/sys/compat/linuxkpi/common/include/linux/pwm.h
@@ -91,4 +91,10 @@ pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
return (-ENOTSUPP);
}
+static inline int
+pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)
+{
+ return (0);
+}
+
#endif /* _LINUXKPI_LINUX_PWM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/qrtr.h b/sys/compat/linuxkpi/common/include/linux/qrtr.h
new file mode 100644
index 000000000000..1d2af0efdce2
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/qrtr.h
@@ -0,0 +1,41 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_QRTR_H
+#define _LINUXKPI_LINUX_QRTR_H
+
+/* Qualcomm IPC Router (QRTR) */
+
+#include <sys/socket.h>
+
+struct sockaddr_qrtr {
+ sa_family_t sq_family;
+ uint32_t sq_node;
+ uint32_t sq_port;
+};
+
+#endif /* _LINUXKPI_LINUX_QRTR_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h
index 86620614fb36..ea75836c26fb 100644
--- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h
+++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h
@@ -25,12 +25,11 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RADIX_TREE_H_
#define _LINUXKPI_LINUX_RADIX_TREE_H_
+#include <linux/rcupdate.h>
#include <linux/types.h>
#define RADIX_TREE_MAP_SHIFT 6
diff --git a/sys/compat/linuxkpi/common/include/linux/random.h b/sys/compat/linuxkpi/common/include/linux/random.h
index fafb87cae9fe..893ee2b7b728 100644
--- a/sys/compat/linuxkpi/common/include/linux/random.h
+++ b/sys/compat/linuxkpi/common/include/linux/random.h
@@ -4,6 +4,10 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
* All rights reserved.
+ * Copyright 2023 The FreeBSD Foundation
+ *
+ * Portions of this software was developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,8 +29,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RANDOM_H_
@@ -36,8 +38,6 @@
#include <sys/random.h>
#include <sys/libkern.h>
-#define get_random_u32() get_random_int()
-
static inline void
get_random_bytes(void *buf, int nbytes)
{
@@ -54,6 +54,39 @@ get_random_int(void)
return (val);
}
+static inline uint8_t
+get_random_u8(void)
+{
+ uint8_t val;
+
+ get_random_bytes(&val, sizeof(val));
+ return (val);
+}
+
+#define get_random_u32() get_random_int()
+
+/*
+ * See "Fast Random Integer Generation in an Interval" by Daniel Lemire
+ * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights.
+ */
+static inline uint32_t
+get_random_u32_inclusive(uint32_t floor, uint32_t ceil)
+{
+ uint64_t x;
+ uint32_t t, v;
+
+ MPASS(ceil >= floor);
+
+ v = get_random_u32();
+ t = ceil - floor + 1;
+ x = (uint64_t)t * v;
+ while (x < t)
+ x = (uint64_t)t * get_random_u32();
+ v = x >> 32;
+
+ return (floor + v);
+}
+
static inline u_long
get_random_long(void)
{
@@ -63,6 +96,21 @@ get_random_long(void)
return (val);
}
+static inline uint64_t
+get_random_u64(void)
+{
+ uint64_t val;
+
+ get_random_bytes(&val, sizeof(val));
+ return (val);
+}
+
+static inline uint32_t
+get_random_u32_below(uint32_t max)
+{
+ return (arc4random_uniform(max));
+}
+
static __inline uint32_t
prandom_u32(void)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/rbtree.h b/sys/compat/linuxkpi/common/include/linux/rbtree.h
index de5ef0d6a3ce..e6033cfd760d 100644
--- a/sys/compat/linuxkpi/common/include/linux/rbtree.h
+++ b/sys/compat/linuxkpi/common/include/linux/rbtree.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RBTREE_H_
#define _LINUXKPI_LINUX_RBTREE_H_
@@ -41,8 +39,8 @@
struct rb_node {
RB_ENTRY(rb_node) __entry;
};
-#define rb_left __entry.rbe_left
-#define rb_right __entry.rbe_right
+#define rb_left __entry.rbe_link[_RB_L]
+#define rb_right __entry.rbe_link[_RB_R]
/*
* We provide a false structure that has the same bit pattern as tree.h
@@ -74,8 +72,11 @@ RB_PROTOTYPE(linux_root, rb_node, __entry, panic_cmp);
#define RB_EMPTY_NODE(node) (RB_PARENT(node, __entry) == node)
#define RB_CLEAR_NODE(node) RB_SET_PARENT(node, node, __entry)
-#define rb_insert_color(node, root) \
- linux_root_RB_INSERT_COLOR((struct linux_root *)(root), (node))
+#define rb_insert_color(node, root) do { \
+ if (rb_parent(node)) \
+ linux_root_RB_INSERT_COLOR((struct linux_root *)(root), \
+ rb_parent(node), (node)); \
+} while (0)
#define rb_erase(node, root) \
linux_root_RB_REMOVE((struct linux_root *)(root), (node))
#define rb_next(node) RB_NEXT(linux_root, NULL, (node))
@@ -132,11 +133,12 @@ rb_replace_node(struct rb_node *victim, struct rb_node *new,
struct rb_root *root)
{
- RB_SWAP_CHILD((struct linux_root *)root, victim, new, __entry);
- if (victim->rb_left)
- RB_SET_PARENT(victim->rb_left, new, __entry);
- if (victim->rb_right)
- RB_SET_PARENT(victim->rb_right, new, __entry);
+ RB_SWAP_CHILD((struct linux_root *)root, rb_parent(victim),
+ victim, new, __entry);
+ if (RB_LEFT(victim, __entry))
+ RB_SET_PARENT(RB_LEFT(victim, __entry), new, __entry);
+ if (RB_RIGHT(victim, __entry))
+ RB_SET_PARENT(RB_RIGHT(victim, __entry), new, __entry);
*new = *victim;
}
@@ -144,7 +146,9 @@ static inline void
rb_insert_color_cached(struct rb_node *node, struct rb_root_cached *root,
bool leftmost)
{
- linux_root_RB_INSERT_COLOR((struct linux_root *)&root->rb_root, node);
+ if (rb_parent(node))
+ linux_root_RB_INSERT_COLOR((struct linux_root *)&root->rb_root,
+ rb_parent(node), node);
if (leftmost)
root->rb_leftmost = node;
}
@@ -171,6 +175,30 @@ rb_replace_node_cached(struct rb_node *old, struct rb_node *new,
root->rb_leftmost = new;
}
+static inline struct rb_node *
+rb_add_cached(struct rb_node *node, struct rb_root_cached *tree,
+ bool (*less)(struct rb_node *, const struct rb_node *))
+{
+ struct rb_node **link = &tree->rb_root.rb_node;
+ struct rb_node *parent = NULL;
+ bool leftmost = true;
+
+ while (*link != NULL) {
+ parent = *link;
+ if (less(node, parent)) {
+ link = &RB_LEFT(parent, __entry);
+ } else {
+ link = &RB_RIGHT(parent, __entry);
+ leftmost = false;
+ }
+ }
+
+ rb_link_node(node, parent, link);
+ rb_insert_color_cached(node, tree, leftmost);
+
+ return (leftmost ? node : NULL);
+}
+
#undef RB_ROOT
#define RB_ROOT (struct rb_root) { NULL }
#define RB_ROOT_CACHED (struct rb_root_cached) { RB_ROOT, NULL }
diff --git a/sys/compat/linuxkpi/common/include/linux/rculist.h b/sys/compat/linuxkpi/common/include/linux/rculist.h
index e0c3f79d9e5a..066ed92b7996 100644
--- a/sys/compat/linuxkpi/common/include/linux/rculist.h
+++ b/sys/compat/linuxkpi/common/include/linux/rculist.h
@@ -23,8 +23,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RCULIST_H_
@@ -44,6 +42,11 @@
&(pos)->member != (head); \
pos = list_entry_rcu((pos)->member.next, typeof(*(pos)), member))
+#define list_for_each_entry_from_rcu(pos, head, member) \
+ for (; \
+ &(pos)->member != (head); \
+ pos = list_entry_rcu((pos)->member.next, typeof(*(pos)), member))
+
#define list_for_each_entry_lockless(pos, head, member) \
list_for_each_entry_rcu(pos, head, member)
diff --git a/sys/compat/linuxkpi/common/include/linux/rcupdate.h b/sys/compat/linuxkpi/common/include/linux/rcupdate.h
index 3599616430af..4aceb7296cd6 100644
--- a/sys/compat/linuxkpi/common/include/linux/rcupdate.h
+++ b/sys/compat/linuxkpi/common/include/linux/rcupdate.h
@@ -1,6 +1,10 @@
/*-
* Copyright (c) 2016-2017 Mellanox Technologies, Ltd.
* All rights reserved.
+ * Copyright (c) 2024-2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,17 +26,25 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RCUPDATE_H_
#define _LINUXKPI_LINUX_RCUPDATE_H_
+#include <sys/cdefs.h>
+
#include <linux/compiler.h>
#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cleanup.h>
#include <machine/atomic.h>
+extern int linuxkpi_rcu_debug;
+#define RCU_WARN_ONCE(c, ...) do { \
+ if (unlikely(linuxkpi_rcu_debug > 0)) \
+ WARN_ONCE((c), ##__VA_ARGS__); \
+} while(0)
+
#define LINUX_KFREE_RCU_OFFSET_MAX 4096 /* exclusive */
/* BSD specific defines */
@@ -63,6 +75,9 @@
linux_rcu_read_unlock(RCU_TYPE_REGULAR);\
} while (0)
+#define rcu_read_lock_held(void) \
+ linux_rcu_read_lock_held(RCU_TYPE_REGULAR)
+
#define synchronize_rcu(void) do { \
linux_synchronize_rcu(RCU_TYPE_REGULAR); \
} while (0)
@@ -81,14 +96,34 @@
#define rcu_access_pointer(p) \
((__typeof(*p) *)READ_ONCE(p))
-#define rcu_dereference_protected(p, c) \
+#define rcu_dereference(p) \
((__typeof(*p) *)READ_ONCE(p))
-#define rcu_dereference(p) \
- rcu_dereference_protected(p, 0)
+#define __rcu_var_name(n, f, l) \
+ __CONCAT(__CONCAT(__CONCAT(rcu_, n), _), __COUNTER__)
-#define rcu_dereference_check(p, c) \
- rcu_dereference_protected(p, c)
+#define __rcu_dereference_protected(p, c, n) \
+({ \
+ RCU_WARN_ONCE(!(c), "%s:%d: condition for %s failed\n", \
+ __func__, __LINE__, __XSTRING(n)); \
+ rcu_dereference(p); \
+})
+
+#define rcu_dereference_protected(p, c) \
+ __rcu_dereference_protected((p), (c), \
+ __rcu_var_name(protected, __func__, __LINE__))
+
+#define __rcu_dereference_check(p, c, n) \
+({ \
+ __typeof(*p) *n = rcu_dereference(p); \
+ RCU_WARN_ONCE(!(c), "%s:%d: condition for %s failed\n", \
+ __func__, __LINE__, __XSTRING(n)); \
+ n; \
+})
+
+#define rcu_dereference_check(p, c) \
+ __rcu_dereference_check((p), (c) || rcu_read_lock_held(), \
+ __rcu_var_name(check, __func__, __LINE__))
#define rcu_dereference_raw(p) \
((__typeof(*p) *)READ_ONCE(p))
@@ -115,11 +150,12 @@
/* prototypes */
-extern void linux_call_rcu(unsigned type, struct rcu_head *ptr, rcu_callback_t func);
-extern void linux_rcu_barrier(unsigned type);
-extern void linux_rcu_read_lock(unsigned type);
-extern void linux_rcu_read_unlock(unsigned type);
-extern void linux_synchronize_rcu(unsigned type);
+void linux_call_rcu(unsigned type, struct rcu_head *ptr, rcu_callback_t func);
+void linux_rcu_barrier(unsigned type);
+void linux_rcu_read_lock(unsigned type);
+void linux_rcu_read_unlock(unsigned type);
+bool linux_rcu_read_lock_held(unsigned);
+void linux_synchronize_rcu(unsigned type);
/* Empty implementation for !DEBUG */
#define init_rcu_head(...)
@@ -127,4 +163,6 @@ extern void linux_synchronize_rcu(unsigned type);
#define init_rcu_head_on_stack(...)
#define destroy_rcu_head_on_stack(...)
+DEFINE_LOCK_GUARD_0(rcu, rcu_read_lock(), rcu_read_unlock())
+
#endif /* _LINUXKPI_LINUX_RCUPDATE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ref_tracker.h b/sys/compat/linuxkpi/common/include/linux/ref_tracker.h
new file mode 100644
index 000000000000..fa510b2498e1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ref_tracker.h
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_REF_TRACKER_H_
+#define _LINUXKPI_LINUX_REF_TRACKER_H_
+
+#include <linux/refcount.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/stackdepot.h>
+
+struct ref_tracker;
+
+struct ref_tracker_dir {
+};
+
+/*
+ * The following functions currently have dummy implementations that, on Linux,
+ * are used when CONFIG_REF_TRACKER is not set at compile time.
+ *
+ * The ref tracker is a tool to associate a refcount increase to a refcount
+ * decrease. This helps developers track, document and debug refcounts. We
+ * don't need this feature for now in linuxkpi.
+ */
+
+static inline void
+ref_tracker_dir_init(struct ref_tracker_dir *dir,
+ unsigned int quarantine_count, const char *name)
+{
+}
+
+static inline void
+ref_tracker_dir_exit(struct ref_tracker_dir *dir)
+{
+}
+
+static inline void
+ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
+ unsigned int display_limit)
+{
+}
+
+static inline void
+ref_tracker_dir_print(struct ref_tracker_dir *dir, unsigned int display_limit)
+{
+}
+
+static inline int
+ref_tracker_dir_snprint(struct ref_tracker_dir *dir, char *buf, size_t size)
+{
+ return (0);
+}
+
+static inline int
+ref_tracker_alloc(struct ref_tracker_dir *dir, struct ref_tracker **trackerp,
+ gfp_t gfp)
+{
+ return (0);
+}
+
+static inline int
+ref_tracker_free(struct ref_tracker_dir *dir, struct ref_tracker **trackerp)
+{
+ return (0);
+}
+
+#endif /* !defined(_LINUXKPI_LINUX_REF_TRACKER_H_) */
diff --git a/sys/compat/linuxkpi/common/include/linux/refcount.h b/sys/compat/linuxkpi/common/include/linux/refcount.h
index 7c055fb32029..46e501a65396 100644
--- a/sys/compat/linuxkpi/common/include/linux/refcount.h
+++ b/sys/compat/linuxkpi/common/include/linux/refcount.h
@@ -24,59 +24,62 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_REFCOUNT_H
#define _LINUXKPI_LINUX_REFCOUNT_H
#include <linux/atomic.h>
+#include <linux/spinlock.h>
-struct refcount_linux {
- atomic_t value;
-};
-typedef struct refcount_linux refcount_t;
+typedef atomic_t refcount_t;
static inline void
refcount_set(refcount_t *ref, unsigned int i)
{
- atomic_set(&ref->value, i);
+ atomic_set(ref, i);
}
static inline void
refcount_inc(refcount_t *ref)
{
- atomic_inc(&ref->value);
+ atomic_inc(ref);
}
static inline bool
refcount_inc_not_zero(refcount_t *ref)
{
- return (atomic_inc_not_zero(&ref->value));
+ return (atomic_inc_not_zero(ref));
}
static inline void
refcount_dec(refcount_t *ref)
{
- atomic_dec(&ref->value);
+ atomic_dec(ref);
}
static inline unsigned int
refcount_read(refcount_t *ref)
{
- return atomic_read(&ref->value);
+ return atomic_read(ref);
}
static inline bool
refcount_dec_and_lock_irqsave(refcount_t *ref, spinlock_t *lock,
unsigned long *flags)
{
- if (atomic_dec_and_test(&ref->value) == true) {
+ if (atomic_dec_and_test(ref) == true) {
spin_lock_irqsave(lock, flags);
return (true);
}
return (false);
}
+static inline bool
+refcount_dec_and_test(refcount_t *r)
+{
+
+ return (atomic_dec_and_test(r));
+}
+
#endif /* __LINUXKPI_LINUX_REFCOUNT_H__ */
diff --git a/sys/compat/linuxkpi/common/include/linux/rhashtable.h b/sys/compat/linuxkpi/common/include/linux/rhashtable.h
new file mode 100644
index 000000000000..c6958b6ee5f3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/rhashtable.h
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_RHASHTABLE_H
+#define _LINUXKPI_LINUX_RHASHTABLE_H
+
+#include <linux/kernel.h> /* pr_debug */
+
+struct rhash_head {
+};
+
+struct rhashtable_params {
+ uint16_t head_offset;
+ uint16_t key_len;
+ uint16_t key_offset;
+ uint16_t nelem_hint;
+ bool automatic_shrinking;
+};
+
+struct rhashtable {
+};
+
+static inline int
+rhashtable_init(struct rhashtable *rht,
+ const struct rhashtable_params *params)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-1);
+}
+
+static inline void
+rhashtable_destroy(struct rhashtable *rht)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline void *
+rhashtable_lookup_fast(struct rhashtable *rht, const void *key,
+ const struct rhashtable_params params)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline void *
+rhashtable_lookup_get_insert_fast(struct rhashtable *rht,
+ struct rhash_head *obj, const struct rhashtable_params params)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline int
+rhashtable_remove_fast(struct rhashtable *rht,
+ struct rhash_head *obj, const struct rhashtable_params params)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENOENT);
+}
+
+#endif /* _LINUXKPI_LINUX_RHASHTABLE_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/rwlock.h b/sys/compat/linuxkpi/common/include/linux/rwlock.h
index e7557d29e77a..3030ec89ff1e 100644
--- a/sys/compat/linuxkpi/common/include/linux/rwlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/rwlock.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RWLOCK_H_
#define _LINUXKPI_LINUX_RWLOCK_H_
@@ -36,14 +34,12 @@
#include <sys/rwlock.h>
#include <sys/libkern.h>
-typedef struct {
- struct rwlock rw;
-} rwlock_t;
+typedef struct rwlock rwlock_t;
-#define read_lock(_l) rw_rlock(&(_l)->rw)
-#define write_lock(_l) rw_wlock(&(_l)->rw)
-#define read_unlock(_l) rw_runlock(&(_l)->rw)
-#define write_unlock(_l) rw_wunlock(&(_l)->rw)
+#define read_lock(_l) rw_rlock(_l)
+#define write_lock(_l) rw_wlock(_l)
+#define read_unlock(_l) rw_runlock(_l)
+#define write_unlock(_l) rw_wunlock(_l)
#define read_lock_irq(lock) read_lock((lock))
#define read_unlock_irq(lock) read_unlock((lock))
#define write_lock_irq(lock) write_lock((lock))
@@ -56,13 +52,6 @@ typedef struct {
do { read_unlock(lock); } while (0)
#define write_unlock_irqrestore(lock, flags) \
do { write_unlock(lock); } while (0)
-
-static inline void
-rwlock_init(rwlock_t *lock)
-{
-
- memset(&lock->rw, 0, sizeof(lock->rw));
- rw_init_flags(&lock->rw, "lnxrw", RW_NOWITNESS);
-}
+#define rwlock_init(_l) rw_init_flags(_l, "lnxrw", RW_NOWITNESS | RW_NEW)
#endif /* _LINUXKPI_LINUX_RWLOCK_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/rwsem.h b/sys/compat/linuxkpi/common/include/linux/rwsem.h
index fc3580bc186e..b7a800b12e18 100644
--- a/sys/compat/linuxkpi/common/include/linux/rwsem.h
+++ b/sys/compat/linuxkpi/common/include/linux/rwsem.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_RWSEM_H_
#define _LINUXKPI_LINUX_RWSEM_H_
@@ -46,6 +44,7 @@ struct rw_semaphore {
#define down_read(_rw) sx_slock(&(_rw)->sx)
#define up_read(_rw) sx_sunlock(&(_rw)->sx)
#define down_read_trylock(_rw) !!sx_try_slock(&(_rw)->sx)
+#define down_read_killable(_rw) linux_down_read_killable(_rw)
#define down_write_trylock(_rw) !!sx_try_xlock(&(_rw)->sx)
#define down_write_killable(_rw) linux_down_write_killable(_rw)
#define downgrade_write(_rw) sx_downgrade(&(_rw)->sx)
@@ -80,6 +79,7 @@ linux_init_rwsem(struct rw_semaphore *rw, const char *name)
sx_init_flags(&rw->sx, name, SX_NOWITNESS);
}
+extern int linux_down_read_killable(struct rw_semaphore *);
extern int linux_down_write_killable(struct rw_semaphore *);
#endif /* _LINUXKPI_LINUX_RWSEM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
index a3da30e1b9a7..537f5bebc5aa 100644
--- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -27,15 +27,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SCATTERLIST_H_
#define _LINUXKPI_LINUX_SCATTERLIST_H_
#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
#include <sys/sf_buf.h>
+#include <linux/err.h>
#include <linux/page.h>
#include <linux/slab.h>
#include <linux/mm.h>
@@ -99,6 +100,12 @@ struct sg_dma_page_iter {
#define for_each_sg(sglist, sg, sgmax, iter) \
for (iter = 0, sg = (sglist); iter < (sgmax); iter++, sg = sg_next(sg))
+#define for_each_sgtable_sg(sgt, sg, i) \
+ for_each_sg((sgt)->sgl, sg, (sgt)->orig_nents, i)
+
+#define for_each_sgtable_page(sgt, iter, pgoffset) \
+ for_each_sg_page((sgt)->sgl, iter, (sgt)->orig_nents, pgoffset)
+
#define for_each_sgtable_dma_sg(sgt, sg, iter) \
for_each_sg((sgt)->sgl, sg, (sgt)->nents, iter)
@@ -152,7 +159,7 @@ sg_next(struct scatterlist *sg)
static inline vm_paddr_t
sg_phys(struct scatterlist *sg)
{
- return (VM_PAGE_TO_PHYS(sg_page(sg)) + sg->offset);
+ return (page_to_phys(sg_page(sg)) + sg->offset);
}
static inline void *
@@ -321,18 +328,40 @@ sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
return (ret);
}
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+static inline struct scatterlist *
+__sg_alloc_table_from_pages(struct sg_table *sgt,
+ struct page **pages, unsigned int count,
+ unsigned long off, unsigned long size,
+ unsigned int max_segment,
+ struct scatterlist *prv, unsigned int left_pages,
+ gfp_t gfp_mask)
+#else
static inline int
__sg_alloc_table_from_pages(struct sg_table *sgt,
struct page **pages, unsigned int count,
unsigned long off, unsigned long size,
unsigned int max_segment, gfp_t gfp_mask)
+#endif
{
unsigned int i, segs, cur, len;
int rc;
- struct scatterlist *s;
+ struct scatterlist *s, *sg_iter;
+
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ if (prv != NULL) {
+ panic(
+ "Support for prv != NULL not implemented in "
+ "__sg_alloc_table_from_pages()");
+ }
+#endif
if (__predict_false(!max_segment || offset_in_page(max_segment)))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (ERR_PTR(-EINVAL));
+#else
return (-EINVAL);
+#endif
len = 0;
for (segs = i = 1; i < count; ++i) {
@@ -344,13 +373,25 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
}
}
if (__predict_false((rc = sg_alloc_table(sgt, segs, gfp_mask))))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (ERR_PTR(rc));
+#else
return (rc);
+#endif
cur = 0;
- for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+ for_each_sg(sgt->sgl, sg_iter, sgt->orig_nents, i) {
unsigned long seg_size;
unsigned int j;
+ /*
+ * We need to make sure that when we exit this loop "s" has the
+ * last sg in the chain so we can call sg_mark_end() on it.
+ * Only set this inside the loop since sg_iter will be iterated
+ * until it is NULL.
+ */
+ s = sg_iter;
+
len = 0;
for (j = cur + 1; j < count; ++j) {
len += PAGE_SIZE;
@@ -365,7 +406,16 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
off = 0;
cur = j;
}
+ KASSERT(s != NULL, ("s is NULL after loop in __sg_alloc_table_from_pages()"));
+
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ if (left_pages == 0)
+ sg_mark_end(s);
+
+ return (s);
+#else
return (0);
+#endif
}
static inline int
@@ -375,8 +425,27 @@ sg_alloc_table_from_pages(struct sg_table *sgt,
gfp_t gfp_mask)
{
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+ SCATTERLIST_MAX_SEGMENT, NULL, 0, gfp_mask)));
+#else
return (__sg_alloc_table_from_pages(sgt, pages, count, off, size,
SCATTERLIST_MAX_SEGMENT, gfp_mask));
+#endif
+}
+
+static inline int
+sg_alloc_table_from_pages_segment(struct sg_table *sgt,
+ struct page **pages, unsigned int count, unsigned int off,
+ unsigned long size, unsigned int max_segment, gfp_t gfp_mask)
+{
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+ max_segment, NULL, 0, gfp_mask)));
+#else
+ return (__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+ max_segment, gfp_mask));
+#endif
}
static inline int
@@ -587,7 +656,7 @@ sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
break;
vaddr = (char *)sf_buf_kva(sf);
} else
- vaddr = (char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(page));
+ vaddr = (char *)PHYS_TO_DMAP(page_to_phys(page));
memcpy(buf, vaddr + sg->offset + offset, len);
if (!PMAP_HAS_DMAP)
sf_buf_free(sf);
@@ -605,4 +674,11 @@ sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
return (total);
}
+static inline void
+sg_set_folio(struct scatterlist *sg, struct folio *folio, size_t len,
+ size_t offset)
+{
+ sg_set_page(sg, &folio->page, len, offset);
+}
+
#endif /* _LINUXKPI_LINUX_SCATTERLIST_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index cb0ffde04b2b..3ad2f8e4ce8b 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SCHED_H_
#define _LINUXKPI_LINUX_SCHED_H_
@@ -44,15 +42,18 @@
#include <linux/completion.h>
#include <linux/hrtimer.h>
#include <linux/mm_types.h>
+#include <linux/nodemask.h>
#include <linux/pid.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/time.h>
+#include <linux/sched/mm.h>
+
#include <asm/atomic.h>
-#define MAX_SCHEDULE_TIMEOUT INT_MAX
+#define MAX_SCHEDULE_TIMEOUT LONG_MAX
#define TASK_RUNNING 0x0000
#define TASK_INTERRUPTIBLE 0x0001
@@ -130,7 +131,8 @@ put_task_struct(struct task_struct *task)
#define yield() kern_yield(PRI_UNCHANGED)
#define sched_yield() sched_relinquish(curthread)
-#define need_resched() (curthread->td_flags & TDF_NEEDRESCHED)
+#define need_resched() (curthread->td_owepreempt || \
+ td_ast_pending(curthread, TDA_SCHED))
static inline int
cond_resched_lock(spinlock_t *lock)
@@ -158,7 +160,7 @@ void linux_send_sig(int signo, struct task_struct *task);
linux_send_sig(signo, task); \
} while (0)
-int linux_schedule_timeout(int timeout);
+long linux_schedule_timeout(long timeout);
static inline void
linux_schedule_save_interrupt_value(struct task_struct *task, int value)
diff --git a/sys/compat/linuxkpi/common/include/linux/sched/mm.h b/sys/compat/linuxkpi/common/include/linux/sched/mm.h
new file mode 100644
index 000000000000..c26d99378974
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/sched/mm.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _LINUXKPI_LINUX_SCHED_MM_H_
+#define _LINUXKPI_LINUX_SCHED_MM_H_
+
+#include <linux/gfp.h>
+
+#define fs_reclaim_acquire(x) do { \
+ } while (0)
+#define fs_reclaim_release(x) do { \
+ } while (0)
+#define memalloc_nofs_save(x) 0
+#define memalloc_nofs_restore(x) do { \
+ } while (0)
+#define memalloc_noreclaim_save(x) 0
+#define memalloc_noreclaim_restore(x) do { \
+ } while (0)
+
+#endif /* _BSD_LKPI_LINUX_SCHED_MM_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/semaphore.h b/sys/compat/linuxkpi/common/include/linux/semaphore.h
index da1fc73b1776..4b1a1502e589 100644
--- a/sys/compat/linuxkpi/common/include/linux/semaphore.h
+++ b/sys/compat/linuxkpi/common/include/linux/semaphore.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SEMAPHORE_H_
#define _LINUXKPI_LINUX_SEMAPHORE_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h
index 9ab5ecce7768..47da16ab8688 100644
--- a/sys/compat/linuxkpi/common/include/linux/seq_file.h
+++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2016-2018, Matthew Macy <mmacy@freebsd.org>
*
@@ -23,20 +23,24 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SEQ_FILE_H_
#define _LINUXKPI_LINUX_SEQ_FILE_H_
+#include <sys/types.h>
+#include <sys/sbuf.h>
+
#include <linux/types.h>
#include <linux/fs.h>
-#include <sys/sbuf.h>
+#include <linux/string_helpers.h>
+#include <linux/printk.h>
#undef file
#define inode vnode
+MALLOC_DECLARE(M_LSEQ);
+
#define DEFINE_SHOW_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct linux_file *file) \
{ \
@@ -51,11 +55,24 @@ static const struct file_operations __name ## _fops = { \
.release = single_release, \
}
-struct seq_operations;
+#define DEFINE_SHOW_STORE_ATTRIBUTE(__name) \
+static int __name ## _open(struct inode *inode, struct linux_file *file) \
+{ \
+ return single_open(file, __name ## _show, inode->i_private); \
+} \
+ \
+static const struct file_operations __name ## _fops = { \
+ .owner = THIS_MODULE, \
+ .open = __name ## _open, \
+ .read = seq_read, \
+ .write = __name ## _write, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
struct seq_file {
- struct sbuf *buf;
-
+ struct sbuf *buf;
+ size_t size;
const struct seq_operations *op;
const struct linux_file *file;
void *private;
@@ -70,18 +87,36 @@ struct seq_operations {
ssize_t seq_read(struct linux_file *, char *, size_t, off_t *);
int seq_write(struct seq_file *seq, const void *data, size_t len);
+void seq_putc(struct seq_file *m, char c);
+void seq_puts(struct seq_file *m, const char *str);
+bool seq_has_overflowed(struct seq_file *m);
+
+void *__seq_open_private(struct linux_file *, const struct seq_operations *, int);
+int seq_release_private(struct inode *, struct linux_file *);
int seq_open(struct linux_file *f, const struct seq_operations *op);
int seq_release(struct inode *inode, struct linux_file *file);
off_t seq_lseek(struct linux_file *file, off_t offset, int whence);
int single_open(struct linux_file *, int (*)(struct seq_file *, void *), void *);
+int single_open_size(struct linux_file *, int (*)(struct seq_file *, void *), void *, size_t);
int single_release(struct inode *, struct linux_file *);
-#define seq_printf(m, fmt, ...) sbuf_printf((m)->buf, (fmt), ##__VA_ARGS__)
+void lkpi_seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
+void lkpi_seq_printf(struct seq_file *m, const char *fmt, ...);
+
+#define seq_vprintf(...) lkpi_seq_vprintf(__VA_ARGS__)
+#define seq_printf(...) lkpi_seq_printf(__VA_ARGS__)
-#define seq_puts(m, str) sbuf_printf((m)->buf, str)
-#define seq_putc(m, str) sbuf_putc((m)->buf, str)
+int __lkpi_hexdump_sbuf_printf(void *, const char *, ...) __printflike(2, 3);
+
+static inline void
+seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
+ int rowsize, int groupsize, const void *buf, size_t len, bool ascii)
+{
+ lkpi_hex_dump(__lkpi_hexdump_sbuf_printf, m->buf, NULL, prefix_str, prefix_type,
+ rowsize, groupsize, buf, len, ascii);
+}
#define file linux_file
diff --git a/sys/compat/linuxkpi/common/include/linux/seqlock.h b/sys/compat/linuxkpi/common/include/linux/seqlock.h
index 6e81e7a0fa45..554fdfd6e202 100644
--- a/sys/compat/linuxkpi/common/include/linux/seqlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/seqlock.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -31,8 +31,10 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/cdefs.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rwlock.h>
#include <sys/seqc.h>
struct lock_class_key;
@@ -48,6 +50,12 @@ struct seqlock {
};
typedef struct seqlock seqlock_t;
+struct seqcount_mutex {
+ seqc_t seqc;
+};
+typedef struct seqcount_mutex seqcount_mutex_t;
+typedef struct seqcount_mutex seqcount_ww_mutex_t;
+
static inline void
__seqcount_init(struct seqcount *seqcount, const char *name __unused,
struct lock_class_key *key __unused)
@@ -57,16 +65,43 @@ __seqcount_init(struct seqcount *seqcount, const char *name __unused,
#define seqcount_init(seqcount) __seqcount_init(seqcount, NULL, NULL)
static inline void
-write_seqcount_begin(struct seqcount *seqcount)
+seqcount_mutex_init(struct seqcount_mutex *seqcount, void *mutex __unused)
{
- seqc_sleepable_write_begin(&seqcount->seqc);
+ seqcount->seqc = 0;
}
+#define seqcount_ww_mutex_init(seqcount, ww_mutex) \
+ seqcount_mutex_init((seqcount), (ww_mutex))
+
+#define write_seqcount_begin(s) \
+ _Generic(*(s), \
+ struct seqcount: seqc_sleepable_write_begin, \
+ struct seqcount_mutex: seqc_write_begin \
+ )(&(s)->seqc)
+
+#define write_seqcount_end(s) \
+ _Generic(*(s), \
+ struct seqcount: seqc_sleepable_write_end, \
+ struct seqcount_mutex: seqc_write_end \
+ )(&(s)->seqc)
+
static inline void
-write_seqcount_end(struct seqcount *seqcount)
+lkpi_write_seqcount_invalidate(seqc_t *seqcp)
{
- seqc_sleepable_write_end(&seqcount->seqc);
+ atomic_thread_fence_rel();
+ *seqcp += SEQC_MOD * 2;
}
+#define write_seqcount_invalidate(s) lkpi_write_seqcount_invalidate(&(s)->seqc)
+
+#define read_seqcount_begin(s) seqc_read(&(s)->seqc)
+#define raw_read_seqcount(s) seqc_read_any(&(s)->seqc)
+
+static inline seqc_t
+lkpi_seqprop_sequence(const seqc_t *seqcp)
+{
+ return (atomic_load_int(seqcp));
+}
+#define seqprop_sequence(s) lkpi_seqprop_sequence(&(s)->seqc)
/*
* XXX: Are predicts from inline functions still not honored by clang?
@@ -76,18 +111,6 @@ write_seqcount_end(struct seqcount *seqcount)
#define read_seqcount_retry(seqcount, gen) \
(!seqc_consistent(&(seqcount)->seqc, gen))
-static inline unsigned
-read_seqcount_begin(const struct seqcount *seqcount)
-{
- return (seqc_read(&seqcount->seqc));
-}
-
-static inline unsigned
-raw_read_seqcount(const struct seqcount *seqcount)
-{
- return (seqc_read_any(&seqcount->seqc));
-}
-
static inline void
seqlock_init(struct seqlock *seqlock)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
index 240d26c47685..5e91725d4a1c 100644
--- a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
@@ -25,20 +25,22 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SHMEM_FS_H_
#define _LINUXKPI_LINUX_SHMEM_FS_H_
-/* Shared memory support */
-unsigned long linux_invalidate_mapping_pages(vm_object_t, pgoff_t, pgoff_t);
-struct page *linux_shmem_read_mapping_page_gfp(vm_object_t, int, gfp_t);
-struct linux_file *linux_shmem_file_setup(const char *, loff_t, unsigned long);
-void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t);
+#include <linux/file.h>
+#include <linux/mempolicy.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
-#define invalidate_mapping_pages(...) \
- linux_invalidate_mapping_pages(__VA_ARGS__)
+/* Shared memory support */
+struct page *linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex,
+ gfp_t gfp);
+struct linux_file *linux_shmem_file_setup(const char *name, loff_t size,
+ unsigned long flags);
+void linux_shmem_truncate_range(vm_object_t obj, loff_t lstart,
+ loff_t lend);
#define shmem_read_mapping_page(...) \
linux_shmem_read_mapping_page_gfp(__VA_ARGS__, 0)
@@ -52,4 +54,14 @@ void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t);
#define shmem_truncate_range(...) \
linux_shmem_truncate_range(__VA_ARGS__)
+static inline struct folio *
+shmem_read_folio_gfp(vm_object_t obj, int pindex, gfp_t gfp)
+{
+ struct page *page;
+
+ page = shmem_read_mapping_page_gfp(obj, pindex, gfp);
+
+ return (page_folio(page));
+}
+
#endif /* _LINUXKPI_LINUX_SHMEM_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/shrinker.h b/sys/compat/linuxkpi/common/include/linux/shrinker.h
index 05f702e62fd5..eb95dafb83ce 100644
--- a/sys/compat/linuxkpi/common/include/linux/shrinker.h
+++ b/sys/compat/linuxkpi/common/include/linux/shrinker.h
@@ -21,8 +21,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SHRINKER_H_
@@ -30,7 +28,11 @@
#include <sys/queue.h>
+#include <linux/bitops.h>
+#include <linux/gfp.h>
+
struct shrink_control {
+ gfp_t gfp_mask;
unsigned long nr_to_scan;
unsigned long nr_scanned;
};
@@ -39,6 +41,8 @@ struct shrinker {
unsigned long (*count_objects)(struct shrinker *, struct shrink_control *);
unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *);
int seeks;
+ unsigned int flags;
+ void * private_data;
long batch;
TAILQ_ENTRY(shrinker) next;
};
@@ -47,10 +51,29 @@ struct shrinker {
#define DEFAULT_SEEKS 2
+#define SHRINKER_REGISTERED BIT(0)
+#define SHRINKER_ALLOCATED BIT(1)
+
+struct shrinker *linuxkpi_shrinker_alloc(
+ unsigned int flags, const char *fmt, ...);
int linuxkpi_register_shrinker(struct shrinker *s);
void linuxkpi_unregister_shrinker(struct shrinker *s);
+void linuxkpi_shrinker_free(struct shrinker *shrinker);
+void linuxkpi_synchronize_shrinkers(void);
+
+#define shrinker_alloc(flags, fmt, ...) \
+ linuxkpi_shrinker_alloc(flags, fmt __VA_OPT__(,) __VA_ARGS__)
+#define shrinker_register(shrinker) \
+ linuxkpi_register_shrinker(shrinker)
+#define shrinker_free(shrinker) \
+ linuxkpi_shrinker_free(shrinker)
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60000
+#define register_shrinker(s, ...) linuxkpi_register_shrinker(s)
+#else
#define register_shrinker(s) linuxkpi_register_shrinker(s)
+#endif
#define unregister_shrinker(s) linuxkpi_unregister_shrinker(s)
+#define synchronize_shrinkers() linuxkpi_synchronize_shrinkers()
#endif /* _LINUXKPI_LINUX_SHRINKER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/sizes.h b/sys/compat/linuxkpi/common/include/linux/sizes.h
index b132eedff933..d8a6e75192f6 100644
--- a/sys/compat/linuxkpi/common/include/linux/sizes.h
+++ b/sys/compat/linuxkpi/common/include/linux/sizes.h
@@ -24,14 +24,13 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SIZES_H_
#define _LINUXKPI_LINUX_SIZES_H_
#define SZ_1K (1024 * 1)
+#define SZ_2K (1024 * 2)
#define SZ_4K (1024 * 4)
#define SZ_8K (1024 * 8)
#define SZ_16K (1024 * 16)
@@ -43,9 +42,22 @@
#define SZ_1M (1024 * 1024 * 1)
#define SZ_2M (1024 * 1024 * 2)
+#define SZ_4M (1024 * 1024 * 4)
#define SZ_8M (1024 * 1024 * 8)
#define SZ_16M (1024 * 1024 * 16)
#define SZ_32M (1024 * 1024 * 32)
#define SZ_64M (1024 * 1024 * 64)
+#define SZ_128M (1024 * 1024 * 128)
+#define SZ_256M (1024 * 1024 * 256)
+#define SZ_512M (1024 * 1024 * 512)
+
+#define SZ_1G (1024 * 1024 * 1024 * 1)
+#define SZ_2G (1024 * 1024 * 1024 * 2)
+#define SZ_4G (1024 * 1024 * 1024 * 4)
+#define SZ_8G (1024 * 1024 * 1024 * 8)
+#define SZ_16G (1024 * 1024 * 1024 * 16)
+#define SZ_32G (1024 * 1024 * 1024 * 32)
+
+#define SZ_64T (1024 * 1024 * 1024 * 1024 * 64)
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index 3caf7059dd15..6e41c368a8b8 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2020-2022 The FreeBSD Foundation
- * Copyright (c) 2021-2022 Bjoern A. Zeeb
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
+ * Copyright (c) 2021-2025 Bjoern A. Zeeb
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -25,8 +25,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
@@ -46,8 +44,16 @@
#include <linux/gfp.h>
#include <linux/compiler.h>
#include <linux/spinlock.h>
+#include <linux/ktime.h>
+#include <linux/compiler.h>
+/*
+ * At least the net/intel-irdma-kmod port pulls this header in; likely through
+ * if_ether.h (see PR289268). This means we no longer can rely on
+ * IEEE80211_DEBUG (opt_wlan.h) to automatically set SKB_DEBUG.
+ */
/* #define SKB_DEBUG */
+
#ifdef SKB_DEBUG
#define DSKB_TODO 0x01
#define DSKB_IMPROVE 0x02
@@ -85,12 +91,25 @@ enum sk_buff_pkt_type {
PACKET_OTHERHOST,
};
+struct skb_shared_hwtstamps {
+ ktime_t hwtstamp;
+};
+
#define NET_SKB_PAD max(CACHE_LINE_SIZE, 32)
+#define SKB_DATA_ALIGN(_x) roundup2(_x, CACHE_LINE_SIZE)
struct sk_buff_head {
/* XXX TODO */
- struct sk_buff *next;
- struct sk_buff *prev;
+ union {
+ struct {
+ struct sk_buff *next;
+ struct sk_buff *prev;
+ };
+ struct sk_buff_head_l {
+ struct sk_buff *next;
+ struct sk_buff *prev;
+ } list;
+ };
size_t qlen;
spinlock_t lock;
};
@@ -99,7 +118,7 @@ enum sk_checksum_flags {
CHECKSUM_NONE = 0x00,
CHECKSUM_UNNECESSARY = 0x01,
CHECKSUM_PARTIAL = 0x02,
- CHECKSUM_COMPLETE = 0x04,
+ CHECKSUM_COMPLETE = 0x03,
};
struct skb_frag {
@@ -124,39 +143,54 @@ struct skb_shared_info {
};
struct sk_buff {
- /* XXX TODO */
- /* struct sk_buff_head */
- struct sk_buff *next;
- struct sk_buff *prev;
- int list; /* XXX TYPE */
- uint32_t _alloc_len; /* Length of alloc data-buf. XXX-BZ give up for truesize? */
+ /* XXX TODO */
+ union {
+ /* struct sk_buff_head */
+ struct {
+ struct sk_buff *next;
+ struct sk_buff *prev;
+ };
+ struct list_head list;
+ };
+
+ uint8_t *head; /* Head of buffer. */
+ uint8_t *data; /* Head of data. */
+ uint8_t *tail; /* End of data. */
+ uint8_t *end; /* End of buffer. */
+
uint32_t len; /* ? */
uint32_t data_len; /* ? If we have frags? */
- uint32_t truesize; /* The total size of all buffers, incl. frags. */
- uint16_t mac_len; /* Link-layer header length. */
- __sum16 csum;
- uint16_t l3hdroff; /* network header offset from *head */
- uint16_t l4hdroff; /* transport header offset from *head */
- uint32_t priority;
- uint16_t qmap; /* queue mapping */
- uint16_t _spareu16_0;
- enum sk_buff_pkt_type pkt_type;
+ union {
+ __wsum csum;
+ struct {
+ uint16_t csum_offset;
+ uint16_t csum_start;
+ };
+ };
+ uint16_t protocol;
+ uint8_t ip_summed; /* 2 bit only. */
+ /* uint8_t */
/* "Scratch" area for layers to store metadata. */
/* ??? I see sizeof() operations so probably an array. */
uint8_t cb[64] __aligned(CACHE_LINE_SIZE);
- struct net_device *dev;
- void *sk; /* XXX net/sock.h? */
+ struct skb_shared_info *shinfo __aligned(CACHE_LINE_SIZE);
- int csum_offset, csum_start, ip_summed, protocol;
-
- uint8_t *head; /* Head of buffer. */
- uint8_t *data; /* Head of data. */
- uint8_t *tail; /* End of data. */
- uint8_t *end; /* End of buffer. */
+ uint32_t truesize; /* The total size of all buffers, incl. frags. */
+ uint32_t priority;
+ uint16_t qmap; /* queue mapping */
+ uint16_t _flags; /* Internal flags. */
+#define _SKB_FLAGS_SKBEXTFRAG 0x0001
+ uint16_t l3hdroff; /* network header offset from *head */
+ uint16_t l4hdroff; /* transport header offset from *head */
+ uint16_t mac_header; /* offset of mac_header */
+ uint16_t mac_len; /* Link-layer header length. */
+ enum sk_buff_pkt_type pkt_type;
+ refcount_t refcnt;
- struct skb_shared_info *shinfo;
+ struct net_device *dev;
+ void *sk; /* XXX net/sock.h? */
/* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
void *m;
@@ -170,9 +204,10 @@ struct sk_buff {
struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
+struct sk_buff *linuxkpi_build_skb(void *, size_t);
void linuxkpi_kfree_skb(struct sk_buff *);
-struct sk_buff *linuxkpi_skb_copy(struct sk_buff *, gfp_t);
+struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t);
/* -------------------------------------------------------------------------- */
@@ -216,6 +251,13 @@ kfree_skb(struct sk_buff *skb)
}
static inline void
+consume_skb(struct sk_buff *skb)
+{
+ SKB_TRACE(skb);
+ kfree_skb(skb);
+}
+
+static inline void
dev_kfree_skb(struct sk_buff *skb)
{
SKB_TRACE(skb);
@@ -237,11 +279,24 @@ dev_kfree_skb_irq(struct sk_buff *skb)
dev_kfree_skb(skb);
}
+static inline struct sk_buff *
+build_skb(void *data, unsigned int fragsz)
+{
+ struct sk_buff *skb;
+
+ skb = linuxkpi_build_skb(data, fragsz);
+ SKB_TRACE(skb);
+ return (skb);
+}
+
/* -------------------------------------------------------------------------- */
-/* XXX BZ review this one for terminal condition as Linux "queues" are special. */
-#define skb_list_walk_safe(_q, skb, tmp) \
- for ((skb) = (_q)->next; (skb) != NULL && ((tmp) = (skb)->next); (skb) = (tmp))
+static inline bool
+skb_is_nonlinear(struct sk_buff *skb)
+{
+ SKB_TRACE(skb);
+ return ((skb->data_len > 0) ? true : false);
+}
/* Add headroom; cannot do once there is data in there. */
static inline void
@@ -266,7 +321,7 @@ skb_reserve(struct sk_buff *skb, size_t len)
* front to copy data in (manually).
*/
static inline void *
-skb_push(struct sk_buff *skb, size_t len)
+__skb_push(struct sk_buff *skb, size_t len)
{
SKB_TRACE(skb);
KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - "
@@ -276,6 +331,14 @@ skb_push(struct sk_buff *skb, size_t len)
return (skb->data);
}
+static inline void *
+skb_push(struct sk_buff *skb, size_t len)
+{
+
+ SKB_TRACE(skb);
+ return (__skb_push(skb, len));
+}
+
/*
* Length of the data on the skb (without any frags)???
*/
@@ -305,12 +368,14 @@ skb_tailroom(struct sk_buff *skb)
SKB_TRACE(skb);
KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, "
"end %p tail %p\n", __func__, skb, skb->end, skb->tail));
+ if (unlikely(skb_is_nonlinear(skb)))
+ return (0);
return (skb->end - skb->tail);
}
-/* Return numer of bytes available at the beginning of buffer. */
+/* Return number of bytes available at the beginning of buffer. */
static inline unsigned int
-skb_headroom(struct sk_buff *skb)
+skb_headroom(const struct sk_buff *skb)
{
SKB_TRACE(skb);
KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, "
@@ -324,7 +389,7 @@ skb_headroom(struct sk_buff *skb)
* the end to copy data in (manually). See also skb_put_data() below.
*/
static inline void *
-skb_put(struct sk_buff *skb, size_t len)
+__skb_put(struct sk_buff *skb, size_t len)
{
void *s;
@@ -347,6 +412,14 @@ skb_put(struct sk_buff *skb, size_t len)
return (s);
}
+static inline void *
+skb_put(struct sk_buff *skb, size_t len)
+{
+
+ SKB_TRACE(skb);
+ return (__skb_put(skb, len));
+}
+
/* skb_put() + copying data in. */
static inline void *
skb_put_data(struct sk_buff *skb, const void *buf, size_t len)
@@ -447,14 +520,12 @@ skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
shinfo->frags[fragno].size = size;
shinfo->nr_frags = fragno + 1;
skb->len += size;
+ skb->data_len += size;
skb->truesize += truesize;
-
- /* XXX TODO EXTEND truesize? */
}
/* -------------------------------------------------------------------------- */
-/* XXX BZ review this one for terminal condition as Linux "queues" are special. */
#define skb_queue_walk(_q, skb) \
for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q); \
(skb) = (skb)->next)
@@ -463,12 +534,23 @@ skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
for ((skb) = (_q)->next, (tmp) = (skb)->next; \
(skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next)
+#define skb_list_walk_safe(_q, skb, tmp) \
+ for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \
+ ((skb) != NULL); \
+ (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL)
+
static inline bool
-skb_queue_empty(struct sk_buff_head *q)
+skb_queue_empty(const struct sk_buff_head *q)
{
+ SKB_TRACE(q);
+ return (q->next == (const struct sk_buff *)q);
+}
+static inline bool
+skb_queue_empty_lockless(const struct sk_buff_head *q)
+{
SKB_TRACE(q);
- return (q->qlen == 0);
+ return (READ_ONCE(q->next) == (const struct sk_buff *)q);
}
static inline void
@@ -483,7 +565,8 @@ static inline void
skb_queue_head_init(struct sk_buff_head *q)
{
SKB_TRACE(q);
- return (__skb_queue_head_init(q));
+ __skb_queue_head_init(q);
+ spin_lock_init(&q->lock);
}
static inline void
@@ -492,11 +575,11 @@ __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next,
{
SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q);
- new->prev = prev;
- new->next = next;
- next->prev = new;
- prev->next = new;
- q->qlen++;
+ WRITE_ONCE(new->prev, prev);
+ WRITE_ONCE(new->next, next);
+ WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new);
+ WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new);
+ WRITE_ONCE(q->qlen, q->qlen + 1);
}
static inline void
@@ -505,7 +588,7 @@ __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb,
{
SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
- __skb_insert(new, skb, skb->next, q);
+ __skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q);
}
static inline void
@@ -518,57 +601,72 @@ __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb,
}
static inline void
-__skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb)
+__skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
{
- struct sk_buff *s;
- SKB_TRACE2(q, skb);
- q->qlen++;
- s = (struct sk_buff *)q;
- s->prev->next = skb;
- skb->prev = s->prev;
- skb->next = s;
- s->prev = skb;
+ SKB_TRACE2(q, new);
+ __skb_queue_before(q, (struct sk_buff *)q, new);
}
static inline void
-skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb)
+skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
{
+ unsigned long flags;
+
+ SKB_TRACE2(q, new);
+ spin_lock_irqsave(&q->lock, flags);
+ __skb_queue_tail(q, new);
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+
+static inline struct sk_buff *
+skb_peek(const struct sk_buff_head *q)
+{
+ struct sk_buff *skb;
+
+ skb = q->next;
SKB_TRACE2(q, skb);
- return (__skb_queue_tail(q, skb));
+ if (skb == (const struct sk_buff *)q)
+ return (NULL);
+ return (skb);
}
static inline struct sk_buff *
-skb_peek_tail(struct sk_buff_head *q)
+skb_peek_tail(const struct sk_buff_head *q)
{
struct sk_buff *skb;
- skb = q->prev;
+ skb = READ_ONCE(q->prev);
SKB_TRACE2(q, skb);
- if (skb == (struct sk_buff *)q)
+ if (skb == (const struct sk_buff *)q)
return (NULL);
return (skb);
}
static inline void
-__skb_unlink(struct sk_buff *skb, struct sk_buff_head *head)
+__skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
{
- SKB_TRACE2(skb, head);
- struct sk_buff *p, *n;;
+ struct sk_buff *p, *n;
+
+ SKB_TRACE2(skb, q);
- head->qlen--;
+ WRITE_ONCE(q->qlen, q->qlen - 1);
p = skb->prev;
n = skb->next;
- p->next = n;
- n->prev = p;
+ WRITE_ONCE(n->prev, p);
+ WRITE_ONCE(p->next, n);
skb->prev = skb->next = NULL;
}
static inline void
-skb_unlink(struct sk_buff *skb, struct sk_buff_head *head)
+skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
{
- SKB_TRACE2(skb, head);
- return (__skb_unlink(skb, head));
+ unsigned long flags;
+
+ SKB_TRACE2(skb, q);
+ spin_lock_irqsave(&q->lock, flags);
+ __skb_unlink(skb, q);
+ spin_unlock_irqrestore(&q->lock, flags);
}
static inline struct sk_buff *
@@ -576,32 +674,47 @@ __skb_dequeue(struct sk_buff_head *q)
{
struct sk_buff *skb;
- SKB_TRACE(q);
- skb = q->next;
- if (skb == (struct sk_buff *)q)
- return (NULL);
+ skb = skb_peek(q);
if (skb != NULL)
__skb_unlink(skb, q);
- SKB_TRACE(skb);
+ SKB_TRACE2(q, skb);
return (skb);
}
static inline struct sk_buff *
skb_dequeue(struct sk_buff_head *q)
{
- SKB_TRACE(q);
- return (__skb_dequeue(q));
+ unsigned long flags;
+ struct sk_buff *skb;
+
+ spin_lock_irqsave(&q->lock, flags);
+ skb = __skb_dequeue(q);
+ spin_unlock_irqrestore(&q->lock, flags);
+ SKB_TRACE2(q, skb);
+ return (skb);
}
static inline struct sk_buff *
-skb_dequeue_tail(struct sk_buff_head *q)
+__skb_dequeue_tail(struct sk_buff_head *q)
{
struct sk_buff *skb;
skb = skb_peek_tail(q);
if (skb != NULL)
__skb_unlink(skb, q);
+ SKB_TRACE2(q, skb);
+ return (skb);
+}
+static inline struct sk_buff *
+skb_dequeue_tail(struct sk_buff_head *q)
+{
+ unsigned long flags;
+ struct sk_buff *skb;
+
+ spin_lock_irqsave(&q->lock, flags);
+ skb = __skb_dequeue_tail(q);
+ spin_unlock_irqrestore(&q->lock, flags);
SKB_TRACE2(q, skb);
return (skb);
}
@@ -617,28 +730,75 @@ __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
static inline void
skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
{
+ unsigned long flags;
SKB_TRACE2(q, skb);
- __skb_queue_after(q, (struct sk_buff *)q, skb);
+ spin_lock_irqsave(&q->lock, flags);
+ __skb_queue_head(q, skb);
+ spin_unlock_irqrestore(&q->lock, flags);
}
static inline uint32_t
-skb_queue_len(struct sk_buff_head *head)
+skb_queue_len(const struct sk_buff_head *q)
{
- SKB_TRACE(head);
- return (head->qlen);
+ SKB_TRACE(q);
+ return (q->qlen);
}
static inline uint32_t
-skb_queue_len_lockless(const struct sk_buff_head *head)
+skb_queue_len_lockless(const struct sk_buff_head *q)
+{
+
+ SKB_TRACE(q);
+ return (READ_ONCE(q->qlen));
+}
+
+static inline void
+___skb_queue_splice(const struct sk_buff_head *from,
+ struct sk_buff *p, struct sk_buff *n)
{
+ struct sk_buff *b, *e;
- SKB_TRACE(head);
- return (READ_ONCE(head->qlen));
+ b = from->next;
+ e = from->prev;
+
+ WRITE_ONCE(b->prev, p);
+ WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b);
+ WRITE_ONCE(e->next, n);
+ WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e);
+}
+
+static inline void
+skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
+{
+
+ SKB_TRACE2(from, to);
+
+ if (skb_queue_empty(from))
+ return;
+
+ ___skb_queue_splice(from, (struct sk_buff *)to, to->next);
+ to->qlen += from->qlen;
+ __skb_queue_head_init(from);
}
static inline void
+skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to)
+{
+
+ SKB_TRACE2(from, to);
+
+ if (skb_queue_empty(from))
+ return;
+
+ ___skb_queue_splice(from, to->prev, (struct sk_buff *)to);
+ to->qlen += from->qlen;
+ __skb_queue_head_init(from);
+}
+
+
+static inline void
__skb_queue_purge(struct sk_buff_head *q)
{
struct sk_buff *skb;
@@ -646,13 +806,26 @@ __skb_queue_purge(struct sk_buff_head *q)
SKB_TRACE(q);
while ((skb = __skb_dequeue(q)) != NULL)
kfree_skb(skb);
+ WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u",
+ __func__, q, skb_queue_len(q));
}
static inline void
skb_queue_purge(struct sk_buff_head *q)
{
+ struct sk_buff_head _q;
+ unsigned long flags;
+
SKB_TRACE(q);
- return (__skb_queue_purge(q));
+
+ if (skb_queue_empty_lockless(q))
+ return;
+
+ __skb_queue_head_init(&_q);
+ spin_lock_irqsave(&q->lock, flags);
+ skb_queue_splice_init(q, &_q);
+ spin_unlock_irqrestore(&q->lock, flags);
+ __skb_queue_purge(&_q);
}
static inline struct sk_buff *
@@ -667,7 +840,7 @@ skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
/* -------------------------------------------------------------------------- */
static inline struct sk_buff *
-skb_copy(struct sk_buff *skb, gfp_t gfp)
+skb_copy(const struct sk_buff *skb, gfp_t gfp)
{
struct sk_buff *new;
@@ -676,13 +849,6 @@ skb_copy(struct sk_buff *skb, gfp_t gfp)
return (new);
}
-static inline void
-consume_skb(struct sk_buff *skb)
-{
- SKB_TRACE(skb);
- SKB_TODO();
-}
-
static inline uint16_t
skb_checksum(struct sk_buff *skb, int offs, size_t len, int x)
{
@@ -712,15 +878,7 @@ static inline size_t
skb_frag_size(const skb_frag_t *frag)
{
SKB_TRACE(frag);
- SKB_TODO();
- return (-1);
-}
-
-static inline bool
-skb_is_nonlinear(struct sk_buff *skb)
-{
- SKB_TRACE(skb);
- return ((skb->data_len > 0) ? true : false);
+ return (frag->size);
}
#define skb_walk_frags(_skb, _frag) \
@@ -745,8 +903,14 @@ static inline void *
skb_frag_address(const skb_frag_t *frag)
{
SKB_TRACE(frag);
- SKB_TODO();
- return (NULL);
+ return (page_address(frag->page + frag->offset));
+}
+
+static inline void
+skb_free_frag(void *frag)
+{
+
+ page_frag_free(frag);
}
static inline struct sk_buff *
@@ -769,31 +933,7 @@ static inline void
skb_mark_not_on_list(struct sk_buff *skb)
{
SKB_TRACE(skb);
- SKB_TODO();
-}
-
-static inline void
-skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
-{
- struct sk_buff *b, *e, *n;
-
- SKB_TRACE2(from, to);
-
- if (skb_queue_empty(from))
- return;
-
- /* XXX do we need a barrier around this? */
- b = from->next;
- e = from->prev;
- n = to->next;
-
- b->prev = (struct sk_buff *)to;
- to->next = b;
- e->next = n;
- n->prev = e;
-
- to->qlen += from->qlen;
- __skb_queue_head_init(from);
+ skb->next = NULL;
}
static inline void
@@ -825,7 +965,13 @@ __skb_linearize(struct sk_buff *skb)
{
SKB_TRACE(skb);
SKB_TODO();
- return (ENXIO);
+ return (-ENXIO);
+}
+
+static inline int
+skb_linearize(struct sk_buff *skb)
+{
+ return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0);
}
static inline int
@@ -853,48 +999,61 @@ skb_get_queue_mapping(struct sk_buff *skb)
return (skb->qmap);
}
+static inline void
+skb_copy_header(struct sk_buff *to, const struct sk_buff *from)
+{
+ SKB_TRACE2(to, from);
+ SKB_TODO();
+}
+
static inline bool
skb_header_cloned(struct sk_buff *skb)
{
SKB_TRACE(skb);
SKB_TODO();
- return (false);
+ return (true);
}
static inline uint8_t *
-skb_mac_header(struct sk_buff *skb)
+skb_mac_header(const struct sk_buff *skb)
{
SKB_TRACE(skb);
- SKB_TODO();
- return (NULL);
+ return (skb->head + skb->mac_header);
}
static inline void
-skb_orphan(struct sk_buff *skb)
+skb_reset_mac_header(struct sk_buff *skb)
{
SKB_TRACE(skb);
- SKB_TODO();
+ skb->mac_header = skb->data - skb->head;
}
static inline void
-skb_reset_mac_header(struct sk_buff *skb)
+skb_set_mac_header(struct sk_buff *skb, const size_t len)
{
SKB_TRACE(skb);
- SKB_TODO();
+ skb_reset_mac_header(skb);
+ skb->mac_header += len;
}
-static inline struct sk_buff *
-skb_peek(struct sk_buff_head *q)
+static inline struct skb_shared_hwtstamps *
+skb_hwtstamps(struct sk_buff *skb)
{
- SKB_TRACE(q);
+ SKB_TRACE(skb);
SKB_TODO();
return (NULL);
}
-static inline __sum16
-csum_unfold(__sum16 sum)
+static inline void
+skb_orphan(struct sk_buff *skb)
{
+ SKB_TRACE(skb);
SKB_TODO();
+}
+
+static inline __wsum
+csum_unfold(__sum16 sum)
+{
return (sum);
}
@@ -909,7 +1068,10 @@ skb_reset_tail_pointer(struct sk_buff *skb)
{
SKB_TRACE(skb);
+#ifdef SKB_DOING_OFFSETS_US_NOT
skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head);
+#endif
+ skb->tail = skb->data;
SKB_TRACE(skb);
}
@@ -917,7 +1079,8 @@ static inline struct sk_buff *
skb_get(struct sk_buff *skb)
{
- SKB_TODO(); /* XXX refcnt? as in get/put_device? */
+ SKB_TRACE(skb);
+ refcount_inc(&skb->refcnt);
return (skb);
}
@@ -938,4 +1101,65 @@ skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len)
memcpy(dst, skb->data, len);
}
+static inline int
+skb_pad(struct sk_buff *skb, int pad)
+{
+
+ SKB_TRACE(skb);
+ SKB_TODO();
+ return (-1);
+}
+
+static inline void
+skb_list_del_init(struct sk_buff *skb)
+{
+
+ SKB_TRACE(skb);
+ __list_del_entry(&skb->list);
+ skb_mark_not_on_list(skb);
+}
+
+static inline void
+napi_consume_skb(struct sk_buff *skb, int budget)
+{
+
+ SKB_TRACE(skb);
+ SKB_TODO();
+}
+
+static inline struct sk_buff *
+napi_build_skb(void *data, size_t len)
+{
+
+ SKB_TODO();
+ return (NULL);
+}
+
+static inline uint32_t
+skb_get_hash(struct sk_buff *skb)
+{
+ SKB_TRACE(skb);
+ SKB_TODO();
+ return (0);
+}
+
+static inline void
+skb_mark_for_recycle(struct sk_buff *skb)
+{
+ SKB_TRACE(skb);
+ /* page_pool */
+ SKB_TODO();
+}
+
+static inline int
+skb_cow_head(struct sk_buff *skb, unsigned int headroom)
+{
+ SKB_TRACE(skb);
+ SKB_TODO();
+ return (-1);
+}
+
+#define SKB_WITH_OVERHEAD(_s) \
+ (_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
+
#endif /* _LINUXKPI_LINUX_SKBUFF_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h
index 1228c4d07aa6..0e649e1e3c4a 100644
--- a/sys/compat/linuxkpi/common/include/linux/slab.h
+++ b/sys/compat/linuxkpi/common/include/linux/slab.h
@@ -4,6 +4,10 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
* All rights reserved.
+ * Copyright (c) 2024-2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,8 +29,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SLAB_H_
#define _LINUXKPI_LINUX_SLAB_H_
@@ -38,24 +40,25 @@
#include <linux/compat.h>
#include <linux/types.h>
#include <linux/gfp.h>
+#include <linux/err.h>
#include <linux/llist.h>
#include <linux/overflow.h>
+#include <linux/cleanup.h>
MALLOC_DECLARE(M_KMALLOC);
-#define kvmalloc(size, flags) kmalloc(size, flags)
-#define kvzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
+#define kvzalloc(size, flags) kvmalloc(size, (flags) | __GFP_ZERO)
#define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO)
#define kzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc_node(size, (flags) | __GFP_ZERO, node)
#define kfree_const(ptr) kfree(ptr)
+#define kfree_async(ptr) kfree(ptr) /* drm-kmod 5.4 compat */
#define vzalloc(size) __vmalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, 0)
#define vfree(arg) kfree(arg)
#define kvfree(arg) kfree(arg)
#define vmalloc_node(size, node) __vmalloc_node(size, GFP_KERNEL, node)
#define vmalloc_user(size) __vmalloc(size, GFP_KERNEL | __GFP_ZERO, 0)
#define vmalloc(size) __vmalloc(size, GFP_KERNEL, 0)
-#define __kmalloc(...) kmalloc(__VA_ARGS__)
/*
* Prefix some functions with linux_ to avoid namespace conflict
@@ -67,6 +70,7 @@ MALLOC_DECLARE(M_KMALLOC);
#define kmem_cache_zalloc(...) lkpi_kmem_cache_zalloc(__VA_ARGS__)
#define kmem_cache_free(...) lkpi_kmem_cache_free(__VA_ARGS__)
#define kmem_cache_destroy(...) linux_kmem_cache_destroy(__VA_ARGS__)
+#define kmem_cache_shrink(x) (0)
#define KMEM_CACHE(__struct, flags) \
linux_kmem_cache_create(#__struct, sizeof(struct __struct), \
@@ -86,8 +90,22 @@ struct linux_kmem_cache;
#define ARCH_KMALLOC_MINALIGN \
__alignof(unsigned long long)
-/* drm-kmod 5.4 compat */
-#define kfree_async(ptr) kfree(ptr);
+#define ZERO_SIZE_PTR ((void *)16)
+#define ZERO_OR_NULL_PTR(x) ((x) == NULL || (x) == ZERO_SIZE_PTR)
+
+struct linux_kmem_cache *linux_kmem_cache_create(const char *name,
+ size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor);
+void *lkpi_kmem_cache_alloc(struct linux_kmem_cache *, gfp_t);
+void *lkpi_kmem_cache_zalloc(struct linux_kmem_cache *, gfp_t);
+void lkpi_kmem_cache_free(struct linux_kmem_cache *, void *);
+void linux_kmem_cache_destroy(struct linux_kmem_cache *);
+
+void *lkpi_kmalloc(size_t, gfp_t);
+void *lkpi_kvmalloc(size_t, gfp_t);
+void *lkpi___kmalloc(size_t, gfp_t);
+void *lkpi___kmalloc_node(size_t, gfp_t, int);
+void *lkpi_krealloc(void *, size_t, gfp_t);
+void lkpi_kfree(const void *);
static inline gfp_t
linux_check_m_flags(gfp_t flags)
@@ -104,35 +122,91 @@ linux_check_m_flags(gfp_t flags)
return (flags & GFP_NATIVE_MASK);
}
+/*
+ * Base functions with a native implementation.
+ */
static inline void *
kmalloc(size_t size, gfp_t flags)
{
- return (malloc(MAX(size, sizeof(struct llist_node)), M_KMALLOC,
- linux_check_m_flags(flags)));
+ return (lkpi_kmalloc(size, flags));
+}
+
+static inline void *
+__kmalloc(size_t size, gfp_t flags)
+{
+ return (lkpi___kmalloc(size, flags));
}
static inline void *
kmalloc_node(size_t size, gfp_t flags, int node)
{
- return (malloc_domainset(size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
+ return (lkpi___kmalloc_node(size, flags, node));
+}
+
+static inline void *
+krealloc(void *ptr, size_t size, gfp_t flags)
+{
+ return (lkpi_krealloc(ptr, size, flags));
+}
+
+static inline void
+kfree(const void *ptr)
+{
+ lkpi_kfree(ptr);
+}
+
+DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
+
+/*
+ * Other k*alloc() funtions using the above as underlying allocator.
+ */
+/* kmalloc */
+static inline void *
+kmalloc_array(size_t n, size_t size, gfp_t flags)
+{
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
+
+ return (kmalloc(size * n, flags));
}
static inline void *
kcalloc(size_t n, size_t size, gfp_t flags)
{
flags |= __GFP_ZERO;
- return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
+ return (kmalloc_array(n, size, flags));
+}
+
+/* kmalloc_node */
+static inline void *
+kmalloc_array_node(size_t n, size_t size, gfp_t flags, int node)
+{
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
+
+ return (kmalloc_node(size * n, flags, node));
}
static inline void *
kcalloc_node(size_t n, size_t size, gfp_t flags, int node)
{
flags |= __GFP_ZERO;
- return (mallocarray_domainset(n, size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
+ return (kmalloc_array_node(n, size, flags, node));
}
+/* krealloc */
+static inline void *
+krealloc_array(void *ptr, size_t n, size_t size, gfp_t flags)
+{
+ if (WOULD_OVERFLOW(n, size))
+ return NULL;
+
+ return (krealloc(ptr, n * size, flags));
+}
+
+/*
+ * vmalloc/kvalloc functions.
+ */
static inline void *
__vmalloc(size_t size, gfp_t flags, int other)
{
@@ -152,45 +226,49 @@ vmalloc_32(size_t size)
return (contigmalloc(size, M_KMALLOC, M_WAITOK, 0, UINT_MAX, 1, 1));
}
+/* May return non-contiguous memory. */
static inline void *
-kmalloc_array(size_t n, size_t size, gfp_t flags)
+kvmalloc(size_t size, gfp_t flags)
{
- return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
-}
-
-static inline void *
-kmalloc_array_node(size_t n, size_t size, gfp_t flags, int node)
-{
- return (mallocarray_domainset(n, size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
+ return (lkpi_kvmalloc(size, flags));
}
static inline void *
kvmalloc_array(size_t n, size_t size, gfp_t flags)
{
- return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
+
+ return (kvmalloc(size * n, flags));
}
static inline void *
-krealloc(void *ptr, size_t size, gfp_t flags)
+kvrealloc(const void *ptr, size_t oldsize, size_t newsize, gfp_t flags)
{
- return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags)));
-}
+ void *newptr;
-extern void linux_kfree_async(void *);
+ if (newsize <= oldsize)
+ return (__DECONST(void *, ptr));
-static inline void
-kfree(const void *ptr)
-{
- if (curthread->td_critnest != 0)
- linux_kfree_async(__DECONST(void *, ptr));
- else
- free(__DECONST(void *, ptr), M_KMALLOC);
+ newptr = kvmalloc(newsize, flags);
+ if (newptr != NULL) {
+ memcpy(newptr, ptr, oldsize);
+ kvfree(ptr);
+ }
+
+ return (newptr);
}
+/*
+ * Misc.
+ */
+
static __inline void
kfree_sensitive(const void *ptr)
{
+ if (ZERO_OR_NULL_PTR(ptr))
+ return;
+
zfree(__DECONST(void *, ptr), M_KMALLOC);
}
@@ -200,11 +278,12 @@ ksize(const void *ptr)
return (malloc_usable_size(ptr));
}
-extern struct linux_kmem_cache *linux_kmem_cache_create(const char *name,
- size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor);
-extern void *lkpi_kmem_cache_alloc(struct linux_kmem_cache *, gfp_t);
-extern void *lkpi_kmem_cache_zalloc(struct linux_kmem_cache *, gfp_t);
-extern void lkpi_kmem_cache_free(struct linux_kmem_cache *, void *);
-extern void linux_kmem_cache_destroy(struct linux_kmem_cache *);
+static inline size_t
+kmalloc_size_roundup(size_t size)
+{
+ if (unlikely(size == 0 || size == SIZE_MAX))
+ return (size);
+ return (malloc_size(size));
+}
#endif /* _LINUXKPI_LINUX_SLAB_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/smp.h b/sys/compat/linuxkpi/common/include/linux/smp.h
index c6d011fceb5f..b057953e6282 100644
--- a/sys/compat/linuxkpi/common/include/linux/smp.h
+++ b/sys/compat/linuxkpi/common/include/linux/smp.h
@@ -22,13 +22,13 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SMP_H_
#define _LINUXKPI_LINUX_SMP_H_
+#include <asm/smp.h>
+
/*
* Important note about the use of the function provided below:
*
diff --git a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
new file mode 100644
index 000000000000..903053e7f6e8
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
@@ -0,0 +1,62 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022-2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H
+#define _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H
+
+struct mtk_wed_device {
+};
+
+#define WED_WO_STA_REC 0x6
+
+#define mtk_wed_device_start(_dev, _mask) do { } while(0)
+#define mtk_wed_device_detach(_dev) do { } while(0)
+#define mtk_wed_device_irq_get(_dev, _mask) 0
+#define mtk_wed_device_irq_set_mask(_dev, _mask) do { } while(0)
+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) (-ENODEV)
+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _entry) \
+ do {} while (0)
+#define mtk_wed_device_stop(_dev) do { } while(0)
+#define mtk_wed_device_start_hw_rro(_dev, _mask, _b) do { } while(0)
+#define mtk_wed_device_setup_tc(_dev, _ndev, _type, _tdata) (-EOPNOTSUPP)
+
+static inline bool
+mtk_wed_device_active(struct mtk_wed_device *dev __unused)
+{
+
+ return (false);
+}
+
+static inline bool
+mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
+{
+
+ return (false);
+}
+
+#endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h b/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h
new file mode 100644
index 000000000000..647eaf271d87
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/soc/qcom/qmi.h
@@ -0,0 +1,173 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022-2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_SOC_QCOM_QMI_H
+#define _LINUXKPI_LINUX_SOC_QCOM_QMI_H
+
+/* QMI (Qualcomm MSM Interface) */
+
+#include <linux/qrtr.h>
+
+enum soc_qcom_qmi_data_type {
+ QMI_EOTI,
+ QMI_DATA_LEN,
+ QMI_OPT_FLAG,
+ QMI_UNSIGNED_1_BYTE,
+ QMI_UNSIGNED_2_BYTE,
+ QMI_UNSIGNED_4_BYTE,
+ QMI_UNSIGNED_8_BYTE,
+ QMI_SIGNED_4_BYTE_ENUM,
+ QMI_STRUCT,
+ QMI_STRING,
+};
+
+#define QMI_RESULT_SUCCESS_V01 __LINE__
+#define QMI_INDICATION __LINE__
+
+struct qmi_handle;
+
+enum soc_qcom_qmi_array_type {
+ NO_ARRAY,
+ STATIC_ARRAY,
+ VAR_LEN_ARRAY,
+};
+
+/* Should this become an enum? */
+#define QMI_COMMON_TLV_TYPE 0
+
+struct qmi_elem_info {
+ enum soc_qcom_qmi_data_type data_type;
+ uint32_t elem_len;
+ uint32_t elem_size;
+ enum soc_qcom_qmi_array_type array_type;
+ uint8_t tlv_type;
+ uint32_t offset;
+ const struct qmi_elem_info *ei_array;
+};
+
+struct qmi_response_type_v01 {
+ uint16_t result;
+ uint16_t error;
+};
+
+struct qmi_txn {
+};
+
+struct qmi_service {
+ uint32_t node;
+ uint32_t port;
+};
+
+struct qmi_msg_handler {
+ uint32_t type;
+ uint32_t msg_id;
+ const struct qmi_elem_info *ei;
+ size_t decoded_size;
+ void (*fn)(struct qmi_handle *, struct sockaddr_qrtr *, struct qmi_txn *, const void *);
+};
+
+struct qmi_ops {
+ int (*new_server)(struct qmi_handle *, struct qmi_service *);
+ void (*del_server)(struct qmi_handle *, struct qmi_service *);
+};
+
+struct qmi_handle {
+ int sock;
+
+ const struct qmi_msg_handler *handler;
+ struct qmi_ops ops;
+};
+
+
+/* XXX-TODO need implementation somewhere... it is not in ath1xk* */
+extern struct qmi_elem_info qmi_response_type_v01_ei[];
+
+static inline int
+qmi_handle_init(struct qmi_handle *handle, size_t resp_len_max,
+ const struct qmi_ops *ops, const struct qmi_msg_handler *handler)
+{
+
+ handle->handler = handler;
+ if (ops != NULL)
+ handle->ops = *ops;
+
+ /* We will find out what else to do here. */
+ /* XXX TODO */
+
+ return (0);
+}
+
+static __inline int
+qmi_add_lookup(struct qmi_handle *handle, uint32_t service, uint32_t version,
+ uint32_t service_ins_id)
+{
+
+ /* XXX TODO */
+ return (0);
+}
+
+static __inline void
+qmi_handle_release(struct qmi_handle *handle)
+{
+
+ /* XXX TODO */
+}
+
+static __inline int
+qmi_send_request(struct qmi_handle *handle, void *x, struct qmi_txn *txn,
+ uint32_t msd_id, size_t len, const struct qmi_elem_info *ei, void *req)
+{
+
+ /* XXX TODO */
+ return (-ENXIO);
+}
+
+static __inline void
+qmi_txn_cancel(struct qmi_txn *txn)
+{
+
+ /* XXX TODO */
+}
+
+static __inline int
+qmi_txn_init(struct qmi_handle *handle, struct qmi_txn *txn,
+ const struct qmi_elem_info *ei, void *resp)
+{
+
+ /* XXX TODO */
+ return (-ENXIO);
+}
+
+static __inline int
+qmi_txn_wait(struct qmi_txn *txn, uint64_t jiffies)
+{
+
+ /* XXX TODO */
+ return (-ENXIO);
+}
+
+#endif /* _LINUXKPI_LINUX_SOC_QCOM_QMI_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/socket.h b/sys/compat/linuxkpi/common/include/linux/socket.h
index 3afb9bdfe3ba..638ee058c2f5 100644
--- a/sys/compat/linuxkpi/common/include/linux/socket.h
+++ b/sys/compat/linuxkpi/common/include/linux/socket.h
@@ -25,14 +25,23 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SOCKET_H_
#define _LINUXKPI_LINUX_SOCKET_H_
#include <sys/socket.h>
+#define AF_QIPCRTR 42
+
+static inline int
+kernel_connect(int sd, struct sockaddr *sa, size_t salen, int flags)
+{
+
+ /* kern_connectat()? It is used for sockaddr_qrtr by ath1xk/qmi. */
+ pr_debug("%s: TODO\n", __func__);
+ return (-EINVAL);
+}
+
#ifdef notyet
static inline int
memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len)
diff --git a/sys/compat/linuxkpi/common/include/linux/sort.h b/sys/compat/linuxkpi/common/include/linux/sort.h
index 91ccd7ff83c4..e6196d1f41c7 100644
--- a/sys/compat/linuxkpi/common/include/linux/sort.h
+++ b/sys/compat/linuxkpi/common/include/linux/sort.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h
index a87cb7180b28..dc10b0457153 100644
--- a/sys/compat/linuxkpi/common/include/linux/spinlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SPINLOCK_H_
#define _LINUXKPI_LINUX_SPINLOCK_H_
@@ -43,9 +41,7 @@
#include <linux/bottom_half.h>
#include <linux/lockdep.h>
-typedef struct {
- struct mtx m;
-} spinlock_t;
+typedef struct mtx spinlock_t;
/*
* By defining CONFIG_SPIN_SKIP LinuxKPI spinlocks and asserts will be
@@ -61,7 +57,7 @@ typedef struct {
#define spin_lock(_l) do { \
if (SPIN_SKIP()) \
break; \
- mtx_lock(&(_l)->m); \
+ mtx_lock(_l); \
local_bh_disable(); \
} while (0)
@@ -78,7 +74,7 @@ typedef struct {
if (SPIN_SKIP()) \
break; \
local_bh_enable(); \
- mtx_unlock(&(_l)->m); \
+ mtx_unlock(_l); \
} while (0)
#define spin_unlock_bh(_l) do { \
@@ -95,7 +91,7 @@ typedef struct {
if (SPIN_SKIP()) { \
__ret = 1; \
} else { \
- __ret = mtx_trylock(&(_l)->m); \
+ __ret = mtx_trylock(_l); \
if (likely(__ret != 0)) \
local_bh_disable(); \
} \
@@ -113,7 +109,7 @@ typedef struct {
#define spin_lock_nested(_l, _n) do { \
if (SPIN_SKIP()) \
break; \
- mtx_lock_flags(&(_l)->m, MTX_DUPOK); \
+ mtx_lock_flags(_l, MTX_DUPOK); \
local_bh_disable(); \
} while (0)
@@ -128,6 +124,7 @@ typedef struct {
} while (0)
#define spin_unlock_irqrestore(_l, flags) do { \
+ (void)(flags); \
spin_unlock(_l); \
} while (0)
@@ -142,31 +139,27 @@ typedef struct {
#define _spin_lock_name(...) __spin_lock_name(__VA_ARGS__)
#define spin_lock_name(name) _spin_lock_name(name, __FILE__, __LINE__)
-#define spin_lock_init(lock) linux_spin_lock_init(lock, spin_lock_name("lnxspin"))
-
-static inline void
-linux_spin_lock_init(spinlock_t *lock, const char *name)
-{
+#define spin_lock_init(lock) mtx_init(lock, spin_lock_name("lnxspin"), \
+ NULL, MTX_DEF | MTX_NOWITNESS | MTX_NEW)
- memset(lock, 0, sizeof(*lock));
- mtx_init(&lock->m, name, NULL, MTX_DEF | MTX_NOWITNESS);
-}
-
-static inline void
-spin_lock_destroy(spinlock_t *lock)
-{
-
- mtx_destroy(&lock->m);
-}
+#define spin_lock_destroy(_l) mtx_destroy(_l)
#define DEFINE_SPINLOCK(lock) \
spinlock_t lock; \
- MTX_SYSINIT(lock, &(lock).m, spin_lock_name("lnxspin"), MTX_DEF)
+ MTX_SYSINIT(lock, &lock, spin_lock_name("lnxspin"), MTX_DEF)
#define assert_spin_locked(_l) do { \
if (SPIN_SKIP()) \
break; \
- mtx_assert(&(_l)->m, MA_OWNED); \
+ mtx_assert(_l, MA_OWNED); \
+} while (0)
+
+#define local_irq_save(flags) do { \
+ (flags) = 0; \
+} while (0)
+
+#define local_irq_restore(flags) do { \
+ (void)(flags); \
} while (0)
#define atomic_dec_and_lock_irqsave(cnt, lock, flags) \
diff --git a/sys/compat/linuxkpi/common/include/linux/srcu.h b/sys/compat/linuxkpi/common/include/linux/srcu.h
index 0742d25d11ac..b42c28a1311b 100644
--- a/sys/compat/linuxkpi/common/include/linux/srcu.h
+++ b/sys/compat/linuxkpi/common/include/linux/srcu.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SRCU_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/stackdepot.h b/sys/compat/linuxkpi/common/include/linux/stackdepot.h
new file mode 100644
index 000000000000..df223d46be6e
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/stackdepot.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _LINUXKPI_LINUX_STACKDEPOT_H_
+#define _LINUXKPI_LINUX_STACKDEPOT_H_
+
+typedef bool depot_stack_handle_t;
+
+#endif /* _LINUXKPI_LINUX_STACKDEPOT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/stdarg.h b/sys/compat/linuxkpi/common/include/linux/stdarg.h
new file mode 100644
index 000000000000..698ac45e9198
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/stdarg.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_STDARG_H_
+#define _LINUXKPI_STDARG_H_
+
+#include <sys/stdarg.h>
+
+#endif /* _LINUXKPI_STDARG_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/stddef.h b/sys/compat/linuxkpi/common/include/linux/stddef.h
new file mode 100644
index 000000000000..d04a5a4bf516
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/stddef.h
@@ -0,0 +1,31 @@
+/* Public domain */
+
+#ifndef _LINUXKPI_LINUX_STDDEF_H_
+#define _LINUXKPI_LINUX_STDDEF_H_
+
+#include <sys/stddef.h>
+
+/*
+ * FreeBSD has multiple (vendor) drivers containing copies of this
+ * and including LinuxKPI headers. Put the #defines behind guards.
+ */
+
+#ifndef __struct_group
+#define __struct_group(_tag, _name, _attrs, _members...) \
+ union { \
+ struct { _members } _attrs; \
+ struct _tag { _members } _attrs _name; \
+ } _attrs
+#endif
+
+#ifndef struct_group
+#define struct_group(_name, _members...) \
+ __struct_group(/* no tag */, _name, /* no attrs */, _members)
+#endif
+
+#ifndef struct_group_tagged
+#define struct_group_tagged(_tag, _name, _members...) \
+ __struct_group(_tag, _name, /* no attrs */, _members)
+#endif
+
+#endif /* _LINUXKPI_LINUX_STDDEF_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h
index 73a38dc42c6c..f7b64560d254 100644
--- a/sys/compat/linuxkpi/common/include/linux/string.h
+++ b/sys/compat/linuxkpi/common/include/linux/string.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_STRING_H_
#define _LINUXKPI_LINUX_STRING_H_
@@ -38,6 +36,9 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/err.h>
+#include <linux/bitops.h> /* for BITS_PER_LONG */
+#include <linux/overflow.h>
+#include <linux/stdarg.h>
#include <sys/libkern.h>
@@ -97,6 +98,27 @@ kmemdup(const void *src, size_t len, gfp_t gfp)
return (dst);
}
+/* See slab.h for kvmalloc/kvfree(). */
+static inline void *
+kvmemdup(const void *src, size_t len, gfp_t gfp)
+{
+ void *dst;
+
+ dst = kvmalloc(len, gfp);
+ if (dst != NULL)
+ memcpy(dst, src, len);
+ return (dst);
+}
+
+static inline char *
+strndup_user(const char __user *ustr, long n)
+{
+ if (n < 1)
+ return (ERR_PTR(-EINVAL));
+
+ return (memdup_user_nul(ustr, n - 1));
+}
+
static inline char *
kstrdup(const char *string, gfp_t gfp)
{
@@ -139,6 +161,24 @@ skip_spaces(const char *str)
return (__DECONST(char *, str));
}
+/*
+ * This function trims whitespaces at the end of a string and returns a pointer
+ * to the first non-whitespace character.
+ */
+static inline char *
+strim(char *str)
+{
+ char *end;
+
+ end = str + strlen(str);
+ while (end >= str && (*end == '\0' || isspace(*end))) {
+ *end = '\0';
+ end--;
+ }
+
+ return (skip_spaces(str));
+}
+
static inline void *
memchr_inv(const void *start, int c, size_t length)
{
@@ -196,4 +236,94 @@ strscpy(char* dst, const char* src, size_t len)
return (-E2BIG);
}
-#endif /* _LINUXKPI_LINUX_STRING_H_ */
+static inline ssize_t
+strscpy_pad(char* dst, const char* src, size_t len)
+{
+
+ bzero(dst, len);
+
+ return (strscpy(dst, src, len));
+}
+
+static inline char *
+strnchr(const char *cp, size_t n, int ch)
+{
+ char *p;
+
+ for (p = __DECONST(char *, cp); n--; ++p) {
+ if (*p == ch)
+ return (p);
+ if (*p == '\0')
+ break;
+ }
+
+ return (NULL);
+}
+
+static inline void *
+memset32(uint32_t *b, uint32_t c, size_t len)
+{
+ uint32_t *dst = b;
+
+ while (len--)
+ *dst++ = c;
+ return (b);
+}
+
+static inline void *
+memset64(uint64_t *b, uint64_t c, size_t len)
+{
+ uint64_t *dst = b;
+
+ while (len--)
+ *dst++ = c;
+ return (b);
+}
+
+static inline void *
+memset_p(void **p, void *v, size_t n)
+{
+
+ if (BITS_PER_LONG == 32)
+ return (memset32((uint32_t *)p, (uintptr_t)v, n));
+ else
+ return (memset64((uint64_t *)p, (uintptr_t)v, n));
+}
+
+static inline void
+memcpy_and_pad(void *dst, size_t dstlen, const void *src, size_t len, int ch)
+{
+
+ if (len >= dstlen) {
+ memcpy(dst, src, dstlen);
+ } else {
+ memcpy(dst, src, len);
+ /* Pad with given padding character. */
+ memset((char *)dst + len, ch, dstlen - len);
+ }
+}
+
+#define memset_startat(ptr, bytepat, smember) \
+({ \
+ uint8_t *_ptr = (uint8_t *)(ptr); \
+ int _c = (int)(bytepat); \
+ size_t _o = offsetof(typeof(*(ptr)), smember); \
+ memset(_ptr + _o, _c, sizeof(*(ptr)) - _o); \
+})
+
+#define memset_after(ptr, bytepat, smember) \
+({ \
+ uint8_t *_ptr = (uint8_t *)(ptr); \
+ int _c = (int)(bytepat); \
+ size_t _o = offsetofend(typeof(*(ptr)), smember); \
+ memset(_ptr + _o, _c, sizeof(*(ptr)) - _o); \
+})
+
+static inline void
+memzero_explicit(void *p, size_t s)
+{
+ memset(p, 0, s);
+ __asm__ __volatile__("": :"r"(p) :"memory");
+}
+
+#endif /* _LINUXKPI_LINUX_STRING_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/string_choices.h b/sys/compat/linuxkpi/common/include/linux/string_choices.h
new file mode 100644
index 000000000000..74aa3fd019b2
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/string_choices.h
@@ -0,0 +1,71 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_STRING_CHOICES_H_
+#define _LINUXKPI_LINUX_STRING_CHOICES_H_
+
+#include <sys/types.h>
+
+static inline const char *
+str_yes_no(bool value)
+{
+ if (value)
+ return "yes";
+ else
+ return "no";
+}
+
+static inline const char *
+str_on_off(bool value)
+{
+ if (value)
+ return "on";
+ else
+ return "off";
+}
+
+static inline const char *
+str_enabled_disabled(bool value)
+{
+ if (value)
+ return "enabled";
+ else
+ return "disabled";
+}
+
+static inline const char *
+str_enable_disable(bool value)
+{
+ if (value)
+ return "enable";
+ else
+ return "disable";
+}
+
+#define str_disable_enable(_v) str_enable_disable(!(_v))
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/string_helpers.h b/sys/compat/linuxkpi/common/include/linux/string_helpers.h
new file mode 100644
index 000000000000..07d113c0cb21
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/string_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_STRING_HELPERS_H_
+#define _LINUXKPI_LINUX_STRING_HELPERS_H_
+
+#include <linux/string_choices.h>
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/stringify.h b/sys/compat/linuxkpi/common/include/linux/stringify.h
index bfdf99a30f2f..9345bdc441aa 100644
--- a/sys/compat/linuxkpi/common/include/linux/stringify.h
+++ b/sys/compat/linuxkpi/common/include/linux/stringify.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_STRINGIFY_H_
diff --git a/sys/compat/linuxkpi/common/include/linux/suspend.h b/sys/compat/linuxkpi/common/include/linux/suspend.h
new file mode 100644
index 000000000000..dacecbebdc08
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/suspend.h
@@ -0,0 +1,23 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_LINUX_SUSPEND_H_
+#define _LINUXKPI_LINUX_SUSPEND_H_
+
+typedef int suspend_state_t;
+
+extern suspend_state_t pm_suspend_target_state;
+
+#define PM_SUSPEND_ON 0
+#define PM_SUSPEND_TO_IDLE 1
+#define PM_SUSPEND_STANDBY 2
+#define PM_SUSPEND_MEM 3
+#define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE
+#define PM_SUSPEND_MAX 4
+
+static inline int
+pm_suspend_via_firmware(void)
+{
+ return 0;
+}
+
+#endif /* _LINUXKPI_LINUX_SUSPEND_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/swap.h b/sys/compat/linuxkpi/common/include/linux/swap.h
index a080895bed98..5828db7ae392 100644
--- a/sys/compat/linuxkpi/common/include/linux/swap.h
+++ b/sys/compat/linuxkpi/common/include/linux/swap.h
@@ -22,16 +22,24 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SWAP_H_
#define _LINUXKPI_LINUX_SWAP_H_
+#include <sys/param.h>
+#include <sys/domainset.h>
+#include <sys/queue.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+
+#include <vm/vm.h>
#include <vm/swap_pager.h>
#include <vm/vm_pageout.h>
+#include <linux/pagemap.h>
+#include <linux/page-flags.h>
+
static inline long
get_nr_swap_pages(void)
{
@@ -49,4 +57,15 @@ current_is_kswapd(void)
return (curproc == pageproc);
}
+static inline void
+folio_mark_accessed(struct folio *folio)
+{
+ mark_page_accessed(&folio->page);
+}
+
+static inline void
+check_move_unevictable_folios(struct folio_batch *fbatch)
+{
+}
+
#endif
diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h b/sys/compat/linuxkpi/common/include/linux/sysfs.h
index 0b6b479d9362..470c224a9778 100644
--- a/sys/compat/linuxkpi/common/include/linux/sysfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_SYSFS_H_
#define _LINUXKPI_LINUX_SYSFS_H_
@@ -37,6 +35,7 @@
#include <linux/kobject.h>
#include <linux/stringify.h>
+#include <linux/mm.h>
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *);
@@ -51,11 +50,23 @@ struct attribute_group {
struct attribute **attrs;
};
+struct bin_attribute {
+ struct attribute attr;
+ size_t size;
+ ssize_t (*read)(struct linux_file *, struct kobject *,
+ struct bin_attribute *, char *, loff_t, size_t);
+ ssize_t (*write)(struct linux_file *, struct kobject *,
+ struct bin_attribute *, char *, loff_t, size_t);
+};
+
#define __ATTR(_name, _mode, _show, _store) { \
.attr = { .name = __stringify(_name), .mode = _mode }, \
.show = _show, .store = _store, \
}
-#define __ATTR_RO(_name) __ATTR(_name, 0444, _name##_show, NULL)
+#define __ATTR_RO(_name) { \
+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
+ .show = _name##_show, \
+}
#define __ATTR_WO(_name) __ATTR(_name, 0200, NULL, _name##_store)
#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)
#define __ATTR_NULL { .attr = { .name = NULL } }
@@ -70,6 +81,39 @@ struct attribute_group {
NULL, \
}
+#define __BIN_ATTR(_name, _mode, _read, _write, _size) { \
+ .attr = { .name = __stringify(_name), .mode = _mode }, \
+ .read = _read, .write = _write, .size = _size, \
+}
+#define __BIN_ATTR_RO(_name, _size) { \
+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
+ .read = _name##_read, .size = _size, \
+}
+#define __BIN_ATTR_WO(_name, _size) { \
+ .attr = { .name = __stringify(_name), .mode = 0200 }, \
+ .write = _name##_write, .size = _size, \
+}
+#define __BIN_ATTR_WR(_name, _size) { \
+ .attr = { .name = __stringify(_name), .mode = 0644 }, \
+ .read = _name##_read, .write = _name##_write, .size = _size, \
+}
+
+#define BIN_ATTR(_name, _mode, _read, _write, _size) \
+struct bin_attribute bin_attr_##_name = \
+ __BIN_ATTR(_name, _mode, _read, _write, _size);
+
+#define BIN_ATTR_RO(_name, _size) \
+struct bin_attribute bin_attr_##_name = \
+ __BIN_ATTR_RO(_name, _size);
+
+#define BIN_ATTR_WO(_name, _size) \
+struct bin_attribute bin_attr_##_name = \
+ __BIN_ATTR_WO(_name, _size);
+
+#define BIN_ATTR_WR(_name, _size) \
+struct bin_attribute bin_attr_##_name = \
+ __BIN_ATTR_WR(_name, _size);
+
/*
* Handle our generic '\0' terminated 'C' string.
* Two cases:
@@ -145,6 +189,50 @@ sysfs_create_file(struct kobject *kobj, const struct attribute *attr)
return (0);
}
+static inline struct kobject *
+__sysfs_lookup_group(struct kobject *kobj, const char *group)
+{
+ int found;
+ struct sysctl_oid *group_oidp;
+ struct kobject *group_kobj;
+
+ found = 0;
+ if (group != NULL) {
+ SYSCTL_FOREACH(group_oidp, SYSCTL_CHILDREN(kobj->oidp)) {
+ if (strcmp(group_oidp->oid_name, group) != 0)
+ continue;
+ found = 1;
+ break;
+ }
+ } else {
+ found = 1;
+ group_oidp = kobj->oidp;
+ }
+
+ if (!found)
+ return (NULL);
+
+ group_kobj = group_oidp->oid_arg1;
+
+ return (group_kobj);
+}
+
+static inline int
+sysfs_add_file_to_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group)
+{
+ int ret;
+ struct kobject *group_kobj;
+
+ group_kobj = __sysfs_lookup_group(kobj, group);
+ if (group_kobj == NULL)
+ return (-ENOENT);
+
+ ret = sysfs_create_file(group_kobj, attr);
+
+ return (ret);
+}
+
static inline void
sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
{
@@ -153,6 +241,108 @@ sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
sysctl_remove_name(kobj->oidp, attr->name, 1, 1);
}
+static inline void
+sysfs_remove_file_from_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group)
+{
+ struct kobject *group_kobj;
+
+ group_kobj = __sysfs_lookup_group(kobj, group);
+ if (group_kobj == NULL)
+ return;
+
+ sysfs_remove_file(group_kobj, attr);
+}
+
+static inline int
+sysctl_handle_bin_attr(SYSCTL_HANDLER_ARGS)
+{
+ struct kobject *kobj;
+ struct bin_attribute *attr;
+ char *buf;
+ int error;
+ ssize_t len;
+
+ kobj = arg1;
+ attr = (struct bin_attribute *)(intptr_t)arg2;
+ if (kobj->ktype == NULL || kobj->ktype->sysfs_ops == NULL)
+ return (ENODEV);
+ buf = (char *)get_zeroed_page(GFP_KERNEL);
+ if (buf == NULL)
+ return (ENOMEM);
+
+ if (attr->read) {
+ len = attr->read(
+ NULL, /* <-- struct file, unimplemented */
+ kobj, attr, buf, req->oldidx, PAGE_SIZE);
+ if (len < 0) {
+ error = -len;
+ if (error != EIO)
+ goto out;
+ }
+ }
+
+ error = sysctl_handle_opaque(oidp, buf, PAGE_SIZE, req);
+ if (error != 0 || req->newptr == NULL || attr->write == NULL)
+ goto out;
+
+ len = attr->write(
+ NULL, /* <-- struct file, unimplemented */
+ kobj, attr, buf, req->newidx, req->newlen);
+ if (len < 0)
+ error = -len;
+out:
+ free_page((unsigned long)buf);
+
+ return (error);
+}
+
+static inline int
+sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr)
+{
+ struct sysctl_oid *oid;
+ int ctlflags;
+
+ ctlflags = CTLTYPE_OPAQUE | CTLFLAG_MPSAFE;
+ if (attr->attr.mode & (S_IRUSR | S_IWUSR))
+ ctlflags |= CTLFLAG_RW;
+ else if (attr->attr.mode & S_IRUSR)
+ ctlflags |= CTLFLAG_RD;
+ else if (attr->attr.mode & S_IWUSR)
+ ctlflags |= CTLFLAG_WR;
+
+ oid = SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(kobj->oidp), OID_AUTO,
+ attr->attr.name, ctlflags, kobj,
+ (uintptr_t)attr, sysctl_handle_bin_attr, "", "");
+ if (oid == NULL)
+ return (-ENOMEM);
+
+ return (0);
+}
+
+static inline void
+sysfs_remove_bin_file(struct kobject *kobj, const struct bin_attribute *attr)
+{
+
+ if (kobj->oidp)
+ sysctl_remove_name(kobj->oidp, attr->attr.name, 1, 1);
+}
+
+static inline int
+sysfs_create_link(struct kobject *kobj __unused,
+ struct kobject *target __unused, const char *name __unused)
+{
+ /* TODO */
+
+ return (0);
+}
+
+static inline void
+sysfs_remove_link(struct kobject *kobj, const char *name)
+{
+ /* TODO (along with sysfs_create_link) */
+}
+
static inline int
sysfs_create_files(struct kobject *kobj, const struct attribute * const *attrs)
{
@@ -246,7 +436,7 @@ sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp)
struct attribute **attr;
struct sysctl_oid *oidp;
- SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) {
+ SYSCTL_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp)) {
if (strcmp(oidp->oid_name, grp->name) != 0)
continue;
for (attr = grp->attrs; *attr != NULL; attr++) {
@@ -295,6 +485,60 @@ sysfs_streq(const char *s1, const char *s2)
return (l1 == l2 && strncmp(s1, s2, l1) == 0);
}
+static inline int
+sysfs_emit(char *buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ if (!buf || offset_in_page(buf)) {
+ pr_warn("invalid sysfs_emit: buf:%p\n", buf);
+ return (0);
+ }
+
+ va_start(args, fmt);
+ i = vscnprintf(buf, PAGE_SIZE, fmt, args);
+ va_end(args);
+
+ return (i);
+}
+
+static inline int
+sysfs_emit_at(char *buf, int at, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ if (!buf || offset_in_page(buf) || at < 0 || at >= PAGE_SIZE) {
+ pr_warn("invalid sysfs_emit: buf:%p at:%d\n", buf, at);
+ return (0);
+ }
+
+ va_start(args, fmt);
+ i = vscnprintf(buf + at, PAGE_SIZE - at, fmt, args);
+ va_end(args);
+
+ return (i);
+}
+
+static inline int
+_sysfs_match_string(const char * const *a, size_t l, const char *s)
+{
+ const char *p;
+ int i;
+
+ for (i = 0; i < l; i++) {
+ p = a[i];
+ if (p == NULL)
+ break;
+ if (sysfs_streq(p, s))
+ return (i);
+ }
+
+ return (-ENOENT);
+}
+#define sysfs_match_string(a, s) _sysfs_match_string(a, ARRAY_SIZE(a), s)
+
#define sysfs_attr_init(attr) do {} while(0)
#endif /* _LINUXKPI_LINUX_SYSFS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/tcp.h b/sys/compat/linuxkpi/common/include/linux/tcp.h
index cfc64b8c7e53..3e461d8e7075 100644
--- a/sys/compat/linuxkpi/common/include/linux/tcp.h
+++ b/sys/compat/linuxkpi/common/include/linux/tcp.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_TCP_H
diff --git a/sys/compat/linuxkpi/common/include/linux/time.h b/sys/compat/linuxkpi/common/include/linux/time.h
index c7a41a83f4aa..ca77a20516ff 100644
--- a/sys/compat/linuxkpi/common/include/linux/time.h
+++ b/sys/compat/linuxkpi/common/include/linux/time.h
@@ -22,12 +22,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_TIME_H_
#define _LINUXKPI_LINUX_TIME_H_
+#define MSEC_PER_SEC 1000L
+
#define NSEC_PER_USEC 1000L
#define NSEC_PER_MSEC 1000000L
#define NSEC_PER_SEC 1000000000L
@@ -40,6 +40,10 @@
#include <sys/time.h>
#include <sys/stdint.h>
+#include <linux/math64.h>
+
+typedef int64_t time64_t;
+
static inline struct timeval
ns_to_timeval(const int64_t nsec)
{
@@ -117,6 +121,8 @@ ns_to_timespec(const int64_t nsec)
return (ts);
}
+#define ns_to_timespec64(_x) ns_to_timespec(_x)
+
static inline int
timespec_valid(const struct timespec *ts)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/timer.h b/sys/compat/linuxkpi/common/include/linux/timer.h
index 3432bfc46c4f..d48939e28a02 100644
--- a/sys/compat/linuxkpi/common/include/linux/timer.h
+++ b/sys/compat/linuxkpi/common/include/linux/timer.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_TIMER_H_
#define _LINUXKPI_LINUX_TIMER_H_
@@ -44,15 +42,20 @@ struct timer_list {
void (*function_415) (struct timer_list *);
};
unsigned long data;
- int expires;
+ unsigned long expires;
};
extern unsigned long linux_timer_hz_mask;
#define TIMER_IRQSAFE 0x0001
+#if defined(LINUXKPI_VERSION) && (LINUXKPI_VERSION < 61600)
#define from_timer(var, arg, field) \
container_of(arg, typeof(*(var)), field)
+#else
+#define timer_container_of(var, arg, field) \
+ container_of(arg, typeof(*(var)), field)
+#endif
#define timer_setup(timer, func, flags) do { \
CTASSERT(((flags) & ~TIMER_IRQSAFE) == 0); \
@@ -78,15 +81,29 @@ extern unsigned long linux_timer_hz_mask;
callout_init(&(timer)->callout, 1); \
} while (0)
-extern int mod_timer(struct timer_list *, int);
+extern int mod_timer(struct timer_list *, unsigned long);
extern void add_timer(struct timer_list *);
extern void add_timer_on(struct timer_list *, int cpu);
-extern int del_timer(struct timer_list *);
-extern int del_timer_sync(struct timer_list *);
+
+extern int timer_delete(struct timer_list *);
+extern int timer_delete_sync(struct timer_list *);
+extern int timer_shutdown_sync(struct timer_list *);
+
+static inline int
+del_timer(struct timer_list *tl)
+{
+ return (timer_delete(tl));
+}
+
+static inline int
+del_timer_sync(struct timer_list *tl)
+{
+ return (timer_delete_sync(tl));
+}
#define timer_pending(timer) callout_pending(&(timer)->callout)
#define round_jiffies(j) \
- ((int)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask))
+ ((unsigned long)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask))
#define round_jiffies_relative(j) round_jiffies(j)
#define round_jiffies_up(j) round_jiffies(j)
#define round_jiffies_up_relative(j) round_jiffies_up(j)
diff --git a/sys/compat/linuxkpi/common/include/linux/topology.h b/sys/compat/linuxkpi/common/include/linux/topology.h
new file mode 100644
index 000000000000..16baffc024d1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/topology.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_TOPOLOGY_H_
+#define _LINUXKPI_LINUX_TOPOLOGY_H_
+
+#include <asm/topology.h>
+
+#endif /* _LINUXKPI_LINUX_TOPOLOGY_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/tracepoint.h b/sys/compat/linuxkpi/common/include/linux/tracepoint.h
index 0171427439f9..8ce7992306b9 100644
--- a/sys/compat/linuxkpi/common/include/linux/tracepoint.h
+++ b/sys/compat/linuxkpi/common/include/linux/tracepoint.h
@@ -23,8 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_TRACEPOINT_H
@@ -37,7 +35,13 @@
#define TP_printk(...)
#define TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \
-static void trace_ ## _name(_proto) \
+static inline void trace_ ## _name(_proto) \
+{ \
+}
+
+#define DECLARE_EVENT_CLASS(...)
+#define DEFINE_EVENT(_x, _name, _proto, _args) \
+static inline void trace_ ## _name(_proto) \
{ \
}
diff --git a/sys/compat/linuxkpi/common/include/linux/types.h b/sys/compat/linuxkpi/common/include/linux/types.h
index dab5e6ddce42..fcc455e5f731 100644
--- a/sys/compat/linuxkpi/common/include/linux/types.h
+++ b/sys/compat/linuxkpi/common/include/linux/types.h
@@ -25,13 +25,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_TYPES_H_
#define _LINUXKPI_LINUX_TYPES_H_
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -66,6 +63,7 @@ typedef unsigned gfp_t;
typedef off_t loff_t;
typedef vm_paddr_t resource_size_t;
typedef uint16_t __bitwise__ __sum16;
+typedef uint32_t __bitwise__ __wsum;
typedef unsigned long pgoff_t;
typedef unsigned __poll_t;
@@ -79,6 +77,14 @@ typedef unsigned long kernel_ulong_t;
typedef unsigned long irq_hw_number_t;
+#ifndef LIST_HEAD_DEF
+#define LIST_HEAD_DEF
+struct list_head {
+ struct list_head *next;
+ struct list_head *prev;
+};
+#endif
+
struct rcu_head {
void *raw[2];
} __aligned(sizeof(void *));
diff --git a/sys/compat/linuxkpi/common/include/linux/uaccess.h b/sys/compat/linuxkpi/common/include/linux/uaccess.h
index c62a94e8e044..660e84e6af3b 100644
--- a/sys/compat/linuxkpi/common/include/linux/uaccess.h
+++ b/sys/compat/linuxkpi/common/include/linux/uaccess.h
@@ -26,8 +26,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_UACCESS_H_
@@ -89,4 +87,29 @@ pagefault_disabled(void)
return ((curthread->td_pflags & TDP_NOFAULTING) != 0);
}
+static inline int
+__copy_to_user_inatomic(void __user *to, const void *from, unsigned n)
+{
+
+ return (copyout_nofault(from, to, n) != 0 ? n : 0);
+}
+#define __copy_to_user_inatomic_nocache(to, from, n) \
+ __copy_to_user_inatomic((to), (from), (n))
+
+static inline unsigned long
+__copy_from_user_inatomic(void *to, const void __user *from,
+ unsigned long n)
+{
+ /*
+ * XXXKIB. Equivalent Linux function is implemented using
+ * MOVNTI for aligned moves. For unaligned head and tail,
+ * normal move is performed. As such, it is not incorrect, if
+ * only somewhat slower, to use normal copyin. All uses
+ * except shmem_pwrite_fast() have the destination mapped WC.
+ */
+ return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0));
+}
+#define __copy_from_user_inatomic_nocache(to, from, n) \
+ __copy_from_user_inatomic((to), (from), (n))
+
#endif /* _LINUXKPI_LINUX_UACCESS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/udp.h b/sys/compat/linuxkpi/common/include/linux/udp.h
index 44c0763a1eeb..f3cd40cf8bb7 100644
--- a/sys/compat/linuxkpi/common/include/linux/udp.h
+++ b/sys/compat/linuxkpi/common/include/linux/udp.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_UDP_H
diff --git a/sys/compat/linuxkpi/common/include/linux/units.h b/sys/compat/linuxkpi/common/include/linux/units.h
new file mode 100644
index 000000000000..304b5c27d87f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/units.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * Copyright (c) 2025 Jean-Sébastien Pédron
+ *
+ * This software was developed by Jean-Sébastien Pédron under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_UNITS_H_
+#define _LINUXKPI_LINUX_UNITS_H_
+
+#define NANOHZ_PER_HZ 1000000000UL
+#define MICROHZ_PER_HZ 1000000UL
+#define MILLIHZ_PER_HZ 1000UL
+#define HZ_PER_KHZ 1000UL
+#define KHZ_PER_MHZ 1000UL
+#define HZ_PER_MHZ 1000000UL
+
+#endif /* _LINUXKPI_LINUX_UNITS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/usb.h b/sys/compat/linuxkpi/common/include/linux/usb.h
index 3b7c8a2cde78..d9649dcb5471 100644
--- a/sys/compat/linuxkpi/common/include/linux/usb.h
+++ b/sys/compat/linuxkpi/common/include/linux/usb.h
@@ -1,4 +1,3 @@
-/* $FreeBSD$ */
/*-
* Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved.
* Copyright (c) 2007 Hans Petter Selasky. All rights reserved.
diff --git a/sys/compat/linuxkpi/common/include/linux/utsname.h b/sys/compat/linuxkpi/common/include/linux/utsname.h
new file mode 100644
index 000000000000..3239801ca17b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/utsname.h
@@ -0,0 +1,51 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_LINUX_UTSNAME_H
+#define _LINUXKPI_LINUX_UTSNAME_H
+
+#include <sys/types.h>
+#include <sys/jail.h>
+
+struct _utsname {
+ char release[OSRELEASELEN];
+};
+
+struct uts_namespace {
+ struct _utsname name;
+};
+
+extern struct uts_namespace init_uts_ns;
+
+static inline struct _utsname *
+init_utsname(void)
+{
+
+ return &init_uts_ns.name;
+}
+
+#endif /* _LINUXKPI_LINUX_UTSNAME_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/uuid.h b/sys/compat/linuxkpi/common/include/linux/uuid.h
index 31a018497f78..4f6f4a8b34f0 100644
--- a/sys/compat/linuxkpi/common/include/linux/uuid.h
+++ b/sys/compat/linuxkpi/common/include/linux/uuid.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 The FreeBSD Foundation
+ * Copyright (c) 2021,2023 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -26,13 +26,13 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_UUID_H
#define _LINUXKPI_LINUX_UUID_H
+#include <linux/random.h>
+
#define UUID_STRING_LEN 36
#define GUID_INIT(x0_3, x4_5, x6_7, x8, x9, x10, x11, x12, x13, x14, x15) \
@@ -59,4 +59,19 @@ typedef struct {
char x[16];
} guid_t;
+static inline void
+guid_gen(guid_t *g)
+{
+
+ get_random_bytes(g, 16);
+ g->x[7] = (g->x[7] & 0x0f) | 0x40;
+ g->x[8] = (g->x[8] & 0x3f) | 0x80;
+}
+
+static inline void
+guid_copy(guid_t *dst, const guid_t *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+
#endif /* _LINUXKPI_LINUX_UUID_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/vgaarb.h b/sys/compat/linuxkpi/common/include/linux/vgaarb.h
new file mode 100644
index 000000000000..d43a88136864
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/vgaarb.h
@@ -0,0 +1,281 @@
+/*
+ * The VGA aribiter manages VGA space routing and VGA resource decode to
+ * allow multiple VGA devices to be used in a system in a safe way.
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _LINUXKPI_LINUX_VGA_H_
+#define _LINUXKPI_LINUX_VGA_H_
+
+#include <video/vga.h>
+
+/* Legacy VGA regions */
+#define VGA_RSRC_NONE 0x00
+#define VGA_RSRC_LEGACY_IO 0x01
+#define VGA_RSRC_LEGACY_MEM 0x02
+#define VGA_RSRC_LEGACY_MASK (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)
+/* Non-legacy access */
+#define VGA_RSRC_NORMAL_IO 0x04
+#define VGA_RSRC_NORMAL_MEM 0x08
+
+/* Passing that instead of a pci_dev to use the system "default"
+ * device, that is the one used by vgacon. Archs will probably
+ * have to provide their own vga_default_device();
+ */
+#define VGA_DEFAULT_DEVICE (NULL)
+
+struct pci_dev;
+
+/* For use by clients */
+
+/**
+ * vga_set_legacy_decoding
+ *
+ * @pdev: pci device of the VGA card
+ * @decodes: bit mask of what legacy regions the card decodes
+ *
+ * Indicates to the arbiter if the card decodes legacy VGA IOs,
+ * legacy VGA Memory, both, or none. All cards default to both,
+ * the card driver (fbdev for example) should tell the arbiter
+ * if it has disabled legacy decoding, so the card can be left
+ * out of the arbitration process (and can be safe to take
+ * interrupts at any time.
+ */
+#if defined(CONFIG_VGA_ARB)
+extern void vga_set_legacy_decoding(struct pci_dev *pdev,
+ unsigned int decodes);
+#else
+static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
+ unsigned int decodes) { };
+#endif
+
+/**
+ * vga_get - acquire & locks VGA resources
+ *
+ * @pdev: pci device of the VGA card or NULL for the system default
+ * @rsrc: bit mask of resources to acquire and lock
+ * @interruptible: blocking should be interruptible by signals ?
+ *
+ * This function acquires VGA resources for the given
+ * card and mark those resources locked. If the resource requested
+ * are "normal" (and not legacy) resources, the arbiter will first check
+ * whether the card is doing legacy decoding for that type of resource. If
+ * yes, the lock is "converted" into a legacy resource lock.
+ * The arbiter will first look for all VGA cards that might conflict
+ * and disable their IOs and/or Memory access, including VGA forwarding
+ * on P2P bridges if necessary, so that the requested resources can
+ * be used. Then, the card is marked as locking these resources and
+ * the IO and/or Memory accesse are enabled on the card (including
+ * VGA forwarding on parent P2P bridges if any).
+ * This function will block if some conflicting card is already locking
+ * one of the required resources (or any resource on a different bus
+ * segment, since P2P bridges don't differenciate VGA memory and IO
+ * afaik). You can indicate whether this blocking should be interruptible
+ * by a signal (for userland interface) or not.
+ * Must not be called at interrupt time or in atomic context.
+ * If the card already owns the resources, the function succeeds.
+ * Nested calls are supported (a per-resource counter is maintained)
+ */
+
+#if defined(CONFIG_VGA_ARB)
+extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible);
+#else
+static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) { return 0; }
+#endif
+
+/**
+ * vga_get_interruptible
+ *
+ * Shortcut to vga_get
+ */
+
+static inline int vga_get_interruptible(struct pci_dev *pdev,
+ unsigned int rsrc)
+{
+ return vga_get(pdev, rsrc, 1);
+}
+
+/**
+ * vga_get_uninterruptible
+ *
+ * Shortcut to vga_get
+ */
+
+static inline int vga_get_uninterruptible(struct pci_dev *pdev,
+ unsigned int rsrc)
+{
+ return vga_get(pdev, rsrc, 0);
+}
+
+/**
+ * vga_tryget - try to acquire & lock legacy VGA resources
+ *
+ * @pdev: pci devivce of VGA card or NULL for system default
+ * @rsrc: bit mask of resources to acquire and lock
+ *
+ * This function performs the same operation as vga_get(), but
+ * will return an error (-EBUSY) instead of blocking if the resources
+ * are already locked by another card. It can be called in any context
+ */
+
+#if defined(CONFIG_VGA_ARB)
+extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc);
+#else
+static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; }
+#endif
+
+/**
+ * vga_put - release lock on legacy VGA resources
+ *
+ * @pdev: pci device of VGA card or NULL for system default
+ * @rsrc: but mask of resource to release
+ *
+ * This function releases resources previously locked by vga_get()
+ * or vga_tryget(). The resources aren't disabled right away, so
+ * that a subsequence vga_get() on the same card will succeed
+ * immediately. Resources have a counter, so locks are only
+ * released if the counter reaches 0.
+ */
+
+#if defined(CONFIG_VGA_ARB)
+extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
+#else
+#define vga_put(pdev, rsrc)
+#endif
+
+
+/**
+ * vga_default_device
+ *
+ * This can be defined by the platform. The default implementation
+ * is rather dumb and will probably only work properly on single
+ * vga card setups and/or x86 platforms.
+ *
+ * If your VGA default device is not PCI, you'll have to return
+ * NULL here. In this case, I assume it will not conflict with
+ * any PCI card. If this is not true, I'll have to define two archs
+ * hooks for enabling/disabling the VGA default device if that is
+ * possible. This may be a problem with real _ISA_ VGA cards, in
+ * addition to a PCI one. I don't know at this point how to deal
+ * with that card. Can theirs IOs be disabled at all ? If not, then
+ * I suppose it's a matter of having the proper arch hook telling
+ * us about it, so we basically never allow anybody to succeed a
+ * vga_get()...
+ */
+
+#ifdef CONFIG_VGA_ARB
+extern struct pci_dev *vga_default_device(void);
+extern void vga_set_default_device(struct pci_dev *pdev);
+#else
+static inline struct pci_dev *vga_default_device(void) { return NULL; };
+static inline void vga_set_default_device(struct pci_dev *pdev) { };
+#endif
+
+/**
+ * vga_conflicts
+ *
+ * Architectures should define this if they have several
+ * independent PCI domains that can afford concurrent VGA
+ * decoding
+ */
+
+#ifndef __ARCH_HAS_VGA_CONFLICT
+static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2)
+{
+ return 1;
+}
+#endif
+
+/**
+ * vga_client_register
+ *
+ * @pdev: pci device of the VGA client
+ * @cookie: client cookie to be used in callbacks
+ * @irq_set_state: irq state change callback
+ * @set_vga_decode: vga decode change callback
+ *
+ * return value: 0 on success, -1 on failure
+ * Register a client with the VGA arbitration logic
+ *
+ * Clients have two callback mechanisms they can use.
+ * irq enable/disable callback -
+ * If a client can't disable its GPUs VGA resources, then we
+ * need to be able to ask it to turn off its irqs when we
+ * turn off its mem and io decoding.
+ * set_vga_decode
+ * If a client can disable its GPU VGA resource, it will
+ * get a callback from this to set the encode/decode state
+ *
+ * Rationale: we cannot disable VGA decode resources unconditionally
+ * some single GPU laptops seem to require ACPI or BIOS access to the
+ * VGA registers to control things like backlights etc.
+ * Hopefully newer multi-GPU laptops do something saner, and desktops
+ * won't have any special ACPI for this.
+ * They driver will get a callback when VGA arbitration is first used
+ * by userspace since we some older X servers have issues.
+ */
+#if defined(CONFIG_VGA_ARB)
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501
+int vga_client_register(struct pci_dev *pdev,
+ unsigned int (*set_vga_decode)(struct pci_dev *pdev, bool state));
+#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+ unsigned int (*set_vga_decode)(void *cookie, bool state));
+#else
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+ void (*irq_set_state)(void *cookie, bool state),
+ unsigned int (*set_vga_decode)(void *cookie, bool state));
+#endif
+#else
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501
+static inline int vga_client_register(struct pci_dev *pdev,
+ unsigned int (*set_vga_decode)(struct pci_dev *pdev, bool state))
+#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500
+static inline int vga_client_register(struct pci_dev *pdev, void *cookie,
+ unsigned int (*set_vga_decode)(void *cookie, bool state))
+#else
+static inline int vga_client_register(struct pci_dev *pdev, void *cookie,
+ void (*irq_set_state)(void *cookie, bool state),
+ unsigned int (*set_vga_decode)(void *cookie, bool state))
+#endif
+{
+ return 0;
+}
+
+static inline int vga_client_unregister(struct pci_dev *pdev)
+{
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51501
+ return (vga_client_register(NULL, NULL));
+#elif defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51500
+ return (vga_client_register(NULL, NULL, NULL));
+#else
+ return (vga_client_register(NULL, NULL, NULL, NULL));
+#endif
+}
+#endif
+
+#endif /* _LINUXKPI_LINUX_VGA_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/vmalloc.h b/sys/compat/linuxkpi/common/include/linux/vmalloc.h
index 450db0f761f2..00650a2df9b6 100644
--- a/sys/compat/linuxkpi/common/include/linux/vmalloc.h
+++ b/sys/compat/linuxkpi/common/include/linux/vmalloc.h
@@ -25,12 +25,11 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_VMALLOC_H_
#define _LINUXKPI_LINUX_VMALLOC_H_
+#include <linux/overflow.h>
#include <linux/page.h>
#define VM_MAP 0x0000
diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h
index 09cb5918b84b..03ddce2c06f5 100644
--- a/sys/compat/linuxkpi/common/include/linux/wait.h
+++ b/sys/compat/linuxkpi/common/include/linux/wait.h
@@ -26,8 +26,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_WAIT_H_
@@ -63,12 +61,14 @@ typedef struct wait_queue_head wait_queue_head_t;
typedef int wait_queue_func_t(wait_queue_t *, unsigned int, int, void *);
+#define WQ_FLAG_WOKEN 0x02
+
/*
* Many API consumers directly reference these fields and those of
* wait_queue_head.
*/
struct wait_queue {
- unsigned int flags; /* always 0 */
+ unsigned int flags;
void *private;
wait_queue_func_t *func;
union {
@@ -89,8 +89,14 @@ struct wait_queue_head {
* This function is referenced by at least one DRM driver, so it may not be
* renamed and furthermore must be the default wait queue callback.
*/
-extern wait_queue_func_t autoremove_wake_function;
-extern wait_queue_func_t default_wake_function;
+wait_queue_func_t autoremove_wake_function;
+wait_queue_func_t default_wake_function;
+wait_queue_func_t woken_wake_function;
+
+long linux_wait_woken(wait_queue_t *wq, unsigned state, long timeout);
+
+#define wait_woken(wq, state, timeout) \
+ linux_wait_woken((wq), (state), (timeout))
#define DEFINE_WAIT_FUNC(name, function) \
wait_queue_t name = { \
@@ -112,10 +118,10 @@ extern wait_queue_func_t default_wake_function;
wait_queue_head_t name = { \
.task_list = LINUX_LIST_HEAD_INIT(name.task_list), \
}; \
- MTX_SYSINIT(name, &(name).lock.m, spin_lock_name("wqhead"), MTX_DEF)
+ MTX_SYSINIT(name, &(name).lock, spin_lock_name("wqhead"), MTX_DEF)
#define init_waitqueue_head(wqh) do { \
- mtx_init(&(wqh)->lock.m, spin_lock_name("wqhead"), \
+ mtx_init(&(wqh)->lock, spin_lock_name("wqhead"), \
NULL, MTX_DEF | MTX_NEW | MTX_NOWITNESS); \
INIT_LIST_HEAD(&(wqh)->task_list); \
} while (0)
@@ -140,7 +146,7 @@ void linux_wake_up(wait_queue_head_t *, unsigned int, int, bool);
#define wake_up_interruptible_all(wqh) \
linux_wake_up(wqh, TASK_INTERRUPTIBLE, 0, false)
-int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
+int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, long,
unsigned int, spinlock_t *);
/*
@@ -150,9 +156,9 @@ int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
*/
#define __wait_event_common(wqh, cond, timeout, state, lock) ({ \
DEFINE_WAIT(__wq); \
- const int __timeout = ((int)(timeout)) < 1 ? 1 : (timeout); \
- int __start = ticks; \
- int __ret = 0; \
+ const long __timeout = ((long)(timeout)) < 1 ? 1 : (timeout); \
+ long __start = jiffies; \
+ long __ret = 0; \
\
for (;;) { \
linux_prepare_to_wait(&(wqh), &__wq, state); \
@@ -168,7 +174,7 @@ int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
if (__ret == -EWOULDBLOCK) \
__ret = !!(cond); \
else if (__ret != -ERESTARTSYS) { \
- __ret = __timeout + __start - ticks; \
+ __ret = __timeout + __start - jiffies; \
/* range check return value */ \
if (__ret < 1) \
__ret = 1; \
@@ -286,7 +292,7 @@ void linux_finish_wait(wait_queue_head_t *, wait_queue_t *);
#define finish_wait(wqh, wq) linux_finish_wait(wqh, wq)
void linux_wake_up_bit(void *, int);
-int linux_wait_on_bit_timeout(unsigned long *, int, unsigned int, int);
+int linux_wait_on_bit_timeout(unsigned long *, int, unsigned int, long);
void linux_wake_up_atomic_t(atomic_t *);
int linux_wait_on_atomic_t(atomic_t *, unsigned int);
diff --git a/sys/compat/linuxkpi/common/include/linux/wait_bit.h b/sys/compat/linuxkpi/common/include/linux/wait_bit.h
index 66c1149da432..573798590b73 100644
--- a/sys/compat/linuxkpi/common/include/linux/wait_bit.h
+++ b/sys/compat/linuxkpi/common/include/linux/wait_bit.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef __LINUXKPI_LINUX_WAITBIT_H__
diff --git a/sys/compat/linuxkpi/common/include/linux/workqueue.h b/sys/compat/linuxkpi/common/include/linux/workqueue.h
index 7ced4270e1db..66d3981d4229 100644
--- a/sys/compat/linuxkpi/common/include/linux/workqueue.h
+++ b/sys/compat/linuxkpi/common/include/linux/workqueue.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_WORKQUEUE_H_
#define _LINUXKPI_LINUX_WORKQUEUE_H_
@@ -92,7 +90,7 @@ struct delayed_work {
struct {
struct callout callout;
struct mtx mtx;
- int expires;
+ unsigned long expires;
} timer;
};
@@ -190,6 +188,9 @@ do { \
#define delayed_work_pending(dwork) \
linux_work_pending(&(dwork)->work)
+#define cancel_work(work) \
+ linux_cancel_work(work)
+
#define cancel_delayed_work(dwork) \
linux_cancel_delayed_work(dwork)
@@ -244,7 +245,8 @@ extern struct workqueue_struct *linux_create_workqueue_common(const char *, int)
extern void linux_destroy_workqueue(struct workqueue_struct *);
extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *);
extern bool linux_queue_delayed_work_on(int cpu, struct workqueue_struct *,
- struct delayed_work *, unsigned delay);
+ struct delayed_work *, unsigned long delay);
+extern bool linux_cancel_work(struct work_struct *);
extern bool linux_cancel_delayed_work(struct delayed_work *);
extern bool linux_cancel_work_sync(struct work_struct *);
extern bool linux_cancel_delayed_work_sync(struct delayed_work *);
@@ -256,4 +258,10 @@ extern struct work_struct *linux_current_work(void);
extern bool linux_queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork);
extern bool linux_flush_rcu_work(struct rcu_work *rwork);
+static inline bool
+queue_work_node(int node __unused, struct workqueue_struct *wq, struct work_struct *work)
+{
+ return (queue_work(wq, work));
+}
+
#endif /* _LINUXKPI_LINUX_WORKQUEUE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ww_mutex.h b/sys/compat/linuxkpi/common/include/linux/ww_mutex.h
index 82ba7a55a7e8..9219755bb78e 100644
--- a/sys/compat/linuxkpi/common/include/linux/ww_mutex.h
+++ b/sys/compat/linuxkpi/common/include/linux/ww_mutex.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_WW_MUTEX_H_
#define _LINUXKPI_LINUX_WW_MUTEX_H_
@@ -61,6 +59,8 @@ struct ww_mutex {
} \
SYSINIT(name, SI_SUB_LOCK, SI_ORDER_SECOND, name##_init, NULL)
+#define DEFINE_WD_CLASS(name) DEFINE_WW_CLASS(name)
+
#define ww_mutex_is_locked(_m) \
sx_xlocked(&(_m)->base.sx)
@@ -70,8 +70,13 @@ struct ww_mutex {
#define ww_mutex_lock_slow_interruptible(_m, _x) \
ww_mutex_lock_interruptible(_m, _x)
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51600
+static inline int __must_check
+ww_mutex_trylock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx __unused)
+#else
static inline int __must_check
ww_mutex_trylock(struct ww_mutex *lock)
+#endif
{
return (mutex_trylock(&lock->base));
}
diff --git a/sys/compat/linuxkpi/common/include/linux/xarray.h b/sys/compat/linuxkpi/common/include/linux/xarray.h
index 408906867479..fba36eea0ab5 100644
--- a/sys/compat/linuxkpi/common/include/linux/xarray.h
+++ b/sys/compat/linuxkpi/common/include/linux/xarray.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_XARRAY_H_
#define _LINUXKPI_LINUX_XARRAY_H_
@@ -31,6 +29,7 @@
#include <linux/gfp.h>
#include <linux/radix-tree.h>
#include <linux/err.h>
+#include <linux/kconfig.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -45,16 +44,19 @@
#define XA_ERROR(x) \
ERR_PTR(x)
+#define xa_is_err(x) \
+ IS_ERR(x)
+
#define xa_limit_32b XA_LIMIT(0, 0xFFFFFFFF)
-#define XA_ASSERT_LOCKED(xa) mtx_assert(&(xa)->mtx, MA_OWNED)
-#define xa_lock(xa) mtx_lock(&(xa)->mtx)
-#define xa_unlock(xa) mtx_unlock(&(xa)->mtx)
+#define XA_ASSERT_LOCKED(xa) mtx_assert(&(xa)->xa_lock, MA_OWNED)
+#define xa_lock(xa) mtx_lock(&(xa)->xa_lock)
+#define xa_unlock(xa) mtx_unlock(&(xa)->xa_lock)
struct xarray {
- struct radix_tree_root root;
- struct mtx mtx; /* internal mutex */
- uint32_t flags; /* see XA_FLAGS_XXX */
+ struct radix_tree_root xa_head;
+ struct mtx xa_lock; /* internal mutex */
+ uint32_t xa_flags; /* see XA_FLAGS_XXX */
};
/*
@@ -65,6 +67,7 @@ void *xa_erase(struct xarray *, uint32_t);
void *xa_load(struct xarray *, uint32_t);
int xa_alloc(struct xarray *, uint32_t *, void *, uint32_t, gfp_t);
int xa_alloc_cyclic(struct xarray *, uint32_t *, void *, uint32_t, uint32_t *, gfp_t);
+int xa_alloc_cyclic_irq(struct xarray *, uint32_t *, void *, uint32_t, uint32_t *, gfp_t);
int xa_insert(struct xarray *, uint32_t, void *, gfp_t);
void *xa_store(struct xarray *, uint32_t, void *, gfp_t);
void xa_init_flags(struct xarray *, uint32_t);
@@ -87,6 +90,27 @@ void *__xa_store(struct xarray *, uint32_t, void *, gfp_t);
bool __xa_empty(struct xarray *);
void *__xa_next(struct xarray *, unsigned long *, bool);
+#define xa_store_irq(xa, index, ptr, gfp) \
+ xa_store((xa), (index), (ptr), (gfp))
+
+#define xa_erase_irq(xa, index) \
+ xa_erase((xa), (index))
+
+#define xa_lock_irq(xa) xa_lock(xa)
+#define xa_unlock_irq(xa) xa_unlock(xa)
+
+#define xa_lock_irqsave(xa, flags) \
+ do { \
+ xa_lock((xa)); \
+ flags = 0; \
+ } while (0)
+
+#define xa_unlock_irqrestore(xa, flags) \
+ do { \
+ xa_unlock((xa)); \
+ flags == 0; \
+ } while (0)
+
static inline int
xa_err(void *ptr)
{
diff --git a/sys/compat/linuxkpi/common/include/net/addrconf.h b/sys/compat/linuxkpi/common/include/net/addrconf.h
index 41cfd21db5be..33c07792d807 100644
--- a/sys/compat/linuxkpi/common/include/net/addrconf.h
+++ b/sys/compat/linuxkpi/common/include/net/addrconf.h
@@ -26,8 +26,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_ADDRCONF_H
diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index 06a3ee626f08..239b4a5ae7b8 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
* Copyright (c) 2021-2022 Bjoern A. Zeeb
*
* This software was developed by Björn Zeeb under sponsorship from
@@ -25,8 +25,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_CFG80211_H
@@ -35,14 +33,20 @@
#include <linux/types.h>
#include <linux/nl80211.h>
#include <linux/ieee80211.h>
+#include <linux/mutex.h>
#include <linux/if_ether.h>
#include <linux/ethtool.h>
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/random.h>
#include <linux/skbuff.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
#include <net/regulatory.h>
+#include <net80211/ieee80211.h>
+
/* linux_80211.c */
extern int linuxkpi_debug_80211;
#ifndef D80211_TODO
@@ -51,10 +55,10 @@ extern int linuxkpi_debug_80211;
#ifndef D80211_IMPROVE
#define D80211_IMPROVE 0x2
#endif
-#define TODO() if (linuxkpi_debug_80211 & D80211_TODO) \
- printf("%s:%d: XXX LKPI80211 TODO\n", __func__, __LINE__)
-#define IMPROVE(...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \
- printf("%s:%d: XXX LKPI80211 IMPROVE\n", __func__, __LINE__)
+#define TODO(fmt, ...) if (linuxkpi_debug_80211 & D80211_TODO) \
+ printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
+#define IMPROVE(fmt, ...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \
+ printf("%s:%d: XXX LKPI80211 IMPROVE " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
enum rfkill_hard_block_reasons {
RFKILL_HARD_BLOCK_NOT_OWNER = BIT(0),
@@ -72,13 +76,19 @@ enum rfkill_hard_block_reasons {
#define IEEE80211_MAX_CHAINS 4 /* net80211: IEEE80211_MAX_CHAINS copied */
enum cfg80211_rate_info_flags {
- RATE_INFO_FLAGS_SHORT_GI = BIT(0),
- RATE_INFO_FLAGS_MCS = BIT(1),
- RATE_INFO_FLAGS_VHT_MCS = BIT(2),
- RATE_INFO_FLAGS_HE_MCS = BIT(3),
+ RATE_INFO_FLAGS_MCS = BIT(0),
+ RATE_INFO_FLAGS_VHT_MCS = BIT(1),
+ RATE_INFO_FLAGS_SHORT_GI = BIT(2),
+ RATE_INFO_FLAGS_HE_MCS = BIT(4),
+ RATE_INFO_FLAGS_EHT_MCS = BIT(7),
+ /* Max 8 bits as used in struct rate_info. */
};
+#define CFG80211_RATE_INFO_FLAGS_BITS \
+ "\20\1MCS\2VHT_MCS\3SGI\5HE_MCS\10EHT_MCS"
+
extern const uint8_t rfc1042_header[6];
+extern const uint8_t bridge_tunnel_header[6];
enum ieee80211_privacy {
IEEE80211_PRIVACY_ANY,
@@ -105,6 +115,11 @@ enum ieee80211_channel_flags {
IEEE80211_CHAN_NO_80MHZ = BIT(7),
IEEE80211_CHAN_NO_160MHZ = BIT(8),
IEEE80211_CHAN_NO_OFDM = BIT(9),
+ IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT = BIT(10),
+ IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT = BIT(11),
+ IEEE80211_CHAN_PSD = BIT(12),
+ IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP = BIT(13),
+ IEEE80211_CHAN_CAN_MONITOR = BIT(14),
};
#define IEEE80211_CHAN_NO_HT40 (IEEE80211_CHAN_NO_HT40MINUS|IEEE80211_CHAN_NO_HT40PLUS)
@@ -113,82 +128,76 @@ struct ieee80211_txrx_stypes {
uint16_t rx;
};
-/* XXX net80211 has an ieee80211_channel as well. */
+/*
+ * net80211 has an ieee80211_channel as well; we use the linuxkpi_ version
+ * interally in LinuxKPI and re-define ieee80211_channel for the drivers
+ * at the end of the file.
+ */
struct linuxkpi_ieee80211_channel {
- /* TODO FIXME */
- uint32_t hw_value; /* ic_ieee */
- uint32_t center_freq; /* ic_freq */
- enum ieee80211_channel_flags flags; /* ic_flags */
+ uint32_t center_freq;
+ uint16_t hw_value;
+ enum ieee80211_channel_flags flags;
enum nl80211_band band;
- int8_t max_power; /* ic_maxpower */
bool beacon_found;
- int max_antenna_gain, max_reg_power;
- int orig_flags;
- int dfs_cac_ms, dfs_state;
-};
-
-/* XXX net80211 calls these IEEE80211_HTCAP_* */
-#define IEEE80211_HT_CAP_LDPC_CODING 0x0001 /* IEEE80211_HTCAP_LDPC */
-#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 /* IEEE80211_HTCAP_CHWIDTH40 */
-#define IEEE80211_HT_CAP_GRN_FLD 0x0010 /* IEEE80211_HTCAP_GREENFIELD */
-#define IEEE80211_HT_CAP_SGI_20 0x0020 /* IEEE80211_HTCAP_SHORTGI20 */
-#define IEEE80211_HT_CAP_SGI_40 0x0040 /* IEEE80211_HTCAP_SHORTGI40 */
-#define IEEE80211_HT_CAP_TX_STBC 0x0080 /* IEEE80211_HTCAP_TXSTBC */
-#define IEEE80211_HT_CAP_RX_STBC 0x0100 /* IEEE80211_HTCAP_RXSTBC */
-#define IEEE80211_HT_CAP_RX_STBC_SHIFT 8 /* IEEE80211_HTCAP_RXSTBC_S */
-#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 /* IEEE80211_HTCAP_MAXAMSDU */
-#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 /* IEEE80211_HTCAP_DSSSCCK40 */
-#define IEEE80211_HT_CAP_SM_PS 0x000c /* IEEE80211_HTCAP_SMPS */
-#define IEEE80211_HT_CAP_SM_PS_SHIFT 2
-#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 /* IEEE80211_HTCAP_LSIGTXOPPROT */
-
-#define IEEE80211_HT_MCS_TX_DEFINED 0x0001
-#define IEEE80211_HT_MCS_TX_RX_DIFF 0x0002
-#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2
-#define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3FF
-#define IEEE80211_HT_MCS_MASK_LEN 10
-
-enum ieee80211_vht_mcs_support {
- LKPI_IEEE80211_VHT_MCS_SUPPORT_0_7,
- LKPI_IEEE80211_VHT_MCS_SUPPORT_0_8,
- LKPI_IEEE80211_VHT_MCS_SUPPORT_0_9,
+ enum nl80211_dfs_state dfs_state;
+ unsigned int dfs_cac_ms;
+ int max_antenna_gain;
+ int max_power;
+ int max_reg_power;
+ uint32_t orig_flags;
+ int orig_mpwr;
};
struct cfg80211_bitrate_mask {
/* TODO FIXME */
- /* This is so weird but nothing else works out...*/
struct {
- uint64_t legacy; /* XXX? */
+ uint32_t legacy;
uint8_t ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
- uint16_t vht_mcs[16]; /* XXX? */
- uint16_t he_mcs[16]; /* XXX? */
+ uint16_t vht_mcs[8];
+ uint16_t he_mcs[8];
enum nl80211_txrate_gi gi;
+ enum nl80211_he_gi he_gi;
+ uint8_t he_ltf; /* XXX enum? */
} control[NUM_NL80211_BANDS];
};
+enum rate_info_bw {
+ RATE_INFO_BW_20 = 0,
+ RATE_INFO_BW_5,
+ RATE_INFO_BW_10,
+ RATE_INFO_BW_40,
+ RATE_INFO_BW_80,
+ RATE_INFO_BW_160,
+ RATE_INFO_BW_HE_RU,
+ RATE_INFO_BW_320,
+ RATE_INFO_BW_EHT_RU,
+};
+
struct rate_info {
- /* TODO FIXME */
- int bw, flags, he_dcm, he_gi, he_ru_alloc, legacy, mcs, nss;
+ uint8_t flags; /* enum cfg80211_rate_info_flags */
+ uint8_t bw; /* enum rate_info_bw */
+ uint16_t legacy;
+ uint8_t mcs;
+ uint8_t nss;
+ uint8_t he_dcm;
+ uint8_t he_gi;
+ uint8_t he_ru_alloc;
+ uint8_t eht_gi;
};
struct ieee80211_rate {
- /* TODO FIXME */
- uint32_t bitrate;
- uint32_t hw_value;
- uint32_t hw_value_short;
- uint32_t flags;
+ uint32_t flags; /* enum ieee80211_rate_flags */
+ uint16_t bitrate;
+ uint16_t hw_value;
+ uint16_t hw_value_short;
};
struct ieee80211_sta_ht_cap {
- /* TODO FIXME */
- int ampdu_density, ampdu_factor;
- bool ht_supported;
- uint16_t cap;
- struct mcs {
- uint16_t rx_mask[IEEE80211_HT_MCS_MASK_LEN]; /* XXX ? > 4 (rtw88) */
- int rx_highest;
- uint32_t tx_params;
- } mcs;
+ bool ht_supported;
+ uint8_t ampdu_density;
+ uint8_t ampdu_factor;
+ uint16_t cap;
+ struct ieee80211_mcs_info mcs;
};
/* XXX net80211 calls these IEEE80211_VHTCAP_* */
@@ -199,7 +208,7 @@ struct ieee80211_sta_ht_cap {
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ << IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK_S)
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80P80MHZ << IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK_S)
-#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK 0x0000000c /* IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK */
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK
#define IEEE80211_VHT_CAP_RXLDPC 0x00000010 /* IEEE80211_VHTCAP_RXLDPC */
@@ -237,12 +246,18 @@ struct ieee80211_sta_ht_cap {
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT) /* IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK */
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_MASK IEEE80211_VHTCAP_EXT_NSS_BW
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT IEEE80211_VHTCAP_EXT_NSS_BW_S
struct ieee80211_sta_vht_cap {
/* TODO FIXME */
- bool vht_supported;
- uint32_t cap;
- struct vht_mcs vht_mcs;
+ bool vht_supported;
+ uint32_t cap;
+ struct ieee80211_vht_mcs_info vht_mcs;
+};
+
+enum ieee80211_vht_opmode {
+ IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT = 4,
};
struct cfg80211_connect_resp_params {
@@ -272,14 +287,16 @@ struct cfg80211_roam_info {
};
struct cfg80211_bss_ies {
- /* XXX TODO, type is best guess. Fix if more info. */
uint8_t *data;
- int len;
+ size_t len;
};
struct cfg80211_bss {
/* XXX TODO */
struct cfg80211_bss_ies *ies;
+ struct cfg80211_bss_ies *beacon_ies;
+
+ int32_t signal;
};
struct cfg80211_chan_def {
@@ -288,6 +305,7 @@ struct cfg80211_chan_def {
enum nl80211_chan_width width;
uint32_t center_freq1;
uint32_t center_freq2;
+ uint16_t punctured;
};
struct cfg80211_ftm_responder_stats {
@@ -372,7 +390,7 @@ struct cfg80211_ssid {
struct cfg80211_scan_6ghz_params {
/* XXX TODO */
uint8_t *bssid;
- int channel_idx, psc_no_listen, short_ssid, short_ssid_valid, unsolicited_probe;
+ int channel_idx, psc_no_listen, short_ssid, short_ssid_valid, unsolicited_probe, psd_20;
};
struct cfg80211_match_set {
@@ -383,14 +401,20 @@ struct cfg80211_match_set {
struct cfg80211_scan_request {
/* XXX TODO */
- int duration, duration_mandatory, flags;
bool no_cck;
bool scan_6ghz;
+ bool duration_mandatory;
+ int8_t tsf_report_link_id;
+ uint16_t duration;
+ uint32_t flags;
struct wireless_dev *wdev;
struct wiphy *wiphy;
+ uint64_t scan_start;
+ uint32_t rates[NUM_NL80211_BANDS];
int ie_len;
uint8_t *ie;
uint8_t mac_addr[ETH_ALEN], mac_addr_mask[ETH_ALEN];
+ uint8_t bssid[ETH_ALEN];
int n_ssids;
int n_6ghz_params;
int n_channels;
@@ -413,6 +437,8 @@ struct cfg80211_sched_scan_request {
int n_scan_plans;
int n_ssids;
int n_channels;
+ int ie_len;
+ uint8_t *ie;
struct cfg80211_match_set *match_sets;
struct cfg80211_sched_scan_plan *scan_plans;
struct cfg80211_ssid *ssids;
@@ -524,33 +550,6 @@ struct cfg80211_pmksa {
const uint8_t *pmkid;
};
-struct cfg80211_wowlan_nd_match {
- /* XXX TODO */
- struct cfg80211_ssid ssid;
- int n_channels;
- uint32_t channels[0]; /* freq! = ieee80211_channel_to_frequency() */
-};
-
-struct cfg80211_wowlan_nd_info {
- /* XXX TODO */
- int n_matches;
- struct cfg80211_wowlan_nd_match *matches[0];
-};
-
-enum wiphy_wowlan_support_flags {
- WIPHY_WOWLAN_DISCONNECT,
- WIPHY_WOWLAN_GTK_REKEY_FAILURE,
- WIPHY_WOWLAN_MAGIC_PKT,
- WIPHY_WOWLAN_SUPPORTS_GTK_REKEY,
- WIPHY_WOWLAN_NET_DETECT,
-};
-
-struct wiphy_wowlan_support {
- /* XXX TODO */
- enum wiphy_wowlan_support_flags flags;
- int max_nd_match_sets, max_pkt_offset, n_patterns, pattern_max_len, pattern_min_len;
-};
-
struct station_del_parameters {
/* XXX TODO */
const uint8_t *mac;
@@ -558,17 +557,39 @@ struct station_del_parameters {
};
struct station_info {
- /* TODO FIXME */
- int assoc_req_ies_len, connected_time;
- int generation, inactive_time, rx_bytes, rx_dropped_misc, rx_packets, signal, tx_bytes, tx_packets;
- int filled, rx_beacon, rx_beacon_signal_avg, signal_avg;
- int rx_duration, tx_failed, tx_retries;
+ uint64_t filled; /* enum nl80211_sta_info */
+ uint32_t connected_time;
+ uint32_t inactive_time;
+
+ uint64_t rx_bytes;
+ uint32_t rx_packets;
+ uint32_t rx_dropped_misc;
+
+ uint64_t rx_duration;
+ uint32_t rx_beacon;
+ uint8_t rx_beacon_signal_avg;
+
+ int8_t signal;
+ int8_t signal_avg;
+ int8_t ack_signal;
+ int8_t avg_ack_signal;
+
+ /* gap */
+ int generation;
+
+ uint64_t tx_bytes;
+ uint32_t tx_packets;
+ uint32_t tx_failed;
+ uint64_t tx_duration;
+ uint32_t tx_retries;
int chains;
uint8_t chain_signal[IEEE80211_MAX_CHAINS];
uint8_t chain_signal_avg[IEEE80211_MAX_CHAINS];
uint8_t *assoc_req_ies;
+ size_t assoc_req_ies_len;
+
struct rate_info rxrate;
struct rate_info txrate;
struct cfg80211_ibss_params bss_param;
@@ -607,6 +628,7 @@ struct mac_address {
struct ieee80211_reg_rule {
/* TODO FIXME */
uint32_t flags;
+ int dfs_cac_ms;
struct freq_range {
int start_freq_khz;
int end_freq_khz;
@@ -626,172 +648,170 @@ struct linuxkpi_ieee80211_regdomain {
struct ieee80211_reg_rule reg_rules[];
};
-/* XXX-BZ this are insensible values probably ... */
-#define IEEE80211_HE_MAC_CAP0_HTC_HE 0x1
-#define IEEE80211_HE_MAC_CAP0_TWT_REQ 0x2
-
-#define IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION 0x1
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8 0x2
-#define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US 0x4
-
-#define IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP 0x1
-#define IEEE80211_HE_MAC_CAP2_ACK_EN 0x2
-#define IEEE80211_HE_MAC_CAP2_BSR 0x4
-#define IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION 0x8
-#define IEEE80211_HE_MAC_CAP2_BCAST_TWT 0x10
-#define IEEE80211_HE_MAC_CAP2_ALL_ACK 0x20
-
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2 0x1
-#define IEEE80211_HE_MAC_CAP3_OMI_CONTROL 0x2
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x10
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x20
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x40
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x70
-#define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80
-
-#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x1
-#define IEEE80211_HE_MAC_CAP4_BQR 0x2
-#define IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39 0x4
-#define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU 0x8
-#define IEEE80211_HE_MAC_CAP4_OPS 0x10
-
-#define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x1
-#define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX 0x2
-#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x4
-#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x8
-#define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x10
-
-#define IEEE80211_HE_MCS_NOT_SUPPORTED 0x0
-#define IEEE80211_HE_MCS_SUPPORT_0_7 0x1
-#define IEEE80211_HE_MCS_SUPPORT_0_9 0x2
-#define IEEE80211_HE_MCS_SUPPORT_0_11 0x4
-
-#define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS 0x01
-#define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS 0x02
-#define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x04
-#define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x08
-#define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x10
-
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G 0x1
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x2
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x4
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G 0x8
-
-#define IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A 0x1
-#define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD 0x2
-#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS 0x4
-#define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK 0x8
-#define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US 0x10
-
-#define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x1
-#define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x2
-#define IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ 0x4
-#define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x8
-#define IEEE80211_HE_PHY_CAP2_DOPPLER_TX 0x10
-
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x1
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_NO_DCM 0x2
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM 0x4
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x8
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 0x10
-#define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x20
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x40
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM 0x80
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2 0x10
-#define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x20
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK 0x40
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK 0x80
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK 0x80
-
-#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8 0x1
-#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 0x2
-#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x4
-#define IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER 0x8
-#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 0x10
-
-#define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2 0x1
-#define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 0x2
-#define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK 0x4
-#define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK 0x8
-#define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK 0x10
-
-#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x1
-#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x2
-#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x4
-#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x8
-#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x20
-#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x40
-#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x80
-#define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x80
-
-#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x1
-#define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x2
-#define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x4
-#define IEEE80211_HE_PHY_CAP7_MAX_NC_MASK 0x6
-#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 0x8
-#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x10
-#define IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ 0x20
-
-#define IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU 0x1
-#define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G 0x2
-#define IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU 0x4
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996 0x8
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242 0x10
-#define IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI 0x20
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996 0x40
-#define IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI 0x80
-
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US 0x1
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US 0x2
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US 0x4
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK 0x8
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED 0x10
-#define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS 0x0
-#define IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK 0x20
-#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x4
-#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x8
-#define IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU 0x10
-#define IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU 0x20
-#define IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM 0x40
-
-#define IEEE80211_HE_PHY_CAP10_HE_MU_M1RU_MAX_LTF 0x1
+#define IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS 0x01
+#define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454 0x02
+#define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK 0x03
+#define IEEE80211_EHT_MAC_CAP0_OM_CONTROL 0x04
+#define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 0x05
+#define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 0x06
+#define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991 0x07
+#define IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC 0x08
+
+#define IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK 0x01
+
+#define IEEE80211_EHT_MCS_NSS_RX 0x01
+#define IEEE80211_EHT_MCS_NSS_TX 0x02
+
+#define IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ 0x01
+#define IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ 0x02
+#define IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK 0x03
+#define IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI 0x04
+#define IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO 0x05
+#define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE 0x06
+#define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER 0x07
+
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK 0x01
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK 0x02
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK 0x03
+
+#define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK 0x01
+#define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK 0x02
+#define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK 0x03
+
+#define IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK 0x01
+#define IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK 0x02
+#define IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK 0x03
+#define IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK 0x04
+#define IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK 0x05
+#define IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK 0x06
+#define IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK 0x07
+#define IEEE80211_EHT_PHY_CAP3_SOUNDING_DIM_320MHZ_MASK 0x08
+
+#define IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI 0x01
+#define IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO 0x02
+#define IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP 0x03
+#define IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK 0x04
+
+#define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_0US 0x01
+#define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US 0x02
+#define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US 0x03
+#define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US 0x04
+#define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK 0x05
+#define IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK 0x06
+#define IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT 0x07
+#define IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP 0x08
+#define IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP 0x09
+#define IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK 0x0a
+#define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF 0x0b
+
+#define IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP 0x01
+#define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK 0x02
+#define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK 0x03
+
+#define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ 0x01
+#define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ 0x02
+#define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ 0x03
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ 0x04
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ 0x05
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ 0x06
+
+#define IEEE80211_EHT_PHY_CAP8_RX_1024QAM_WIDER_BW_DL_OFDMA 0x01
+#define IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA 0x02
+
+#define IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE 0x01
+#define IEEE80211_EHT_PPE_THRES_NSS_MASK 0x02
+#define IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK 0x03
+#define IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE 0x04
+
+#define IEEE80211_EML_CAP_EMLSR_SUPP 0x01
+#define IEEE80211_EML_CAP_TRANSITION_TIMEOUT 0x02
+#define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU 0x04
+#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY 0x08
+#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US 0x10
+#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US 0x10
+#define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY 0x20
+#define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US 0x40
+#define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US 0x40
#define VENDOR_CMD_RAW_DATA (void *)(uintptr_t)(-ENOENT)
-struct ieee80211_he_cap_elem {
- u8 mac_cap_info[6];
- u8 phy_cap_info[11];
-} __packed;
-
-struct ieee80211_he_mcs_nss_supp {
- /* TODO FIXME */
- uint32_t rx_mcs_80;
- uint32_t tx_mcs_80;
- uint32_t rx_mcs_160;
- uint32_t tx_mcs_160;
- uint32_t rx_mcs_80p80;
- uint32_t tx_mcs_80p80;
-};
-
-#define IEEE80211_STA_HE_CAP_PPE_THRES_MAX 32
+/* net80211::net80211_he_cap */
struct ieee80211_sta_he_cap {
- /* TODO FIXME */
- int has_he;
+ bool has_he;
struct ieee80211_he_cap_elem he_cap_elem;
struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp;
- uint8_t ppe_thres[IEEE80211_STA_HE_CAP_PPE_THRES_MAX];
+ uint8_t ppe_thres[IEEE80211_HE_CAP_PPE_THRES_MAX];
+};
+
+struct cfg80211_he_bss_color {
+ int color, enabled;
+};
+
+struct ieee80211_he_obss_pd {
+ bool enable;
+ uint8_t min_offset;
+ uint8_t max_offset;
+ uint8_t non_srg_max_offset;
+ uint8_t sr_ctrl;
+ uint8_t bss_color_bitmap[8];
+ uint8_t partial_bssid_bitmap[8];
+};
+
+struct ieee80211_eht_mcs_nss_supp_20mhz_only {
+ union {
+ struct {
+ uint8_t rx_tx_mcs7_max_nss;
+ uint8_t rx_tx_mcs9_max_nss;
+ uint8_t rx_tx_mcs11_max_nss;
+ uint8_t rx_tx_mcs13_max_nss;
+ };
+ uint8_t rx_tx_max_nss[4];
+ };
+};
+
+struct ieee80211_eht_mcs_nss_supp_bw {
+ union {
+ struct {
+ uint8_t rx_tx_mcs9_max_nss;
+ uint8_t rx_tx_mcs11_max_nss;
+ uint8_t rx_tx_mcs13_max_nss;
+ };
+ uint8_t rx_tx_max_nss[3];
+ };
+};
+
+struct ieee80211_eht_cap_elem_fixed {
+ uint8_t mac_cap_info[2];
+ uint8_t phy_cap_info[9];
};
-struct ieee80211_sta_he_6ghz_capa {
+struct ieee80211_eht_mcs_nss_supp {
/* TODO FIXME */
- int capa;
+ /* Can only have either or... */
+ union {
+ struct ieee80211_eht_mcs_nss_supp_20mhz_only only_20mhz;
+ struct {
+ struct ieee80211_eht_mcs_nss_supp_bw _80;
+ struct ieee80211_eht_mcs_nss_supp_bw _160;
+ struct ieee80211_eht_mcs_nss_supp_bw _320;
+ } bw;
+ };
+};
+
+#define IEEE80211_STA_EHT_PPE_THRES_MAX 32
+struct ieee80211_sta_eht_cap {
+ bool has_eht;
+ struct ieee80211_eht_cap_elem_fixed eht_cap_elem;
+ struct ieee80211_eht_mcs_nss_supp eht_mcs_nss_supp;
+ uint8_t eht_ppe_thres[IEEE80211_STA_EHT_PPE_THRES_MAX];
};
struct ieee80211_sband_iftype_data {
/* TODO FIXME */
enum nl80211_iftype types_mask;
struct ieee80211_sta_he_cap he_cap;
- struct ieee80211_sta_he_6ghz_capa he_6ghz_capa;
+ struct ieee80211_he_6ghz_capa he_6ghz_capa;
+ struct ieee80211_sta_eht_cap eht_cap;
struct {
const uint8_t *data;
size_t len;
@@ -800,7 +820,7 @@ struct ieee80211_sband_iftype_data {
struct ieee80211_supported_band {
/* TODO FIXME */
- struct linuxkpi_ieee80211_channel *channels;
+ struct linuxkpi_ieee80211_channel *channels;
struct ieee80211_rate *bitrates;
struct ieee80211_sband_iftype_data *iftype_data;
int n_channels;
@@ -819,22 +839,86 @@ struct cfg80211_pkt_pattern {
int pkt_offset;
};
+struct cfg80211_wowlan_nd_match {
+ /* XXX TODO */
+ struct cfg80211_ssid ssid;
+ int n_channels;
+ uint32_t channels[0]; /* freq! = ieee80211_channel_to_frequency() */
+};
+
+struct cfg80211_wowlan_nd_info {
+ /* XXX TODO */
+ int n_matches;
+ struct cfg80211_wowlan_nd_match *matches[0];
+};
+
+enum wiphy_wowlan_support_flags {
+ WIPHY_WOWLAN_DISCONNECT,
+ WIPHY_WOWLAN_MAGIC_PKT,
+ WIPHY_WOWLAN_SUPPORTS_GTK_REKEY,
+ WIPHY_WOWLAN_GTK_REKEY_FAILURE,
+ WIPHY_WOWLAN_EAP_IDENTITY_REQ,
+ WIPHY_WOWLAN_4WAY_HANDSHAKE,
+ WIPHY_WOWLAN_RFKILL_RELEASE,
+ WIPHY_WOWLAN_NET_DETECT,
+};
+
+struct wiphy_wowlan_support {
+ /* XXX TODO */
+ enum wiphy_wowlan_support_flags flags;
+ int max_nd_match_sets, max_pkt_offset, n_patterns, pattern_max_len, pattern_min_len;
+};
+
+struct cfg80211_wowlan_wakeup {
+ /* XXX TODO */
+ uint16_t pattern_idx;
+ bool disconnect;
+ bool unprot_deauth_disassoc;
+ bool eap_identity_req;
+ bool four_way_handshake;
+ bool gtk_rekey_failure;
+ bool magic_pkt;
+ bool rfkill_release;
+ bool tcp_connlost;
+ bool tcp_nomoretokens;
+ bool tcp_match;
+ bool packet_80211;
+ struct cfg80211_wowlan_nd_info *net_detect;
+ uint8_t *packet;
+ uint16_t packet_len;
+ uint16_t packet_present_len;
+};
+
struct cfg80211_wowlan {
/* XXX TODO */
- int disconnect, gtk_rekey_failure, magic_pkt;
+ bool any;
+ bool disconnect;
+ bool magic_pkt;
+ bool gtk_rekey_failure;
+ bool eap_identity_req;
+ bool four_way_handshake;
+ bool rfkill_release;
+
+ /* Magic packet patterns. */
int n_patterns;
- struct cfg80211_sched_scan_request *nd_config;
struct cfg80211_pkt_pattern *patterns;
+
+ /* netdetect? if not assoc? */
+ struct cfg80211_sched_scan_request *nd_config;
+
+ void *tcp; /* XXX ? */
};
struct cfg80211_gtk_rekey_data {
/* XXX TODO */
- int kck, kek, replay_ctr;
+ const uint8_t *kck, *kek, *replay_ctr;
+ uint32_t akm;
+ uint8_t kck_len, kek_len;
};
struct cfg80211_tid_cfg {
/* XXX TODO */
- int mask, noack, retry_long, rtscts, tids;
+ int mask, noack, retry_long, rtscts, tids, amsdu, ampdu;
enum nl80211_tx_rate_setting txrate_type;
struct cfg80211_bitrate_mask txrate_mask;
};
@@ -856,6 +940,7 @@ struct ieee80211_iface_combination {
int n_limits;
int max_interfaces, num_different_channels;
int beacon_int_infra_match, beacon_int_min_gcd;
+ int radar_detect_widths;
};
struct iface_combination_params {
@@ -866,7 +951,14 @@ struct iface_combination_params {
struct regulatory_request {
/* XXX TODO */
uint8_t alpha2[2];
+ enum environment_cap country_ie_env;
int initiator, dfs_region;
+ int user_reg_hint_type;
+};
+
+struct cfg80211_set_hw_timestamp {
+ const uint8_t *macaddr;
+ bool enable;
};
enum wiphy_vendor_cmd_need_flags {
@@ -891,7 +983,8 @@ struct wiphy_iftype_ext_capab {
const uint8_t *extended_capabilities;
const uint8_t *extended_capabilities_mask;
uint8_t extended_capabilities_len;
-
+ uint16_t eml_capabilities;
+ uint16_t mld_capa_and_ops;
};
struct tid_config_support {
@@ -910,29 +1003,60 @@ enum cfg80211_regulatory {
REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(6),
};
-#define WIPHY_FLAG_AP_UAPSD 0x00000001
-#define WIPHY_FLAG_HAS_CHANNEL_SWITCH 0x00000002
-#define WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL 0x00000004
-#define WIPHY_FLAG_HAVE_AP_SME 0x00000008
-#define WIPHY_FLAG_IBSS_RSN 0x00000010
-#define WIPHY_FLAG_NETNS_OK 0x00000020
-#define WIPHY_FLAG_OFFCHAN_TX 0x00000040
-#define WIPHY_FLAG_PS_ON_BY_DEFAULT 0x00000080
-#define WIPHY_FLAG_SPLIT_SCAN_6GHZ 0x00000100
-#define WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK 0x00000200
-#define WIPHY_FLAG_SUPPORTS_FW_ROAM 0x00000400
-#define WIPHY_FLAG_SUPPORTS_TDLS 0x00000800
-#define WIPHY_FLAG_TDLS_EXTERNAL_SETUP 0x00001000
-#define WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD 0x00002000
+struct wiphy_radio_freq_range {
+ uint32_t start_freq;
+ uint32_t end_freq;
+};
-struct wiphy {
+struct wiphy_radio {
+ int n_freq_range;
+ int n_iface_combinations;
+ const struct wiphy_radio_freq_range *freq_range;
+ const struct ieee80211_iface_combination *iface_combinations;
+};
+enum wiphy_flags {
+ WIPHY_FLAG_AP_UAPSD = BIT(0),
+ WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(1),
+ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(2),
+ WIPHY_FLAG_HAVE_AP_SME = BIT(3),
+ WIPHY_FLAG_IBSS_RSN = BIT(4),
+ WIPHY_FLAG_NETNS_OK = BIT(5),
+ WIPHY_FLAG_OFFCHAN_TX = BIT(6),
+ WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(7),
+ WIPHY_FLAG_SPLIT_SCAN_6GHZ = BIT(8),
+ WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(9),
+ WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(10),
+ WIPHY_FLAG_SUPPORTS_TDLS = BIT(11),
+ WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(12),
+ WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(13),
+ WIPHY_FLAG_4ADDR_AP = BIT(14),
+ WIPHY_FLAG_4ADDR_STATION = BIT(15),
+ WIPHY_FLAG_SUPPORTS_MLO = BIT(16),
+ WIPHY_FLAG_DISABLE_WEXT = BIT(17),
+};
+
+struct wiphy_work;
+typedef void (*wiphy_work_fn)(struct wiphy *, struct wiphy_work *);
+struct wiphy_work {
+ struct list_head entry;
+ wiphy_work_fn fn;
+};
+struct wiphy_delayed_work {
+ struct wiphy_work work;
+ struct wiphy *wiphy;
+ struct timer_list timer;
+};
+
+struct wiphy {
+ struct mutex mtx;
struct device *dev;
struct mac_address *addresses;
int n_addresses;
uint32_t flags;
struct ieee80211_supported_band *bands[NUM_NL80211_BANDS];
uint8_t perm_addr[ETH_ALEN];
+ uint16_t max_scan_ie_len;
/* XXX TODO */
const struct cfg80211_pmsr_capabilities *pmsr_capa;
@@ -952,28 +1076,41 @@ struct wiphy {
uint32_t rts_threshold;
uint32_t frag_threshold;
struct tid_config_support tid_config_support;
+ uint8_t available_antennas_rx;
+ uint8_t available_antennas_tx;
+
+ int n_radio;
+ const struct wiphy_radio *radio;
- int available_antennas_rx, available_antennas_tx;
int features, hw_version;
- int interface_modes, max_match_sets, max_remain_on_channel_duration, max_scan_ie_len, max_scan_ssids, max_sched_scan_ie_len, max_sched_scan_plan_interval, max_sched_scan_plan_iterations, max_sched_scan_plans, max_sched_scan_reqs, max_sched_scan_ssids;
+ int interface_modes, max_match_sets, max_remain_on_channel_duration, max_scan_ssids, max_sched_scan_ie_len, max_sched_scan_plan_interval, max_sched_scan_plan_iterations, max_sched_scan_plans, max_sched_scan_reqs, max_sched_scan_ssids;
int num_iftype_ext_capab;
int max_ap_assoc_sta, probe_resp_offload, software_iftypes;
int bss_select_support, max_num_pmkids, retry_long, retry_short, signal_type;
int max_data_retry_count;
int tx_queue_len, rfkill;
+ int mbssid_max_interfaces;
+ int hw_timestamp_max_peers;
+ int ema_max_profile_periodicity;
unsigned long ext_features[BITS_TO_LONGS(NUM_NL80211_EXT_FEATURES)];
struct dentry *debugfsdir;
- struct cfg80211_wowlan_support *wowlan;
+
+ const struct wiphy_wowlan_support *wowlan;
+ struct cfg80211_wowlan *wowlan_config;
/* Lower layer (driver/mac80211) specific data. */
/* Must stay last. */
uint8_t priv[0] __aligned(CACHE_LINE_SIZE);
};
+#define lockdep_assert_wiphy(wiphy) \
+ lockdep_assert_held(&(wiphy)->mtx)
+
struct wireless_dev {
/* XXX TODO, like ic? */
- int iftype;
- int address;
+ enum nl80211_iftype iftype;
+ uint32_t radio_mask;
+ uint8_t address[ETH_ALEN];
struct net_device *netdev;
struct wiphy *wiphy;
};
@@ -1034,12 +1171,29 @@ struct cfg80211_ops {
struct wiphy *linuxkpi_wiphy_new(const struct cfg80211_ops *, size_t);
void linuxkpi_wiphy_free(struct wiphy *wiphy);
+void linuxkpi_wiphy_work_queue(struct wiphy *, struct wiphy_work *);
+void linuxkpi_wiphy_work_cancel(struct wiphy *, struct wiphy_work *);
+void linuxkpi_wiphy_work_flush(struct wiphy *, struct wiphy_work *);
+void lkpi_wiphy_delayed_work_timer(struct timer_list *);
+void linuxkpi_wiphy_delayed_work_queue(struct wiphy *,
+ struct wiphy_delayed_work *, unsigned long);
+void linuxkpi_wiphy_delayed_work_cancel(struct wiphy *,
+ struct wiphy_delayed_work *);
+
int linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
struct linuxkpi_ieee80211_regdomain *regd);
+uint32_t linuxkpi_cfg80211_calculate_bitrate(struct rate_info *);
uint32_t linuxkpi_ieee80211_channel_to_frequency(uint32_t, enum nl80211_band);
uint32_t linuxkpi_ieee80211_frequency_to_channel(uint32_t, uint32_t);
struct linuxkpi_ieee80211_channel *
linuxkpi_ieee80211_get_channel(struct wiphy *, uint32_t);
+struct cfg80211_bss *linuxkpi_cfg80211_get_bss(struct wiphy *,
+ struct linuxkpi_ieee80211_channel *, const uint8_t *,
+ const uint8_t *, size_t, enum ieee80211_bss_type, enum ieee80211_privacy);
+void linuxkpi_cfg80211_put_bss(struct wiphy *, struct cfg80211_bss *);
+void linuxkpi_cfg80211_bss_flush(struct wiphy *);
+struct linuxkpi_ieee80211_regdomain *
+ lkpi_get_linuxkpi_ieee80211_regdomain(size_t);
/* -------------------------------------------------------------------------- */
@@ -1078,34 +1232,43 @@ wiphy_dev(struct wiphy *wiphy)
return (wiphy->dev);
}
-#define wiphy_err(_wiphy, _fmt, ...) \
- dev_err((_wiphy)->dev, _fmt, __VA_ARGS__)
+#define wiphy_dereference(_w, p) \
+ rcu_dereference_check(p, lockdep_is_held(&(_w)->mtx))
-static __inline const struct linuxkpi_ieee80211_regdomain *
-wiphy_dereference(struct wiphy *wiphy,
- const struct linuxkpi_ieee80211_regdomain *regd)
+#define wiphy_lock(_w) mutex_lock(&(_w)->mtx)
+#define wiphy_unlock(_w) mutex_unlock(&(_w)->mtx)
+
+static __inline void
+wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked,
+ enum rfkill_hard_block_reasons reason)
{
TODO();
- return (NULL);
}
-static __inline void
-wiphy_lock(struct wiphy *wiphy)
+/* -------------------------------------------------------------------------- */
+
+static inline struct cfg80211_bss *
+cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
+ const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len,
+ enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy)
{
- TODO();
+
+ return (linuxkpi_cfg80211_get_bss(wiphy, chan, bssid, ssid, ssid_len,
+ bss_type, privacy));
}
-static __inline void
-wiphy_unlock(struct wiphy *wiphy)
+static inline void
+cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
{
- TODO();
+
+ linuxkpi_cfg80211_put_bss(wiphy, bss);
}
-static __inline void
-wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked,
- enum rfkill_hard_block_reasons reason)
+static inline void
+cfg80211_bss_flush(struct wiphy *wiphy)
{
- TODO();
+
+ linuxkpi_cfg80211_bss_flush(wiphy);
}
/* -------------------------------------------------------------------------- */
@@ -1124,15 +1287,26 @@ rfkill_soft_blocked(int rfkill)
return (false);
}
+static __inline void
+wiphy_rfkill_start_polling(struct wiphy *wiphy)
+{
+ TODO();
+}
+
+static __inline void
+wiphy_rfkill_stop_polling(struct wiphy *wiphy)
+{
+ TODO();
+}
+
static __inline int
reg_query_regdb_wmm(uint8_t *alpha2, uint32_t center_freq,
struct ieee80211_reg_rule *rule)
{
- /* ETSI has special rules. FreeBSD regdb needs to learn about them. */
- TODO();
+ IMPROVE("regdomain.xml needs to grow wmm information for at least ETSI");
- return (-ENXIO);
+ return (-ENODATA);
}
static __inline const u8 *
@@ -1144,7 +1318,7 @@ cfg80211_find_ie_match(uint32_t f, const u8 *ies, size_t ies_len,
}
static __inline const u8 *
-cfg80211_find_ie(uint8_t eid, uint8_t *variable, uint32_t frame_size)
+cfg80211_find_ie(uint8_t eid, const uint8_t *ie, uint32_t ielen)
{
TODO();
return (NULL);
@@ -1165,32 +1339,74 @@ cfg80211_pmsr_report(struct wireless_dev *wdev,
TODO();
}
-static __inline void
+static inline void
cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
- struct linuxkpi_ieee80211_channel *chan, enum nl80211_chan_flags chan_flag)
+ struct linuxkpi_ieee80211_channel *chan, enum nl80211_channel_type chan_type)
{
KASSERT(chandef != NULL, ("%s: chandef is NULL\n", __func__));
KASSERT(chan != NULL, ("%s: chan is NULL\n", __func__));
- memset(chandef, 0, sizeof(*chandef));
+ /* memset(chandef, 0, sizeof(*chandef)); */
chandef->chan = chan;
- chandef->center_freq2 = 0; /* Set here and only overwrite if needed. */
+ chandef->center_freq1 = chan->center_freq;
+ /* chandef->width, center_freq2, punctured */
- switch (chan_flag) {
+ switch (chan_type) {
case NL80211_CHAN_NO_HT:
chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
- chandef->center_freq1 = chan->center_freq;
break;
- default:
- printf("%s: unsupported chan_flag %#0x\n", __func__, chan_flag);
- /* XXX-BZ should we panic instead? */
+ case NL80211_CHAN_HT20:
chandef->width = NL80211_CHAN_WIDTH_20;
- chandef->center_freq1 = chan->center_freq;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ chandef->width = NL80211_CHAN_WIDTH_40;
+ chandef->center_freq1 -= 10;
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ chandef->width = NL80211_CHAN_WIDTH_40;
+ chandef->center_freq1 += 10;
break;
};
}
+static __inline bool
+cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+cfg80211_chandef_dfs_usable(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef)
+{
+ TODO();
+ return (false);
+}
+
+static __inline unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef)
+{
+ TODO();
+ return (0);
+}
+
+static __inline bool
+cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef_1,
+ const struct cfg80211_chan_def *chandef_2)
+{
+ TODO();
+ return (false);
+}
+
+static __inline bool
+cfg80211_chandef_usable(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef, uint32_t flags)
+{
+ TODO();
+ return (false);
+}
+
static __inline void
cfg80211_bss_iter(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
void (*iterfunc)(struct wiphy *, struct cfg80211_bss *, void *), void *data)
@@ -1199,23 +1415,84 @@ cfg80211_bss_iter(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
}
struct element {
- uint8_t id;
- uint8_t datalen;
- uint8_t data[0];
-};
+ uint8_t id;
+ uint8_t datalen;
+ uint8_t data[0];
+} __packed;
+
+static inline const struct element *
+lkpi_cfg80211_find_elem_pattern(enum ieee80211_eid eid,
+ const uint8_t *data, size_t len, uint8_t *pattern, size_t plen)
+{
+ const struct element *elem;
+ const uint8_t *p;
+ size_t ielen;
+
+ p = data;
+ elem = (const struct element *)p;
+ ielen = len;
+ while (elem != NULL && ielen > 1) {
+ if ((2 + elem->datalen) > ielen)
+ /* Element overruns our memory. */
+ return (NULL);
+ if (elem->id == eid) {
+ if (pattern == NULL)
+ return (elem);
+ if (elem->datalen >= plen &&
+ memcmp(elem->data, pattern, plen) == 0)
+ return (elem);
+ }
+ ielen -= 2 + elem->datalen;
+ p += 2 + elem->datalen;
+ elem = (const struct element *)p;
+ }
-static __inline const struct element *
-cfg80211_find_elem(enum ieee80211_eid eid, uint8_t *data, size_t len)
-{
- TODO();
return (NULL);
}
-static __inline uint32_t
+static inline const struct element *
+cfg80211_find_elem(enum ieee80211_eid eid, const uint8_t *data, size_t len)
+{
+
+ return (lkpi_cfg80211_find_elem_pattern(eid, data, len, NULL, 0));
+}
+
+static inline const struct element *
+ieee80211_bss_get_elem(struct cfg80211_bss *bss, uint32_t eid)
+{
+
+ if (bss->ies == NULL)
+ return (NULL);
+ return (cfg80211_find_elem(eid, bss->ies->data, bss->ies->len));
+}
+
+static inline const uint8_t *
+ieee80211_bss_get_ie(struct cfg80211_bss *bss, uint32_t eid)
+{
+
+ return ((const uint8_t *)ieee80211_bss_get_elem(bss, eid));
+}
+
+static inline uint8_t *
+cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
+ uint8_t *data, size_t len)
+{
+ const struct element *elem;
+ uint8_t pattern[4] = { oui << 16, oui << 8, oui, oui_type };
+ uint8_t plen = 4; /* >= 3? oui_type always part of this? */
+ IMPROVE("plen currently always incl. oui_type");
+
+ elem = lkpi_cfg80211_find_elem_pattern(IEEE80211_ELEMID_VENDOR,
+ data, len, pattern, plen);
+ if (elem == NULL)
+ return (NULL);
+ return (__DECONST(uint8_t *, elem));
+}
+
+static inline uint32_t
cfg80211_calculate_bitrate(struct rate_info *rate)
{
- TODO();
- return (-1);
+ return (linuxkpi_cfg80211_calculate_bitrate(rate));
}
static __inline uint32_t
@@ -1271,8 +1548,22 @@ regulatory_set_wiphy_regd(struct wiphy *wiphy,
static __inline int
regulatory_hint(struct wiphy *wiphy, const uint8_t *alpha2)
{
- TODO();
- return (-ENXIO);
+ struct linuxkpi_ieee80211_regdomain *regd;
+
+ if (wiphy->regd != NULL)
+ return (-EBUSY);
+
+ regd = lkpi_get_linuxkpi_ieee80211_regdomain(0);
+ if (regd == NULL)
+ return (-ENOMEM);
+
+ regd->alpha2[0] = alpha2[0];
+ regd->alpha2[1] = alpha2[1];
+ wiphy->regd = regd;
+
+ IMPROVE("are there flags who is managing? update net8011?");
+
+ return (0);
}
static __inline const char *
@@ -1296,20 +1587,6 @@ freq_reg_info(struct wiphy *wiphy, uint32_t center_freq)
return (NULL);
}
-static __inline struct cfg80211_bss *
-cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
- uint8_t *bssid, void *p, int x, uint32_t f1, uint32_t f2)
-{
- TODO();
- return (NULL);
-}
-
-static __inline void
-cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
-{
- TODO();
-}
-
static __inline void
wiphy_apply_custom_regulatory(struct wiphy *wiphy,
const struct linuxkpi_ieee80211_regdomain *regd)
@@ -1336,14 +1613,6 @@ wiphy_read_of_freq_limits(struct wiphy *wiphy)
#endif
}
-static __inline uint8_t *
-cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
- uint8_t *data, size_t len)
-{
- TODO();
- return (NULL);
-}
-
static __inline void
wiphy_ext_feature_set(struct wiphy *wiphy, enum nl80211_ext_feature ef)
{
@@ -1351,6 +1620,12 @@ wiphy_ext_feature_set(struct wiphy *wiphy, enum nl80211_ext_feature ef)
set_bit(ef, wiphy->ext_features);
}
+static inline bool
+wiphy_ext_feature_isset(struct wiphy *wiphy, enum nl80211_ext_feature ef)
+{
+ return (test_bit(ef, wiphy->ext_features));
+}
+
static __inline void *
wiphy_net(struct wiphy *wiphy)
{
@@ -1563,18 +1838,23 @@ ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq)
return (linuxkpi_ieee80211_get_channel(wiphy, freq));
}
-static __inline size_t
+static inline size_t
ieee80211_get_hdrlen_from_skb(struct sk_buff *skb)
{
+ const struct ieee80211_hdr *hdr;
+ size_t len;
- TODO();
- return (-1);
-}
+ if (skb->len < 10) /* sizeof(ieee80211_frame_[ack,cts]) */
+ return (0);
-static __inline void
-cfg80211_bss_flush(struct wiphy *wiphy)
-{
- TODO();
+ hdr = (const struct ieee80211_hdr *)skb->data;
+ len = ieee80211_hdrlen(hdr->frame_control);
+
+ /* If larger than what is in the skb return. */
+ if (len > skb->len)
+ return (0);
+
+ return (len);
}
static __inline bool
@@ -1589,12 +1869,36 @@ cfg80211_channel_is_psc(struct linuxkpi_ieee80211_channel *channel)
return (false);
}
-static __inline int
+static inline int
cfg80211_get_ies_channel_number(const uint8_t *ie, size_t len,
- enum nl80211_band band, enum cfg80211_bss_frame_type ftype)
+ enum nl80211_band band)
{
+ const struct element *elem;
- TODO();
+ switch (band) {
+ case NL80211_BAND_6GHZ:
+ TODO();
+ break;
+ case NL80211_BAND_5GHZ:
+ case NL80211_BAND_2GHZ:
+ /* DSPARAMS has the channel number. */
+ elem = cfg80211_find_elem(IEEE80211_ELEMID_DSPARMS, ie, len);
+ if (elem != NULL && elem->datalen == 1)
+ return (elem->data[0]);
+ /* HTINFO has the primary center channel. */
+ elem = cfg80211_find_elem(IEEE80211_ELEMID_HTINFO, ie, len);
+ if (elem != NULL &&
+ elem->datalen >= (sizeof(struct ieee80211_ie_htinfo) - 2)) {
+ const struct ieee80211_ie_htinfo *htinfo;
+ htinfo = (const struct ieee80211_ie_htinfo *)elem;
+ return (htinfo->hi_ctrlchannel);
+ }
+ /* What else? */
+ break;
+ default:
+ IMPROVE("Unsupported");
+ break;
+ }
return (-1);
}
@@ -1616,22 +1920,240 @@ cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
TODO();
}
+static __inline bool
+cfg80211_reg_can_beacon(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
+ enum nl80211_iftype iftype)
+{
+ TODO();
+ return (false);
+}
+
+static __inline void
+cfg80211_background_radar_event(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef, gfp_t gfp)
+{
+ TODO();
+}
+
+static __inline const u8 *
+cfg80211_find_ext_ie(uint8_t eid, const uint8_t *p, size_t len)
+{
+ TODO();
+ return (NULL);
+}
+
+static inline void
+_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *band,
+ struct ieee80211_sband_iftype_data *iftype_data, size_t nitems)
+{
+ band->iftype_data = iftype_data;
+ band->n_iftype_data = nitems;
+}
+
+static inline const struct ieee80211_sband_iftype_data *
+ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *band,
+ enum nl80211_iftype iftype)
+{
+ const struct ieee80211_sband_iftype_data *iftype_data;
+ int i;
+
+ for (i = 0; i < band->n_iftype_data; i++) {
+ iftype_data = (const void *)&band->iftype_data[i];
+ if (iftype_data->types_mask & BIT(iftype))
+ return (iftype_data);
+ }
+
+ return (NULL);
+}
+
+static inline const struct ieee80211_sta_he_cap *
+ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *band,
+ enum nl80211_iftype iftype)
+{
+ const struct ieee80211_sband_iftype_data *iftype_data;
+ const struct ieee80211_sta_he_cap *he_cap;
+
+ iftype_data = ieee80211_get_sband_iftype_data(band, iftype);
+ if (iftype_data == NULL)
+ return (NULL);
+
+ he_cap = NULL;
+ if (iftype_data->he_cap.has_he)
+ he_cap = &iftype_data->he_cap;
+
+ return (he_cap);
+}
+
+static inline const struct ieee80211_sta_eht_cap *
+ieee80211_get_eht_iftype_cap(const struct ieee80211_supported_band *band,
+ enum nl80211_iftype iftype)
+{
+ const struct ieee80211_sband_iftype_data *iftype_data;
+ const struct ieee80211_sta_eht_cap *eht_cap;
+
+ iftype_data = ieee80211_get_sband_iftype_data(band, iftype);
+ if (iftype_data == NULL)
+ return (NULL);
+
+ eht_cap = NULL;
+ if (iftype_data->eht_cap.has_eht)
+ eht_cap = &iftype_data->eht_cap;
+
+ return (eht_cap);
+}
+
+static inline bool
+cfg80211_ssid_eq(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
+{
+ int error;
+
+ if (ssid1 == NULL || ssid2 == NULL) /* Can we KASSERT this? */
+ return (false);
+
+ if (ssid1->ssid_len != ssid2->ssid_len)
+ return (false);
+ error = memcmp(ssid1->ssid, ssid2->ssid, ssid2->ssid_len);
+ if (error != 0)
+ return (false);
+ return (true);
+}
+
+static inline void
+cfg80211_rx_unprot_mlme_mgmt(struct net_device *ndev, const uint8_t *hdr,
+ uint32_t len)
+{
+ TODO();
+}
+
+static inline const struct wiphy_iftype_ext_capab *
+cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype iftype)
+{
+
+ TODO();
+ return (NULL);
+}
+
+static inline uint16_t
+ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband,
+ enum nl80211_iftype iftype)
+{
+ TODO();
+ return (0);
+}
+
+static inline int
+nl80211_chan_width_to_mhz(enum nl80211_chan_width width)
+{
+ switch (width) {
+ case NL80211_CHAN_WIDTH_5:
+ return (5);
+ break;
+ case NL80211_CHAN_WIDTH_10:
+ return (10);
+ break;
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ return (20);
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ return (40);
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_80P80:
+ return (80);
+ break;
+ case NL80211_CHAN_WIDTH_160:
+ return (160);
+ break;
+ case NL80211_CHAN_WIDTH_320:
+ return (320);
+ break;
+ }
+}
+
+static __inline ssize_t
+wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file,
+ char *buf, size_t bufsize, const char __user *userbuf, size_t count,
+ loff_t *ppos,
+ ssize_t (*handler)(struct wiphy *, struct file *, char *, size_t, void *),
+ void *data)
+{
+ TODO();
+ return (-ENXIO);
+}
+
+
+static __inline ssize_t
+wiphy_locked_debugfs_write(struct wiphy *wiphy, struct file *file,
+ char *buf, size_t bufsize, const char __user *userbuf, size_t count,
+ ssize_t (*handler)(struct wiphy *, struct file *, char *, size_t, void *),
+ void *data)
+{
+ TODO();
+ return (-ENXIO);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static inline void
+wiphy_work_init(struct wiphy_work *wwk, wiphy_work_fn fn)
+{
+ INIT_LIST_HEAD(&wwk->entry);
+ wwk->fn = fn;
+}
+
+static inline void
+wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+ linuxkpi_wiphy_work_queue(wiphy, wwk);
+}
+
+static inline void
+wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+ linuxkpi_wiphy_work_cancel(wiphy, wwk);
+}
+
+static inline void
+wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+ linuxkpi_wiphy_work_flush(wiphy, wwk);
+}
+
+static inline void
+wiphy_delayed_work_init(struct wiphy_delayed_work *wdwk, wiphy_work_fn fn)
+{
+ wiphy_work_init(&wdwk->work, fn);
+ timer_setup(&wdwk->timer, lkpi_wiphy_delayed_work_timer, 0);
+}
+
+static inline void
+wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk,
+ unsigned long delay)
+{
+ linuxkpi_wiphy_delayed_work_queue(wiphy, wdwk, delay);
+}
+
+static inline void
+wiphy_delayed_work_cancel(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk)
+{
+ linuxkpi_wiphy_delayed_work_cancel(wiphy, wdwk);
+}
+
+/* -------------------------------------------------------------------------- */
+
+#define wiphy_err(_wiphy, _fmt, ...) \
+ dev_err((_wiphy)->dev, _fmt, __VA_ARGS__)
+#define wiphy_info(wiphy, fmt, ...) \
+ dev_info((wiphy)->dev, fmt, ##__VA_ARGS__)
+#define wiphy_info_once(wiphy, fmt, ...) \
+ dev_info_once((wiphy)->dev, fmt, ##__VA_ARGS__)
+
#ifndef LINUXKPI_NET80211
#define ieee80211_channel linuxkpi_ieee80211_channel
#define ieee80211_regdomain linuxkpi_ieee80211_regdomain
-/* net80211::IEEE80211_VHT_MCS_SUPPORT_0_n() conflicts */
-#if defined(IEEE80211_VHT_MCS_SUPPORT_0_7)
-#undef IEEE80211_VHT_MCS_SUPPORT_0_7
-#endif
-#if defined(IEEE80211_VHT_MCS_SUPPORT_0_8)
-#undef IEEE80211_VHT_MCS_SUPPORT_0_8
-#endif
-#if defined(IEEE80211_VHT_MCS_SUPPORT_0_9)
-#undef IEEE80211_VHT_MCS_SUPPORT_0_9
-#endif
-#define IEEE80211_VHT_MCS_SUPPORT_0_7 LKPI_IEEE80211_VHT_MCS_SUPPORT_0_7
-#define IEEE80211_VHT_MCS_SUPPORT_0_8 LKPI_IEEE80211_VHT_MCS_SUPPORT_0_8
-#define IEEE80211_VHT_MCS_SUPPORT_0_9 LKPI_IEEE80211_VHT_MCS_SUPPORT_0_9
#endif
+#include <net/mac80211.h>
+
#endif /* _LINUXKPI_NET_CFG80211_H */
diff --git a/sys/compat/linuxkpi/common/include/net/ieee80211_radiotap.h b/sys/compat/linuxkpi/common/include/net/ieee80211_radiotap.h
index 932c0b037026..82e554f6b96e 100644
--- a/sys/compat/linuxkpi/common/include/net/ieee80211_radiotap.h
+++ b/sys/compat/linuxkpi/common/include/net/ieee80211_radiotap.h
@@ -24,8 +24,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_IEEE80211_RADIOTAP_H
diff --git a/sys/compat/linuxkpi/common/include/net/if_inet6.h b/sys/compat/linuxkpi/common/include/net/if_inet6.h
index d4a16d967ecf..c340909d7098 100644
--- a/sys/compat/linuxkpi/common/include/net/if_inet6.h
+++ b/sys/compat/linuxkpi/common/include/net/if_inet6.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_IF_INET6_H_
#define _LINUXKPI_NET_IF_INET6_H_
diff --git a/sys/compat/linuxkpi/common/include/net/ip.h b/sys/compat/linuxkpi/common/include/net/ip.h
index 6fadfd92b8e8..3e7baab6cc0b 100644
--- a/sys/compat/linuxkpi/common/include/net/ip.h
+++ b/sys/compat/linuxkpi/common/include/net/ip.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_IP_H_
#define _LINUXKPI_NET_IP_H_
diff --git a/sys/compat/linuxkpi/common/include/net/ipv6.h b/sys/compat/linuxkpi/common/include/net/ipv6.h
index bf29a28a9a46..3a85781e3a49 100644
--- a/sys/compat/linuxkpi/common/include/net/ipv6.h
+++ b/sys/compat/linuxkpi/common/include/net/ipv6.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_IPV6_H_
#define _LINUXKPI_NET_IPV6_H_
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index b5ee9467591d..8de03410c6b6 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2020-2021 The FreeBSD Foundation
- * Copyright (c) 2020-2022 Bjoern A. Zeeb
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 Bjoern A. Zeeb
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -25,8 +25,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_MAC80211_H
@@ -36,12 +34,16 @@
#include <asm/atomic64.h>
#include <linux/bitops.h>
+#include <linux/bitfield.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
+#include <linux/dcache.h>
+#include <linux/ieee80211.h>
#include <net/cfg80211.h>
+#include <net/if_inet6.h>
#define ARPHRD_IEEE80211_RADIOTAP __LINE__ /* XXX TODO brcmfmac */
@@ -51,11 +53,14 @@
#define WLAN_OUI_TYPE_WFA_P2P (9)
#define WLAN_OUI_WFA (0x506F9A)
+#define IEEE80211_LINK_UNSPECIFIED 0x0f
+
/* hw->conf.flags */
enum ieee80211_hw_conf_flags {
IEEE80211_CONF_IDLE = BIT(0),
IEEE80211_CONF_PS = BIT(1),
IEEE80211_CONF_MONITOR = BIT(2),
+ IEEE80211_CONF_OFFCHANNEL = BIT(3),
};
/* (*ops->config()) */
@@ -64,9 +69,11 @@ enum ieee80211_hw_conf_changed_flags {
IEEE80211_CONF_CHANGE_IDLE = BIT(1),
IEEE80211_CONF_CHANGE_PS = BIT(2),
IEEE80211_CONF_CHANGE_MONITOR = BIT(3),
+ IEEE80211_CONF_CHANGE_POWER = BIT(4),
};
#define CFG80211_TESTMODE_CMD(_x) /* XXX TODO */
+#define CFG80211_TESTMODE_DUMP(_x) /* XXX TODO */
#define FCS_LEN 4
@@ -79,6 +86,10 @@ enum mcast_filter_flags {
FIF_OTHER_BSS = BIT(4),
FIF_PSPOLL = BIT(5),
FIF_CONTROL = BIT(6),
+ FIF_MCAST_ACTION = BIT(7),
+
+ /* Must stay last. */
+ FIF_FLAGS_MASK = BIT(8)-1,
};
enum ieee80211_bss_changed {
@@ -108,6 +119,14 @@ enum ieee80211_bss_changed {
BSS_CHANGED_IBSS = BIT(23),
BSS_CHANGED_MCAST_RATE = BIT(24),
BSS_CHANGED_SSID = BIT(25),
+ BSS_CHANGED_FILS_DISCOVERY = BIT(26),
+ BSS_CHANGED_HE_OBSS_PD = BIT(27),
+ BSS_CHANGED_TWT = BIT(28),
+ BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = BIT(30),
+ BSS_CHANGED_EHT_PUNCTURING = BIT(31),
+ BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(32),
+ BSS_CHANGED_MLD_TTLM = BIT_ULL(33),
+ BSS_CHANGED_TPE = BIT_ULL(34),
};
/* 802.11 Figure 9-256 Suite selector format. [OUI(3), SUITE TYPE(1)] */
@@ -132,6 +151,9 @@ enum ieee80211_bss_changed {
#define WLAN_CIPHER_SUITE_BIP_CMAC_256 WLAN_CIPHER_SUITE(13)
/* Reserved 14-255 */
+/* See ISO/IEC JTC 1 N 9880 Table 11 */
+#define WLAN_CIPHER_SUITE_SMS4 WLAN_CIPHER_SUITE_OUI(0x001472, 1)
+
/* 802.11 Table 9-133 AKM suite selectors. */
#define WLAN_AKM_SUITE(_x) WLAN_CIPHER_SUITE_OUI(0x000fac, _x)
@@ -152,15 +174,35 @@ enum ieee80211_bss_changed {
/* Reserved 14-255 */
/* Apparently 11ax defines more. Seen (19,20) mentioned. */
+#define TKIP_PN_TO_IV16(_x) ((uint16_t)(_x & 0xffff))
+#define TKIP_PN_TO_IV32(_x) ((uint32_t)((_x >> 16) & 0xffffffff))
+
+enum ieee80211_neg_ttlm_res {
+ NEG_TTLM_RES_ACCEPT,
+ NEG_TTLM_RES_REJECT,
+};
+
+#define IEEE80211_TTLM_NUM_TIDS 8
+struct ieee80211_neg_ttlm {
+ uint16_t downlink[IEEE80211_TTLM_NUM_TIDS];
+ uint16_t uplink[IEEE80211_TTLM_NUM_TIDS];
+};
+
+/* 802.11-2020 9.4.2.55.3 A-MPDU Parameters field */
+#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x3
+#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2
+#define IEEE80211_HT_AMPDU_PARM_DENSITY (0x7 << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT)
struct ieee80211_sta;
struct ieee80211_ampdu_params {
- /* TODO FIXME */
struct ieee80211_sta *sta;
- uint8_t tid;
+ enum ieee80211_ampdu_mlme_action action;
+ uint16_t buf_size;
+ uint16_t timeout;
uint16_t ssn;
- int action, amsdu, buf_size, timeout;
+ uint8_t tid;
+ bool amsdu;
};
struct ieee80211_bar {
@@ -170,35 +212,85 @@ struct ieee80211_bar {
uint16_t frame_control;
};
-struct ieee80211_p2p_noa_desc {
- uint32_t count; /* uint8_t ? */
- uint32_t duration;
- uint32_t interval;
- uint32_t start_time;
+struct ieee80211_mutable_offsets {
+ /* TODO FIXME */
+ uint16_t tim_offset;
+ uint16_t cntdwn_counter_offs[2];
+
+ int mbssid_off;
};
-struct ieee80211_p2p_noa_attr {
- uint8_t index;
- uint8_t oppps_ctwindow;
- struct ieee80211_p2p_noa_desc desc[4];
+struct mac80211_fils_discovery {
+ uint32_t max_interval;
};
-struct ieee80211_mutable_offsets {
- /* TODO FIXME */
- uint16_t tim_offset;
- int cntdwn_counter_offs;
+struct ieee80211_chanctx_conf {
+ struct cfg80211_chan_def def;
+ struct cfg80211_chan_def min_def;
+ struct cfg80211_chan_def ap;
+
+ uint8_t rx_chains_dynamic;
+ uint8_t rx_chains_static;
+ bool radar_enabled;
+
+ /* Must stay last. */
+ uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
+};
+
+struct ieee80211_rate_status {
+ struct rate_info rate_idx;
+ uint8_t try_count;
+};
+
+struct ieee80211_ema_beacons {
+ uint8_t cnt;
+ struct {
+ struct sk_buff *skb;
+ struct ieee80211_mutable_offsets offs;
+ } bcn[0];
+};
+
+struct ieee80211_chanreq {
+ struct cfg80211_chan_def oper;
};
#define WLAN_MEMBERSHIP_LEN (8)
#define WLAN_USER_POSITION_LEN (16)
+/*
+ * 802.11ac-2013, 8.4.2.164 VHT Transmit Power Envelope element
+ * 802.11-???? ?
+ */
+struct ieee80211_parsed_tpe_eirp {
+ int8_t power[5];
+ uint8_t count;
+ bool valid;
+};
+struct ieee80211_parsed_tpe_psd {
+ int8_t power[16];
+ uint8_t count;
+ bool valid;
+};
+struct ieee80211_parsed_tpe {
+ /* We see access to [0] so assume at least 2. */
+ struct ieee80211_parsed_tpe_eirp max_local[2];
+ struct ieee80211_parsed_tpe_eirp max_reg_client[2];
+ struct ieee80211_parsed_tpe_psd psd_local[2];
+ struct ieee80211_parsed_tpe_psd psd_reg_client[2];
+};
+
struct ieee80211_bss_conf {
/* TODO FIXME */
- uint8_t bssid[ETH_ALEN];
+ struct ieee80211_vif *vif;
+ struct cfg80211_bss *bss;
+ const uint8_t *bssid;
+ uint8_t addr[ETH_ALEN];
+ uint8_t link_id;
+ uint8_t _pad0;
uint8_t transmitter_bssid[ETH_ALEN];
struct ieee80211_ftm_responder_params *ftmr_params;
struct ieee80211_p2p_noa_attr p2p_noa_attr;
- struct cfg80211_chan_def chandef;
+ struct ieee80211_chanreq chanreq;
__be32 arp_addr_list[1]; /* XXX TODO */
struct ieee80211_rate *beacon_rate;
struct {
@@ -206,29 +298,56 @@ struct ieee80211_bss_conf {
uint8_t position[WLAN_USER_POSITION_LEN];
} mu_group;
struct {
- int color;
- } he_bss_color;
- size_t ssid_len;
- uint8_t ssid[IEEE80211_NWID_LEN];
- uint16_t aid;
+ uint32_t params;
+ /* single field struct? */
+ } he_oper;
+ struct cfg80211_he_bss_color he_bss_color;
+ struct ieee80211_he_obss_pd he_obss_pd;
+
+ bool ht_ldpc;
+ bool vht_ldpc;
+ bool he_ldpc;
+ bool vht_mu_beamformee;
+ bool vht_mu_beamformer;
+ bool vht_su_beamformee;
+ bool vht_su_beamformer;
+ bool he_mu_beamformer;
+ bool he_su_beamformee;
+ bool he_su_beamformer;
+ bool he_full_ul_mumimo;
+ bool eht_su_beamformee;
+ bool eht_su_beamformer;
+ bool eht_mu_beamformer;
+
uint16_t ht_operation_mode;
int arp_addr_cnt;
+ uint16_t eht_puncturing;
uint8_t dtim_period;
- bool assoc;
- bool idle;
+ uint8_t sync_dtim_count;
+ uint8_t bss_param_ch_cnt_link_id;
bool qos;
- bool ps;
bool twt_broadcast;
bool use_cts_prot;
bool use_short_preamble;
bool use_short_slot;
- uint16_t beacon_int;
+ bool he_support;
+ bool eht_support;
+ bool csa_active;
+ bool mu_mimo_owner;
+ bool color_change_active;
uint32_t sync_device_ts;
uint64_t sync_tsf;
- uint8_t sync_dtim_count;
+ uint16_t beacon_int;
int16_t txpower;
+ uint32_t basic_rates;
int mcast_rate[NUM_NL80211_BANDS];
+ enum ieee80211_ap_reg_power power_type;
+ struct cfg80211_bitrate_mask beacon_tx_rate;
+ struct mac80211_fils_discovery fils_discovery;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_vif *mbssid_tx_vif;
+ struct ieee80211_parsed_tpe tpe;
int ack_enabled, bssid_index, bssid_indicator, cqm_rssi_hyst, cqm_rssi_thold, ema_ap, frame_time_rts_th, ftm_responder;
int htc_trig_based_pkt_ext;
@@ -236,40 +355,16 @@ struct ieee80211_bss_conf {
int profile_periodicity;
int twt_requester, uora_exists, uora_ocw_range;
int assoc_capability, enable_beacon, hidden_ssid, ibss_joined, twt_protected;
- int fils_discovery, he_obss_pd, he_oper, twt_responder, unsol_bcast_probe_resp_interval;
- unsigned long basic_rates;
- bool he_support;
-};
-
-struct ieee80211_chanctx_conf {
- /* TODO FIXME */
- int rx_chains_dynamic, rx_chains_static;
- bool radar_enabled;
- struct cfg80211_chan_def def;
- struct cfg80211_chan_def min_def;
-
- /* Must stay last. */
- uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
+ int twt_responder, unsol_bcast_probe_resp_interval;
};
struct ieee80211_channel_switch {
/* TODO FIXME */
int block_tx, count, delay, device_timestamp, timestamp;
+ uint8_t link_id;
struct cfg80211_chan_def chandef;
};
-struct ieee80211_cipher_scheme {
- uint32_t cipher;
- uint8_t iftype; /* We do not know the size of this. */
- uint8_t hdr_len;
- uint8_t pn_len;
- uint8_t pn_off;
- uint8_t key_idx_off;
- uint8_t key_idx_mask;
- uint8_t key_idx_shift;
- uint8_t mic_len;
-};
-
enum ieee80211_event_type {
BA_FRAME_TIMEOUT,
BAR_RX_EVENT,
@@ -321,14 +416,11 @@ struct ieee80211_ftm_responder_params {
int civicloc_len;
};
-struct ieee80211_he_mu_edca_param_ac_rec {
- /* TODO FIXME */
- int aifsn, ecw_min_max, mu_edca_timer;
-};
-
struct ieee80211_conf {
int dynamic_ps_timeout;
+ int power_level;
uint32_t listen_interval;
+ bool radar_enabled;
enum ieee80211_hw_conf_flags flags;
struct cfg80211_chan_def chandef;
};
@@ -371,6 +463,15 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_PER_STA_GTK,
IEEE80211_HW_REPORTS_LOW_ACK,
IEEE80211_HW_QUEUE_CONTROL,
+ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
+ IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
+ IEEE80211_HW_SUPPORTS_RC_TABLE,
+ IEEE80211_HW_DETECTS_COLOR_COLLISION,
+ IEEE80211_HW_DISALLOW_PUNCTURING,
+ IEEE80211_HW_DISALLOW_PUNCTURING_5GHZ,
+ IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
+ IEEE80211_HW_HANDLES_QUIET_CSA,
+ IEEE80211_HW_NO_VIRTUAL_MONITOR,
/* Keep last. */
NUM_IEEE80211_HW_FLAGS
@@ -381,11 +482,8 @@ struct ieee80211_hw {
struct wiphy *wiphy;
/* TODO FIXME */
- int max_rx_aggregation_subframes, max_tx_aggregation_subframes;
int extra_tx_headroom, weight_multiplier;
int max_rate_tries, max_rates, max_report_rates;
- struct ieee80211_cipher_scheme *cipher_schemes;
- int n_cipher_schemes;
const char *rate_control_algorithm;
struct {
uint16_t units_pos; /* radiotap "spec" is .. inconsistent. */
@@ -401,8 +499,11 @@ struct ieee80211_hw {
uint16_t offchannel_tx_hw_queue;
uint16_t uapsd_max_sp_len;
uint16_t uapsd_queues;
+ uint16_t max_rx_aggregation_subframes;
+ uint16_t max_tx_aggregation_subframes;
uint16_t max_tx_fragments;
uint16_t max_listen_interval;
+ uint32_t extra_beacon_tailroom;
netdev_features_t netdev_features;
unsigned long flags[BITS_TO_LONGS(NUM_IEEE80211_HW_FLAGS)];
struct ieee80211_conf conf;
@@ -423,9 +524,20 @@ enum ieee802111_key_flag {
IEEE80211_KEY_FLAG_PUT_MIC_SPACE = BIT(4),
IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(5),
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(6),
+ IEEE80211_KEY_FLAG_GENERATE_MMIE = BIT(7),
+ IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(8),
+ IEEE80211_KEY_FLAG_SPP_AMSDU = BIT(9),
};
+#define IEEE80211_KEY_FLAG_BITS \
+ "\20\1GENERATE_IV\2GENERATE_MMIC\3PAIRWISE\4PUT_IV_SPACE" \
+ "\5PUT_MIC_SPACE\6SW_MGMT_TX\7GENERATE_IV_MGMT\10GENERATE_MMIE" \
+ "\11RESERVE_TAILROOM\12SPP_AMSDU"
+
struct ieee80211_key_conf {
+#if defined(__FreeBSD__)
+ const struct ieee80211_key *_k; /* backpointer to net80211 */
+#endif
atomic64_t tx_pn;
uint32_t cipher;
uint8_t icv_len; /* __unused nowadays? */
@@ -433,8 +545,9 @@ struct ieee80211_key_conf {
uint8_t hw_key_idx; /* Set by drv. */
uint8_t keyidx;
uint16_t flags;
+ int8_t link_id; /* signed! */
uint8_t keylen;
- uint8_t key[0];
+ uint8_t key[0]; /* Must stay last! */
};
struct ieee80211_key_seq {
@@ -448,9 +561,15 @@ struct ieee80211_key_seq {
uint8_t pn[IEEE80211_CCMP_PN_LEN];
} ccmp;
struct {
- uint8_t pn[IEEE80211_CCMP_PN_LEN];
+ uint8_t pn[IEEE80211_GCMP_PN_LEN];
+ } gcmp;
+ struct {
+ uint8_t pn[IEEE80211_CMAC_PN_LEN];
} aes_cmac;
struct {
+ uint8_t pn[IEEE80211_GMAC_PN_LEN];
+ } aes_gmac;
+ struct {
uint32_t iv32;
uint16_t iv16;
} tkip;
@@ -467,8 +586,10 @@ enum ieee80211_rx_status_flags {
RX_FLAG_DUP_VALIDATED = BIT(5),
RX_FLAG_FAILED_FCS_CRC = BIT(6),
RX_FLAG_ICV_STRIPPED = BIT(7),
- RX_FLAG_MACTIME_PLCP_START = BIT(8),
- RX_FLAG_MACTIME_START = BIT(9),
+ RX_FLAG_MACTIME = BIT(8) | BIT(9),
+ RX_FLAG_MACTIME_PLCP_START = 1 << 8,
+ RX_FLAG_MACTIME_START = 2 << 8,
+ RX_FLAG_MACTIME_END = 3 << 8,
RX_FLAG_MIC_STRIPPED = BIT(10),
RX_FLAG_MMIC_ERROR = BIT(11),
RX_FLAG_MMIC_STRIPPED = BIT(12),
@@ -483,43 +604,82 @@ enum ieee80211_rx_status_flags {
RX_FLAG_AMPDU_IS_LAST = BIT(21),
RX_FLAG_AMPDU_LAST_KNOWN = BIT(22),
RX_FLAG_AMSDU_MORE = BIT(23),
- RX_FLAG_MACTIME_END = BIT(24),
+ /* = BIT(24), */
RX_FLAG_ONLY_MONITOR = BIT(25),
RX_FLAG_SKIP_MONITOR = BIT(26),
+ RX_FLAG_8023 = BIT(27),
+ RX_FLAG_RADIOTAP_TLV_AT_END = BIT(28),
+ /* = BIT(29), */
+ RX_FLAG_MACTIME_IS_RTAP_TS64 = BIT(30),
+ RX_FLAG_FAILED_PLCP_CRC = BIT(31),
+};
+
+#define IEEE80211_RX_STATUS_FLAGS_BITS \
+ "\20\1ALLOW_SAME_PN\2AMPDU_DETAILS\3AMPDU_EOF_BIT\4AMPDU_EOF_BIT_KNOWN" \
+ "\5DECRYPTED\6DUP_VALIDATED\7FAILED_FCS_CRC\10ICV_STRIPPED" \
+ "\11MACTIME_PLCP_START\12MACTIME_START\13MIC_STRIPPED" \
+ "\14MMIC_ERROR\15MMIC_STRIPPED\16NO_PSDU\17PN_VALIDATED" \
+ "\20RADIOTAP_HE\21RADIOTAP_HE_MU\22RADIOTAP_LSIG\23RADIOTAP_VENDOR_DATA" \
+ "\24NO_SIGNAL_VAL\25IV_STRIPPED\26AMPDU_IS_LAST\27AMPDU_LAST_KNOWN" \
+ "\30AMSDU_MORE\31MACTIME_END\32ONLY_MONITOR\33SKIP_MONITOR" \
+ "\348023\35RADIOTAP_TLV_AT_END\36MACTIME\37MACTIME_IS_RTAP_TS64" \
+ "\40FAILED_PLCP_CRC"
+
+enum mac80211_rx_encoding {
+ RX_ENC_LEGACY = 0,
+ RX_ENC_HT,
+ RX_ENC_VHT,
+ RX_ENC_HE,
+ RX_ENC_EHT,
};
struct ieee80211_rx_status {
/* TODO FIXME, this is too large. Over-reduce types to u8 where possible. */
- uint64_t boottime_ns;
+ union {
+ uint64_t boottime_ns;
+ int64_t ack_tx_hwtstamp;
+ };
uint64_t mactime;
uint32_t device_timestamp;
enum ieee80211_rx_status_flags flag;
uint16_t freq;
- uint8_t bw;
-#define RATE_INFO_BW_20 0x01
-#define RATE_INFO_BW_40 0x02
-#define RATE_INFO_BW_80 0x04
-#define RATE_INFO_BW_160 0x08
-#define RATE_INFO_BW_HE_RU 0x10
- uint8_t encoding;
-#define RX_ENC_LEGACY 0x00
-#define RX_ENC_HE 0x01
-#define RX_ENC_HT 0x02
-#define RX_ENC_VHT 0x04
+ uint8_t encoding:3, bw:4; /* enum mac80211_rx_encoding, rate_info_bw */ /* See mt76.h */
uint8_t ampdu_reference;
uint8_t band;
uint8_t chains;
int8_t chain_signal[IEEE80211_MAX_CHAINS];
int8_t signal;
uint8_t enc_flags;
- uint8_t he_dcm;
- uint8_t he_gi;
- uint8_t he_ru;
+ union {
+ struct {
+ uint8_t he_ru:3; /* nl80211::enum nl80211_he_ru_alloc */
+ uint8_t he_gi:2; /* nl80211::enum nl80211_he_gi */
+ uint8_t he_dcm:1;
+ };
+ struct {
+ uint8_t ru:4; /* nl80211::enum nl80211_eht_ru_alloc */
+ uint8_t gi:2; /* nl80211::enum nl80211_eht_gi */
+ } eht;
+ };
+ bool link_valid;
+ uint8_t link_id; /* very incosistent sizes? */
uint8_t zero_length_psdu_type;
uint8_t nss;
uint8_t rate_idx;
};
+struct ieee80211_tx_status {
+ struct ieee80211_sta *sta;
+ struct ieee80211_tx_info *info;
+ int64_t ack_hwtstamp;
+
+ u8 n_rates;
+ struct ieee80211_rate_status *rates;
+
+ struct sk_buff *skb;
+ struct list_head *free_list;
+};
+
struct ieee80211_scan_ies {
/* TODO FIXME */
int common_ie_len;
@@ -547,9 +707,10 @@ struct ieee80211_sta_rates {
/* XXX TODO */
/* XXX some _rcu thing */
struct {
- int idx;
- int flags;
- } rate[1]; /* XXX what is the real number? */
+ uint8_t idx;
+ uint8_t count;
+ uint16_t flags;
+ } rate[4]; /* XXX what is the real number? */
};
struct ieee80211_sta_txpwr {
@@ -558,29 +719,46 @@ struct ieee80211_sta_txpwr {
short power;
};
+#define IEEE80211_NUM_TIDS 16 /* net80211::WME_NUM_TID */
+struct ieee80211_sta_agg {
+ uint16_t max_amsdu_len;
+ uint16_t max_rc_amsdu_len;
+ uint16_t max_tid_amsdu_len[IEEE80211_NUM_TIDS];
+};
+
struct ieee80211_link_sta {
+ struct ieee80211_sta *sta;
+ uint8_t addr[ETH_ALEN];
+ uint8_t link_id;
uint32_t supp_rates[NUM_NL80211_BANDS];
struct ieee80211_sta_ht_cap ht_cap;
struct ieee80211_sta_vht_cap vht_cap;
struct ieee80211_sta_he_cap he_cap;
- struct ieee80211_sta_he_6ghz_capa he_6ghz_capa;
+ struct ieee80211_he_6ghz_capa he_6ghz_capa;
+ struct ieee80211_sta_eht_cap eht_cap;
uint8_t rx_nss;
- enum ieee80211_sta_rx_bw bandwidth;
+ enum ieee80211_sta_rx_bandwidth bandwidth;
+ enum ieee80211_smps_mode smps_mode;
+ struct ieee80211_sta_agg agg;
struct ieee80211_sta_txpwr txpwr;
};
-#define IEEE80211_NUM_TIDS 16 /* net80211::WME_NUM_TID */
struct ieee80211_sta {
/* TODO FIXME */
- int max_amsdu_len, max_amsdu_subframes, max_rc_amsdu_len, max_sp;
- int mfp, smps_mode, tdls, tdls_initiator, uapsd_queues, wme;
+ int max_amsdu_subframes;
+ int mfp, smps_mode, tdls, tdls_initiator;
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1]; /* iwlwifi: 8 and adds +1 to tid_data, net80211::IEEE80211_TID_SIZE */
struct ieee80211_sta_rates *rates; /* some rcu thing? */
- uint32_t max_tid_amsdu_len[IEEE80211_NUM_TIDS];
uint8_t addr[ETH_ALEN];
uint16_t aid;
+ bool wme;
+ bool mlo;
+ uint8_t max_sp;
+ uint8_t uapsd_queues;
+ uint16_t valid_links;
struct ieee80211_link_sta deflink;
+ struct ieee80211_link_sta *link[IEEE80211_MLD_MAX_NUM_LINKS]; /* rcu? */
/* Must stay last. */
uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
@@ -621,22 +799,52 @@ enum ieee80211_vif_driver_flags {
IEEE80211_VIF_BEACON_FILTER = BIT(0),
IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1),
IEEE80211_VIF_SUPPORTS_UAPSD = BIT(2),
+#if defined(LINUXKPI_VERSION) && (LINUXKPI_VERSION < 60600) /* v6.6 */
+ IEEE80211_VIF_DISABLE_SMPS_OVERRIDE = BIT(3), /* Renamed to IEEE80211_VIF_EML_ACTIVE. */
+#endif
+ IEEE80211_VIF_EML_ACTIVE = BIT(4),
+ IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW = BIT(5),
+ IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC = BIT(6),
+};
+
+#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4
+
+struct ieee80211_vif_cfg {
+ uint16_t aid;
+ uint16_t eml_cap;
+ uint16_t eml_med_sync_delay;
+ bool assoc;
+ bool ps;
+ bool idle;
+ bool ibss_joined;
+ int arp_addr_cnt;
+ size_t ssid_len;
+ uint32_t arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; /* big endian */
+ uint8_t ssid[IEEE80211_NWID_LEN];
+ uint8_t ap_addr[ETH_ALEN];
};
struct ieee80211_vif {
/* TODO FIXME */
enum nl80211_iftype type;
- int csa_active, mu_mimo_owner;
int cab_queue;
- int color_change_active, offload_flags;
+ int offload_flags;
enum ieee80211_vif_driver_flags driver_flags;
bool p2p;
bool probe_req_reg;
uint8_t addr[ETH_ALEN];
- struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_vif_cfg cfg;
struct ieee80211_txq *txq;
struct ieee80211_bss_conf bss_conf;
+ struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; /* rcu? */
uint8_t hw_queue[IEEE80211_NUM_ACS];
+ uint16_t active_links;
+ uint16_t valid_links;
+ struct ieee80211_vif *mbssid_tx_vif;
+
+/* #ifdef CONFIG_MAC80211_DEBUGFS */ /* Do not change structure depending on compile-time option. */
+ struct dentry *debugfs_dir;
+/* #endif */
/* Must stay last. */
uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
@@ -645,25 +853,29 @@ struct ieee80211_vif {
struct ieee80211_vif_chanctx_switch {
struct ieee80211_chanctx_conf *old_ctx, *new_ctx;
struct ieee80211_vif *vif;
+ struct ieee80211_bss_conf *link_conf;
};
struct ieee80211_prep_tx_info {
u16 duration;
bool success;
+ bool was_assoc;
+ int link_id;
};
/* XXX-BZ too big, over-reduce size to u8, and array sizes to minuimum to fit in skb->cb. */
/* Also warning: some sizes change by pointer size! This is 64bit only. */
struct ieee80211_tx_info {
- enum ieee80211_tx_info_flags flags;
+ enum ieee80211_tx_info_flags flags; /* 32 bits */
/* TODO FIXME */
- u8 band;
- u8 hw_queue;
- bool tx_time_est;
+ enum nl80211_band band; /* 3 bits */
+ uint16_t hw_queue:4, /* 4 bits */
+ tx_time_est:10; /* 10 bits */
union {
struct {
struct ieee80211_tx_rate rates[4];
bool use_rts;
+ uint8_t antennas:2;
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
enum ieee80211_tx_control_flags flags;
@@ -675,10 +887,10 @@ struct ieee80211_tx_info {
uint8_t ampdu_len;
uint8_t antenna;
uint16_t tx_time;
- bool is_valid_ack_signal;
+ uint8_t flags;
void *status_driver_data[16 / sizeof(void *)]; /* XXX TODO */
} status;
-#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE (5 * sizeof(void *)) /* XXX TODO 5? */
+#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE 40
void *driver_data[IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
};
};
@@ -717,11 +929,11 @@ enum ieee80211_iface_iter {
IEEE80211_IFACE_ITER_NORMAL = BIT(0),
IEEE80211_IFACE_ITER_RESUME_ALL = BIT(1),
IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER = BIT(2), /* seems to be an iter flag */
+ IEEE80211_IFACE_ITER_ACTIVE = BIT(3),
/* Internal flags only. */
- /* ieee80211_iterate_active_interfaces*(). */
IEEE80211_IFACE_ITER__ATOMIC = BIT(6),
- IEEE80211_IFACE_ITER__ACTIVE = BIT(7),
+ IEEE80211_IFACE_ITER__MTX = BIT(8),
};
enum set_key_cmd {
@@ -729,13 +941,15 @@ enum set_key_cmd {
DISABLE_KEY,
};
+/* 802.11-2020, 9.4.2.55.2 HT Capability Information field. */
enum rx_enc_flags {
RX_ENC_FLAG_SHORTPRE = BIT(0),
- RX_ENC_FLAG_SHORT_GI = BIT(1),
- RX_ENC_FLAG_HT_GF = BIT(2),
- RX_ENC_FLAG_LDPC = BIT(3),
- RX_ENC_FLAG_BF = BIT(4),
-#define RX_ENC_FLAG_STBC_SHIFT 6
+ RX_ENC_FLAG_SHORT_GI = BIT(2),
+ RX_ENC_FLAG_HT_GF = BIT(3),
+ RX_ENC_FLAG_STBC_MASK = BIT(4) | BIT(5),
+#define RX_ENC_FLAG_STBC_SHIFT 4
+ RX_ENC_FLAG_LDPC = BIT(6),
+ RX_ENC_FLAG_BF = BIT(7),
};
enum sta_notify_cmd {
@@ -743,14 +957,29 @@ enum sta_notify_cmd {
STA_NOTIFY_SLEEP,
};
+struct ieee80211_low_level_stats {
+ /* Can we make them uint64_t? */
+ uint32_t dot11ACKFailureCount;
+ uint32_t dot11FCSErrorCount;
+ uint32_t dot11RTSFailureCount;
+ uint32_t dot11RTSSuccessCount;
+};
+
+enum ieee80211_offload_flags {
+ IEEE80211_OFFLOAD_ENCAP_4ADDR,
+ IEEE80211_OFFLOAD_ENCAP_ENABLED,
+ IEEE80211_OFFLOAD_DECAP_ENABLED,
+};
+
struct ieee80211_ops {
/* TODO FIXME */
int (*start)(struct ieee80211_hw *);
- void (*stop)(struct ieee80211_hw *);
+ void (*stop)(struct ieee80211_hw *, bool);
int (*config)(struct ieee80211_hw *, u32);
void (*reconfig_complete)(struct ieee80211_hw *, enum ieee80211_reconfig_type);
+ void (*prep_add_interface)(struct ieee80211_hw *, enum nl80211_iftype);
int (*add_interface)(struct ieee80211_hw *, struct ieee80211_vif *);
void (*remove_interface)(struct ieee80211_hw *, struct ieee80211_vif *);
int (*change_interface)(struct ieee80211_hw *, struct ieee80211_vif *, enum nl80211_iftype, bool);
@@ -762,16 +991,17 @@ struct ieee80211_ops {
int (*hw_scan)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_scan_request *);
void (*cancel_hw_scan)(struct ieee80211_hw *, struct ieee80211_vif *);
- int (*conf_tx)(struct ieee80211_hw *, struct ieee80211_vif *, u16, const struct ieee80211_tx_queue_params *);
+ int (*conf_tx)(struct ieee80211_hw *, struct ieee80211_vif *, u32, u16, const struct ieee80211_tx_queue_params *);
void (*tx)(struct ieee80211_hw *, struct ieee80211_tx_control *, struct sk_buff *);
int (*tx_last_beacon)(struct ieee80211_hw *);
void (*wake_tx_queue)(struct ieee80211_hw *, struct ieee80211_txq *);
void (*mgd_prepare_tx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_prep_tx_info *);
void (*mgd_complete_tx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_prep_tx_info *);
- void (*mgd_protect_tdls_discover)(struct ieee80211_hw *, struct ieee80211_vif *);
+ void (*mgd_protect_tdls_discover)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int);
void (*flush)(struct ieee80211_hw *, struct ieee80211_vif *, u32, bool);
+ void (*flush_sta)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
int (*set_frag_threshold)(struct ieee80211_hw *, u32);
@@ -788,8 +1018,10 @@ struct ieee80211_ops {
int (*sta_state)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, enum ieee80211_sta_state, enum ieee80211_sta_state);
void (*sta_notify)(struct ieee80211_hw *, struct ieee80211_vif *, enum sta_notify_cmd, struct ieee80211_sta *);
void (*sta_rc_update)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u32);
+ void (*link_sta_rc_update)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_link_sta *, u32);
void (*sta_rate_tbl_update)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
void (*sta_set_4addr)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, bool);
+ void (*sta_set_decap_offload)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, bool);
u64 (*prepare_multicast)(struct ieee80211_hw *, struct netdev_hw_addr_list *);
@@ -798,9 +1030,10 @@ struct ieee80211_ops {
bool (*can_aggregate_in_amsdu)(struct ieee80211_hw *, struct sk_buff *, struct sk_buff *);
int (*pre_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
- int (*post_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *);
+ int (*post_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *);
void (*channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
- void (*abort_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *);
+ void (*channel_switch_beacon)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_chan_def *);
+ void (*abort_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *);
void (*channel_switch_rx_beacon)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
int (*tdls_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u8, struct cfg80211_chan_def *, struct sk_buff *, u32);
void (*tdls_cancel_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
@@ -809,8 +1042,8 @@ struct ieee80211_ops {
int (*add_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
void (*remove_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
void (*change_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, u32);
- int (*assign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_chanctx_conf *);
- void (*unassign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_chanctx_conf *);
+ int (*assign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
+ void (*unassign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
int (*switch_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif_chanctx_switch *, int, enum ieee80211_chanctx_switch_mode);
int (*get_antenna)(struct ieee80211_hw *, u32 *, u32 *);
@@ -822,40 +1055,80 @@ struct ieee80211_ops {
void (*configure_filter)(struct ieee80211_hw *, unsigned int, unsigned int *, u64);
void (*config_iface_filter)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int, unsigned int);
- void (*bss_info_changed)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u32);
+ void (*bss_info_changed)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u64);
+ void (*link_info_changed)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u64);
+
int (*set_rts_threshold)(struct ieee80211_hw *, u32);
void (*event_callback)(struct ieee80211_hw *, struct ieee80211_vif *, const struct ieee80211_event *);
int (*get_survey)(struct ieee80211_hw *, int, struct survey_info *);
int (*get_ftm_responder_stats)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_ftm_responder_stats *);
+
+ uint64_t (*get_tsf)(struct ieee80211_hw *, struct ieee80211_vif *);
+ void (*set_tsf)(struct ieee80211_hw *, struct ieee80211_vif *, uint64_t);
void (*offset_tsf)(struct ieee80211_hw *, struct ieee80211_vif *, s64);
+
int (*set_bitrate_mask)(struct ieee80211_hw *, struct ieee80211_vif *, const struct cfg80211_bitrate_mask *);
void (*set_coverage_class)(struct ieee80211_hw *, s16);
int (*set_tim)(struct ieee80211_hw *, struct ieee80211_sta *, bool);
int (*set_key)(struct ieee80211_hw *, enum set_key_cmd, struct ieee80211_vif *, struct ieee80211_sta *, struct ieee80211_key_conf *);
- void (*set_default_unicast_key)(struct ieee80211_hw *, struct ieee80211_vif *, int);
void (*update_tkip_key)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_key_conf *, struct ieee80211_sta *, u32, u16 *);
int (*start_pmsr)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_pmsr_request *);
void (*abort_pmsr)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_pmsr_request *);
- int (*start_ap)(struct ieee80211_hw *, struct ieee80211_vif *);
- void (*stop_ap)(struct ieee80211_hw *, struct ieee80211_vif *);
+ int (*start_ap)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *link_conf);
+ void (*stop_ap)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *link_conf);
int (*join_ibss)(struct ieee80211_hw *, struct ieee80211_vif *);
void (*leave_ibss)(struct ieee80211_hw *, struct ieee80211_vif *);
- int (*set_sar_specs)(struct ieee80211_hw *, const struct cfg80211_sar_specs *);
+ int (*set_sar_specs)(struct ieee80211_hw *, const struct cfg80211_sar_specs *);
- int (*set_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct cfg80211_tid_config *);
- int (*reset_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u8);
+ int (*set_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct cfg80211_tid_config *);
+ int (*reset_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u8);
- int (*get_et_sset_count)(struct ieee80211_hw *, struct ieee80211_vif *, int);
+ int (*get_et_sset_count)(struct ieee80211_hw *, struct ieee80211_vif *, int);
void (*get_et_stats)(struct ieee80211_hw *, struct ieee80211_vif *, struct ethtool_stats *, u64 *);
void (*get_et_strings)(struct ieee80211_hw *, struct ieee80211_vif *, u32, u8 *);
void (*update_vif_offload)(struct ieee80211_hw *, struct ieee80211_vif *);
-};
+ int (*get_txpower)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int, int *);
+ int (*get_stats)(struct ieee80211_hw *, struct ieee80211_low_level_stats *);
+
+ int (*set_radar_background)(struct ieee80211_hw *, struct cfg80211_chan_def *);
+
+ void (*add_twt_setup)(struct ieee80211_hw *, struct ieee80211_sta *, struct ieee80211_twt_setup *);
+ void (*twt_teardown_request)(struct ieee80211_hw *, struct ieee80211_sta *, u8);
+
+ int (*set_hw_timestamp)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_set_hw_timestamp *);
+
+ void (*vif_cfg_changed)(struct ieee80211_hw *, struct ieee80211_vif *, u64);
+
+ int (*change_vif_links)(struct ieee80211_hw *, struct ieee80211_vif *, u16, u16, struct ieee80211_bss_conf *[IEEE80211_MLD_MAX_NUM_LINKS]);
+ int (*change_sta_links)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u16, u16);
+ bool (*can_activate_links)(struct ieee80211_hw *, struct ieee80211_vif *, u16);
+ enum ieee80211_neg_ttlm_res (*can_neg_ttlm)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_neg_ttlm *);
+
+ void (*rfkill_poll)(struct ieee80211_hw *);
+
+/* #ifdef CONFIG_MAC80211_DEBUGFS */ /* Do not change depending on compile-time option. */
+ void (*sta_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct dentry *);
+ void (*vif_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *);
+ void (*link_sta_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_link_sta *, struct dentry *);
+ void (*link_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, struct dentry *);
+/* #endif */
+/* #ifdef CONFIG_PM_SLEEP */ /* Do not change depending on compile-time option. */
+ int (*suspend)(struct ieee80211_hw *, struct cfg80211_wowlan *);
+ int (*resume)(struct ieee80211_hw *);
+ void (*set_wakeup)(struct ieee80211_hw *, bool);
+ void (*set_rekey_data)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_gtk_rekey_data *);
+ void (*set_default_unicast_key)(struct ieee80211_hw *, struct ieee80211_vif *, int);
+/* #if IS_ENABLED(CONFIG_IPV6) */
+ void (*ipv6_addr_change)(struct ieee80211_hw *, struct ieee80211_vif *, struct inet6_dev *);
+/* #endif */
+/* #endif CONFIG_PM_SLEEP */
+};
/* -------------------------------------------------------------------------- */
@@ -865,10 +1138,12 @@ extern const struct cfg80211_ops linuxkpi_mac80211cfgops;
struct ieee80211_hw *linuxkpi_ieee80211_alloc_hw(size_t,
const struct ieee80211_ops *);
void linuxkpi_ieee80211_iffree(struct ieee80211_hw *);
-void linuxkpi_set_ieee80211_dev(struct ieee80211_hw *, char *);
+void linuxkpi_set_ieee80211_dev(struct ieee80211_hw *);
int linuxkpi_ieee80211_ifattach(struct ieee80211_hw *);
void linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *);
+void linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw *);
struct ieee80211_hw * linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *);
+void linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *);
void linuxkpi_ieee80211_iterate_interfaces(
struct ieee80211_hw *hw, enum ieee80211_iface_iter flags,
void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
@@ -877,7 +1152,7 @@ void linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *,
struct ieee80211_vif *,
void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
- void *);
+ void *, bool);
void linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *,
void(*iterfunc)(struct ieee80211_hw *,
struct ieee80211_chanctx_conf *, void *),
@@ -887,8 +1162,8 @@ void linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *,
void linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *,
struct cfg80211_scan_info *);
void linuxkpi_ieee80211_rx(struct ieee80211_hw *, struct sk_buff *,
- struct ieee80211_sta *, struct napi_struct *);
-uint8_t linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *);
+ struct ieee80211_sta *, struct napi_struct *, struct list_head *);
+uint8_t linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *, bool);
struct ieee80211_sta *linuxkpi_ieee80211_find_sta(struct ieee80211_vif *,
const u8 *);
struct ieee80211_sta *linuxkpi_ieee80211_find_sta_by_ifaddr(
@@ -905,15 +1180,27 @@ void linuxkpi_ieee80211_queue_work(struct ieee80211_hw *, struct work_struct *);
struct sk_buff *linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *,
struct ieee80211_vif *);
struct sk_buff *linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *,
- struct ieee80211_vif *, bool);
+ struct ieee80211_vif *, int, bool);
void linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *, unsigned long *,
unsigned long *);
struct wireless_dev *linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *);
void linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *);
void linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *);
struct sk_buff *linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *,
- uint8_t *, uint8_t *, size_t, size_t);
+ const uint8_t *, const uint8_t *, size_t, size_t);
void linuxkpi_ieee80211_tx_status(struct ieee80211_hw *, struct sk_buff *);
+void linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *,
+ struct ieee80211_tx_status *);
+void linuxkpi_ieee80211_stop_queues(struct ieee80211_hw *);
+void linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *);
+void linuxkpi_ieee80211_stop_queue(struct ieee80211_hw *, int);
+void linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *, int);
+void linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *, uint8_t);
+struct ieee80211_txq *linuxkpi_ieee80211_next_txq(struct ieee80211_hw *, uint8_t);
+void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *,
+ struct ieee80211_txq *, bool);
+void linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *,
+ struct ieee80211_txq *);
/* -------------------------------------------------------------------------- */
@@ -971,7 +1258,7 @@ SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev)
{
set_wiphy_dev(hw->wiphy, dev);
- linuxkpi_set_ieee80211_dev(hw, dev_name(dev));
+ linuxkpi_set_ieee80211_dev(hw);
IMPROVE();
}
@@ -998,14 +1285,11 @@ ieee80211_register_hw(struct ieee80211_hw *hw)
return (error);
}
-static __inline void
+static inline void
ieee80211_unregister_hw(struct ieee80211_hw *hw)
{
- wiphy_unregister(hw->wiphy);
- linuxkpi_ieee80211_ifdetach(hw);
-
- IMPROVE();
+ linuxkpi_ieee80211_unregister_hw(hw);
}
static __inline struct ieee80211_hw *
@@ -1015,321 +1299,164 @@ wiphy_to_ieee80211_hw(struct wiphy *wiphy)
return (linuxkpi_wiphy_to_ieee80211_hw(wiphy));
}
-/* -------------------------------------------------------------------------- */
-
-static __inline bool
-ieee80211_is_action(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_ACTION | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_is_probe_resp(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_RESP | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_is_auth(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_AUTH | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_is_assoc_req(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_is_assoc_resp(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_is_reassoc_req(__le16 fc)
+static inline void
+ieee80211_restart_hw(struct ieee80211_hw *hw)
{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
+ linuxkpi_ieee80211_restart_hw(hw);
}
-static __inline bool
-ieee80211_is_reassoc_resp(__le16 fc)
+static inline void
+ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif)
{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
+ TODO();
}
-static __inline bool
-ieee80211_is_disassoc(__le16 fc)
-{
- __le16 v;
+/* -------------------------------------------------------------------------- */
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_DISASSOC | IEEE80211_FC0_TYPE_MGT);
+#define link_conf_dereference_check(_vif, _linkid) \
+ rcu_dereference_check((_vif)->link_conf[_linkid], true)
- return (fc == v);
-}
+#define link_conf_dereference_protected(_vif, _linkid) \
+ rcu_dereference_protected((_vif)->link_conf[_linkid], true)
-static __inline bool
-ieee80211_is_data_present(__le16 fc)
-{
- __le16 v;
-
- /* If it is a data frame and NODATA is not present. */
- fc &= htole16(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_NODATA);
- v = htole16(IEEE80211_FC0_TYPE_DATA);
+#define link_sta_dereference_check(_sta, _linkid) \
+ rcu_dereference_check((_sta)->link[_linkid], true)
- return (fc == v);
-}
+#define link_sta_dereference_protected(_sta, _linkid) \
+ rcu_dereference_protected((_sta)->link[_linkid], true)
-static __inline bool
-ieee80211_is_deauth(__le16 fc)
-{
- __le16 v;
+#define for_each_vif_active_link(_vif, _link, _linkid) \
+ for (_linkid = 0; _linkid < nitems((_vif)->link_conf); _linkid++) \
+ if ( ((_vif)->active_links == 0 /* no MLO */ || \
+ ((_vif)->active_links & BIT(_linkid)) != 0) && \
+ (_link = rcu_dereference((_vif)->link_conf[_linkid])) )
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_DEAUTH | IEEE80211_FC0_TYPE_MGT);
+#define for_each_sta_active_link(_vif, _sta, _linksta, _linkid) \
+ for (_linkid = 0; _linkid < nitems((_sta)->link); _linkid++) \
+ if ( ((_vif)->active_links == 0 /* no MLO */ || \
+ ((_vif)->active_links & BIT(_linkid)) != 0) && \
+ (_linksta = link_sta_dereference_protected((_sta), (_linkid))) )
- return (fc == v);
-}
+/* -------------------------------------------------------------------------- */
static __inline bool
-ieee80211_is_beacon(__le16 fc)
+ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
{
- __le16 v;
-
- /*
- * For as much as I get it this comes in LE and unlike FreeBSD
- * where we get the entire frame header and u8[], here we get the
- * 9.2.4.1 Frame Control field only. Mask and compare.
- */
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_BEACON | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
+ TODO();
+ return (false);
}
-static __inline bool
-ieee80211_is_probe_req(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT);
-
- return (fc == v);
-}
-
-static __inline bool
-ieee80211_has_protected(__le16 fc)
-{
+/* -------------------------------------------------------------------------- */
+/* Receive functions (air/driver to mac80211/net80211). */
- return (fc & htole16(IEEE80211_FC1_PROTECTED << 8));
-}
-static __inline bool
-ieee80211_is_back_req(__le16 fc)
+static __inline void
+ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct napi_struct *napi)
{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_BAR | IEEE80211_FC0_TYPE_CTL);
- return (fc == v);
+ linuxkpi_ieee80211_rx(hw, skb, sta, napi, NULL);
}
-static __inline bool
-ieee80211_is_bufferable_mmpdu(__le16 fc)
+static __inline void
+ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct list_head *list)
{
- /* 11.2.2 Bufferable MMPDUs, 80211-2020. */
- /* XXX we do not care about IBSS yet. */
-
- if (!ieee80211_is_mgmt(fc))
- return (false);
- if (ieee80211_is_action(fc)) /* XXX FTM? */
- return (true);
- if (ieee80211_is_disassoc(fc))
- return (true);
- if (ieee80211_is_deauth(fc))
- return (true);
-
- return (false);
+ linuxkpi_ieee80211_rx(hw, skb, sta, NULL, list);
}
-static __inline bool
-ieee80211_is_nullfunc(__le16 fc)
+static __inline void
+ieee80211_rx_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- __le16 v;
-
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA);
- return (fc == v);
+ linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
}
-static __inline bool
-ieee80211_is_qos_nullfunc(__le16 fc)
+static __inline void
+ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- __le16 v;
- fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
- v = htole16(IEEE80211_FC0_SUBTYPE_QOS_NULL | IEEE80211_FC0_TYPE_DATA);
-
- return (fc == v);
+ linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
}
-static __inline bool
-ieee80211_is_any_nullfunc(__le16 fc)
+static __inline void
+ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
-}
-
-static __inline bool
-ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
-{
- TODO();
- return (false);
+ linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
}
-static __inline bool
-ieee80211_has_a4(__le16 fc)
-{
- __le16 v;
-
- fc &= htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
- v = htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
-
- return (fc == v);
-}
+/* -------------------------------------------------------------------------- */
-static __inline bool
-ieee80211_has_order(__le16 fc)
+static inline void
+ieee80211_stop_queues(struct ieee80211_hw *hw)
{
-
- return (fc & htole16(IEEE80211_FC1_ORDER << 8));
+ linuxkpi_ieee80211_stop_queues(hw);
}
-static __inline bool
-ieee80211_has_retry(__le16 fc)
+static inline void
+ieee80211_wake_queues(struct ieee80211_hw *hw)
{
-
- return (fc & htole16(IEEE80211_FC1_RETRY << 8));
+ linuxkpi_ieee80211_wake_queues(hw);
}
-
-static __inline bool
-ieee80211_has_fromds(__le16 fc)
+static inline void
+ieee80211_stop_queue(struct ieee80211_hw *hw, int qnum)
{
-
- return (fc & htole16(IEEE80211_FC1_DIR_FROMDS << 8));
+ linuxkpi_ieee80211_stop_queue(hw, qnum);
}
-static __inline bool
-ieee80211_has_tods(__le16 fc)
+static inline void
+ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
{
-
- return (fc & htole16(IEEE80211_FC1_DIR_TODS << 8));
+ linuxkpi_ieee80211_wake_queue(hw, qnum);
}
-static __inline uint8_t *
-ieee80211_get_SA(struct ieee80211_hdr *hdr)
+static inline void
+ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
-
- if (ieee80211_has_a4(hdr->frame_control))
- return (hdr->addr4);
- if (ieee80211_has_fromds(hdr->frame_control))
- return (hdr->addr3);
- return (hdr->addr2);
+ linuxkpi_ieee80211_schedule_txq(hw, txq, true);
}
-static __inline uint8_t *
-ieee80211_get_DA(struct ieee80211_hdr *hdr)
+static inline void
+ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
+ bool withoutpkts)
{
-
- if (ieee80211_has_tods(hdr->frame_control))
- return (hdr->addr3);
- return (hdr->addr1);
+ linuxkpi_ieee80211_schedule_txq(hw, txq, withoutpkts);
}
-static __inline bool
-ieee80211_has_morefrags(__le16 fc)
+static inline void
+ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint8_t ac)
{
-
- fc &= htole16(IEEE80211_FC1_MORE_FRAG << 8);
- return (fc != 0);
+ linuxkpi_ieee80211_txq_schedule_start(hw, ac);
}
-static __inline u8 *
-ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
+static inline void
+ieee80211_txq_schedule_end(struct ieee80211_hw *hw, uint8_t ac)
{
- if (ieee80211_has_a4(hdr->frame_control))
- return (u8 *)hdr + 30;
- else
- return (u8 *)hdr + 24;
+ /* DO_NADA; */
}
-/* -------------------------------------------------------------------------- */
-/* Receive functions (air/driver to mac80211/net80211). */
-
-
-static __inline void
-ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- struct sk_buff *skb, struct napi_struct *napi)
+static inline struct ieee80211_txq *
+ieee80211_next_txq(struct ieee80211_hw *hw, uint8_t ac)
{
-
- linuxkpi_ieee80211_rx(hw, skb, sta, napi);
+ return (linuxkpi_ieee80211_next_txq(hw, ac));
}
-static __inline void
-ieee80211_rx_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
+static inline void
+ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
{
-
- linuxkpi_ieee80211_rx(hw, skb, NULL, NULL);
+ linuxkpi_ieee80211_handle_wake_tx_queue(hw, txq);
}
-static __inline void
-ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
+static inline void
+ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+ struct sk_buff_head *skbs)
{
-
- linuxkpi_ieee80211_rx(hw, skb, NULL, NULL);
+ TODO();
}
/* -------------------------------------------------------------------------- */
@@ -1338,12 +1465,12 @@ static __inline uint8_t
ieee80211_get_tid(struct ieee80211_hdr *hdr)
{
- return (linuxkpi_ieee80211_get_tid(hdr));
+ return (linuxkpi_ieee80211_get_tid(hdr, false));
}
static __inline struct sk_buff *
ieee80211_beacon_get_tim(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- uint16_t *tim_offset, uint16_t *tim_len)
+ uint16_t *tim_offset, uint16_t *tim_len, uint32_t link_id)
{
if (tim_offset != NULL)
@@ -1362,7 +1489,7 @@ ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
{
flags |= IEEE80211_IFACE_ITER__ATOMIC;
- flags |= IEEE80211_IFACE_ITER__ACTIVE;
+ flags |= IEEE80211_IFACE_ITER_ACTIVE;
linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
}
@@ -1373,7 +1500,18 @@ ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
void *arg)
{
- flags |= IEEE80211_IFACE_ITER__ACTIVE;
+ flags |= IEEE80211_IFACE_ITER_ACTIVE;
+ linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
+}
+
+static __inline void
+ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw,
+ enum ieee80211_iface_iter flags,
+ void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
+ void *arg)
+{
+ flags |= IEEE80211_IFACE_ITER_ACTIVE;
+ flags |= IEEE80211_IFACE_ITER__MTX;
linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
}
@@ -1387,25 +1525,22 @@ ieee80211_iterate_interfaces(struct ieee80211_hw *hw,
linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
}
-static __inline void
+static inline void
ieee80211_iter_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
void *arg)
{
-
- linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg);
+ linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg, false);
}
-static __inline void
+static inline void
ieee80211_iter_keys_rcu(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
void *arg)
{
-
- IMPROVE(); /* "rcu" */
- linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg);
+ linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg, true);
}
static __inline void
@@ -1434,7 +1569,8 @@ ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
static __inline struct sk_buff *
ieee80211_beacon_get_template(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs)
+ struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs,
+ uint32_t link_id)
{
TODO();
return (NULL);
@@ -1447,7 +1583,7 @@ ieee80211_beacon_loss(struct ieee80211_vif *vif)
}
static __inline void
-ieee80211_chswitch_done(struct ieee80211_vif *vif, bool t)
+ieee80211_chswitch_done(struct ieee80211_vif *vif, bool t, uint32_t link_id)
{
TODO();
}
@@ -1473,12 +1609,12 @@ ieee80211_csa_update_counter(struct ieee80211_vif *vif)
}
static __inline void
-ieee80211_csa_finish(struct ieee80211_vif *vif)
+ieee80211_csa_finish(struct ieee80211_vif *vif, uint32_t link_id)
{
TODO();
}
-static __inline enum nl80211_iftype
+static inline enum nl80211_iftype
ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
{
@@ -1505,12 +1641,53 @@ ieee80211_tu_to_usec(unsigned long tu)
return (tu * IEEE80211_DUR_TU);
}
+/*
+ * Below we assume that the two values from different emums are the same.
+ * Make sure this does not accidentally change.
+ */
+CTASSERT((int)IEEE80211_ACTION_SM_TPCREP == (int)IEEE80211_ACTION_RADIO_MEASUREMENT_LMREP);
-static __inline int
+static __inline bool
ieee80211_action_contains_tpc(struct sk_buff *skb)
{
- TODO();
- return (0);
+ struct ieee80211_mgmt *mgmt;
+
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+
+ /* Check that this is a mgmt/action frame? */
+ if (!ieee80211_is_action(mgmt->frame_control))
+ return (false);
+
+ /*
+ * This is a bit convoluted but according to docs both actions
+ * are checked for this. Kind-of makes sense for the only consumer
+ * (iwlwifi) I am aware off given the txpower fields are at the
+ * same location so firmware can update the value.
+ */
+ /* 80211-2020 9.6.2 Spectrum Management Action frames */
+ /* 80211-2020 9.6.2.5 TPC Report frame format */
+ /* 80211-2020 9.6.6 Radio Measurement action details */
+ /* 80211-2020 9.6.6.4 Link Measurement Report frame format */
+ /* Check that it is Spectrum Management or Radio Measurement? */
+ if (mgmt->u.action.category != IEEE80211_ACTION_CAT_SM &&
+ mgmt->u.action.category != IEEE80211_ACTION_CAT_RADIO_MEASUREMENT)
+ return (false);
+
+ /*
+ * Check that it is TPC Report or Link Measurement Report?
+ * The values of each are the same (see CTASSERT above function).
+ */
+ if (mgmt->u.action.u.tpc_report.spec_mgmt != IEEE80211_ACTION_SM_TPCREP)
+ return (false);
+
+ /* 80211-2020 9.4.2.16 TPC Report element */
+ /* Check that the ELEMID and length are correct? */
+ if (mgmt->u.action.u.tpc_report.tpc_elem_id != IEEE80211_ELEMID_TPCREP ||
+ mgmt->u.action.u.tpc_report.tpc_elem_length != 4)
+ return (false);
+
+ /* All the right fields in the right place. */
+ return (true);
}
static __inline void
@@ -1535,21 +1712,6 @@ ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, const uint8_t *addr,
return (linuxkpi_ieee80211_find_sta_by_ifaddr(hw, addr, ourvifaddr));
}
-
-static __inline void
-ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
- struct sk_buff *skb_frag, u8 *key)
-{
- TODO();
-}
-
-static __inline void
-ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
- const u8 *addr, uint32_t iv32, u16 *p1k)
-{
- TODO();
-}
-
static __inline size_t
ieee80211_ie_split(const u8 *ies, size_t ies_len,
const u8 *ie_ids, size_t ie_ids_len, size_t start)
@@ -1574,10 +1736,23 @@ ieee80211_ie_split(const u8 *ies, size_t ies_len,
}
static __inline void
-ieee80211_request_smps(struct ieee80211_vif *vif, enum ieee80211_smps_mode smps)
+ieee80211_request_smps(struct ieee80211_vif *vif, u_int link_id,
+ enum ieee80211_smps_mode smps)
{
+ static const char *smps_mode_name[] = {
+ "SMPS_OFF",
+ "SMPS_STATIC",
+ "SMPS_DYNAMIC",
+ "SMPS_AUTOMATIC",
+ };
- TODO();
+ if (vif->type != NL80211_IFTYPE_STATION)
+ return;
+
+ if (smps >= nitems(smps_mode_name))
+ panic("%s: unsupported smps value: %d\n", __func__, smps);
+
+ IMPROVE("XXX LKPI80211 TODO smps %d %s\n", smps, smps_mode_name[smps]);
}
static __inline void
@@ -1589,18 +1764,6 @@ ieee80211_tdls_oper_request(struct ieee80211_vif *vif, uint8_t *addr,
}
static __inline void
-ieee80211_stop_queues(struct ieee80211_hw *hw)
-{
- TODO();
-}
-
-static __inline void
-ieee80211_wake_queues(struct ieee80211_hw *hw)
-{
- TODO();
-}
-
-static __inline void
wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool state)
{
TODO();
@@ -1620,12 +1783,6 @@ ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
}
static __inline void
-ieee80211_restart_hw(struct ieee80211_hw *hw)
-{
- TODO();
-}
-
-static __inline void
ieee80211_ready_on_channel(struct ieee80211_hw *hw)
{
TODO();
@@ -1645,127 +1802,268 @@ ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
TODO();
}
-static __inline void
-ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *sta, uint8_t tid,
- uint32_t ssn, uint64_t bitmap, uint16_t received_mpdu)
-{
- TODO();
-}
+/* -------------------------------------------------------------------------- */
-static __inline bool
+static inline bool
ieee80211_sn_less(uint16_t sn1, uint16_t sn2)
{
- TODO();
- return (false);
+ return (IEEE80211_SEQ_BA_BEFORE(sn1, sn2));
}
-static __inline uint16_t
+static inline uint16_t
ieee80211_sn_inc(uint16_t sn)
{
- TODO();
- return (sn + 1);
+ return (IEEE80211_SEQ_INC(sn));
}
-static __inline uint16_t
+static inline uint16_t
ieee80211_sn_add(uint16_t sn, uint16_t a)
{
- TODO();
- return (sn + a);
+ return (IEEE80211_SEQ_ADD(sn, a));
}
-static __inline void
-ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, uint32_t x, uint8_t *addr)
+static inline uint16_t
+ieee80211_sn_sub(uint16_t sa, uint16_t sb)
{
- TODO();
+ return (IEEE80211_SEQ_SUB(sa, sb));
}
static __inline void
-ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint32_t f1, uint32_t f2)
+ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *sta, uint8_t tid,
+ uint32_t ssn, uint64_t bitmap, uint16_t received_mpdu)
{
TODO();
}
static __inline void
-ieee80211_reserve_tid(struct ieee80211_sta *sta, uint8_t tid)
+ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, uint32_t x, uint8_t *addr)
{
TODO();
}
static __inline void
-ieee80211_unreserve_tid(struct ieee80211_sta *sta, uint8_t tid)
+ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif, uint8_t *addr,
+ uint8_t tid)
{
TODO();
}
static __inline void
-ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif, uint8_t *addr,
+ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
uint8_t tid)
{
TODO();
}
static __inline void
-ieee80211_send_eosp_nullfunc(struct ieee80211_sta *sta, uint8_t tid)
+ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
+ uint8_t tid)
{
TODO();
}
-static __inline uint16_t
-ieee80211_sn_sub(uint16_t sa, uint16_t sb)
+/* -------------------------------------------------------------------------- */
+
+static inline void
+ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint8_t mcs, uint8_t nss)
+{
+
+ /* XXX-BZ make it KASSERTS? */
+ if (((mcs & 0xF0) != 0) || (((nss - 1) & 0xf8) != 0)) {
+ printf("%s:%d: mcs %#04x nss %#04x invalid\n",
+ __func__, __LINE__, mcs, nss);
+ return;
+ }
+
+ r->idx = mcs;
+ r->idx |= ((nss - 1) << 4);
+}
+
+static inline uint8_t
+ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *r)
+{
+ return (((r->idx >> 4) & 0x07) + 1);
+}
+
+static inline uint8_t
+ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *r)
{
+ return (r->idx & 0x0f);
+}
+
+static inline int
+ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *vht_cap,
+ enum ieee80211_vht_chanwidth chanwidth, /* defined in net80211. */
+ int mcs /* always 0 */, bool ext_nss_bw_cap /* always true */, int max_nss)
+{
+ enum ieee80211_vht_mcs_support mcs_s;
+ uint32_t supp_cw, ext_nss_bw;
+
+ switch (mcs) {
+ case 0 ... 7:
+ mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_7;
+ break;
+ case 8:
+ mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_8;
+ break;
+ case 9:
+ mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_9;
+ break;
+ default:
+ printf("%s: unsupported mcs value %d\n", __func__, mcs);
+ return (0);
+ }
+
+ if (max_nss == 0) {
+ uint16_t map;
+
+ map = le16toh(vht_cap->supp_mcs.rx_mcs_map);
+ for (int i = 7; i >= 0; i--) {
+ uint8_t val;
+
+ val = (map >> (2 * i)) & 0x03;
+ if (val == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+ continue;
+ if (val >= mcs_s) {
+ max_nss = i + 1;
+ break;
+ }
+ }
+ }
+
+ if (max_nss == 0)
+ return (0);
- return ((sa - sb) &
- (IEEE80211_SEQ_SEQ_MASK >> IEEE80211_SEQ_SEQ_SHIFT));
+ if ((le16toh(vht_cap->supp_mcs.tx_mcs_map) &
+ IEEE80211_VHT_EXT_NSS_BW_CAPABLE) == 0)
+ return (max_nss);
+
+ supp_cw = le32_get_bits(vht_cap->vht_cap_info,
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
+ ext_nss_bw = le32_get_bits(vht_cap->vht_cap_info,
+ IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
+
+ /* If requested as ext nss not supported assume ext_nss_bw 0. */
+ if (!ext_nss_bw_cap)
+ ext_nss_bw = 0;
+
+ /*
+ * Cover 802.11-2016, Table 9-250.
+ */
+
+ /* Unsupported settings. */
+ if (supp_cw == 3)
+ return (0);
+ if (supp_cw == 2 && (ext_nss_bw == 1 || ext_nss_bw == 2))
+ return (0);
+
+ /* Settings with factor != 1 or unsupported. */
+ switch (chanwidth) {
+ case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
+ if (supp_cw == 0 && (ext_nss_bw == 0 || ext_nss_bw == 1))
+ return (0);
+ if (supp_cw == 1 && ext_nss_bw == 0)
+ return (0);
+ if ((supp_cw == 0 || supp_cw == 1) && ext_nss_bw == 2)
+ return (max_nss / 2);
+ if ((supp_cw == 0 || supp_cw == 1) && ext_nss_bw == 3)
+ return (3 * max_nss / 4);
+ break;
+ case IEEE80211_VHT_CHANWIDTH_160MHZ:
+ if (supp_cw == 0 && ext_nss_bw == 0)
+ return (0);
+ if (supp_cw == 0 && (ext_nss_bw == 1 || ext_nss_bw == 2))
+ return (max_nss / 2);
+ if (supp_cw == 0 && ext_nss_bw == 3)
+ return (3 * max_nss / 4);
+ if (supp_cw == 1 && ext_nss_bw == 3)
+ return (2 * max_nss);
+ break;
+ case IEEE80211_VHT_CHANWIDTH_80MHZ:
+ case IEEE80211_VHT_CHANWIDTH_USE_HT:
+ if ((supp_cw == 1 || supp_cw == 2) && ext_nss_bw == 3)
+ return (2 * max_nss);
+ break;
+ }
+
+ /* Everything else has a factor of 1. */
+ return (max_nss);
}
+
static __inline void
-ieee80211_sta_block_awake(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- bool disable)
+ieee80211_reserve_tid(struct ieee80211_sta *sta, uint8_t tid)
{
TODO();
}
static __inline void
-ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool sleeping)
+ieee80211_unreserve_tid(struct ieee80211_sta *sta, uint8_t tid)
{
TODO();
}
static __inline void
-ieee80211_sta_pspoll(struct ieee80211_sta *sta)
+ieee80211_send_eosp_nullfunc(struct ieee80211_sta *sta, uint8_t tid)
{
TODO();
}
static __inline void
-ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, int ntids)
+ieee80211_sta_block_awake(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ bool disable)
{
TODO();
}
static __inline void
-ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, uint8_t *addr,
- uint8_t tid)
+ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool sleeping)
{
TODO();
}
static __inline void
-ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf,
- uint64_t pn)
+ieee80211_sta_pspoll(struct ieee80211_sta *sta)
{
TODO();
}
-static __inline struct sk_buff *
+static inline void
+ieee80211_sta_recalc_aggregates(struct ieee80211_sta *sta)
+{
+ if (sta->valid_links) {
+ TODO();
+ }
+}
+
+static __inline void
+ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, int ntids)
+{
+ TODO();
+}
+
+static inline struct sk_buff *
ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
return (linuxkpi_ieee80211_tx_dequeue(hw, txq));
}
+static inline struct sk_buff *
+ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+{
+ struct sk_buff *skb;
+
+ local_bh_disable();
+ skb = linuxkpi_ieee80211_tx_dequeue(hw, txq);
+ local_bh_enable();
+
+ return (skb);
+}
+
static __inline void
-ieee80211_update_mu_groups(struct ieee80211_vif *vif, uint8_t *ms, uint8_t *up)
+ieee80211_update_mu_groups(struct ieee80211_vif *vif,
+ u_int _i, uint8_t *ms, uint8_t *up)
{
TODO();
}
@@ -1777,36 +2075,43 @@ ieee80211_sta_set_buffered(struct ieee80211_sta *sta, uint8_t tid, bool t)
}
static __inline void
-ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+ieee80211_sched_scan_results(struct ieee80211_hw *hw)
{
-
- linuxkpi_ieee80211_tx_status(hw, skb);
+ TODO();
}
static __inline void
-ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, uint8_t tid,
- struct ieee80211_key_seq *seq)
+ieee80211_sta_eosp(struct ieee80211_sta *sta)
{
TODO();
}
-static __inline void
-ieee80211_sched_scan_results(struct ieee80211_hw *hw)
+static __inline int
+ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid, int x)
{
- TODO();
+ TODO("rtw8x");
+ return (-EINVAL);
+}
+
+static __inline int
+ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid)
+{
+ TODO("rtw89");
+ return (-EINVAL);
}
static __inline void
-ieee80211_sta_eosp(struct ieee80211_sta *sta)
+ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, uint8_t *addr,
+ uint8_t tid)
{
- TODO();
+ TODO("iwlwifi");
}
static __inline void
ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, uint8_t *addr,
uint8_t tid)
{
- TODO();
+ TODO("iwlwifi/rtw8x/...");
}
static __inline void
@@ -1824,7 +2129,8 @@ ieee80211_scan_completed(struct ieee80211_hw *hw,
}
static __inline struct sk_buff *
-ieee80211_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ieee80211_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ uint32_t link_id)
{
TODO();
return (NULL);
@@ -1850,19 +2156,19 @@ ieee80211_proberesp_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
static __inline struct sk_buff *
ieee80211_nullfunc_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- bool qos)
+ int linkid, bool qos)
{
/* Only STA needs this. Otherwise return NULL and panic bad drivers. */
if (vif->type != NL80211_IFTYPE_STATION)
return (NULL);
- return (linuxkpi_ieee80211_nullfunc_get(hw, vif, qos));
+ return (linuxkpi_ieee80211_nullfunc_get(hw, vif, linkid, qos));
}
static __inline struct sk_buff *
-ieee80211_probereq_get(struct ieee80211_hw *hw, uint8_t *addr,
- uint8_t *ssid, size_t ssid_len, size_t tailroom)
+ieee80211_probereq_get(struct ieee80211_hw *hw, const uint8_t *addr,
+ const uint8_t *ssid, size_t ssid_len, size_t tailroom)
{
return (linuxkpi_ieee80211_probereq_get(hw, addr, ssid, ssid_len,
@@ -1884,14 +2190,23 @@ ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *w)
linuxkpi_ieee80211_queue_work(hw, w);
}
-static __inline void
-ieee80211_stop_queue(struct ieee80211_hw *hw, uint16_t q)
+static __inline bool
+ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct sk_buff *skb, enum nl80211_band band, struct ieee80211_sta **sta)
{
TODO();
+ return (false);
}
static __inline void
-ieee80211_wake_queue(struct ieee80211_hw *hw, uint16_t q)
+ieee80211_tx_status_skb(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ linuxkpi_ieee80211_tx_status(hw, skb);
+}
+
+static inline void
+ieee80211_tx_status_noskb(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_tx_info *info)
{
TODO();
}
@@ -1900,21 +2215,22 @@ static __inline void
ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
{
IMPROVE();
- ieee80211_tx_status(hw, skb);
+ linuxkpi_ieee80211_tx_status(hw, skb);
}
static __inline void
ieee80211_tx_status_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
{
IMPROVE();
- ieee80211_tx_status(hw, skb);
+ linuxkpi_ieee80211_tx_status(hw, skb);
}
-static __inline int
-ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid, int x)
+static __inline void
+ieee80211_tx_status_ext(struct ieee80211_hw *hw,
+ struct ieee80211_tx_status *txstat)
{
- TODO();
- return (-EINVAL);
+
+ linuxkpi_ieee80211_tx_status_ext(hw, txstat);
}
static __inline void
@@ -1948,15 +2264,6 @@ ieee80211_txq_get_depth(struct ieee80211_txq *txq, unsigned long *frame_cnt,
linuxkpi_ieee80211_txq_get_depth(txq, frame_cnt, byte_cnt);
}
-static __inline int
-rate_lowest_index(struct ieee80211_supported_band *band,
- struct ieee80211_sta *sta)
-{
- IMPROVE();
- return (0);
-}
-
-
static __inline void
SET_IEEE80211_PERM_ADDR (struct ieee80211_hw *hw, uint8_t *addr)
{
@@ -1964,158 +2271,422 @@ SET_IEEE80211_PERM_ADDR (struct ieee80211_hw *hw, uint8_t *addr)
ether_addr_copy(hw->wiphy->perm_addr, addr);
}
-static __inline uint8_t *
-ieee80211_bss_get_ie(struct cfg80211_bss *bss, uint32_t x)
+static __inline void
+ieee80211_report_low_ack(struct ieee80211_sta *sta, int x)
{
TODO();
- return (NULL);
}
static __inline void
-ieee80211_report_low_ack(struct ieee80211_sta *sta, int x)
+ieee80211_tx_rate_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_tx_info *info)
{
TODO();
}
-static __inline void
-ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
- uint8_t tid)
+static __inline bool
+ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
TODO();
+ return (false);
}
static __inline void
-ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
- uint8_t tid)
+ieee80211_radar_detected(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *chanctx_conf)
{
TODO();
}
-static __inline struct sk_buff *
-ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+static __inline void
+ieee80211_sta_register_airtime(struct ieee80211_sta *sta,
+ uint8_t tid, uint32_t duration, int x)
{
TODO();
- return (NULL);
}
static __inline void
-ieee80211_tx_rate_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- struct ieee80211_tx_info *info)
+ieee80211_beacon_set_cntdwn(struct ieee80211_vif *vif, u8 counter)
{
TODO();
}
-static __inline bool
-ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+static __inline int
+ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif, uint32_t link_id)
{
TODO();
- return (false);
+ return (-1);
}
-static __inline struct ieee80211_txq *
-ieee80211_next_txq(struct ieee80211_hw *hw, uint32_t ac)
+static __inline bool
+ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif, uint32_t link_id)
{
TODO();
- return (NULL);
+ return (true);
}
static __inline void
-ieee80211_radar_detected(struct ieee80211_hw *hw)
+ieee80211_disconnect(struct ieee80211_vif *vif, bool _x)
{
TODO();
}
static __inline void
-ieee80211_sta_register_airtime(struct ieee80211_sta *sta,
- uint8_t tid, uint32_t duration, int x)
+ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif)
{
TODO();
}
+static __inline uint32_t
+ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
+ struct ieee80211_rx_status *rxstat, int len)
+{
+ TODO();
+ return (0);
+}
static __inline void
-ieee80211_return_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq, bool _t)
+ieee80211_get_tx_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct ieee80211_tx_rate *txrate, int nrates)
{
TODO();
}
static __inline void
-ieee80211_txq_schedule_end(struct ieee80211_hw *hw, uint32_t ac)
+ieee80211_color_change_finish(struct ieee80211_vif *vif, uint8_t link_id)
{
TODO();
}
-static __inline void
-ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint32_t ac)
+static __inline struct sk_buff *
+ieee80211_get_fils_discovery_tmpl(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
TODO();
+ return (NULL);
}
-static __inline void
-ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+static __inline struct sk_buff *
+ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
TODO();
+ return (NULL);
}
static __inline void
-ieee80211_beacon_set_cntdwn(struct ieee80211_vif *vif, u8 counter)
+linuxkpi_ieee80211_send_bar(struct ieee80211_vif *vif, uint8_t *ra, uint16_t tid,
+ uint16_t ssn)
{
TODO();
}
+static __inline void
+ieee80211_resume_disconnect(struct ieee80211_vif *vif)
+{
+ TODO();
+}
+
static __inline int
-ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif)
+ieee80211_data_to_8023(struct sk_buff *skb, const uint8_t *addr,
+ enum nl80211_iftype iftype)
+{
+ TODO();
+ return (-1);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline void
+ieee80211_key_mic_failure(struct ieee80211_key_conf *key)
{
TODO();
- return (-1);
}
-static __inline int
-ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *vht_cap, uint32_t chanwidth,
- int x, bool t, int nss)
+static __inline void
+ieee80211_key_replay(struct ieee80211_key_conf *key)
{
TODO();
- return (-1);
}
-static __inline bool
-ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif)
+static __inline void
+ieee80211_remove_key(struct ieee80211_key_conf *key)
+{
+ TODO();
+}
+
+static __inline struct ieee80211_key_conf *
+ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *key, int link_id)
+{
+ TODO();
+ return (NULL);
+}
+
+static __inline void
+ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const uint8_t *bssid,
+ const uint8_t *replay_ctr, gfp_t gfp)
+{
+ TODO();
+}
+
+static __inline void
+ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf,
+ uint64_t pn)
{
TODO();
- return (true);
}
static __inline void
-ieee80211_disconnect(struct ieee80211_vif *vif, bool _x)
+ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
+ const u8 *addr, uint32_t iv32, u16 *p1k)
{
+
+ KASSERT(keyconf != NULL && addr != NULL && p1k != NULL,
+ ("%s: keyconf %p addr %p p1k %p\n", __func__, keyconf, addr, p1k));
+
TODO();
+ memset(p1k, 0xfa, 5 * sizeof(*p1k)); /* Just initializing. */
}
static __inline void
-ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool _x)
+ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *key,
+ uint32_t iv32, uint16_t *p1k)
+{
+ TODO();
+}
+
+static __inline void
+ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
+ struct sk_buff *skb_frag, u8 *key)
{
TODO();
}
-static __inline const struct ieee80211_sta_he_cap *
-ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *band,
- enum nl80211_iftype type)
+static inline void
+ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, int8_t tid,
+ struct ieee80211_key_seq *seq)
+{
+ const struct ieee80211_key *k;
+ const uint8_t *p;
+
+ KASSERT(keyconf != NULL && seq != NULL, ("%s: keyconf %p seq %p\n",
+ __func__, keyconf, seq));
+ k = keyconf->_k;
+ KASSERT(k != NULL, ("%s: keyconf %p ieee80211_key is NULL\n", __func__, keyconf));
+
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ if (tid < 0 || tid >= IEEE80211_NUM_TIDS)
+ return;
+ /* See net80211::tkip_decrypt() */
+ seq->tkip.iv32 = TKIP_PN_TO_IV32(k->wk_keyrsc[tid]);
+ seq->tkip.iv16 = TKIP_PN_TO_IV16(k->wk_keyrsc[tid]);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ if (tid < -1 || tid >= IEEE80211_NUM_TIDS)
+ return;
+ if (tid == -1)
+ p = (const uint8_t *)&k->wk_keyrsc[IEEE80211_NUM_TIDS]; /* IEEE80211_NONQOS_TID */
+ else
+ p = (const uint8_t *)&k->wk_keyrsc[tid];
+ memcpy(seq->ccmp.pn, p, sizeof(seq->ccmp.pn));
+ break;
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ if (tid < -1 || tid >= IEEE80211_NUM_TIDS)
+ return;
+ if (tid == -1)
+ p = (const uint8_t *)&k->wk_keyrsc[IEEE80211_NUM_TIDS]; /* IEEE80211_NONQOS_TID */
+ else
+ p = (const uint8_t *)&k->wk_keyrsc[tid];
+ memcpy(seq->gcmp.pn, p, sizeof(seq->gcmp.pn));
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ TODO();
+ memset(seq->aes_cmac.pn, 0xfa, sizeof(seq->aes_cmac.pn)); /* XXX TODO */
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ TODO();
+ memset(seq->aes_gmac.pn, 0xfa, sizeof(seq->aes_gmac.pn)); /* XXX TODO */
+ break;
+ default:
+ pr_debug("%s: unsupported cipher suite %d\n", __func__, keyconf->cipher);
+ break;
+ }
+}
+
+static __inline void
+ieee80211_set_key_rx_seq(struct ieee80211_key_conf *key, int tid,
+ struct ieee80211_key_seq *seq)
+{
+ TODO();
+}
+
+/* -------------------------------------------------------------------------- */
+
+static __inline void
+ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+ struct cfg80211_wowlan_wakeup *wakeup, gfp_t gfp)
+{
+ TODO();
+}
+
+static __inline void
+ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
+ uint64_t obss_color_bitmap, gfp_t gfp)
{
TODO();
- return (NULL);
}
static __inline void
-ieee80211_key_mic_failure(struct ieee80211_key_conf *key)
+ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta,
+ uint8_t tid)
+{
+ TODO();
+}
+
+static __inline struct ieee80211_ema_beacons *
+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, uint32_t link_id)
{
TODO();
+ return (NULL);
}
static __inline void
-ieee80211_key_replay(struct ieee80211_key_conf *key)
+ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *bcns)
+{
+ TODO();
+}
+
+static inline bool
+ieee80211_vif_is_mld(const struct ieee80211_vif *vif)
+{
+
+ /* If valid_links is non-zero, the vif is an MLD. */
+ return (vif->valid_links != 0);
+}
+
+static inline const struct ieee80211_sta_he_cap *
+ieee80211_get_he_iftype_cap_vif(const struct ieee80211_supported_band *band,
+ struct ieee80211_vif *vif)
+{
+ enum nl80211_iftype iftype;
+
+ iftype = ieee80211_vif_type_p2p(vif);
+ return (ieee80211_get_he_iftype_cap(band, iftype));
+}
+
+static inline const struct ieee80211_sta_eht_cap *
+ieee80211_get_eht_iftype_cap_vif(const struct ieee80211_supported_band *band,
+ struct ieee80211_vif *vif)
+{
+ enum nl80211_iftype iftype;
+
+ iftype = ieee80211_vif_type_p2p(vif);
+ return (ieee80211_get_eht_iftype_cap(band, iftype));
+}
+
+static inline uint32_t
+ieee80211_vif_usable_links(const struct ieee80211_vif *vif)
+{
+ IMPROVE("MLO usable links likely are not just valid");
+ return (vif->valid_links);
+}
+
+static inline bool
+ieee80211_vif_link_active(const struct ieee80211_vif *vif, uint8_t link_id)
+{
+ if (ieee80211_vif_is_mld(vif))
+ return (vif->active_links & BIT(link_id));
+ return (link_id == 0);
+}
+
+static inline void
+ieee80211_set_active_links_async(struct ieee80211_vif *vif,
+ uint32_t new_active_links)
{
TODO();
}
+static inline int
+ieee80211_set_active_links(struct ieee80211_vif *vif,
+ uint32_t active_links)
+{
+ TODO();
+ return (-ENXIO);
+}
+
+static inline void
+ieee80211_cqm_beacon_loss_notify(struct ieee80211_vif *vif, gfp_t gfp __unused)
+{
+ IMPROVE("we notify user space by a vap state change eventually");
+ linuxkpi_ieee80211_beacon_loss(vif);
+}
+
+#define ieee80211_send_bar(_v, _r, _t, _s) \
+ linuxkpi_ieee80211_send_bar(_v, _r, _t, _s)
+
+/* -------------------------------------------------------------------------- */
+
+int lkpi_80211_update_chandef(struct ieee80211_hw *,
+ struct ieee80211_chanctx_conf *);
+
+static inline int
+ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *chanctx_conf)
+{
+ int error;
+
+ hw->conf.radar_enabled = chanctx_conf->radar_enabled;
+ error = lkpi_80211_update_chandef(hw, chanctx_conf);
+ return (error);
+}
+
+static inline void
+ieee80211_emulate_remove_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *chanctx_conf __unused)
+{
+ hw->conf.radar_enabled = false;
+ lkpi_80211_update_chandef(hw, NULL);
+}
+
+static inline void
+ieee80211_emulate_change_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *chanctx_conf, uint32_t changed __unused)
+{
+ hw->conf.radar_enabled = chanctx_conf->radar_enabled;
+ lkpi_80211_update_chandef(hw, chanctx_conf);
+}
+
+static inline int
+ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif_chanctx_switch *vifs, int n_vifs,
+ enum ieee80211_chanctx_switch_mode mode __unused)
+{
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ int error;
+
+ /* Sanity check. */
+ if (n_vifs <= 0)
+ return (-EINVAL);
+ if (vifs == NULL || vifs[0].new_ctx == NULL)
+ return (-EINVAL);
+
+ /*
+ * What to do if n_vifs > 1?
+ * Does that make sense for drivers not supporting chanctx?
+ */
+ hw->conf.radar_enabled = vifs[0].new_ctx->radar_enabled;
+ chanctx_conf = vifs[0].new_ctx;
+ error = lkpi_80211_update_chandef(hw, chanctx_conf);
+ return (error);
+}
+
+/* -------------------------------------------------------------------------- */
+
#endif /* _LINUXKPI_NET_MAC80211_H */
diff --git a/sys/compat/linuxkpi/common/include/net/netevent.h b/sys/compat/linuxkpi/common/include/net/netevent.h
index 40df26705c7b..c1c39af3a772 100644
--- a/sys/compat/linuxkpi/common/include/net/netevent.h
+++ b/sys/compat/linuxkpi/common/include/net/netevent.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_NETEVENT_H_
#define _LINUXKPI_NET_NETEVENT_H_
diff --git a/sys/compat/linuxkpi/common/include/net/netlink.h b/sys/compat/linuxkpi/common/include/net/netlink.h
new file mode 100644
index 000000000000..ae250177d18b
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/netlink.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2020,2022 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_NET_NETLINK_H
+#define _LINUXKPI_NET_NETLINK_H
+
+#include <netlink/netlink.h>
+
+struct nla_policy {
+};
+
+struct netlink_callback {
+ int args[8];
+};
+
+static __inline int
+nla_put(struct sk_buff *skb, int attr, size_t len, void *data)
+{
+
+ pr_debug("%s: TODO -- now native?\n", __func__);
+ return (-ENXIO);
+}
+
+static __inline int
+nla_put_u16(struct sk_buff *skb, int attr, uint32_t val)
+{
+
+ return (nla_put(skb, attr, sizeof(uint32_t), &val));
+}
+
+#endif /* _LINUXKPI_NET_NETLINK_H */
diff --git a/sys/compat/linuxkpi/common/include/net/page_pool.h b/sys/compat/linuxkpi/common/include/net/page_pool.h
new file mode 100644
index 000000000000..2dc8f74b31f3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/page_pool.h
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 2023 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_NET_PAGE_POOL_H
+#define _LINUXKPI_NET_PAGE_POOL_H
+
+#include <linux/kernel.h> /* pr_debug */
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+
+struct device;
+
+struct page_pool_params {
+ struct device *dev;
+ uint32_t flags;
+ uint32_t order;
+ uint32_t pool_size;
+ uint32_t max_len;
+ uint32_t offset;
+ int nid; /* NUMA */
+ enum dma_data_direction dma_dir;
+ struct napi_struct *napi;
+};
+
+struct page_pool {
+};
+
+#define PP_FLAG_DMA_MAP BIT(0)
+#define PP_FLAG_DMA_SYNC_DEV BIT(1)
+#define PP_FLAG_PAGE_FRAG BIT(2)
+
+static inline struct page_pool *
+page_pool_create(const struct page_pool_params *ppparams)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline void
+page_pool_destroy(struct page_pool *ppool)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline struct page *
+page_pool_dev_alloc_frag(struct page_pool *ppool, uint32_t *offset,
+ size_t size)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline dma_addr_t
+page_pool_get_dma_addr(struct page *page)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static inline enum dma_data_direction
+page_pool_get_dma_dir(const struct page_pool *ppool)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (DMA_BIDIRECTIONAL);
+}
+
+static inline void
+page_pool_put_full_page(struct page_pool *ppool, struct page *page,
+ bool allow_direct)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline int
+page_pool_ethtool_stats_get_count(void)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static inline uint8_t *
+page_pool_ethtool_stats_get_strings(uint8_t *x)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (x);
+}
+
+#endif /* _LINUXKPI_NET_PAGE_POOL_H */
diff --git a/sys/compat/linuxkpi/common/include/net/regulatory.h b/sys/compat/linuxkpi/common/include/net/regulatory.h
index a7b31812e308..0a538f1531f9 100644
--- a/sys/compat/linuxkpi/common/include/net/regulatory.h
+++ b/sys/compat/linuxkpi/common/include/net/regulatory.h
@@ -25,13 +25,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_REGULATORY_H
#define _LINUXKPI_NET_REGULATORY_H
+enum environment_cap {
+ ENVIRON_INDOOR = 1, /* keep != 0 */
+};
+
#define REG_RULE(_begin, _end, _bw, _mag, _meirp, _flags) \
{ \
.flags = (_flags), \
diff --git a/sys/compat/linuxkpi/common/include/net/tcp.h b/sys/compat/linuxkpi/common/include/net/tcp.h
index f083cebd3505..4804a2b09b9d 100644
--- a/sys/compat/linuxkpi/common/include/net/tcp.h
+++ b/sys/compat/linuxkpi/common/include/net/tcp.h
@@ -25,8 +25,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _LINUXKPI_NET_TCP_H_
#define _LINUXKPI_NET_TCP_H_
diff --git a/sys/compat/linuxkpi/common/include/stdarg.h b/sys/compat/linuxkpi/common/include/stdarg.h
index b6141038d69a..698ac45e9198 100644
--- a/sys/compat/linuxkpi/common/include/stdarg.h
+++ b/sys/compat/linuxkpi/common/include/stdarg.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
*
@@ -28,6 +28,6 @@
#ifndef _LINUXKPI_STDARG_H_
#define _LINUXKPI_STDARG_H_
-#include <machine/stdarg.h>
+#include <sys/stdarg.h>
#endif /* _LINUXKPI_STDARG_H_ */
diff --git a/sys/compat/linuxkpi/common/include/video/cmdline.h b/sys/compat/linuxkpi/common/include/video/cmdline.h
new file mode 100644
index 000000000000..eaa9a998fda2
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/video/cmdline.h
@@ -0,0 +1,44 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _VIDEO_CMDLINE_H_
+#define _VIDEO_CMDLINE_H_
+
+#include <linux/types.h>
+
+#define CONFIG_VIDEO_CMDLINE
+
+#if defined(CONFIG_VIDEO_CMDLINE)
+const char *video_get_options(const char *name);
+#else
+static inline const char *
+video_get_options(const char *name)
+{
+ return (NULL);
+}
+#endif
+#endif /* _VIDEO_CMDLINE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/video/mipi_display.h b/sys/compat/linuxkpi/common/include/video/mipi_display.h
new file mode 100644
index 000000000000..ea079a57d39f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/video/mipi_display.h
@@ -0,0 +1,64 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_VIDEO_MIPI_DISPLAY_H_
+#define _LINUXKPI_VIDEO_MIPI_DISPLAY_H_
+
+#define MIPI_DSI_V_SYNC_START 0x01
+#define MIPI_DSI_V_SYNC_END 0x11
+#define MIPI_DSI_H_SYNC_START 0x21
+#define MIPI_DSI_H_SYNC_END 0x31
+#define MIPI_DSI_COMPRESSION_MODE 0x07
+#define MIPI_DSI_END_OF_TRANSMISSION 0x08
+#define MIPI_DSI_COLOR_MODE_OFF 0x02
+#define MIPI_DSI_COLOR_MODE_ON 0x12
+#define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22
+#define MIPI_DSI_TURN_ON_PERIPHERAL 0x32
+#define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03
+#define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13
+#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
+#define MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM 0x04
+#define MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM 0x14
+#define MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM 0x24
+#define MIPI_DSI_DCS_SHORT_WRITE 0x05
+#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
+#define MIPI_DSI_DCS_READ 0x06
+#define MIPI_DSI_EXECUTE_QUEUE 0x16
+#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
+#define MIPI_DSI_NULL_PACKET 0x09
+#define MIPI_DSI_BLANKING_PACKET 0x19
+#define MIPI_DSI_GENERIC_LONG_WRITE 0x29
+#define MIPI_DSI_DCS_LONG_WRITE 0x39
+#define MIPI_DSI_PICTURE_PARAMETER_SET 0x0a
+#define MIPI_DSI_COMPRESSED_PIXEL_STREAM 0x0b
+#define MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 0x0c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 0x1c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 0x2c
+#define MIPI_DSI_PACKED_PIXEL_STREAM_30 0x0d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_36 0x1d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 0x3d
+#define MIPI_DSI_PACKED_PIXEL_STREAM_16 0x0e
+#define MIPI_DSI_PACKED_PIXEL_STREAM_18 0x1e
+#define MIPI_DSI_PIXEL_STREAM_3BYTE_18 0x2e
+#define MIPI_DSI_PACKED_PIXEL_STREAM_24 0x3e
+
+#define MIPI_DCS_NOP 0x00
+#define MIPI_DCS_SOFT_RESET 0x01
+#define MIPI_DCS_GET_POWER_MODE 0x0a
+#define MIPI_DCS_GET_PIXEL_FORMAT 0x0c
+#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
+#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
+#define MIPI_DCS_SET_DISPLAY_OFF 0x28
+#define MIPI_DCS_SET_DISPLAY_ON 0x29
+#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2a
+#define MIPI_DCS_SET_PAGE_ADDRESS 0x2b
+#define MIPI_DCS_SET_TEAR_OFF 0x34
+#define MIPI_DCS_SET_TEAR_ON 0x35
+#define MIPI_DCS_SET_PIXEL_FORMAT 0x3a
+#define MIPI_DCS_SET_TEAR_SCANLINE 0x44
+#define MIPI_DCS_SET_DISPLAY_BRIGHTNESS 0x51
+#define MIPI_DCS_GET_DISPLAY_BRIGHTNESS 0x52
+#define MIPI_DCS_WRITE_CONTROL_DISPLAY 0x53
+#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54
+#define MIPI_DCS_WRITE_POWER_SAVE 0x55
+
+#endif /* _LINUXKPI_VIDEO_MIPI_DISPLAY_H_ */
diff --git a/sys/compat/linuxkpi/common/include/video/vga.h b/sys/compat/linuxkpi/common/include/video/vga.h
new file mode 100644
index 000000000000..a5012d9e2f3f
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/video/vga.h
@@ -0,0 +1,19 @@
+/* Public domain. */
+
+#ifndef _LINUXKPI_VIDEO_VGA_H
+#define _LINUXKPI_VIDEO_VGA_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+#define VGA_MIS_W 0x3c2
+#define VGA_SEQ_I 0x3c4
+#define VGA_SEQ_D 0x3c5
+#define VGA_MIS_R 0x3cc
+
+#define VGA_SR01_SCREEN_OFF (1 << 5)
+
+#define VGA_FB_PHYS_BASE 0xA0000
+#define VGA_FB_PHYS_SIZE 65536
+
+#endif
diff --git a/sys/compat/linuxkpi/common/include/xen/xen.h b/sys/compat/linuxkpi/common/include/xen/xen.h
new file mode 100644
index 000000000000..16e77724111d
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/xen/xen.h
@@ -0,0 +1,37 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Serenity Cyber Security, LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUXKPI_XEN_XEN_H_
+#define _LINUXKPI_XEN_XEN_H_
+
+#define xen_initial_domain() lkpi_xen_initial_domain()
+#define xen_pv_domain() lkpi_xen_pv_domain()
+
+bool lkpi_xen_initial_domain(void);
+bool lkpi_xen_pv_domain(void);
+
+#endif /* _LINUXKPI_XEN_XEN_H_ */