diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h index d44b813ada8d..4c914a7b45a1 100644 --- a/sys/compat/linuxkpi/common/include/linux/interrupt.h +++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -1,164 +1,173 @@ /*- * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_INTERRUPT_H_ #define _LINUXKPI_LINUX_INTERRUPT_H_ #include #include #include #include #include #include #include typedef irqreturn_t (*irq_handler_t)(int, void *); #define IRQF_SHARED RF_SHAREABLE int lkpi_request_irq(struct device *, unsigned int, irq_handler_t, irq_handler_t, unsigned long, const char *, void *); int lkpi_enable_irq(unsigned int); void lkpi_disable_irq(unsigned int); int lkpi_bind_irq_to_cpu(unsigned int, int); void lkpi_free_irq(unsigned int, void *); void lkpi_devm_free_irq(struct device *, unsigned int, void *); static inline int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *arg) { return (lkpi_request_irq(NULL, irq, handler, NULL, flags, name, arg)); } static inline int request_threaded_irq(int irq, irq_handler_t handler, irq_handler_t thread_handler, unsigned long flags, const char *name, void *arg) { return (lkpi_request_irq(NULL, irq, handler, thread_handler, flags, name, arg)); } static inline int devm_request_irq(struct device *dev, int irq, irq_handler_t handler, unsigned long flags, const char *name, void *arg) { return (lkpi_request_irq(dev, irq, handler, NULL, flags, name, arg)); } static inline int devm_request_threaded_irq(struct device *dev, int irq, irq_handler_t handler, irq_handler_t thread_handler, unsigned long flags, const char *name, void *arg) { return (lkpi_request_irq(dev, irq, handler, thread_handler, flags, name, arg)); } static inline int enable_irq(unsigned int irq) { return (lkpi_enable_irq(irq)); } static inline void disable_irq(unsigned int irq) { lkpi_disable_irq(irq); } static inline int bind_irq_to_cpu(unsigned int irq, int cpu_id) { return (lkpi_bind_irq_to_cpu(irq, cpu_id)); } static inline void free_irq(unsigned int irq, void *device) { lkpi_free_irq(irq, device); } static inline void devm_free_irq(struct device *xdev, unsigned int irq, void *p) { lkpi_devm_free_irq(xdev, irq, p); } static inline int irq_set_affinity_hint(int vector, cpumask_t *mask) { int error; if (mask != NULL) error = intr_setaffinity(vector, CPU_WHICH_IRQ, mask); else error = intr_setaffinity(vector, CPU_WHICH_IRQ, cpuset_root); return (-error); } /* * LinuxKPI tasklet support */ +struct tasklet_struct; typedef void tasklet_func_t(unsigned long); +typedef void tasklet_callback_t(struct tasklet_struct *); struct tasklet_struct { TAILQ_ENTRY(tasklet_struct) entry; tasklet_func_t *func; /* Our "state" implementation is different. Avoid same name as Linux. */ volatile u_int tasklet_state; atomic_t count; unsigned long data; + tasklet_callback_t *callback; + bool use_callback; }; #define DECLARE_TASKLET(_name, _func, _data) \ struct tasklet_struct _name = { .func = (_func), .data = (_data) } #define tasklet_hi_schedule(t) tasklet_schedule(t) +/* Some other compat code in the tree has this defined as well. */ +#define from_tasklet(_dev, _t, _field) \ + container_of(_t, typeof(*(_dev)), _field) + +void tasklet_setup(struct tasklet_struct *, tasklet_callback_t *); extern void tasklet_schedule(struct tasklet_struct *); extern void tasklet_kill(struct tasklet_struct *); extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *, unsigned long data); extern void tasklet_enable(struct tasklet_struct *); extern void tasklet_disable(struct tasklet_struct *); extern void tasklet_disable_nosync(struct tasklet_struct *); extern int tasklet_trylock(struct tasklet_struct *); extern void tasklet_unlock(struct tasklet_struct *); extern void tasklet_unlock_wait(struct tasklet_struct *ts); #endif /* _LINUXKPI_LINUX_INTERRUPT_H_ */ diff --git a/sys/compat/linuxkpi/common/src/linux_tasklet.c b/sys/compat/linuxkpi/common/src/linux_tasklet.c index 26e7bb75cf19..d6e20a63c579 100644 --- a/sys/compat/linuxkpi/common/src/linux_tasklet.c +++ b/sys/compat/linuxkpi/common/src/linux_tasklet.c @@ -1,262 +1,280 @@ /*- * Copyright (c) 2017 Hans Petter Selasky * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #define TASKLET_ST_IDLE 0 #define TASKLET_ST_BUSY 1 #define TASKLET_ST_EXEC 2 #define TASKLET_ST_LOOP 3 #define TASKLET_ST_CMPSET(ts, old, new) \ atomic_cmpset_int((volatile u_int *)&(ts)->tasklet_state, old, new) #define TASKLET_ST_SET(ts, new) \ WRITE_ONCE(*(volatile u_int *)&(ts)->tasklet_state, new) #define TASKLET_ST_GET(ts) \ READ_ONCE(*(volatile u_int *)&(ts)->tasklet_state) struct tasklet_worker { struct mtx mtx; TAILQ_HEAD(tasklet_list, tasklet_struct) head; struct grouptask gtask; } __aligned(CACHE_LINE_SIZE); #define TASKLET_WORKER_LOCK(tw) mtx_lock(&(tw)->mtx) #define TASKLET_WORKER_UNLOCK(tw) mtx_unlock(&(tw)->mtx) DPCPU_DEFINE_STATIC(struct tasklet_worker, tasklet_worker); static void tasklet_handler(void *arg) { struct tasklet_worker *tw = (struct tasklet_worker *)arg; struct tasklet_struct *ts; struct tasklet_struct *last; linux_set_current(curthread); TASKLET_WORKER_LOCK(tw); last = TAILQ_LAST(&tw->head, tasklet_list); while (1) { ts = TAILQ_FIRST(&tw->head); if (ts == NULL) break; TAILQ_REMOVE(&tw->head, ts, entry); if (!atomic_read(&ts->count)) { TASKLET_WORKER_UNLOCK(tw); do { /* reset executing state */ TASKLET_ST_SET(ts, TASKLET_ST_EXEC); - ts->func(ts->data); + if (ts->use_callback) + ts->callback(ts); + else + ts->func(ts->data); } while (TASKLET_ST_CMPSET(ts, TASKLET_ST_EXEC, TASKLET_ST_IDLE) == 0); TASKLET_WORKER_LOCK(tw); } else { TAILQ_INSERT_TAIL(&tw->head, ts, entry); } if (ts == last) break; } TASKLET_WORKER_UNLOCK(tw); } static void tasklet_subsystem_init(void *arg __unused) { struct tasklet_worker *tw; char buf[32]; int i; CPU_FOREACH(i) { if (CPU_ABSENT(i)) continue; tw = DPCPU_ID_PTR(i, tasklet_worker); mtx_init(&tw->mtx, "linux_tasklet", NULL, MTX_DEF); TAILQ_INIT(&tw->head); GROUPTASK_INIT(&tw->gtask, 0, tasklet_handler, tw); snprintf(buf, sizeof(buf), "softirq%d", i); taskqgroup_attach_cpu(qgroup_softirq, &tw->gtask, "tasklet", i, NULL, NULL, buf); } } SYSINIT(linux_tasklet, SI_SUB_TASKQ, SI_ORDER_THIRD, tasklet_subsystem_init, NULL); static void tasklet_subsystem_uninit(void *arg __unused) { struct tasklet_worker *tw; int i; taskqgroup_drain_all(qgroup_softirq); CPU_FOREACH(i) { if (CPU_ABSENT(i)) continue; tw = DPCPU_ID_PTR(i, tasklet_worker); taskqgroup_detach(qgroup_softirq, &tw->gtask); mtx_destroy(&tw->mtx); } } SYSUNINIT(linux_tasklet, SI_SUB_TASKQ, SI_ORDER_THIRD, tasklet_subsystem_uninit, NULL); void tasklet_init(struct tasklet_struct *ts, tasklet_func_t *func, unsigned long data) { ts->entry.tqe_prev = NULL; ts->entry.tqe_next = NULL; ts->func = func; + ts->callback = NULL; ts->data = data; atomic_set_int(&ts->tasklet_state, TASKLET_ST_IDLE); atomic_set(&ts->count, 0); + ts->use_callback = false; +} + +void +tasklet_setup(struct tasklet_struct *ts, tasklet_callback_t *c) +{ + ts->entry.tqe_prev = NULL; + ts->entry.tqe_next = NULL; + ts->func = NULL; + ts->callback = c; + ts->data = 0; + atomic_set_int(&ts->tasklet_state, TASKLET_ST_IDLE); + atomic_set(&ts->count, 0); + ts->use_callback = true; } void local_bh_enable(void) { sched_unpin(); } void local_bh_disable(void) { sched_pin(); } void tasklet_schedule(struct tasklet_struct *ts) { /* tasklet is paused */ if (atomic_read(&ts->count)) return; if (TASKLET_ST_CMPSET(ts, TASKLET_ST_EXEC, TASKLET_ST_LOOP)) { /* tasklet_handler() will loop */ } else if (TASKLET_ST_CMPSET(ts, TASKLET_ST_IDLE, TASKLET_ST_BUSY)) { struct tasklet_worker *tw; tw = &DPCPU_GET(tasklet_worker); /* tasklet_handler() was not queued */ TASKLET_WORKER_LOCK(tw); /* enqueue tasklet */ TAILQ_INSERT_TAIL(&tw->head, ts, entry); /* schedule worker */ GROUPTASK_ENQUEUE(&tw->gtask); TASKLET_WORKER_UNLOCK(tw); } else { /* * tasklet_handler() is already executing * * If the state is neither EXEC nor IDLE, it is either * LOOP or BUSY. If the state changed between the two * CMPSET's above the only possible transitions by * elimination are LOOP->EXEC and BUSY->EXEC. If a * EXEC->LOOP transition was missed that is not a * problem because the callback function is then * already about to be called again. */ } } void tasklet_kill(struct tasklet_struct *ts) { WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "tasklet_kill() can sleep"); /* wait until tasklet is no longer busy */ while (TASKLET_ST_GET(ts) != TASKLET_ST_IDLE) pause("W", 1); } void tasklet_enable(struct tasklet_struct *ts) { atomic_dec(&ts->count); } void tasklet_disable(struct tasklet_struct *ts) { atomic_inc(&ts->count); tasklet_unlock_wait(ts); } void tasklet_disable_nosync(struct tasklet_struct *ts) { atomic_inc(&ts->count); barrier(); } int tasklet_trylock(struct tasklet_struct *ts) { return (TASKLET_ST_CMPSET(ts, TASKLET_ST_IDLE, TASKLET_ST_BUSY)); } void tasklet_unlock(struct tasklet_struct *ts) { TASKLET_ST_SET(ts, TASKLET_ST_IDLE); } void tasklet_unlock_wait(struct tasklet_struct *ts) { WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "tasklet_kill() can sleep"); /* wait until tasklet is no longer busy */ while (TASKLET_ST_GET(ts) != TASKLET_ST_IDLE) pause("W", 1); } diff --git a/sys/dev/irdma/fbsd_kcompat.h b/sys/dev/irdma/fbsd_kcompat.h index 179229d6be03..a6e3941440f8 100644 --- a/sys/dev/irdma/fbsd_kcompat.h +++ b/sys/dev/irdma/fbsd_kcompat.h @@ -1,251 +1,253 @@ /*- * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB * * Copyright (c) 2021 - 2022 Intel Corporation * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenFabrics.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - 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. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /*$FreeBSD$*/ #ifndef FBSD_KCOMPAT_H #define FBSD_KCOMPAT_H #include "ice_rdma.h" #define TASKLET_DATA_TYPE unsigned long #define TASKLET_FUNC_TYPE void (*)(TASKLET_DATA_TYPE) #define tasklet_setup(tasklet, callback) \ tasklet_init((tasklet), (TASKLET_FUNC_TYPE)(callback), \ (TASKLET_DATA_TYPE)(tasklet)) +#ifndef from_tasklet #define from_tasklet(var, callback_tasklet, tasklet_fieldname) \ container_of(callback_tasklet, typeof(*var), tasklet_fieldname) +#endif #define IRDMA_SET_RDMA_OBJ_SIZE(ib_struct, drv_struct, member) \ (sizeof(struct drv_struct) + \ BUILD_BUG_ON_ZERO(offsetof(struct drv_struct, member)) + \ BUILD_BUG_ON_ZERO( \ !__same_type(((struct drv_struct *)NULL)->member, \ struct ib_struct))) #define set_ibdev_dma_device(ibdev, dev) \ ibdev.dma_device = (dev) #define set_max_sge(props, rf) \ ((props)->max_sge = (rf)->sc_dev.hw_attrs.uk_attrs.max_hw_wq_frags) #define kc_set_props_ip_gid_caps(props) \ ((props)->port_cap_flags |= IB_PORT_IP_BASED_GIDS) #define rdma_query_gid(ibdev, port, index, gid) \ ib_get_cached_gid(ibdev, port, index, gid, NULL) #define kmap(pg) page_address(pg) #define kmap_local_page(pg) page_address(pg) #define kunmap(pg) #define kunmap_local(pg) #define kc_free_lsmm_dereg_mr(iwdev, iwqp) \ ((iwdev)->ibdev.dereg_mr((iwqp)->lsmm_mr, NULL)) #define IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION IB_CQ_FLAGS_TIMESTAMP_COMPLETION #define kc_irdma_destroy_qp(ibqp, udata) irdma_destroy_qp(ibqp, udata) #ifndef IB_QP_ATTR_STANDARD_BITS #define IB_QP_ATTR_STANDARD_BITS GENMASK(20, 0) #endif #define IRDMA_QOS_MODE_VLAN 0x0 #define IRDMA_QOS_MODE_DSCP 0x1 void kc_set_roce_uverbs_cmd_mask(struct irdma_device *iwdev); void kc_set_rdma_uverbs_cmd_mask(struct irdma_device *iwdev); struct irdma_tunable_info { struct sysctl_ctx_list irdma_sysctl_ctx; struct sysctl_oid *irdma_sysctl_tree; u8 roce_ena; }; static inline int irdma_iw_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) { *pkey = 0; return 0; } static inline int cq_validate_flags(u32 flags, u8 hw_rev) { /* GEN1 does not support CQ create flags */ if (hw_rev == IRDMA_GEN_1) return flags ? -EOPNOTSUPP : 0; return flags & ~IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION ? -EOPNOTSUPP : 0; } static inline u64 *irdma_next_pbl_addr(u64 *pbl, struct irdma_pble_info **pinfo, u32 *idx) { *idx += 1; if (!(*pinfo) || *idx != (*pinfo)->cnt) return ++pbl; *idx = 0; (*pinfo)++; return (*pinfo)->addr; } int irdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, struct ib_udata *udata); struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, struct ib_qp_init_attr *init_attr, struct ib_udata *udata); int irdma_create_ah(struct ib_ah *ib_ah, struct ib_ah_attr *attr, u32 flags, struct ib_udata *udata); int irdma_create_ah_stub(struct ib_ah *ib_ah, struct ib_ah_attr *attr, u32 flags, struct ib_udata *udata); void irdma_ether_copy(u8 *dmac, struct ib_ah_attr *attr); void irdma_destroy_ah(struct ib_ah *ibah, u32 flags); void irdma_destroy_ah_stub(struct ib_ah *ibah, u32 flags); int irdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata); int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata); void irdma_get_eth_speed_and_width(u32 link_speed, u8 *active_speed, u8 *active_width); enum rdma_link_layer irdma_get_link_layer(struct ib_device *ibdev, u8 port_num); int irdma_roce_port_immutable(struct ib_device *ibdev, u8 port_num, struct ib_port_immutable *immutable); int irdma_iw_port_immutable(struct ib_device *ibdev, u8 port_num, struct ib_port_immutable *immutable); int irdma_query_gid(struct ib_device *ibdev, u8 port, int index, union ib_gid *gid); int irdma_query_gid_roce(struct ib_device *ibdev, u8 port, int index, union ib_gid *gid); int irdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey); int irdma_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props); struct rdma_hw_stats *irdma_alloc_hw_stats(struct ib_device *ibdev, u8 port_num); int irdma_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, u8 port_num, int index); int irdma_register_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node); void irdma_unregister_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node); void ib_unregister_device(struct ib_device *ibdev); void irdma_disassociate_ucontext(struct ib_ucontext *context); int kc_irdma_set_roce_cm_info(struct irdma_qp *iwqp, struct ib_qp_attr *attr, u16 *vlan_id); struct irdma_device *kc_irdma_get_device(struct ifnet *netdev); void kc_irdma_put_device(struct irdma_device *iwdev); void kc_set_loc_seq_num_mss(struct irdma_cm_node *cm_node); void irdma_get_dev_fw_str(struct ib_device *dev, char *str, size_t str_len); int irdma_modify_port(struct ib_device *ibdev, u8 port, int mask, struct ib_port_modify *props); int irdma_get_dst_mac(struct irdma_cm_node *cm_node, struct sockaddr *dst_sin, u8 *dst_mac); int irdma_resolve_neigh_lpb_chk(struct irdma_device *iwdev, struct irdma_cm_node *cm_node, struct irdma_cm_info *cm_info); int irdma_addr_resolve_neigh(struct irdma_cm_node *cm_node, u32 dst_ip, int arpindex); int irdma_addr_resolve_neigh_ipv6(struct irdma_cm_node *cm_node, u32 *dest, int arpindex); void irdma_dcqcn_tunables_init(struct irdma_pci_f *rf); u32 irdma_create_stag(struct irdma_device *iwdev); void irdma_free_stag(struct irdma_device *iwdev, u32 stag); struct irdma_mr; struct irdma_cq; struct irdma_cq_buf; struct ib_mr *irdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max_num_sg, struct ib_udata *udata); int irdma_hw_alloc_mw(struct irdma_device *iwdev, struct irdma_mr *iwmr); struct ib_mw *irdma_alloc_mw(struct ib_pd *pd, enum ib_mw_type type, struct ib_udata *udata); int irdma_hw_alloc_stag(struct irdma_device *iwdev, struct irdma_mr *iwmr); void irdma_cq_free_rsrc(struct irdma_pci_f *rf, struct irdma_cq *iwcq); int irdma_validate_qp_attrs(struct ib_qp_init_attr *init_attr, struct irdma_device *iwdev); void irdma_setup_virt_qp(struct irdma_device *iwdev, struct irdma_qp *iwqp, struct irdma_qp_init_info *init_info); int irdma_setup_kmode_qp(struct irdma_device *iwdev, struct irdma_qp *iwqp, struct irdma_qp_init_info *info, struct ib_qp_init_attr *init_attr); void irdma_roce_fill_and_set_qpctx_info(struct irdma_qp *iwqp, struct irdma_qp_host_ctx_info *ctx_info); void irdma_iw_fill_and_set_qpctx_info(struct irdma_qp *iwqp, struct irdma_qp_host_ctx_info *ctx_info); int irdma_cqp_create_qp_cmd(struct irdma_qp *iwqp); void irdma_dealloc_push_page(struct irdma_pci_f *rf, struct irdma_sc_qp *qp); int irdma_process_resize_list(struct irdma_cq *iwcq, struct irdma_device *iwdev, struct irdma_cq_buf *lcqe_buf); void irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata); int irdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata); void irdma_dealloc_ucontext(struct ib_ucontext *context); int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata); void irdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); int irdma_add_gid(struct ib_device *, u8, unsigned int, const union ib_gid *, const struct ib_gid_attr *, void **); int irdma_del_gid(struct ib_device *, u8, unsigned int, void **); struct ib_device *ib_device_get_by_netdev(struct ifnet *ndev, int driver_id); void ib_device_put(struct ib_device *device); void ib_unregister_device_put(struct ib_device *device); enum ib_mtu ib_mtu_int_to_enum(int mtu); struct irdma_pbl *irdma_get_pbl(unsigned long va, struct list_head *pbl_list); void irdma_clean_cqes(struct irdma_qp *iwqp, struct irdma_cq *iwcq); void irdma_remove_push_mmap_entries(struct irdma_qp *iwqp); struct irdma_ucontext; void irdma_del_memlist(struct irdma_mr *iwmr, struct irdma_ucontext *ucontext); void irdma_copy_user_pgaddrs(struct irdma_mr *iwmr, u64 *pbl, enum irdma_pble_level level); void irdma_reg_ipaddr_event_cb(struct irdma_pci_f *rf); void irdma_dereg_ipaddr_event_cb(struct irdma_pci_f *rf); /* Introduced in this series https://lore.kernel.org/linux-rdma/0-v2-270386b7e60b+28f4-umem_1_jgg@nvidia.com/ * An irdma version helper doing same for older functions with difference that iova is passed in * as opposed to derived from umem->iova. */ static inline size_t irdma_ib_umem_num_dma_blocks(struct ib_umem *umem, unsigned long pgsz, u64 iova) { /* some older OFED distros do not have ALIGN_DOWN */ #ifndef ALIGN_DOWN #define ALIGN_DOWN(x, a) ALIGN((x) - ((a) - 1), (a)) #endif return (size_t)((ALIGN(iova + umem->length, pgsz) - ALIGN_DOWN(iova, pgsz))) / pgsz; } #endif /* FBSD_KCOMPAT_H */