diff options
Diffstat (limited to 'sys/compat/linuxkpi/common/include')
28 files changed, 567 insertions, 99 deletions
diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi.h b/sys/compat/linuxkpi/common/include/acpi/acpi.h index 1e398d05ba20..9bb435591daa 100644 --- a/sys/compat/linuxkpi/common/include/acpi/acpi.h +++ b/sys/compat/linuxkpi/common/include/acpi/acpi.h @@ -37,7 +37,7 @@ /* * 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_verison + * Once that happened and checks are implemented based on __FreeBSD_version * we will remove these conditions again. */ @@ -131,7 +131,7 @@ acpi_format_exception(ACPI_STATUS Exception) } static inline ACPI_STATUS -acpi_get_handle(ACPI_HANDLE Parent, ACPI_STRING Pathname, +acpi_get_handle(ACPI_HANDLE Parent, const char *Pathname, ACPI_HANDLE *RetHandle) { return (AcpiGetHandle(Parent, Pathname, RetHandle)); 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/kunit/static_stub.h b/sys/compat/linuxkpi/common/include/kunit/static_stub.h new file mode 100644 index 000000000000..9d425d46dbb0 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/kunit/static_stub.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 The FreeBSD Foundation + * + * This software was developed by Björn Zeeb under sponsorship from + * the FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _LINUXKPI_KUNIT_STATIC_STUB_H +#define _LINUXKPI_KUNIT_STATIC_STUB_H + +#define KUNIT_STATIC_STUB_REDIRECT(_fn, ...) do { } while(0) + +#endif /* _LINUXKPI_KUNIT_STATIC_STUB_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index bc776a0db9c4..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))) -#define HWEIGHT16(x) (bitcount16(x)) -#define HWEIGHT32(x) (bitcount32(x)) -#define HWEIGHT64(x) (bitcount64(x)) +#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/cleanup.h b/sys/compat/linuxkpi/common/include/linux/cleanup.h index 01f234f0cbe7..5bb146f082ed 100644 --- a/sys/compat/linuxkpi/common/include/linux/cleanup.h +++ b/sys/compat/linuxkpi/common/include/linux/cleanup.h @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2024 The FreeBSD Foundation + * Copyright (c) 2024-2025 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -43,4 +43,51 @@ guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__ \ __cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create +#define DEFINE_FREE(_n, _t, _f) \ + static inline void \ + __free_ ## _n(void *p) \ + { \ + _t _T; \ + \ + _T = *(_t *)p; \ + _f; \ + } + +#define __free(_n) __cleanup(__free_##_n) + +/* + * Given this is a _0 version it should likely be broken up into parts. + * But we have no idead what a _1, _2, ... version would do different + * until we see a call. + * This is used for a not-real-type (rcu). We use a bool to "simulate" + * the lock held. Also _T still special, may not always be used, so tag + * with __unused (or better the LinuxKPI __maybe_unused). + */ +#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \ + \ + typedef struct { \ + bool lock; \ + __VA_ARGS__; \ + } guard_ ## _n ## _t; \ + \ + static inline void \ + guard_ ## _n ## _destroy(guard_ ## _n ## _t *_T) \ + { \ + if (_T->lock) { \ + _unlock; \ + } \ + } \ + \ + static inline guard_ ## _n ## _t \ + guard_ ## _n ## _create(void) \ + { \ + guard_ ## _n ## _t _tmp; \ + guard_ ## _n ## _t *_T __maybe_unused; \ + \ + _tmp.lock = true; \ + _T = &_tmp; \ + _lock; \ + return (_tmp); \ + } + #endif /* _LINUXKPI_LINUX_CLEANUP_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/compiler.h b/sys/compat/linuxkpi/common/include/linux/compiler.h index fb5ad3bf4fe4..948396144ad6 100644 --- a/sys/compat/linuxkpi/common/include/linux/compiler.h +++ b/sys/compat/linuxkpi/common/include/linux/compiler.h @@ -130,4 +130,10 @@ #define is_signed_type(t) ((t)-1 < (t)1) #define is_unsigned_type(t) ((t)-1 > (t)1) +#if __has_builtin(__builtin_dynamic_object_size) +#define __struct_size(_s) __builtin_dynamic_object_size(_s, 0) +#else +#define __struct_size(_s) __builtin_object_size(_s, 0) +#endif + #endif /* _LINUXKPI_LINUX_COMPILER_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index 2556b0c45e49..7dd6340746d2 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -4,7 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2021-2022 The FreeBSD Foundation + * Copyright (c) 2021-2025 The FreeBSD Foundation * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -284,7 +284,8 @@ int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *) void lkpi_devres_release_free_list(struct device *); void lkpi_devres_unlink(struct device *, void *); void lkpi_devm_kmalloc_release(struct device *, void *); -#define devm_kfree(_d, _p) lkpi_devm_kmalloc_release(_d, _p) +void lkpi_devm_kfree(struct device *, const void *); +#define devm_kfree(_d, _p) lkpi_devm_kfree(_d, _p) static inline const char * dev_driver_string(const struct device *dev) diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h index 4c4caa621789..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> 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 3644ef80861b..17041bb03ce8 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 @@ -394,6 +408,14 @@ enum ieee80211_sta_state { IEEE80211_STA_AUTHORIZED = 4, /* 802.1x */ }; +enum ieee80211_sta_rx_bandwidth { + IEEE80211_STA_RX_BW_20 = 0, + IEEE80211_STA_RX_BW_40, + IEEE80211_STA_RX_BW_80, + IEEE80211_STA_RX_BW_160, + IEEE80211_STA_RX_BW_320, +}; + enum ieee80211_tx_info_flags { /* XXX TODO .. right shift numbers - not sure where that came from? */ IEEE80211_TX_CTL_AMPDU = BIT(0), @@ -510,24 +532,24 @@ struct ieee80211_mgmt { uint16_t beacon_int; uint16_t capab_info; uint8_t variable[0]; - } beacon; + } __packed beacon; /* 9.3.3.5 Association Request frame format */ struct { uint16_t capab_info; uint16_t listen_interval; uint8_t variable[0]; - } assoc_req; + } __packed assoc_req; /* 9.3.3.10 Probe Request frame format */ struct { uint8_t variable[0]; - } probe_req; + } __packed probe_req; /* 9.3.3.11 Probe Response frame format */ struct { uint64_t timestamp; uint16_t beacon_int; uint16_t capab_info; uint8_t variable[0]; - } probe_resp; + } __packed probe_resp; /* 9.3.3.14 Action frame format */ struct { /* 9.4.1.11 Action field */ @@ -543,7 +565,7 @@ struct ieee80211_mgmt { uint8_t tpc_elem_length; uint8_t tpc_elem_tx_power; uint8_t tpc_elem_link_margin; - } tpc_report; + } __packed tpc_report; /* 9.6.8.33 Fine Timing Measurement frame format */ struct { uint8_t dialog_token; @@ -553,7 +575,7 @@ struct ieee80211_mgmt { uint16_t tod_error; uint16_t toa_error; uint8_t variable[0]; - } ftm; + } __packed ftm; /* 802.11-2016, 9.6.5.2 ADDBA Request frame format */ struct { uint8_t action_code; @@ -563,16 +585,16 @@ struct ieee80211_mgmt { uint16_t start_seq_num; /* Optional follows... */ uint8_t variable[0]; - } addba_req; + } __packed addba_req; /* XXX */ struct { uint8_t dialog_token; - } wnm_timing_msr; + } __packed wnm_timing_msr; } u; - } action; + } __packed action; DECLARE_FLEX_ARRAY(uint8_t, body); } u; -}; +} __packed __aligned(2); struct ieee80211_cts { /* net80211::ieee80211_frame_cts */ __le16 frame_control; 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/math.h b/sys/compat/linuxkpi/common/include/linux/math.h index 5a348a57747b..1d50e011f66d 100644 --- a/sys/compat/linuxkpi/common/include/linux/math.h +++ b/sys/compat/linuxkpi/common/include/linux/math.h @@ -56,7 +56,7 @@ __ret; \ }) -#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60600 +#if !defined(LINUXKPI_VERSION) || (LINUXKPI_VERSION >= 60600) #define abs_diff(x, y) ({ \ __typeof(x) _x = (x); \ __typeof(y) _y = (y); \ diff --git a/sys/compat/linuxkpi/common/include/linux/math64.h b/sys/compat/linuxkpi/common/include/linux/math64.h index a216d350570f..25ca9da1b622 100644 --- a/sys/compat/linuxkpi/common/include/linux/math64.h +++ b/sys/compat/linuxkpi/common/include/linux/math64.h @@ -98,6 +98,12 @@ div64_u64_round_up(uint64_t dividend, uint64_t divisor) return ((dividend + divisor - 1) / divisor); } +static inline uint64_t +roundup_u64(uint64_t x1, uint32_t x2) +{ + return (div_u64(x1 + x2 - 1, x2) * x2); +} + #define DIV64_U64_ROUND_UP(...) \ div64_u64_round_up(__VA_ARGS__) 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/overflow.h b/sys/compat/linuxkpi/common/include/linux/overflow.h index 9ba9b9500f11..e811037b8ecc 100644 --- a/sys/compat/linuxkpi/common/include/linux/overflow.h +++ b/sys/compat/linuxkpi/common/include/linux/overflow.h @@ -33,8 +33,10 @@ * credit to Christian Biere. */ #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) -#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) -#define type_min(T) ((T)((T)-type_max(T)-(T)1)) +#define __type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) +#define type_max(t) __type_max(typeof(t)) +#define __type_min(T) ((T)((T)-type_max(T)-(T)1)) +#define type_min(t) __type_min(typeof(t)) /* * Avoids triggering -Wtype-limits compilation warning, @@ -59,46 +61,123 @@ static inline bool __must_check __must_check_overflow(bool overflow) * @b: second addend * @d: pointer to store sum * - * Returns 0 on success. + * Returns true on wrap-around, false otherwise. * - * *@d holds the results of the attempted addition, but is not considered - * "safe for use" on a non-zero return value, which indicates that the - * sum has overflowed or been truncated. + * *@d holds the results of the attempted addition, regardless of whether + * wrap-around occurred. */ #define check_add_overflow(a, b, d) \ __must_check_overflow(__builtin_add_overflow(a, b, d)) /** + * wrapping_add() - Intentionally perform a wrapping addition + * @type: type for result of calculation + * @a: first addend + * @b: second addend + * + * Return the potentially wrapped-around addition without + * tripping any wrap-around sanitizers that may be enabled. + */ +#define wrapping_add(type, a, b) \ + ({ \ + type __val; \ + __builtin_add_overflow(a, b, &__val); \ + __val; \ + }) + +/** + * wrapping_assign_add() - Intentionally perform a wrapping increment assignment + * @var: variable to be incremented + * @offset: amount to add + * + * Increments @var by @offset with wrap-around. Returns the resulting + * value of @var. Will not trip any wrap-around sanitizers. + * + * Returns the new value of @var. + */ +#define wrapping_assign_add(var, offset) \ + ({ \ + typeof(var) *__ptr = &(var); \ + *__ptr = wrapping_add(typeof(var), *__ptr, offset); \ + }) + +/** * check_sub_overflow() - Calculate subtraction with overflow checking * @a: minuend; value to subtract from * @b: subtrahend; value to subtract from @a * @d: pointer to store difference * - * Returns 0 on success. + * Returns true on wrap-around, false otherwise. * - * *@d holds the results of the attempted subtraction, but is not considered - * "safe for use" on a non-zero return value, which indicates that the - * difference has underflowed or been truncated. + * *@d holds the results of the attempted subtraction, regardless of whether + * wrap-around occurred. */ #define check_sub_overflow(a, b, d) \ __must_check_overflow(__builtin_sub_overflow(a, b, d)) /** + * wrapping_sub() - Intentionally perform a wrapping subtraction + * @type: type for result of calculation + * @a: minuend; value to subtract from + * @b: subtrahend; value to subtract from @a + * + * Return the potentially wrapped-around subtraction without + * tripping any wrap-around sanitizers that may be enabled. + */ +#define wrapping_sub(type, a, b) \ + ({ \ + type __val; \ + __builtin_sub_overflow(a, b, &__val); \ + __val; \ + }) + +/** + * wrapping_assign_sub() - Intentionally perform a wrapping decrement assign + * @var: variable to be decremented + * @offset: amount to subtract + * + * Decrements @var by @offset with wrap-around. Returns the resulting + * value of @var. Will not trip any wrap-around sanitizers. + * + * Returns the new value of @var. + */ +#define wrapping_assign_sub(var, offset) \ + ({ \ + typeof(var) *__ptr = &(var); \ + *__ptr = wrapping_sub(typeof(var), *__ptr, offset); \ + }) + +/** * check_mul_overflow() - Calculate multiplication with overflow checking * @a: first factor * @b: second factor * @d: pointer to store product * - * Returns 0 on success. + * Returns true on wrap-around, false otherwise. * - * *@d holds the results of the attempted multiplication, but is not - * considered "safe for use" on a non-zero return value, which indicates - * that the product has overflowed or been truncated. + * *@d holds the results of the attempted multiplication, regardless of whether + * wrap-around occurred. */ #define check_mul_overflow(a, b, d) \ __must_check_overflow(__builtin_mul_overflow(a, b, d)) /** + * wrapping_mul() - Intentionally perform a wrapping multiplication + * @type: type for result of calculation + * @a: first factor + * @b: second factor + * + * Return the potentially wrapped-around multiplication without + * tripping any wrap-around sanitizers that may be enabled. + */ +#define wrapping_mul(type, a, b) \ + ({ \ + type __val; \ + __builtin_mul_overflow(a, b, &__val); \ + __val; \ + }) + +/** * check_shl_overflow() - Calculate a left-shifted value and check overflow * @a: Value to be shifted * @s: How many bits left to shift @@ -122,7 +201,7 @@ static inline bool __must_check __must_check_overflow(bool overflow) typeof(a) _a = a; \ typeof(s) _s = s; \ typeof(d) _d = d; \ - u64 _a_full = _a; \ + unsigned long long _a_full = _a; \ unsigned int _to_shift = \ is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \ *_d = (_a_full << _to_shift); \ @@ -132,10 +211,10 @@ static inline bool __must_check __must_check_overflow(bool overflow) #define __overflows_type_constexpr(x, T) ( \ is_unsigned_type(typeof(x)) ? \ - (x) > type_max(typeof(T)) : \ + (x) > type_max(T) : \ is_unsigned_type(typeof(T)) ? \ - (x) < 0 || (x) > type_max(typeof(T)) : \ - (x) < type_min(typeof(T)) || (x) > type_max(typeof(T))) + (x) < 0 || (x) > type_max(T) : \ + (x) < type_min(T) || (x) > type_max(T)) #define __overflows_type(x, T) ({ \ typeof(T) v = 0; \ @@ -312,27 +391,40 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) struct_size((type *)NULL, member, count) /** - * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. - * Enables caller macro to pass (different) initializer. + * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. + * Enables caller macro to pass arbitrary trailing expressions * * @type: structure type name, including "struct" keyword. * @name: Name for a variable to define. * @member: Name of the array member. * @count: Number of elements in the array; must be compile-time const. - * @initializer: initializer expression (could be empty for no init). + * @trailer: Trailing expressions for attributes and/or initializers. */ -#define _DEFINE_FLEX(type, name, member, count, initializer) \ +#define __DEFINE_FLEX(type, name, member, count, trailer...) \ _Static_assert(__builtin_constant_p(count), \ "onstack flex array members require compile-time const count"); \ union { \ u8 bytes[struct_size_t(type, member, count)]; \ type obj; \ - } name##_u initializer; \ + } name##_u trailer; \ type *name = (type *)&name##_u /** - * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing - * flexible array member. + * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. + * Enables caller macro to pass (different) initializer. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * @initializer: Initializer expression (e.g., pass `= { }` at minimum). + */ +#define _DEFINE_FLEX(type, name, member, count, initializer...) \ + __DEFINE_FLEX(type, name, member, count, = { .obj initializer }) + +/** + * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member, when it does not have a __counted_by annotation. * * @type: structure type name, including "struct" keyword. * @name: Name for a variable to define. @@ -342,8 +434,42 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * Define a zeroed, on-stack, instance of @type structure with a trailing * flexible array member. * Use __struct_size(@name) to get compile-time size of it afterwards. + * Use __member_size(@name->member) to get compile-time size of @name members. + * Use STACK_FLEX_ARRAY_SIZE(@name, @member) to get compile-time number of + * elements in array @member. + */ +#define DEFINE_RAW_FLEX(type, name, member, count) \ + __DEFINE_FLEX(type, name, member, count, = { }) + +/** + * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member. + * + * @TYPE: structure type name, including "struct" keyword. + * @NAME: Name for a variable to define. + * @MEMBER: Name of the array member. + * @COUNTER: Name of the __counted_by member. + * @COUNT: Number of elements in the array; must be compile-time const. + * + * Define a zeroed, on-stack, instance of @TYPE structure with a trailing + * flexible array member. + * Use __struct_size(@NAME) to get compile-time size of it afterwards. + * Use __member_size(@NAME->member) to get compile-time size of @NAME members. + * Use STACK_FLEX_ARRAY_SIZE(@name, @member) to get compile-time number of + * elements in array @member. + */ +#define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT) \ + _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .COUNTER = COUNT, }) + +/** + * STACK_FLEX_ARRAY_SIZE() - helper macro for DEFINE_FLEX() family. + * Returns the number of elements in @array. + * + * @name: Name for a variable defined in DEFINE_RAW_FLEX()/DEFINE_FLEX(). + * @array: Name of the array member. */ -#define DEFINE_FLEX(type, name, member, count) \ - _DEFINE_FLEX(type, name, member, count, = {}) +#define STACK_FLEX_ARRAY_SIZE(name, array) \ + (__member_size((name)->array) / sizeof(*(name)->array) + \ + __must_be_array((name)->array)) #endif /* _LINUXKPI_LINUX_OVERFLOW_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index ba1c0d2ac99e..d891d0df3546 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -223,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 @@ -355,7 +355,6 @@ struct pci_dev { TAILQ_HEAD(, pci_mmio_region) mmio; }; -int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name); int pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv, unsigned int flags); bool pci_device_is_present(struct pci_dev *pdev); @@ -365,10 +364,13 @@ void __iomem **linuxkpi_pcim_iomap_table(struct pci_dev *pdev); void *linuxkpi_pci_iomap_range(struct pci_dev *, int, unsigned long, unsigned long); void *linuxkpi_pci_iomap(struct pci_dev *, int, unsigned long); +void *linuxkpi_pcim_iomap(struct pci_dev *, int, unsigned long); void linuxkpi_pci_iounmap(struct pci_dev *pdev, void *res); int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask, const char *name); +int linuxkpi_pci_request_region(struct pci_dev *, int, const char *); int linuxkpi_pci_request_regions(struct pci_dev *pdev, const char *res_name); +int linuxkpi_pcim_request_all_regions(struct pci_dev *, const char *); void linuxkpi_pci_release_region(struct pci_dev *pdev, int bar); void linuxkpi_pci_release_regions(struct pci_dev *pdev); int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, @@ -561,12 +563,16 @@ done: return (pdev->bus->self); } +#define pci_request_region(pdev, bar, res_name) \ + linuxkpi_pci_request_region(pdev, bar, res_name) #define pci_release_region(pdev, bar) \ linuxkpi_pci_release_region(pdev, bar) -#define pci_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_regions(pdev) \ + linuxkpi_pci_release_regions(pdev) +#define pcim_request_all_regions(pdev, name) \ + linuxkpi_pcim_request_all_regions(pdev, name) static inline void lkpi_pci_disable_msix(struct pci_dev *pdev) @@ -803,6 +809,8 @@ static inline void pci_disable_sriov(struct pci_dev *dev) linuxkpi_pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) #define pci_iomap(pdev, mmio_bar, mmio_size) \ linuxkpi_pci_iomap(pdev, mmio_bar, mmio_size) +#define pcim_iomap(pdev, bar, maxlen) \ + linuxkpi_pcim_iomap(pdev, bar, maxlen) #define pci_iounmap(pdev, res) \ linuxkpi_pci_iounmap(pdev, res) @@ -1445,6 +1453,9 @@ linuxkpi_pci_get_device(uint32_t vendor, uint32_t device, struct pci_dev *odev) return (lkpi_pci_get_device(vendor, device, odev)); } +#define for_each_pci_dev(_pdev) \ + while ((_pdev = linuxkpi_pci_get_device(PCI_ANY_ID, PCI_ANY_ID, _pdev)) != NULL) + /* This is a FreeBSD extension so we can use bus_*(). */ static inline void linuxkpi_pcim_want_to_use_bus_functions(struct pci_dev *pdev) diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h index da9d45122d4d..d2d197682782 100644 --- a/sys/compat/linuxkpi/common/include/linux/printk.h +++ b/sys/compat/linuxkpi/common/include/linux/printk.h @@ -94,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/rcupdate.h b/sys/compat/linuxkpi/common/include/linux/rcupdate.h index 85d766c8dbc9..4aceb7296cd6 100644 --- a/sys/compat/linuxkpi/common/include/linux/rcupdate.h +++ b/sys/compat/linuxkpi/common/include/linux/rcupdate.h @@ -1,7 +1,7 @@ /*- * Copyright (c) 2016-2017 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2024 The FreeBSD Foundation + * Copyright (c) 2024-2025 The FreeBSD Foundation * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -35,6 +35,7 @@ #include <linux/compiler.h> #include <linux/types.h> #include <linux/kernel.h> +#include <linux/cleanup.h> #include <machine/atomic.h> @@ -162,4 +163,6 @@ void linux_synchronize_rcu(unsigned type); #define init_rcu_head_on_stack(...) #define destroy_rcu_head_on_stack(...) +DEFINE_LOCK_GUARD_0(rcu, rcu_read_lock(), rcu_read_unlock()) + #endif /* _LINUXKPI_LINUX_RCUPDATE_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/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/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h index 876ef9e8dfe5..47da16ab8688 100644 --- a/sys/compat/linuxkpi/common/include/linux/seq_file.h +++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h @@ -55,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; diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h index c8ad90281e34..6e41c368a8b8 100644 --- a/sys/compat/linuxkpi/common/include/linux/skbuff.h +++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2020-2025 The FreeBSD Foundation - * Copyright (c) 2021-2023 Bjoern A. Zeeb + * Copyright (c) 2021-2025 Bjoern A. Zeeb * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -47,13 +47,11 @@ #include <linux/ktime.h> #include <linux/compiler.h> -#include "opt_wlan.h" - -/* Currently this is only used for wlan so we can depend on that. */ -#if defined(IEEE80211_DEBUG) && !defined(SKB_DEBUG) -#define SKB_DEBUG -#endif - +/* + * At least the net/intel-irdma-kmod port pulls this header in; likely through + * if_ether.h (see PR289268). This means we no longer can rely on + * IEEE80211_DEBUG (opt_wlan.h) to automatically set SKB_DEBUG. + */ /* #define SKB_DEBUG */ #ifdef SKB_DEBUG @@ -120,7 +118,7 @@ enum sk_checksum_flags { CHECKSUM_NONE = 0x00, CHECKSUM_UNNECESSARY = 0x01, CHECKSUM_PARTIAL = 0x02, - CHECKSUM_COMPLETE = 0x04, + CHECKSUM_COMPLETE = 0x03, }; struct skb_frag { @@ -170,7 +168,7 @@ struct sk_buff { }; }; uint16_t protocol; - uint8_t ip_summed; + uint8_t ip_summed; /* 2 bit only. */ /* uint8_t */ /* "Scratch" area for layers to store metadata. */ diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h index efa5c8cb67b3..0e649e1e3c4a 100644 --- a/sys/compat/linuxkpi/common/include/linux/slab.h +++ b/sys/compat/linuxkpi/common/include/linux/slab.h @@ -40,8 +40,10 @@ #include <linux/compat.h> #include <linux/types.h> #include <linux/gfp.h> +#include <linux/err.h> #include <linux/llist.h> #include <linux/overflow.h> +#include <linux/cleanup.h> MALLOC_DECLARE(M_KMALLOC); @@ -99,6 +101,7 @@ 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); @@ -152,6 +155,8 @@ kfree(const void *ptr) lkpi_kfree(ptr); } +DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T)) + /* * Other k*alloc() funtions using the above as underlying allocator. */ @@ -225,7 +230,7 @@ vmalloc_32(size_t size) static inline void * kvmalloc(size_t size, gfp_t flags) { - return (malloc(size, M_KMALLOC, linux_check_m_flags(flags))); + return (lkpi_kvmalloc(size, flags)); } static inline void * diff --git a/sys/compat/linuxkpi/common/include/linux/string_helpers.h b/sys/compat/linuxkpi/common/include/linux/string_helpers.h index 1bdff2730361..2c6fe0b1708d 100644 --- a/sys/compat/linuxkpi/common/include/linux/string_helpers.h +++ b/sys/compat/linuxkpi/common/include/linux/string_helpers.h @@ -66,4 +66,6 @@ str_enable_disable(bool value) return "disable"; } +#define str_disable_enable(_v) str_enable_disable(!(_v)) + #endif diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h b/sys/compat/linuxkpi/common/include/linux/sysfs.h index 65e023031bb2..470c224a9778 100644 --- a/sys/compat/linuxkpi/common/include/linux/sysfs.h +++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h @@ -189,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) { @@ -197,6 +241,19 @@ 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) { diff --git a/sys/compat/linuxkpi/common/include/linux/timer.h b/sys/compat/linuxkpi/common/include/linux/timer.h index a635f0faea59..d48939e28a02 100644 --- a/sys/compat/linuxkpi/common/include/linux/timer.h +++ b/sys/compat/linuxkpi/common/include/linux/timer.h @@ -49,8 +49,13 @@ extern unsigned long linux_timer_hz_mask; #define TIMER_IRQSAFE 0x0001 +#if defined(LINUXKPI_VERSION) && (LINUXKPI_VERSION < 61600) #define from_timer(var, arg, field) \ container_of(arg, typeof(*(var)), field) +#else +#define timer_container_of(var, arg, field) \ + container_of(arg, typeof(*(var)), field) +#endif #define timer_setup(timer, func, flags) do { \ CTASSERT(((flags) & ~TIMER_IRQSAFE) == 0); \ @@ -79,11 +84,23 @@ extern unsigned long linux_timer_hz_mask; extern int mod_timer(struct timer_list *, unsigned long); extern void add_timer(struct timer_list *); extern void add_timer_on(struct timer_list *, int cpu); -extern int del_timer(struct timer_list *); -extern int del_timer_sync(struct timer_list *); + +extern int timer_delete(struct timer_list *); extern int timer_delete_sync(struct timer_list *); extern int timer_shutdown_sync(struct timer_list *); +static inline int +del_timer(struct timer_list *tl) +{ + return (timer_delete(tl)); +} + +static inline int +del_timer_sync(struct timer_list *tl) +{ + return (timer_delete_sync(tl)); +} + #define timer_pending(timer) callout_pending(&(timer)->callout) #define round_jiffies(j) \ ((unsigned long)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask)) 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/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h index 18b34f0e90ec..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> @@ -56,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), @@ -127,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 { @@ -722,8 +728,10 @@ 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) @@ -1296,10 +1304,9 @@ 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 * @@ -2065,6 +2072,18 @@ 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 *), diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index af3199c38939..8de03410c6b6 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -87,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 { @@ -734,7 +737,7 @@ struct ieee80211_link_sta { struct ieee80211_he_6ghz_capa he_6ghz_capa; struct ieee80211_sta_eht_cap eht_cap; uint8_t rx_nss; - enum ieee80211_sta_rx_bw bandwidth; + enum ieee80211_sta_rx_bandwidth bandwidth; enum ieee80211_smps_mode smps_mode; struct ieee80211_sta_agg agg; struct ieee80211_sta_txpwr txpwr; @@ -1135,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 *); @@ -1184,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 *); @@ -1255,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(); } @@ -1741,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 @@ -2161,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, |