diff options
Diffstat (limited to 'sys/compat/linuxkpi')
26 files changed, 806 insertions, 86 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/acpi.h b/sys/compat/linuxkpi/common/include/linux/acpi.h index 3e1ec1b20626..a764a975c983 100644 --- a/sys/compat/linuxkpi/common/include/linux/acpi.h +++ b/sys/compat/linuxkpi/common/include/linux/acpi.h @@ -32,7 +32,7 @@ #include <linux/device.h> #include <linux/uuid.h> -#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__) +#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__) || defined(__riscv) #include <acpi/acpi.h> #include <acpi/acpi_bus.h> diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index ebe9aa120094..125081ab5b74 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitops.h +++ b/sys/compat/linuxkpi/common/include/linux/bitops.h @@ -51,12 +51,6 @@ #define BITS_PER_TYPE(t) (sizeof(t) * BITS_PER_BYTE) #define BITS_TO_BYTES(n) howmany((n), BITS_PER_BYTE) -#define hweight8(x) bitcount((uint8_t)(x)) -#define hweight16(x) bitcount16(x) -#define hweight32(x) bitcount32(x) -#define hweight64(x) bitcount64(x) -#define hweight_long(x) bitcountl(x) - #if __has_builtin(__builtin_popcountg) #define HWEIGHT8(x) (__builtin_popcountg((uint8_t)(x))) #define HWEIGHT16(x) (__builtin_popcountg((uint16_t)(x))) @@ -70,6 +64,12 @@ #define HWEIGHT64(x) (__const_bitcount64((uint64_t)(x))) #endif +#define hweight8(x) (__builtin_constant_p(x) ? HWEIGHT8(x) : bitcount((uint8_t)(x))) +#define hweight16(x) (__builtin_constant_p(x) ? HWEIGHT16(x) : bitcount16(x)) +#define hweight32(x) (__builtin_constant_p(x) ? HWEIGHT32(x) : bitcount32(x)) +#define hweight64(x) (__builtin_constant_p(x) ? HWEIGHT64(x) : bitcount64(x)) +#define hweight_long(x) bitcountl(x) + static inline int __ffs(int mask) { diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h index 2d8e1196d3d3..76efbfd51074 100644 --- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h @@ -96,6 +96,8 @@ 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); +void linuxkpi_dmam_free_coherent(struct device *dev, size_t size, + void *addr, dma_addr_t dma_handle); 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); @@ -181,6 +183,13 @@ dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, kmem_free(cpu_addr, size); } +static inline void +dmam_free_coherent(struct device *dev, size_t size, void *addr, + dma_addr_t dma_handle) +{ + linuxkpi_dmam_free_coherent(dev, size, addr, dma_handle); +} + 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 direction, unsigned long attrs) diff --git a/sys/compat/linuxkpi/common/include/linux/eventfd.h b/sys/compat/linuxkpi/common/include/linux/eventfd.h new file mode 100644 index 000000000000..d167d4b7d189 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/eventfd.h @@ -0,0 +1,54 @@ +/*- + * 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_EVENTFD_H_ +#define _LINUXKPI_LINUX_EVENTFD_H_ + +#include <sys/eventfd.h> + +#include <linux/wait.h> +#include <linux/err.h> +#include <linux/percpu-defs.h> +#include <linux/percpu.h> +#include <linux/sched.h> + +/* + * Linux uses `struct eventfd_ctx`, but FreeBSD defines `struct eventfd`. Here, + * we define a synonym to the FreeBSD structure. This allows to keep Linux code + * unmodified. + */ +#define eventfd_ctx eventfd + +#define eventfd_ctx_fdget lkpi_eventfd_ctx_fdget +struct eventfd_ctx *lkpi_eventfd_ctx_fdget(int fd); + +#define eventfd_ctx_put lkpi_eventfd_ctx_put +void lkpi_eventfd_ctx_put(struct eventfd_ctx *ctx); + +#endif /* _LINUXKPI_LINUX_EVENTFD_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h index 12160df43915..d1eba94a3ad8 100644 --- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h +++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2020-2025 The FreeBSD Foundation + * Copyright (c) 2020-2026 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -51,8 +51,16 @@ extern int linuxkpi_debug_80211; #define IMPROVE(fmt, ...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \ printf("%s:%d: XXX LKPI80211 IMPROVE " fmt "\n", __func__, __LINE__, ##__VA_ARGS__) - -/* 9.4.2.55 Management MIC element (CMAC-256, GMAC-128, and GMAC-256). */ +/* 802.11-2024, 9.4.2.53 MME. */ +/* BIP-CMAC-128 */ +struct ieee80211_mmie { + uint8_t element_id; + uint8_t length; + uint16_t key_id; + uint8_t ipn[6]; + uint8_t mic[8]; +}; +/* BIP-CMAC-256, BIP-GMAC-128, BIP-GMAC-256 */ struct ieee80211_mmie_16 { uint8_t element_id; uint8_t length; @@ -108,7 +116,18 @@ struct ieee80211_mmie_16 { #define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100 enum ieee80211_rate_flags { - IEEE80211_RATE_SHORT_PREAMBLE = BIT(0), + IEEE80211_RATE_SHORT_PREAMBLE = BIT(0), /* 2.4Ghz, CCK */ + IEEE80211_RATE_SUPPORTS_5MHZ = BIT(1), + IEEE80211_RATE_SUPPORTS_10MHZ = BIT(2), + IEEE80211_RATE_ERP_G = BIT(3), + + /* + * According to documentation these are flags initialized internally. + * See lkpi_wiphy_band_annotate(). + */ + IEEE80211_RATE_MANDATORY_A = BIT(4), + IEEE80211_RATE_MANDATORY_G = BIT(5), + IEEE80211_RATE_MANDATORY_B = BIT(6), }; enum ieee80211_rate_control_changed_flags { @@ -200,6 +219,7 @@ enum ieee80211_min_mpdu_start_spacing { #define IEEE80211_FCTL_TODS (IEEE80211_FC1_DIR_TODS << 8) #define IEEE80211_FCTL_MOREFRAGS (IEEE80211_FC1_MORE_FRAG << 8) #define IEEE80211_FCTL_PM (IEEE80211_FC1_PWR_MGT << 8) +#define IEEE80211_FCTL_MOREDATA (IEEE80211_FC1_MORE_DATA << 8) #define IEEE80211_FTYPE_MGMT IEEE80211_FC0_TYPE_MGT #define IEEE80211_FTYPE_CTL IEEE80211_FC0_TYPE_CTL @@ -461,18 +481,6 @@ enum ieee80211_tx_control_flags { IEEE80211_TX_CTRL_MLO_LINK = 0xF0000000, /* This is IEEE80211_LINK_UNSPECIFIED on the high bits. */ }; -enum ieee80211_tx_rate_flags { - /* XXX TODO .. right shift numbers */ - IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(0), - IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(1), - IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(2), - IEEE80211_TX_RC_GREEN_FIELD = BIT(3), - IEEE80211_TX_RC_MCS = BIT(4), - IEEE80211_TX_RC_SHORT_GI = BIT(5), - IEEE80211_TX_RC_VHT_MCS = BIT(6), - IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(7), -}; - #define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128 #define IEEE80211_HT_CTL_LEN 4 diff --git a/sys/compat/linuxkpi/common/include/linux/minmax.h b/sys/compat/linuxkpi/common/include/linux/minmax.h index d48958f0899f..fb8eb6f704b4 100644 --- a/sys/compat/linuxkpi/common/include/linux/minmax.h +++ b/sys/compat/linuxkpi/common/include/linux/minmax.h @@ -71,4 +71,7 @@ b = _swap_tmp; \ } while (0) +/* XXX would have to make sure both are unsigned. */ +#define umin(x, y) MIN(x, y) + #endif /* _LINUXKPI_LINUX_MINMAX_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h index cf27753bcb80..dfed5fbd61b4 100644 --- a/sys/compat/linuxkpi/common/include/linux/netdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h @@ -160,6 +160,30 @@ struct net_device { #define SET_NETDEV_DEV(_ndev, _dev) (_ndev)->dev.parent = _dev; +enum net_device_path_type { + DEV_PATH_MTK_WDMA, +}; + +struct net_device_path { + enum net_device_path_type type; + const struct net_device *dev; + /* We assume there's a struct per type. */ + union { + struct { + uint16_t wcid; + uint8_t wdma_idx; + uint8_t queue; + uint8_t bss; + uint8_t amsdu; + } mtk_wdma; + }; +}; + +struct net_device_path_ctx { + const struct net_device *dev; +}; + + /* -------------------------------------------------------------------------- */ /* According to linux::ipoib_main.c. */ struct netdev_notifier_info { diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 8fe09554aed2..c337be67f5a4 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -1136,19 +1136,28 @@ pci_num_vf(struct pci_dev *dev) static inline enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) { + struct pci_dev *pbus; device_t root; uint32_t lnkcap, lnkcap2; int error, pos; - root = device_get_parent(dev->dev.bsddev); - if (root == NULL) - return (PCI_SPEED_UNKNOWN); - root = device_get_parent(root); - if (root == NULL) - return (PCI_SPEED_UNKNOWN); - root = device_get_parent(root); - if (root == NULL) - return (PCI_SPEED_UNKNOWN); + /* + * We should always be called on a PCI device. + * The only current consumer I could find was amdgpu which either + * calls us directly on a pdev(drmn?) or with the result of + * pci_upstream_bridge(). + * + * Treat "drmn" as special again as it is not a PCI device. + */ + if (dev->pdrv != NULL && dev->pdrv->isdrm) { + pbus = pci_upstream_bridge(dev); + if (pbus == NULL) + return (PCI_SPEED_UNKNOWN); + } else + pbus = dev; + + /* "root" may be misleading as it may not be that. */ + root = pbus->dev.bsddev; if (pci_get_vendor(root) == PCI_VENDOR_ID_VIA || pci_get_vendor(root) == PCI_VENDOR_ID_SERVERWORKS) diff --git a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h index aad46cc25b1b..6491cbeab7e2 100644 --- a/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h +++ b/sys/compat/linuxkpi/common/include/linux/ptp_clock_kernel.h @@ -49,6 +49,7 @@ struct ptp_clock_info { int (*adjtime)(struct ptp_clock_info *, s64); int (*getcrosststamp)(struct ptp_clock_info *, struct system_device_crosststamp *); int (*gettime64)(struct ptp_clock_info *, struct timespec *); + int (*settime64)(struct ptp_clock_info *, const struct timespec *); }; static inline struct ptp_clock * diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h index 55f0fc949807..7182f4a9e407 100644 --- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h +++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h @@ -38,12 +38,19 @@ #define RADIX_TREE_MAX_HEIGHT \ howmany(sizeof(long) * NBBY, RADIX_TREE_MAP_SHIFT) +#define RADIX_TREE_MAX_TAGS 3 +#define RADIX_TREE_TAG_LONGS RADIX_TREE_MAP_SIZE + #define RADIX_TREE_ENTRY_MASK 3UL #define RADIX_TREE_EXCEPTIONAL_ENTRY 2UL #define RADIX_TREE_EXCEPTIONAL_SHIFT 2 +#define RADIX_TREE_ITER_TAG_MASK 0x0f +#define RADIX_TREE_ITER_TAGGED 0x10 + struct radix_tree_node { void *slots[RADIX_TREE_MAP_SIZE]; + unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; int count; }; @@ -51,6 +58,8 @@ struct radix_tree_root { struct radix_tree_node *rnode; gfp_t gfp_mask; int height; + /* Linux stores root tags inside `gfp_mask`. */ + unsigned long tags[RADIX_TREE_MAX_TAGS]; }; struct radix_tree_iter { @@ -64,9 +73,16 @@ struct radix_tree_iter { #define RADIX_TREE(name, mask) \ struct radix_tree_root name = RADIX_TREE_INIT(mask) -#define radix_tree_for_each_slot(slot, root, iter, start) \ - for ((iter)->index = (start); \ - radix_tree_iter_find(root, iter, &(slot)); (iter)->index++) +#define radix_tree_for_each_slot(slot, root, iter, start) \ + for ((iter)->index = (start); \ + radix_tree_iter_find(root, iter, &(slot), 0); \ + (iter)->index++) + +#define radix_tree_for_each_slot_tagged(slot, root, iter, start, tag) \ + for ((iter)->index = (start); \ + radix_tree_iter_find(root, iter, &(slot), \ + RADIX_TREE_ITER_TAGGED | tag); \ + (iter)->index++) static inline void * radix_tree_deref_slot(void **slot) @@ -84,7 +100,12 @@ void *radix_tree_lookup(const struct radix_tree_root *, unsigned long); void *radix_tree_delete(struct radix_tree_root *, unsigned long); int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); int radix_tree_store(struct radix_tree_root *, unsigned long, void **); -bool radix_tree_iter_find(const struct radix_tree_root *, struct radix_tree_iter *, void ***); +bool radix_tree_iter_find(const struct radix_tree_root *, struct radix_tree_iter *, void ***, int); void radix_tree_iter_delete(struct radix_tree_root *, struct radix_tree_iter *, void **); +void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, unsigned int tag); +void *radix_tree_tag_clear(struct radix_tree_root *root, unsigned long index, unsigned int tag); +int radix_tree_tagged(const struct radix_tree_root *root, unsigned int tag); +unsigned int radix_tree_gang_lookup(const struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); +unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag); #endif /* _LINUXKPI_LINUX_RADIX_TREE_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/seq_buf.h b/sys/compat/linuxkpi/common/include/linux/seq_buf.h new file mode 100644 index 000000000000..d6246a40e6f7 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/seq_buf.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025-2026 The FreeBSD Foundation + * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org> + * + * This software was developed by Jean-Sébastien Pédron under sponsorship + * from the FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _LINUXKPI_LINUX_SEQ_BUF_H_ +#define _LINUXKPI_LINUX_SEQ_BUF_H_ + +#include <linux/bug.h> +#include <linux/minmax.h> +#include <linux/seq_file.h> +#include <linux/types.h> + +struct seq_buf { + char *buffer; + size_t size; + size_t len; +}; + +#define DECLARE_SEQ_BUF(NAME, SIZE) \ + struct seq_buf NAME = { \ + .buffer = (char[SIZE]) { 0 }, \ + .size = SIZE, \ + } + +static inline void +seq_buf_clear(struct seq_buf *s) +{ + s->len = 0; + if (s->size > 0) + s->buffer[0] = '\0'; +} + +static inline void +seq_buf_set_overflow(struct seq_buf *s) +{ + s->len = s->size + 1; +} + +static inline bool +seq_buf_has_overflowed(struct seq_buf *s) +{ + return (s->len > s->size); +} + +static inline bool +seq_buf_buffer_left(struct seq_buf *s) +{ + if (seq_buf_has_overflowed(s)) + return (0); + + return (s->size - s->len); +} + +#define seq_buf_init(s, buf, size) linuxkpi_seq_buf_init((s), (buf), (size)) +void linuxkpi_seq_buf_init(struct seq_buf *s, char *buf, unsigned int size); + +#define seq_buf_printf(s, f, ...) linuxkpi_seq_buf_printf((s), (f), __VA_ARGS__) +int linuxkpi_seq_buf_printf(struct seq_buf *s, const char *fmt, ...) \ + __printflike(2, 3); + +#define seq_buf_vprintf(s, f, a) linuxkpi_seq_buf_vprintf((s), (f), (a)) +int linuxkpi_seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); + +#define seq_buf_str(s) linuxkpi_seq_buf_str((s)) +const char * linuxkpi_seq_buf_str(struct seq_buf *s); + +#endif diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h index 2e560a120e41..c43d6daff5ee 100644 --- a/sys/compat/linuxkpi/common/include/linux/skbuff.h +++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h @@ -770,7 +770,7 @@ ___skb_queue_splice(const struct sk_buff_head *from, } static inline void -skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) +skb_queue_splice(const struct sk_buff_head *from, struct sk_buff_head *to) { SKB_TRACE2(from, to); @@ -780,6 +780,13 @@ skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) ___skb_queue_splice(from, (struct sk_buff *)to, to->next); to->qlen += from->qlen; +} + +static inline void +skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) +{ + + skb_queue_splice(from, to); __skb_queue_head_init(from); } diff --git a/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h new file mode 100644 index 000000000000..ade0b06d839f --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2026 Bjoern A. Zeeb + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H +#define _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H + +#include <linux/kernel.h> /* pr_debug */ + +enum airoha_npu_wlan_get_cmd { + __dummy_airoha_npu_wlan_get_cmd, +}; +enum airoha_npu_wlan_set_cmd { + __dummy_airoha_npu_wlan_set_cmd, +}; + +struct airoha_npu { +}; +struct airoha_npu_rx_dma_desc { +}; +struct airoha_npu_tx_dma_desc { +}; + +static __inline int +airoha_npu_wlan_send_msg(void *npu, int ifindex, + enum airoha_npu_wlan_set_cmd cmd, void *val, size_t len, gfp_t gfp) +{ + pr_debug("%s: TODO\n", __func__); + return (-EOPNOTSUPP); +} + +static __inline int +airoha_npu_wlan_get_msg(void *npu, int ifindex, + enum airoha_npu_wlan_get_cmd cmd, void *val, size_t len, gfp_t gfp) +{ + pr_debug("%s: TODO\n", __func__); + return (-EOPNOTSUPP); +} + +static __inline void +airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) +{ + pr_debug("%s: TODO\n", __func__); +} + +#endif /* _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_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 2b9c6ae4911e..64daa8c78c9d 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 @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2022-2025 Bjoern A. Zeeb + * Copyright (c) 2022-2026 Bjoern A. Zeeb * * SPDX-License-Identifier: BSD-2-Clause */ @@ -37,7 +37,13 @@ mtk_wed_device_active(struct mtk_wed_device *dev __unused) static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused) { + pr_debug("%s: TODO\n", __func__); + return (false); +} +static inline bool +mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused) +{ pr_debug("%s: TODO\n", __func__); return (false); } @@ -66,6 +72,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused) { return (false); } + +static inline bool +mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused) +{ + return (false); +} #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ #endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */ diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h index d7ed2bc97c98..94d34fb9dc0c 100644 --- a/sys/compat/linuxkpi/common/include/net/cfg80211.h +++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h @@ -124,6 +124,7 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_PSD = BIT(12), IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP = BIT(13), IEEE80211_CHAN_CAN_MONITOR = BIT(14), + IEEE80211_CHAN_NO_EHT = BIT(15), }; #define IEEE80211_CHAN_NO_HT40 (IEEE80211_CHAN_NO_HT40MINUS|IEEE80211_CHAN_NO_HT40PLUS) @@ -152,6 +153,8 @@ struct linuxkpi_ieee80211_channel { int orig_mpwr; }; +#define NL80211_EHT_NSS_MAX 16 + struct cfg80211_bitrate_mask { /* TODO FIXME */ struct { @@ -159,6 +162,7 @@ struct cfg80211_bitrate_mask { uint8_t ht_mcs[IEEE80211_HT_MCS_MASK_LEN]; uint16_t vht_mcs[8]; uint16_t he_mcs[8]; + uint16_t eht_mcs[NL80211_EHT_NSS_MAX]; enum nl80211_txrate_gi gi; enum nl80211_he_gi he_gi; uint8_t he_ltf; /* XXX enum? */ @@ -1230,6 +1234,7 @@ struct cfg80211_ops { struct wiphy *linuxkpi_wiphy_new(const struct cfg80211_ops *, size_t); void linuxkpi_wiphy_free(struct wiphy *wiphy); +int linuxkpi_80211_wiphy_register(struct wiphy *); void linuxkpi_wiphy_work_queue(struct wiphy *, struct wiphy_work *); void linuxkpi_wiphy_work_cancel(struct wiphy *, struct wiphy_work *); @@ -1749,8 +1754,7 @@ wiphy_net(struct wiphy *wiphy) static __inline int wiphy_register(struct wiphy *wiphy) { - TODO(); - return (0); + return (linuxkpi_80211_wiphy_register(wiphy)); } static __inline void diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index 6e2f3f2d8781..18891d035094 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2020-2025 The FreeBSD Foundation + * Copyright (c) 2020-2026 The FreeBSD Foundation * Copyright (c) 2020-2025 Bjoern A. Zeeb * * This software was developed by Björn Zeeb under sponsorship from @@ -789,10 +789,21 @@ struct ieee80211_tx_queue_params { struct ieee80211_he_mu_edca_param_ac_rec mu_edca_param_rec; }; +enum mac80211_rate_control_flags { + IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(0), + IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(1), + IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(2), + IEEE80211_TX_RC_GREEN_FIELD = BIT(3), + IEEE80211_TX_RC_MCS = BIT(4), + IEEE80211_TX_RC_SHORT_GI = BIT(5), + IEEE80211_TX_RC_VHT_MCS = BIT(6), + IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(7), +}; + struct ieee80211_tx_rate { uint8_t idx; uint16_t count:5, - flags:11; + flags:11; /* enum mac80211_rate_control_flags */ }; enum ieee80211_vif_driver_flags { @@ -1092,6 +1103,8 @@ struct ieee80211_ops { void (*rfkill_poll)(struct ieee80211_hw *); + int (*net_fill_forward_path)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct net_device_path_ctx *, struct net_device_path *); + /* #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 *); diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 1ac28dfef448..4ce0a2094adb 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -896,41 +896,34 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], /* Deflink information. */ for (band = 0; band < NUM_NL80211_BANDS; band++) { struct ieee80211_supported_band *supband; + uint32_t rate_mandatory;; supband = hw->wiphy->bands[band]; if (supband == NULL) continue; + switch (band) { + case NL80211_BAND_2GHZ: + /* We have to assume 11g support here. */ + rate_mandatory = IEEE80211_RATE_MANDATORY_G | + IEEE80211_RATE_MANDATORY_B; + break; + case NL80211_BAND_5GHZ: + rate_mandatory = IEEE80211_RATE_MANDATORY_A; + break; + default: + continue; + } + for (i = 0; i < supband->n_bitrates; i++) { - switch (band) { - case NL80211_BAND_2GHZ: - switch (supband->bitrates[i].bitrate) { - case 240: /* 11g only */ - case 120: /* 11g only */ - case 110: - case 60: /* 11g only */ - case 55: - case 20: - case 10: - sta->deflink.supp_rates[band] |= BIT(i); - break; - } - break; - case NL80211_BAND_5GHZ: - switch (supband->bitrates[i].bitrate) { - case 240: - case 120: - case 60: - sta->deflink.supp_rates[band] |= BIT(i); - break; - } - break; - } + if ((supband->bitrates[i].flags & rate_mandatory) != 0) + sta->deflink.supp_rates[band] |= BIT(i); } } sta->deflink.smps_mode = IEEE80211_SMPS_OFF; sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20; + sta->deflink.agg.max_rc_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA; sta->deflink.rx_nss = 1; sta->deflink.sta = sta; @@ -6979,7 +6972,9 @@ linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) } if (bootverbose) { - ic_printf(ic, "netdev_features %b\n", hw->netdev_features, NETIF_F_BITS); + if (hw->netdev_features != 0) + ic_printf(ic, "netdev_features %b\n", + hw->netdev_features, NETIF_F_BITS); ieee80211_announce(ic); } @@ -8028,6 +8023,77 @@ linuxkpi_wiphy_free(struct wiphy *wiphy) kfree(lwiphy); } +static void +lkpi_wiphy_band_annotate(struct wiphy *wiphy) +{ + int band; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + struct ieee80211_supported_band *supband; + int i; + + supband = wiphy->bands[band]; + if (supband == NULL) + continue; + + switch (band) { + case NL80211_BAND_2GHZ: + case NL80211_BAND_5GHZ: + break; + default: +#ifdef LINUXKPI_DEBUG_80211 + IMPROVE("band %d(%s) not yet supported", + band, lkpi_nl80211_band_name(band)); + /* For bands added here, also check lkpi_lsta_alloc(). */ +#endif + continue; + } + + for (i = 0; i < supband->n_bitrates; i++) { + switch (band) { + case NL80211_BAND_2GHZ: + switch (supband->bitrates[i].bitrate) { + case 110: + case 55: + case 20: + case 10: + supband->bitrates[i].flags |= + IEEE80211_RATE_MANDATORY_B; + /* FALLTHROUGH */ + /* 11g only */ + case 240: + case 120: + case 60: + supband->bitrates[i].flags |= + IEEE80211_RATE_MANDATORY_G; + break; + } + break; + case NL80211_BAND_5GHZ: + switch (supband->bitrates[i].bitrate) { + case 240: + case 120: + case 60: + supband->bitrates[i].flags |= + IEEE80211_RATE_MANDATORY_A; + break; + } + break; + } + } + } +} + +int +linuxkpi_80211_wiphy_register(struct wiphy *wiphy) +{ + TODO("Lots of checks and initialization"); + + lkpi_wiphy_band_annotate(wiphy); + + return (0); +} + static uint32_t lkpi_cfg80211_calculate_bitrate_ht(struct rate_info *rate) { diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c index c342eb279caa..3bc5d31d211a 100644 --- a/sys/compat/linuxkpi/common/src/linux_current.c +++ b/sys/compat/linuxkpi/common/src/linux_current.c @@ -90,11 +90,8 @@ linux_alloc_current(struct thread *td, int flags) } ts = uma_zalloc(linux_current_zone, flags | M_ZERO); - if (ts == NULL) { - if ((flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK) - panic("linux_alloc_current: failed to allocate task"); + if (ts == NULL) return (ENOMEM); - } mm = NULL; /* setup new task structure */ @@ -118,10 +115,7 @@ linux_alloc_current(struct thread *td, int flags) PROC_UNLOCK(proc); mm = uma_zalloc(linux_mm_zone, flags | M_ZERO); if (mm == NULL) { - if ((flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK) - panic( - "linux_alloc_current: failed to allocate mm"); - uma_zfree(linux_current_zone, mm); + uma_zfree(linux_current_zone, ts); return (ENOMEM); } diff --git a/sys/compat/linuxkpi/common/src/linux_eventfd.c b/sys/compat/linuxkpi/common/src/linux_eventfd.c new file mode 100644 index 000000000000..126c6c54b9a5 --- /dev/null +++ b/sys/compat/linuxkpi/common/src/linux_eventfd.c @@ -0,0 +1,63 @@ +/*- + * 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. + */ + +#include <sys/param.h> +#include <sys/file.h> +#include <sys/filedesc.h> + +#include <linux/eventfd.h> + +struct eventfd_ctx * +lkpi_eventfd_ctx_fdget(int fd) +{ + struct file *fp; + struct eventfd_ctx *ctx; + + /* Lookup file pointer by file descriptor index. */ + if (fget_unlocked(curthread, fd, &cap_no_rights, &fp) != 0) + return (ERR_PTR(-EBADF)); + + /* + * eventfd_get() bumps the refcount, so we can safely release the + * reference on the file itself afterwards. + */ + ctx = eventfd_get(fp); + fdrop(fp, curthread); + + if (ctx == NULL) + return (ERR_PTR(-EBADF)); + + return (ctx); +} + +void +lkpi_eventfd_ctx_put(struct eventfd_ctx *ctx) +{ + eventfd_put(ctx); +} diff --git a/sys/compat/linuxkpi/common/src/linux_firmware.c b/sys/compat/linuxkpi/common/src/linux_firmware.c index 12658df5ce83..0c6d855501ef 100644 --- a/sys/compat/linuxkpi/common/src/linux_firmware.c +++ b/sys/compat/linuxkpi/common/src/linux_firmware.c @@ -66,7 +66,8 @@ _linuxkpi_request_firmware(const char *fw_name, const struct linuxkpi_firmware * uint32_t flags; if (fw_name == NULL || fw == NULL || dev == NULL) { - *fw = NULL; + if (fw != NULL) + *fw = NULL; return (-EINVAL); } diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index df5255d8a6ca..9e4fad45433a 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -1796,6 +1796,42 @@ lkpi_dmam_free_coherent(struct device *dev, void *p) dma_free_coherent(dev, dr->size, dr->mem, *dr->handle); } +static int +lkpi_dmam_coherent_match(struct device *dev, void *dr, void *mp) +{ + struct lkpi_devres_dmam_coherent *a, *b; + + a = dr; + b = mp; + + if (a->mem != b->mem) + return (0); + if (a->size != b->size || a->handle != b->handle) + dev_WARN(dev, "for mem %p: size %zu != %zu || handle %#jx != %#jx\n", + a->mem, a->size, b->size, + (uintmax_t)a->handle, (uintmax_t)b->handle); + return (1); +} + +void +linuxkpi_dmam_free_coherent(struct device *dev, size_t size, + void *addr, dma_addr_t dma_handle) +{ + struct lkpi_devres_dmam_coherent match = { + .size = size, + .handle = &dma_handle, + .mem = addr + }; + int error; + + error = devres_destroy(dev, lkpi_dmam_free_coherent, + lkpi_dmam_coherent_match, &match); + if (error != 0) + dev_WARN(dev, "devres_destroy returned %d, size %zu addr %p " + "dma_handle %#jx\n", error, size, addr, (uintmax_t)dma_handle); + dma_free_coherent(dev, size, addr, dma_handle); +} + void * linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) diff --git a/sys/compat/linuxkpi/common/src/linux_radix.c b/sys/compat/linuxkpi/common/src/linux_radix.c index ee6b3a63c370..760f583f25c8 100644 --- a/sys/compat/linuxkpi/common/src/linux_radix.c +++ b/sys/compat/linuxkpi/common/src/linux_radix.c @@ -52,6 +52,81 @@ radix_pos(long id, int height) return (id >> (RADIX_TREE_MAP_SHIFT * height)) & RADIX_TREE_MAP_MASK; } +static inline int +root_tag_get(const struct radix_tree_root *root, unsigned tag) +{ + return (test_bit(tag, root->tags)); +} + +static inline void +root_tag_set(struct radix_tree_root *root, unsigned tag) +{ + set_bit(tag, root->tags); +} + +static inline void +root_tag_clear(struct radix_tree_root *root, unsigned tag) +{ + clear_bit(tag, root->tags); +} + +static inline int +tag_get(const struct radix_tree_node *node, unsigned int tag, int pos) +{ + return (test_bit(pos, node->tags[tag])); +} + +static inline void +tag_set(struct radix_tree_node *node, unsigned int tag, int pos) +{ + set_bit(pos, node->tags[tag]); +} + +static inline void +tag_clear(struct radix_tree_node *node, unsigned int tag, int pos) +{ + clear_bit(pos, node->tags[tag]); +} + +static inline bool +any_tag_set(const struct radix_tree_node *node, unsigned int tag) +{ + unsigned int pos; + + for (pos = 0; pos < RADIX_TREE_TAG_LONGS; pos++) + if (node->tags[tag][pos]) + return (true); + + return (false); +} + +static void +node_tag_clear(struct radix_tree_root *root, struct radix_tree_node *stack[], + unsigned long index, unsigned int tag) +{ + struct radix_tree_node *node; + int height, pos; + + height = 1; + node = stack[height]; + + while (node && height <= root->height - 1) { + pos = radix_pos(index, height); + if (!tag_get(node, tag, pos)) + return; + + tag_clear(node, tag, pos); + if (any_tag_set(node, tag)) + return; + + height++; + node = stack[height]; + } + + if (root_tag_get(root, tag)) + root_tag_clear(root, tag); +} + static void radix_tree_clean_root_node(struct radix_tree_root *root) { @@ -84,14 +159,70 @@ out: return (item); } +unsigned int +radix_tree_gang_lookup(const struct radix_tree_root *root, void **results, + unsigned long first_index, unsigned int max_items) +{ + struct radix_tree_iter iter; + void **slot; + int count; + + count = 0; + if (max_items == 0) + return (count); + + radix_tree_for_each_slot(slot, root, &iter, first_index) { + results[count] = *slot; + if (results[count] == NULL) + continue; + + count++; + if (count == max_items) + break; + } + + return (count); +} + +unsigned int +radix_tree_gang_lookup_tag(const struct radix_tree_root *root, + void **results, unsigned long first_index, unsigned int max_items, + unsigned int tag) +{ + struct radix_tree_iter iter; + void **slot; + int count; + + count = 0; + if (max_items == 0) + return (count); + + radix_tree_for_each_slot_tagged(slot, root, &iter, first_index, tag) { + results[count] = *slot; + if (results[count] == NULL) + continue; + + count++; + if (count == max_items) + break; + } + + return (count); +} + bool radix_tree_iter_find(const struct radix_tree_root *root, - struct radix_tree_iter *iter, void ***pppslot) + struct radix_tree_iter *iter, void ***pppslot, int flags) { struct radix_tree_node *node; unsigned long index = iter->index; + unsigned int tag; int height; + tag = flags & RADIX_TREE_ITER_TAG_MASK; + if ((flags & RADIX_TREE_ITER_TAGGED) && !root_tag_get(root, tag)) + return (false); + restart: node = root->rnode; if (node == NULL) @@ -109,7 +240,9 @@ restart: *pppslot = node->slots + pos; next = node->slots[pos]; - if (next == NULL) { + if (next == NULL || + (flags & RADIX_TREE_ITER_TAGGED && + !tag_get(next, tag, pos))) { index += step; index &= -step; if ((index & mask) == 0) @@ -131,6 +264,7 @@ radix_tree_delete(struct radix_tree_root *root, unsigned long index) void *item; int height; int idx; + int tag; item = NULL; node = root->rnode; @@ -144,9 +278,15 @@ radix_tree_delete(struct radix_tree_root *root, unsigned long index) stack[height] = node; node = node->slots[radix_pos(index, height--)]; } - idx = radix_pos(index, 0); - if (node) + + if (node) { + idx = radix_pos(index, 0); item = node->slots[idx]; + + for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) + node_tag_clear(root, stack, index, tag); + } + /* * If we removed something reduce the height of the tree. */ @@ -380,3 +520,74 @@ radix_tree_store(struct radix_tree_root *root, unsigned long index, void **ppite node->count++; return (0); } + +void * +radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, + unsigned int tag) +{ + struct radix_tree_node *node; + void *item; + int height, pos; + + item = NULL; + node = root->rnode; + height = root->height - 1; + if (index > radix_max(root)) + goto out; + + while (height) { + KASSERT( + node != NULL, + ("Node at index %lu does not exist in radix tree %p", + index, root)); + + pos = radix_pos(index, height--); + node = node->slots[pos]; + + if (!tag_get(node, tag, pos)) + tag_set(node, tag, pos); + } + + item = node->slots[radix_pos(index, 0)]; + + root_tag_set(root, tag); + +out: + return (item); +} + +void * +radix_tree_tag_clear(struct radix_tree_root *root, + unsigned long index, unsigned int tag) +{ + struct radix_tree_node *stack[RADIX_TREE_MAX_HEIGHT]; + struct radix_tree_node *node; + void *item; + int height; + + item = NULL; + node = root->rnode; + height = root->height - 1; + if (index > radix_max(root)) + goto out; + + while (height && node) { + stack[height] = node; + node = node->slots[radix_pos(index, height--)]; + } + + if (node) { + item = node->slots[radix_pos(index, 0)]; + + node_tag_clear(root, stack, index, tag); + } + +out: + return (item); +} + +int +radix_tree_tagged(const struct radix_tree_root *root, unsigned int tag) +{ + return (root_tag_get(root, tag)); +} diff --git a/sys/compat/linuxkpi/common/src/linux_seq_buf.c b/sys/compat/linuxkpi/common/src/linux_seq_buf.c new file mode 100644 index 000000000000..112c53044c22 --- /dev/null +++ b/sys/compat/linuxkpi/common/src/linux_seq_buf.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025-2026 The FreeBSD Foundation + * Copyright (c) 2025-2026 Jean-Sébastien Pédron <dumbbell@FreeBSD.org> + * + * This software was developed by Jean-Sébastien Pédron under sponsorship + * from the FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <linux/seq_buf.h> + +void +linuxkpi_seq_buf_init(struct seq_buf *s, char *buf, unsigned int size) +{ + s->buffer = buf; + s->size = size; + + seq_buf_clear(s); +} + +int +linuxkpi_seq_buf_printf(struct seq_buf *s, const char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = seq_buf_vprintf(s, fmt, args); + va_end(args); + + return (ret); +} + +int +linuxkpi_seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) +{ + int ret; + + if (!seq_buf_has_overflowed(s)) { + ret = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); + if (s->len + ret < s->size) { + s->len += ret; + return (0); + } + } + + seq_buf_set_overflow(s); + return (-1); +} + +const char * +linuxkpi_seq_buf_str(struct seq_buf *s) +{ + if (s->size == 0) + return (""); + + if (seq_buf_buffer_left(s)) + s->buffer[s->len] = '\0'; + else + s->buffer[s->size - 1] = '\0'; + + return (s->buffer); +} diff --git a/sys/compat/linuxkpi/common/src/linux_shmemfs.c b/sys/compat/linuxkpi/common/src/linux_shmemfs.c index 1fb17bc5c0cb..d5c118ba7624 100644 --- a/sys/compat/linuxkpi/common/src/linux_shmemfs.c +++ b/sys/compat/linuxkpi/common/src/linux_shmemfs.c @@ -62,11 +62,10 @@ linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex, gfp_t gfp) struct linux_file * linux_shmem_file_setup(const char *name, loff_t size, unsigned long flags) { - struct fileobj { + struct { struct linux_file file __aligned(sizeof(void *)); struct vnode vnode __aligned(sizeof(void *)); - }; - struct fileobj *fileobj; + } *fileobj; struct linux_file *filp; struct vnode *vp; int error; @@ -89,7 +88,7 @@ linux_shmem_file_setup(const char *name, loff_t size, unsigned long flags) } return (filp); err_1: - kfree(filp); + kfree(fileobj); err_0: return (ERR_PTR(error)); } diff --git a/sys/compat/linuxkpi/common/src/linux_xarray.c b/sys/compat/linuxkpi/common/src/linux_xarray.c index 3f07f6d7c59f..8caefbaf7e50 100644 --- a/sys/compat/linuxkpi/common/src/linux_xarray.c +++ b/sys/compat/linuxkpi/common/src/linux_xarray.c @@ -389,7 +389,7 @@ __xa_empty(struct xarray *xa) XA_ASSERT_LOCKED(xa); - return (!radix_tree_iter_find(&xa->xa_head, &iter, &temp)); + return (!radix_tree_iter_find(&xa->xa_head, &iter, &temp, 0)); } bool @@ -426,7 +426,7 @@ __xa_next(struct xarray *xa, unsigned long *pindex, bool not_first) return (NULL); } - found = radix_tree_iter_find(&xa->xa_head, &iter, &ppslot); + found = radix_tree_iter_find(&xa->xa_head, &iter, &ppslot, 0); if (likely(found)) { retval = *ppslot; if (retval == NULL_VALUE) diff --git a/sys/compat/linuxkpi/dummy/include/linux/eventfd.h b/sys/compat/linuxkpi/dummy/include/linux/eventfd.h deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/sys/compat/linuxkpi/dummy/include/linux/eventfd.h +++ /dev/null |
