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.h76
-rw-r--r--sys/compat/linuxkpi/common/include/acpi/acpi_bus.h10
-rw-r--r--sys/compat/linuxkpi/common/include/asm/topology.h54
-rw-r--r--sys/compat/linuxkpi/common/include/linux/acpi_amd_wbrf.h97
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitops.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/completion.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/container_of.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/debugfs.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/devcoredump.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/dma-mapping.h64
-rw-r--r--sys/compat/linuxkpi/common/include/linux/etherdevice.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fs.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/gfp.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/highmem.h32
-rw-r--r--sys/compat/linuxkpi/common/include/linux/idr.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ieee80211.h44
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ioport.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/jiffies.h40
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kmod.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kobject.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ktime.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/leds.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/math64.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm.h82
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm_types.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mutex.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdev_features.h25
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdevice.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/nl80211.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/page-flags.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pagemap.h11
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pagevec.h68
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci.h98
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci_ids.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pm_runtime.h5
-rw-r--r--sys/compat/linuxkpi/common/include/linux/printk.h60
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ref_tracker.h93
-rw-r--r--sys/compat/linuxkpi/common/include/linux/refcount.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/scatterlist.h7
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h4
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seq_file.h29
-rw-r--r--sys/compat/linuxkpi/common/include/linux/shmem_fs.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/skbuff.h55
-rw-r--r--sys/compat/linuxkpi/common/include/linux/slab.h159
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/spinlock.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stdarg.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/stddef.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/swap.h14
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sysfs.h191
-rw-r--r--sys/compat/linuxkpi/common/include/linux/time.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/timer.h6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/topology.h35
-rw-r--r--sys/compat/linuxkpi/common/include/linux/types.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/wait.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/workqueue.h10
-rw-r--r--sys/compat/linuxkpi/common/include/net/cfg80211.h380
-rw-r--r--sys/compat/linuxkpi/common/include/net/mac80211.h239
-rw-r--r--sys/compat/linuxkpi/common/include/stdarg.h2
60 files changed, 1530 insertions, 643 deletions
diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi.h b/sys/compat/linuxkpi/common/include/acpi/acpi.h
index e0218bdde12e..016c7ede0f6e 100644
--- a/sys/compat/linuxkpi/common/include/acpi/acpi.h
+++ b/sys/compat/linuxkpi/common/include/acpi/acpi.h
@@ -3,6 +3,10 @@
*
* 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
@@ -31,6 +35,13 @@
#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.
*/
@@ -46,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;
@@ -55,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 *
@@ -83,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
@@ -101,4 +162,9 @@ 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 65bcbe7f1bdd..da50d25a63bb 100644
--- a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
+++ b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
@@ -45,9 +45,9 @@ struct acpi_bus_event {
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);
@@ -58,4 +58,10 @@ bool lkpi_acpi_dev_present(const char *hid, const char *uid,
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/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/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/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h
index 23aabb546cb2..00dd1f9a1ec0 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitops.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitops.h
@@ -62,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)
diff --git a/sys/compat/linuxkpi/common/include/linux/completion.h b/sys/compat/linuxkpi/common/include/linux/completion.h
index 26e41a51c10b..9f8bebb4cf82 100644
--- a/sys/compat/linuxkpi/common/include/linux/completion.h
+++ b/sys/compat/linuxkpi/common/include/linux/completion.h
@@ -60,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
index 449507fcf9c1..7210d531b055 100644
--- a/sys/compat/linuxkpi/common/include/linux/container_of.h
+++ b/sys/compat/linuxkpi/common/include/linux/container_of.h
@@ -41,6 +41,14 @@
(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/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h
index 54145b61503e..4d146e085a7b 100644
--- a/sys/compat/linuxkpi/common/include/linux/debugfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h
@@ -115,6 +115,8 @@ 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);
diff --git a/sys/compat/linuxkpi/common/include/linux/devcoredump.h b/sys/compat/linuxkpi/common/include/linux/devcoredump.h
index b58c490615ad..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.
@@ -71,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 a5f6874a07f6..2556b0c45e49 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -90,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 {
diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
index 84f0361de765..2d8e1196d3d3 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
@@ -96,13 +96,17 @@ void *linux_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
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);
-void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size);
+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);
@@ -173,16 +177,17 @@ dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr)
{
- linux_dma_unmap(dev, dma_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, 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 */
@@ -197,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, page_to_phys(page) + offset, size));
+ return (lkpi_dma_map_phys(dev, page_to_phys(page) + offset, size,
+ direction, 0));
}
static inline void
@@ -205,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
@@ -263,28 +283,33 @@ 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)
@@ -306,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
diff --git a/sys/compat/linuxkpi/common/include/linux/etherdevice.h b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
index 5d3df744ae0e..1f2d6cf22d7e 100644
--- a/sys/compat/linuxkpi/common/include/linux/etherdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
@@ -58,9 +58,15 @@ is_zero_ether_addr(const u8 * addr)
}
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
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
index 76a81e676744..f1568ad6282d 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -150,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);
diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h
index 35dbe3e2a436..7a32e7862338 100644
--- a/sys/compat/linuxkpi/common/include/linux/gfp.h
+++ b/sys/compat/linuxkpi/common/include/linux/gfp.h
@@ -34,6 +34,7 @@
#include <sys/malloc.h>
#include <linux/page.h>
+#include <linux/topology.h>
#include <vm/vm_param.h>
#include <vm/vm_object.h>
@@ -134,6 +135,8 @@ 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:
*/
diff --git a/sys/compat/linuxkpi/common/include/linux/highmem.h b/sys/compat/linuxkpi/common/include/linux/highmem.h
index b8874481f9c6..58a9cdcdf60f 100644
--- a/sys/compat/linuxkpi/common/include/linux/highmem.h
+++ b/sys/compat/linuxkpi/common/include/linux/highmem.h
@@ -79,9 +79,7 @@ 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));
@@ -139,4 +137,34 @@ 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/idr.h b/sys/compat/linuxkpi/common/include/linux/idr.h
index 535d8ce07fb4..06850c94a5e9 100644
--- a/sys/compat/linuxkpi/common/include/linux/idr.h
+++ b/sys/compat/linuxkpi/common/include/linux/idr.h
@@ -147,6 +147,13 @@ 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 efac2a26e27e..b9161c586d07 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -35,6 +35,7 @@
#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
+#include <linux/bitfield.h>
#include <linux/if_ether.h>
/* linux_80211.c */
@@ -121,7 +122,20 @@ enum ieee80211_rate_control_changed_flags {
/* 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
@@ -133,9 +147,9 @@ 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
@@ -295,6 +309,7 @@ enum ieee80211_ac_numbers {
#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
@@ -303,7 +318,7 @@ struct ieee80211_mcs_info {
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 {
@@ -313,7 +328,7 @@ struct ieee80211_ht_cap {
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
@@ -349,6 +364,7 @@ enum ieee80211_chanctx_change_flags {
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 {
@@ -426,6 +442,7 @@ enum ieee80211_tx_control_flags {
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. */
};
@@ -783,6 +800,20 @@ struct ieee80211_bss_load_elem {
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)
@@ -1225,5 +1256,4 @@ ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
return (u8 *)hdr + 24;
}
-
#endif /* _LINUXKPI_LINUX_IEEE80211_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/ioport.h b/sys/compat/linuxkpi/common/include/linux/ioport.h
index 444f3ad94602..763af2de7c4f 100644
--- a/sys/compat/linuxkpi/common/include/linux/ioport.h
+++ b/sys/compat/linuxkpi/common/include/linux/ioport.h
@@ -40,6 +40,7 @@
struct resource {
resource_size_t start;
resource_size_t end;
+ const char *name;
};
static inline resource_size_t
diff --git a/sys/compat/linuxkpi/common/include/linux/jiffies.h b/sys/compat/linuxkpi/common/include/linux/jiffies.h
index f099caa1ce18..c2409726e874 100644
--- a/sys/compat/linuxkpi/common/include/linux/jiffies.h
+++ b/sys/compat/linuxkpi/common/include/linux/jiffies.h
@@ -32,21 +32,21 @@
#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
+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))
@@ -68,7 +68,7 @@ extern uint64_t lkpi_msec2hz_rem;
extern uint64_t lkpi_msec2hz_div;
extern uint64_t lkpi_msec2hz_max;
-static inline int
+static inline unsigned long
msecs_to_jiffies(uint64_t msec)
{
uint64_t result;
@@ -79,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;
@@ -93,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
@@ -120,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/kmod.h b/sys/compat/linuxkpi/common/include/linux/kmod.h
index b3cbe2ed2e02..8f9f034aabd8 100644
--- a/sys/compat/linuxkpi/common/include/linux/kmod.h
+++ b/sys/compat/linuxkpi/common/include/linux/kmod.h
@@ -33,7 +33,7 @@
#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(...) \
diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h
index 512f47f9e4b4..98f55d1234c4 100644
--- a/sys/compat/linuxkpi/common/include/linux/kobject.h
+++ b/sys/compat/linuxkpi/common/include/linux/kobject.h
@@ -29,7 +29,7 @@
#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>
diff --git a/sys/compat/linuxkpi/common/include/linux/ktime.h b/sys/compat/linuxkpi/common/include/linux/ktime.h
index 53c2abd64fc6..6a2f04f3d789 100644
--- a/sys/compat/linuxkpi/common/include/linux/ktime.h
+++ b/sys/compat/linuxkpi/common/include/linux/ktime.h
@@ -232,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)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/leds.h b/sys/compat/linuxkpi/common/include/linux/leds.h
index f7ee7a68dcf5..89f7286f6800 100644
--- a/sys/compat/linuxkpi/common/include/linux/leds.h
+++ b/sys/compat/linuxkpi/common/include/linux/leds.h
@@ -27,7 +27,7 @@
#define _LINUXKPI_LINUX_LEDS_H
enum led_brightness {
- __DUMMY,
+ LED_OFF,
};
struct led_classdev {
@@ -35,6 +35,7 @@ struct led_classdev {
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/math64.h b/sys/compat/linuxkpi/common/include/linux/math64.h
index cae5e30b08df..a216d350570f 100644
--- a/sys/compat/linuxkpi/common/include/linux/math64.h
+++ b/sys/compat/linuxkpi/common/include/linux/math64.h
@@ -61,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)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h
index b4c8bf3c1c30..156b00a0c0f0 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm.h
@@ -161,6 +161,14 @@ 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.
@@ -184,7 +192,7 @@ get_order(unsigned long size)
*
* NOTE: This function only works for pages allocated by the kernel.
*/
-void *linux_page_address(struct page *);
+void *linux_page_address(const struct page *);
#define page_address(page) linux_page_address(page)
static inline void *
@@ -275,6 +283,38 @@ 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
lkpi_get_user_pages(unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **);
@@ -331,12 +371,6 @@ pin_user_pages_remote(struct task_struct *task, struct mm_struct *mm,
task, mm, start, nr_pages, gup_flags, pages, vmas);
}
-static inline void
-put_page(struct page *page)
-{
- vm_page_unwire(page, PQ_ACTIVE);
-}
-
#define unpin_user_page(page) put_page(page)
#define unpin_user_pages(pages, npages) release_pages(pages, npages)
@@ -372,14 +406,14 @@ vmalloc_to_page(const void *addr)
static inline int
trylock_page(struct page *page)
{
- return (vm_page_trylock(page));
+ return (vm_page_tryxbusy(page));
}
static inline void
unlock_page(struct page *page)
{
- vm_page_unlock(page);
+ vm_page_xunbusy(page);
}
extern int is_vmalloc_addr(const void *addr);
@@ -412,4 +446,34 @@ 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 c08e2511725b..3ea68e97004c 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm_types.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm_types.h
@@ -79,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/mutex.h b/sys/compat/linuxkpi/common/include/linux/mutex.h
index 1d85ba20baca..6fb6a7744a89 100644
--- a/sys/compat/linuxkpi/common/include/linux/mutex.h
+++ b/sys/compat/linuxkpi/common/include/linux/mutex.h
@@ -35,6 +35,7 @@
#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/netdev_features.h b/sys/compat/linuxkpi/common/include/linux/netdev_features.h
index 06e88d107708..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.
@@ -33,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 cd7d23077a62..3b808a4a1749 100644
--- a/sys/compat/linuxkpi/common/include/linux/netdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h
@@ -4,7 +4,7 @@
* 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-2025 The FreeBSD Foundation
* Copyright (c) 2020-2022 Bjoern A. Zeeb
*
* Portions of this software were developed by Björn Zeeb
@@ -302,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)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index b2a33a28b3a7..f3979d3a2abc 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -190,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 {
@@ -436,6 +434,9 @@ 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
diff --git a/sys/compat/linuxkpi/common/include/linux/page-flags.h b/sys/compat/linuxkpi/common/include/linux/page-flags.h
index 9dd49c8492a5..a22b3a24c330 100644
--- a/sys/compat/linuxkpi/common/include/linux/page-flags.h
+++ b/sys/compat/linuxkpi/common/include/linux/page-flags.h
@@ -29,6 +29,13 @@
#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/pagemap.h b/sys/compat/linuxkpi/common/include/linux/pagemap.h
index 7244b61257dc..cb6a1820ea8b 100644
--- a/sys/compat/linuxkpi/common/include/linux/pagemap.h
+++ b/sys/compat/linuxkpi/common/include/linux/pagemap.h
@@ -33,6 +33,8 @@
#include <linux/highmem.h>
#include <linux/vmalloc.h>
+struct folio_batch;
+
#define invalidate_mapping_pages(...) \
linux_invalidate_mapping_pages(__VA_ARGS__)
@@ -40,15 +42,6 @@ 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)
-{
- int i;
-
- for (i = 0; i < nr; i++)
- put_page(pages[i]);
-}
-
-static inline void
mapping_clear_unevictable(vm_object_t mapping)
{
}
diff --git a/sys/compat/linuxkpi/common/include/linux/pagevec.h b/sys/compat/linuxkpi/common/include/linux/pagevec.h
index 9ba8ff8effa0..0a952e965b5a 100644
--- a/sys/compat/linuxkpi/common/include/linux/pagevec.h
+++ b/sys/compat/linuxkpi/common/include/linux/pagevec.h
@@ -66,4 +66,72 @@ 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 afd6c827b3b4..3fd4191b9917 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-2022 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.
@@ -72,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) \
\
@@ -85,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
@@ -220,11 +223,11 @@ 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
@@ -359,9 +362,9 @@ 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 *pdev, int mmio_bar,
- unsigned long mmio_off, unsigned long mmio_size);
-void *linuxkpi_pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size);
+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_pci_iounmap(struct pci_dev *pdev, void *res);
int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask,
const char *name);
@@ -374,13 +377,15 @@ int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries,
/* Internal helper function(s). */
struct pci_dev *lkpinew_pci_dev(device_t);
void lkpi_pci_devres_release(struct device *, void *);
-struct pci_dev *lkpi_pci_get_device(uint16_t, uint16_t, struct pci_dev *);
+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__)
+ 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)
@@ -523,7 +528,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);
@@ -543,10 +561,12 @@ done:
return (pdev->bus->self);
}
-#define pci_release_region(pdev, bar) linuxkpi_pci_release_region(pdev, bar)
-#define pci_release_regions(pdev) linuxkpi_pci_release_regions(pdev)
-#define pci_request_regions(pdev, res_name) \
- linuxkpi_pci_request_regions(pdev, res_name)
+#define pci_release_region(pdev, bar) \
+ linuxkpi_pci_release_region(pdev, bar)
+#define pci_release_regions(pdev) \
+ linuxkpi_pci_release_regions(pdev)
+#define pci_request_regions(pdev, res_name) \
+ linuxkpi_pci_request_regions(pdev, res_name)
static inline void
lkpi_pci_disable_msix(struct pci_dev *pdev)
@@ -712,8 +732,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)
+#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
@@ -722,10 +744,11 @@ void linux_pci_unregister_drm_driver(struct pci_driver *pdrv);
* NB: define added to prevent this definition of pci_enable_msix from
* clashing with the native FreeBSD version.
*/
-#define pci_enable_msix(...) linuxkpi_pci_enable_msix(__VA_ARGS__)
+#define pci_enable_msix(...) \
+ linuxkpi_pci_enable_msix(__VA_ARGS__)
-#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,
@@ -750,8 +773,8 @@ 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)
@@ -776,11 +799,12 @@ static inline void pci_disable_sriov(struct pci_dev *dev)
{
}
-#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 pci_iounmap(pdev, res) linuxkpi_pci_iounmap(pdev, res)
+#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 pci_iounmap(pdev, res) \
+ linuxkpi_pci_iounmap(pdev, res)
static inline void
lkpi_pci_save_state(struct pci_dev *pdev)
@@ -1369,10 +1393,12 @@ struct pci_dev *lkpi_pci_get_base_class(unsigned int class,
/* -------------------------------------------------------------------------- */
-#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)
+#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)
@@ -1413,7 +1439,7 @@ err:
* using pci_get_device() need to be changed to call linuxkpi_pci_get_device().
*/
static inline struct pci_dev *
-linuxkpi_pci_get_device(uint16_t vendor, uint16_t device, struct pci_dev *odev)
+linuxkpi_pci_get_device(uint32_t vendor, uint32_t device, struct pci_dev *odev)
{
return (lkpi_pci_get_device(vendor, device, odev));
diff --git a/sys/compat/linuxkpi/common/include/linux/pci_ids.h b/sys/compat/linuxkpi/common/include/linux/pci_ids.h
index 2f02d6ad1c14..e318f6f75ce7 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci_ids.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci_ids.h
@@ -46,6 +46,7 @@
#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
diff --git a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
index 616dd508e562..6114b7b159d7 100644
--- a/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
+++ b/sys/compat/linuxkpi/common/include/linux/pm_runtime.h
@@ -34,8 +34,13 @@ 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;
}
diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h
index 3840a6e5fb8a..d2d197682782 100644
--- a/sys/compat/linuxkpi/common/include/linux/printk.h
+++ b/sys/compat/linuxkpi/common/include/linux/printk.h
@@ -44,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
@@ -132,4 +94,10 @@ print_hex_dump_bytes(const char *prefix_str, const int prefix_type,
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/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 02a7eda3f4a9..46e501a65396 100644
--- a/sys/compat/linuxkpi/common/include/linux/refcount.h
+++ b/sys/compat/linuxkpi/common/include/linux/refcount.h
@@ -30,6 +30,7 @@
#define _LINUXKPI_LINUX_REFCOUNT_H
#include <linux/atomic.h>
+#include <linux/spinlock.h>
typedef atomic_t refcount_t;
diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
index 51ced19e6b5b..537f5bebc5aa 100644
--- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -674,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 80354493f955..3ad2f8e4ce8b 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -53,7 +53,7 @@
#include <asm/atomic.h>
-#define MAX_SCHEDULE_TIMEOUT INT_MAX
+#define MAX_SCHEDULE_TIMEOUT LONG_MAX
#define TASK_RUNNING 0x0000
#define TASK_INTERRUPTIBLE 0x0001
@@ -160,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/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h
index d8b327f59538..47da16ab8688 100644
--- a/sys/compat/linuxkpi/common/include/linux/seq_file.h
+++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h
@@ -28,9 +28,13 @@
#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 <linux/string_helpers.h>
+#include <linux/printk.h>
#undef file
#define inode vnode
@@ -51,6 +55,21 @@ static const struct file_operations __name ## _fops = { \
.release = single_release, \
}
+#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;
size_t size;
@@ -89,6 +108,16 @@ 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__)
+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
#endif /* _LINUXKPI_LINUX_SEQ_FILE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
index efa2c855fe7d..5e91725d4a1c 100644
--- a/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/shmem_fs.h
@@ -54,4 +54,14 @@ void linux_shmem_truncate_range(vm_object_t obj, loff_t lstart,
#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/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index 9db29c72e20c..c8ad90281e34 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -154,38 +154,46 @@ struct sk_buff {
};
struct list_head list;
};
- uint32_t _alloc_len; /* Length of alloc data-buf. XXX-BZ give up for truesize? */
+
+ 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? */
+ union {
+ __wsum csum;
+ struct {
+ uint16_t csum_offset;
+ uint16_t csum_start;
+ };
+ };
+ uint16_t protocol;
+ uint8_t ip_summed;
+ /* 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 skb_shared_info *shinfo __aligned(CACHE_LINE_SIZE);
+
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 _flags; /* Internal flags. */
#define _SKB_FLAGS_SKBEXTFRAG 0x0001
- enum sk_buff_pkt_type pkt_type;
+ 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;
- /* "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? */
- 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. */
-
- struct skb_shared_info *shinfo;
-
/* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
void *m;
void(*m_free_func)(void *);
@@ -993,6 +1001,13 @@ 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)
{
@@ -1038,7 +1053,7 @@ skb_orphan(struct sk_buff *skb)
SKB_TODO();
}
-static inline __sum16
+static inline __wsum
csum_unfold(__sum16 sum)
{
return (sum);
diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h
index 07c16884b00e..47e3d133eb6c 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
@@ -41,13 +45,12 @@
MALLOC_DECLARE(M_KMALLOC);
-#define kmalloc(size, flags) lkpi_kmalloc(size, flags)
-#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)
@@ -85,15 +88,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)
-extern void *lkpi_kmalloc(size_t size, gfp_t flags);
-void *lkpi___kmalloc(size_t size, gfp_t flags);
-#define __kmalloc(_s, _f) lkpi___kmalloc(_s, _f)
+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)
@@ -110,103 +120,122 @@ linux_check_m_flags(gfp_t flags)
return (flags & GFP_NATIVE_MASK);
}
+/*
+ * Base functions with a native implementation.
+ */
static inline void *
-kmalloc_node(size_t size, gfp_t flags, int node)
+kmalloc(size_t size, gfp_t flags)
{
- return (malloc_domainset(size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
+ return (lkpi_kmalloc(size, flags));
}
static inline void *
-kcalloc(size_t n, size_t size, gfp_t flags)
+__kmalloc(size_t size, gfp_t flags)
{
- flags |= __GFP_ZERO;
- return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
+ return (lkpi___kmalloc(size, flags));
}
static inline void *
-kcalloc_node(size_t n, size_t size, gfp_t flags, int node)
+kmalloc_node(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 (lkpi___kmalloc_node(size, flags, node));
}
static inline void *
-__vmalloc(size_t size, gfp_t flags, int other)
+krealloc(void *ptr, size_t size, gfp_t flags)
{
- return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
+ return (lkpi_krealloc(ptr, size, flags));
}
-static inline void *
-__vmalloc_node(size_t size, gfp_t flags, int node)
+static inline void
+kfree(const void *ptr)
{
- return (malloc_domainset(size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
+ lkpi_kfree(ptr);
}
+/*
+ * Other k*alloc() funtions using the above as underlying allocator.
+ */
+/* kmalloc */
static inline void *
-vmalloc_32(size_t size)
+kmalloc_array(size_t n, size_t size, gfp_t flags)
{
- return (contigmalloc(size, M_KMALLOC, M_WAITOK, 0, UINT_MAX, 1, 1));
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
+
+ return (kmalloc(size * n, flags));
}
static inline void *
-kmalloc_array(size_t n, size_t size, gfp_t flags)
+kcalloc(size_t n, size_t size, gfp_t flags)
{
- return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
+ flags |= __GFP_ZERO;
+ 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)
{
- return (mallocarray_domainset(n, size, M_KMALLOC,
- linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
-}
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
-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)));
+ return (kmalloc_node(size * n, flags, node));
}
static inline void *
-krealloc(void *ptr, size_t size, gfp_t flags)
+kcalloc_node(size_t n, size_t size, gfp_t flags, int node)
{
- return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags)));
+ flags |= __GFP_ZERO;
+ 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)) {
+ if (WOULD_OVERFLOW(n, size))
return NULL;
- }
- return (realloc(ptr, n * size, M_KMALLOC, linux_check_m_flags(flags)));
+ return (krealloc(ptr, n * size, flags));
+}
+
+/*
+ * vmalloc/kvalloc functions.
+ */
+static inline void *
+__vmalloc(size_t size, gfp_t flags, int other)
+{
+ return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
}
-extern void linux_kfree_async(void *);
+static inline void *
+__vmalloc_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)));
+}
-static inline void
-kfree(const void *ptr)
+static inline void *
+vmalloc_32(size_t size)
{
- if (ZERO_OR_NULL_PTR(ptr))
- return;
+ return (contigmalloc(size, M_KMALLOC, M_WAITOK, 0, UINT_MAX, 1, 1));
+}
- if (curthread->td_critnest != 0)
- linux_kfree_async(__DECONST(void *, ptr));
- else
- free(__DECONST(void *, ptr), M_KMALLOC);
+/* May return non-contiguous memory. */
+static inline void *
+kvmalloc(size_t size, gfp_t flags)
+{
+ return (lkpi_kvmalloc(size, flags));
}
-static __inline void
-kfree_sensitive(const void *ptr)
+static inline void *
+kvmalloc_array(size_t n, size_t size, gfp_t flags)
{
- if (ZERO_OR_NULL_PTR(ptr))
- return;
+ if (WOULD_OVERFLOW(n, size))
+ panic("%s: %zu * %zu overflowed", __func__, n, size);
- zfree(__DECONST(void *, ptr), M_KMALLOC);
+ return (kvmalloc(size * n, flags));
}
static inline void *
@@ -226,6 +255,19 @@ kvrealloc(const void *ptr, size_t oldsize, size_t newsize, gfp_t flags)
return (newptr);
}
+/*
+ * Misc.
+ */
+
+static __inline void
+kfree_sensitive(const void *ptr)
+{
+ if (ZERO_OR_NULL_PTR(ptr))
+ return;
+
+ zfree(__DECONST(void *, ptr), M_KMALLOC);
+}
+
static inline size_t
ksize(const void *ptr)
{
@@ -240,11 +282,4 @@ kmalloc_size_roundup(size_t size)
return (malloc_size(size));
}
-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 *);
-
#endif /* _LINUXKPI_LINUX_SLAB_H_ */
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
index 74038f0e7520..903053e7f6e8 100644
--- a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
+++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
@@ -43,6 +43,7 @@ struct mtk_wed_device {
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)
diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h
index 2992e41c9c02..dc10b0457153 100644
--- a/sys/compat/linuxkpi/common/include/linux/spinlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h
@@ -154,6 +154,14 @@ typedef struct mtx spinlock_t;
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) \
_atomic_dec_and_lock_irqsave(cnt, lock, &(flags))
static inline int
diff --git a/sys/compat/linuxkpi/common/include/linux/stdarg.h b/sys/compat/linuxkpi/common/include/linux/stdarg.h
index ab2fdf7534e5..698ac45e9198 100644
--- a/sys/compat/linuxkpi/common/include/linux/stdarg.h
+++ b/sys/compat/linuxkpi/common/include/linux/stdarg.h
@@ -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/linux/stddef.h b/sys/compat/linuxkpi/common/include/linux/stddef.h
index a3bc6b13765e..d04a5a4bf516 100644
--- a/sys/compat/linuxkpi/common/include/linux/stddef.h
+++ b/sys/compat/linuxkpi/common/include/linux/stddef.h
@@ -5,11 +5,27 @@
#include <sys/stddef.h>
-#define struct_group(NAME, ...) \
+/*
+ * 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 { __VA_ARGS__ }; \
- struct { __VA_ARGS__ } NAME; \
- }
+ struct { _members } _attrs; \
+ struct _tag { _members } _attrs _name; \
+ } _attrs
+#endif
-#endif /* _LINUXKPI_LINUX_STDDEF_H_ */
+#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/swap.h b/sys/compat/linuxkpi/common/include/linux/swap.h
index a353d353cd33..5828db7ae392 100644
--- a/sys/compat/linuxkpi/common/include/linux/swap.h
+++ b/sys/compat/linuxkpi/common/include/linux/swap.h
@@ -37,6 +37,9 @@
#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)
{
@@ -54,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 b5ad73e4460b..470c224a9778 100644
--- a/sys/compat/linuxkpi/common/include/linux/sysfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h
@@ -50,6 +50,15 @@ 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, \
@@ -72,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:
@@ -147,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)
{
@@ -155,6 +241,93 @@ 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)
@@ -348,6 +521,24 @@ sysfs_emit_at(char *buf, int at, const char *fmt, ...)
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/time.h b/sys/compat/linuxkpi/common/include/linux/time.h
index 6c9a781d5e0e..ca77a20516ff 100644
--- a/sys/compat/linuxkpi/common/include/linux/time.h
+++ b/sys/compat/linuxkpi/common/include/linux/time.h
@@ -42,6 +42,8 @@
#include <linux/math64.h>
+typedef int64_t time64_t;
+
static inline struct timeval
ns_to_timeval(const int64_t nsec)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/timer.h b/sys/compat/linuxkpi/common/include/linux/timer.h
index 8bea082c3e6c..a635f0faea59 100644
--- a/sys/compat/linuxkpi/common/include/linux/timer.h
+++ b/sys/compat/linuxkpi/common/include/linux/timer.h
@@ -42,7 +42,7 @@ struct timer_list {
void (*function_415) (struct timer_list *);
};
unsigned long data;
- int expires;
+ unsigned long expires;
};
extern unsigned long linux_timer_hz_mask;
@@ -76,7 +76,7 @@ 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 *);
@@ -86,7 +86,7 @@ extern int timer_shutdown_sync(struct timer_list *);
#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/types.h b/sys/compat/linuxkpi/common/include/linux/types.h
index b11ce1cdd805..fcc455e5f731 100644
--- a/sys/compat/linuxkpi/common/include/linux/types.h
+++ b/sys/compat/linuxkpi/common/include/linux/types.h
@@ -63,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;
diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h
index 309c7816aa7b..03ddce2c06f5 100644
--- a/sys/compat/linuxkpi/common/include/linux/wait.h
+++ b/sys/compat/linuxkpi/common/include/linux/wait.h
@@ -61,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 {
@@ -87,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 = { \
@@ -138,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 *);
/*
@@ -148,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); \
@@ -166,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; \
@@ -284,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/workqueue.h b/sys/compat/linuxkpi/common/include/linux/workqueue.h
index 1c9df9fcb74d..66d3981d4229 100644
--- a/sys/compat/linuxkpi/common/include/linux/workqueue.h
+++ b/sys/compat/linuxkpi/common/include/linux/workqueue.h
@@ -90,7 +90,7 @@ struct delayed_work {
struct {
struct callout callout;
struct mtx mtx;
- int expires;
+ unsigned long expires;
} timer;
};
@@ -245,7 +245,7 @@ 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 *);
@@ -258,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/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index 2cdb96ffccdf..239b4a5ae7b8 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -36,6 +36,7 @@
#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>
@@ -44,6 +45,8 @@
#include <linux/workqueue.h>
#include <net/regulatory.h>
+#include <net80211/ieee80211.h>
+
/* linux_80211.c */
extern int linuxkpi_debug_80211;
#ifndef D80211_TODO
@@ -54,8 +57,8 @@ extern int linuxkpi_debug_80211;
#endif
#define TODO(fmt, ...) if (linuxkpi_debug_80211 & D80211_TODO) \
printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
-#define IMPROVE(...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \
- printf("%s:%d: XXX LKPI80211 IMPROVE\n", __func__, __LINE__)
+#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),
@@ -125,19 +128,24 @@ 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;
- int orig_mpwr;
+ 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 {
@@ -640,174 +648,6 @@ 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_CAP0_TWT_RES 0x4
-
-#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_CAP1_TF_MAC_PAD_DUR_MASK 0x8
-
-#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_CAP2_MU_CASCADING 0x40
-#define IEEE80211_HE_MAC_CAP2_TRS 0x80
-
-#define IEEE80211_HE_MAC_CAP3_OMI_CONTROL 0x02
-#define IEEE80211_HE_MAC_CAP3_OFDMA_RA 0x04
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18
-#define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40
-#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_CAP4_BSRP_BQRP_A_MPDU_AGG 0x20
-
-#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_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x20
-#define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING 0x40
-#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x80
-
-#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_6GHZ_CAP_SM_PS 0x20
-
-#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_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G 0x10
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G 0x20
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK 0x40
-#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL 0xff
-
-#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_CAP2_UL_MU_PARTIAL_MU_MIMO 0x20
-#define IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO 0x40
-
-#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_CAP3_DCM_MAX_CONST_RX_QPSK 0x80
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK 0x80
-#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 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_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4 0x20
-#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK 0x40
-#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK 0x80
-
-#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_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK 0x20
-
-#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_CAP6_TRIG_CQI_FB 0x80
-#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 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_CAP7_STBC_TX_ABOVE_80MHZ 0x40
-#define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x80
-
-#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_242 0x8
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484 0x10
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996 0x18
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996 0x20
-#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_MASK 0x28
-#define IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI 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_HE_OPERATION_BSS_COLOR_DISABLED 0x1
-#define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET 0x2
-#define IEEE80211_HE_OPERATION_ER_SU_DISABLE 0x4
-
-#define IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED 0x01
-#define IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED 0x02
-#define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT 0x04
-#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT 0x08
-
#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
@@ -888,33 +728,19 @@ struct linuxkpi_ieee80211_regdomain {
#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 {
@@ -931,11 +757,6 @@ struct ieee80211_he_obss_pd {
uint8_t partial_bssid_bitmap[8];
};
-struct ieee80211_sta_he_6ghz_capa {
- /* TODO FIXME */
- int capa;
-};
-
struct ieee80211_eht_mcs_nss_supp_20mhz_only {
union {
struct {
@@ -989,7 +810,7 @@ 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;
@@ -1182,6 +1003,18 @@ enum cfg80211_regulatory {
REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(6),
};
+struct wiphy_radio_freq_range {
+ uint32_t start_freq;
+ uint32_t end_freq;
+};
+
+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),
@@ -1246,6 +1079,9 @@ struct wiphy {
uint8_t available_antennas_rx;
uint8_t available_antennas_tx;
+ int n_radio;
+ const struct wiphy_radio *radio;
+
int features, hw_version;
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;
@@ -1259,6 +1095,7 @@ struct wiphy {
unsigned long ext_features[BITS_TO_LONGS(NUM_NL80211_EXT_FEATURES)];
struct dentry *debugfsdir;
+
const struct wiphy_wowlan_support *wowlan;
struct cfg80211_wowlan *wowlan_config;
/* Lower layer (driver/mac80211) specific data. */
@@ -1271,8 +1108,9 @@ struct wiphy {
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;
};
@@ -1394,20 +1232,11 @@ wiphy_dev(struct wiphy *wiphy)
return (wiphy->dev);
}
-#define wiphy_dereference(wiphy, p) \
- rcu_dereference_check(p, lockdep_is_held(&(wiphy)->mtx))
+#define wiphy_dereference(_w, p) \
+ rcu_dereference_check(p, lockdep_is_held(&(_w)->mtx))
-static __inline void
-wiphy_lock(struct wiphy *wiphy)
-{
- mutex_lock(&wiphy->mtx);
-}
-
-static __inline void
-wiphy_unlock(struct wiphy *wiphy)
-{
- mutex_unlock(&wiphy->mtx);
-}
+#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,
@@ -1458,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 *
@@ -1530,6 +1370,43 @@ cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
};
}
+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)
@@ -1994,7 +1871,7 @@ cfg80211_channel_is_psc(struct linuxkpi_ieee80211_channel *channel)
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;
@@ -2065,27 +1942,6 @@ cfg80211_find_ext_ie(uint8_t eid, const uint8_t *p, size_t len)
return (NULL);
}
-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 void
_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *band,
struct ieee80211_sband_iftype_data *iftype_data, size_t nitems)
@@ -2177,6 +2033,14 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype iftype)
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)
{
@@ -2207,6 +2071,28 @@ nl80211_chan_width_to_mhz(enum nl80211_chan_width width)
}
}
+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
@@ -2259,9 +2145,9 @@ wiphy_delayed_work_cancel(struct wiphy *wiphy, struct wiphy_delayed_work *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__)
+ dev_info((wiphy)->dev, fmt, ##__VA_ARGS__)
#define wiphy_info_once(wiphy, fmt, ...) \
- dev_info_once(&(wiphy)->dev, fmt, ##__VA_ARGS__)
+ dev_info_once((wiphy)->dev, fmt, ##__VA_ARGS__)
#ifndef LINUXKPI_NET80211
#define ieee80211_channel linuxkpi_ieee80211_channel
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 9830d8f16d05..0106e6648bd4 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-2025 The FreeBSD Foundation
- * Copyright (c) 2020-2022 Bjoern A. Zeeb
+ * Copyright (c) 2020-2025 Bjoern A. Zeeb
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -41,6 +41,7 @@
#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>
@@ -86,6 +87,9 @@ enum mcast_filter_flags {
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 {
@@ -208,19 +212,6 @@ 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_p2p_noa_attr {
- uint8_t index;
- uint8_t oppps_ctwindow;
- struct ieee80211_p2p_noa_desc desc[4];
-};
-
struct ieee80211_mutable_offsets {
/* TODO FIXME */
uint16_t tim_offset;
@@ -334,6 +325,7 @@ struct ieee80211_bss_conf {
uint8_t dtim_period;
uint8_t sync_dtim_count;
+ uint8_t bss_param_ch_cnt_link_id;
bool qos;
bool twt_broadcast;
bool use_cts_prot;
@@ -343,6 +335,7 @@ struct ieee80211_bss_conf {
bool eht_support;
bool csa_active;
bool mu_mimo_owner;
+ bool color_change_active;
uint32_t sync_device_ts;
uint64_t sync_tsf;
uint16_t beacon_int;
@@ -363,7 +356,6 @@ struct ieee80211_bss_conf {
int twt_requester, uora_exists, uora_ocw_range;
int assoc_capability, enable_beacon, hidden_ssid, ibss_joined, twt_protected;
int twt_responder, unsol_bcast_probe_resp_interval;
- int color_change_active;
};
struct ieee80211_channel_switch {
@@ -373,18 +365,6 @@ struct ieee80211_channel_switch {
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,
@@ -436,11 +416,6 @@ 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;
@@ -496,6 +471,7 @@ enum ieee80211_hw_flags {
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
@@ -508,8 +484,6 @@ struct ieee80211_hw {
/* TODO FIXME */
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. */
@@ -555,6 +529,11 @@ enum ieee802111_key_flag {
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 */
@@ -728,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 {
@@ -754,7 +734,7 @@ struct ieee80211_link_sta {
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;
@@ -772,6 +752,7 @@ struct ieee80211_sta {
uint8_t addr[ETH_ALEN];
uint16_t aid;
bool wme;
+ bool mlo;
uint8_t max_sp;
uint8_t uapsd_queues;
uint16_t valid_links;
@@ -823,6 +804,7 @@ enum ieee80211_vif_driver_flags {
#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
@@ -845,15 +827,13 @@ struct ieee80211_vif_cfg {
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_vif_cfg cfg;
- struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_txq *txq;
struct ieee80211_bss_conf bss_conf;
struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; /* rcu? */
@@ -999,6 +979,7 @@ struct ieee80211_ops {
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);
@@ -1037,6 +1018,7 @@ 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);
@@ -1111,7 +1093,7 @@ struct ieee80211_ops {
void (*update_vif_offload)(struct ieee80211_hw *, struct ieee80211_vif *);
- int (*get_txpower)(struct ieee80211_hw *, struct ieee80211_vif *, int *);
+ 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 *);
@@ -1128,6 +1110,8 @@ struct ieee80211_ops {
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 *);
@@ -1154,7 +1138,7 @@ 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 *);
@@ -1203,7 +1187,7 @@ 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 *);
@@ -1274,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();
}
@@ -1468,6 +1452,13 @@ ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
linuxkpi_ieee80211_handle_wake_tx_queue(hw, txq);
}
+static inline void
+ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+ struct sk_buff_head *skbs)
+{
+ TODO();
+}
+
/* -------------------------------------------------------------------------- */
static __inline uint8_t
@@ -1721,26 +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)
-{
-
- 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 size_t
ieee80211_ie_split(const u8 *ies, size_t ies_len,
const u8 *ie_ids, size_t ie_ids_len, size_t start)
@@ -1773,12 +1744,15 @@ ieee80211_request_smps(struct ieee80211_vif *vif, u_int link_id,
"SMPS_STATIC",
"SMPS_DYNAMIC",
"SMPS_AUTOMATIC",
- "SMPS_NUM_MODES"
};
- if (linuxkpi_debug_80211 & D80211_TODO)
- printf("%s:%d: XXX LKPI80211 TODO smps %d %s\n",
- __func__, __LINE__, smps, smps_mode_name[smps]);
+ 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
@@ -1906,13 +1880,13 @@ ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint8_t mcs, uint8_t nss)
}
static inline uint8_t
-ieee80211_rate_get_vht_nss(struct ieee80211_tx_rate *r)
+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(struct ieee80211_tx_rate *r)
+ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *r)
{
return (r->idx & 0x0f);
}
@@ -2068,13 +2042,6 @@ ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, int ntids)
TODO();
}
-static __inline void
-ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf,
- uint64_t pn)
-{
- TODO();
-}
-
static inline struct sk_buff *
ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
@@ -2200,8 +2167,8 @@ ieee80211_nullfunc_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
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,
@@ -2223,12 +2190,27 @@ ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *w)
linuxkpi_ieee80211_queue_work(hw, w);
}
+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_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();
+}
+
static __inline void
ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
{
@@ -2310,7 +2292,8 @@ ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
}
static __inline void
-ieee80211_radar_detected(struct ieee80211_hw *hw)
+ieee80211_radar_detected(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *chanctx_conf)
{
TODO();
}
@@ -2349,19 +2332,7 @@ ieee80211_disconnect(struct ieee80211_vif *vif, bool _x)
}
static __inline void
-ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool _x)
-{
- TODO();
-}
-
-static __inline void
-ieee80211_key_mic_failure(struct ieee80211_key_conf *key)
-{
- TODO();
-}
-
-static __inline void
-ieee80211_key_replay(struct ieee80211_key_conf *key)
+ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif)
{
TODO();
}
@@ -2382,7 +2353,7 @@ ieee80211_get_tx_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
}
static __inline void
-ieee80211_color_change_finish(struct ieee80211_vif *vif)
+ieee80211_color_change_finish(struct ieee80211_vif *vif, uint8_t link_id)
{
TODO();
}
@@ -2424,9 +2395,22 @@ ieee80211_data_to_8023(struct sk_buff *skb, const uint8_t *addr,
return (-1);
}
+/* -------------------------------------------------------------------------- */
+
static __inline void
-ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *key,
- uint32_t iv32, uint16_t *p1k)
+ieee80211_key_mic_failure(struct ieee80211_key_conf *key)
+{
+ TODO();
+}
+
+static __inline void
+ieee80211_key_replay(struct ieee80211_key_conf *key)
+{
+ TODO();
+}
+
+static __inline void
+ieee80211_remove_key(struct ieee80211_key_conf *key)
{
TODO();
}
@@ -2447,11 +2431,38 @@ ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const uint8_t *bssid,
}
static __inline void
-ieee80211_remove_key(struct ieee80211_key_conf *key)
+ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf,
+ uint64_t pn)
+{
+ TODO();
+}
+
+static __inline void
+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_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 void
ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, int8_t tid,
struct ieee80211_key_seq *seq)
@@ -2461,28 +2472,46 @@ ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, int8_t tid,
KASSERT(keyconf != NULL && seq != NULL, ("%s: keyconf %p seq %p\n",
__func__, keyconf, seq));
- KASSERT(tid <= IEEE80211_NUM_TIDS, ("%s: tid out of bounds %d\n",
- __func__, tid));
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 < 0)
+ 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_TKIP:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
TODO();
- seq->tkip.iv32 = 0xfa; /* XXX TODO */
- seq->tkip.iv16 = 0xfa; /* XXX 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);
@@ -2497,6 +2526,8 @@ ieee80211_set_key_rx_seq(struct ieee80211_key_conf *key, int tid,
TODO();
}
+/* -------------------------------------------------------------------------- */
+
static __inline void
ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
struct cfg80211_wowlan_wakeup *wakeup, gfp_t gfp)
diff --git a/sys/compat/linuxkpi/common/include/stdarg.h b/sys/compat/linuxkpi/common/include/stdarg.h
index ab2fdf7534e5..698ac45e9198 100644
--- a/sys/compat/linuxkpi/common/include/stdarg.h
+++ b/sys/compat/linuxkpi/common/include/stdarg.h
@@ -28,6 +28,6 @@
#ifndef _LINUXKPI_STDARG_H_
#define _LINUXKPI_STDARG_H_
-#include <machine/stdarg.h>
+#include <sys/stdarg.h>
#endif /* _LINUXKPI_STDARG_H_ */