freebsd_iflib: Import.

This is the iflib from FreeBSD 12.0 with a few select patches from
FreeBSD trunk applied (and a lot of #ifdef __HAIKU__s, as you can see.)

There are certain things it adds to SYSINIT that can't be un-initialized
(like the grouptaskqueues), and so rather than adding this to every
driver unnecessarily, a separate .a for it makes the most sense.
This commit is contained in:
Augustin Cavalier
2019-01-03 21:20:36 -05:00
parent fd41233b07
commit 83c8026372
22 changed files with 13104 additions and 0 deletions
+1
View File
@@ -1,4 +1,5 @@
SubDir HAIKU_TOP src libs compat ;
SubInclude HAIKU_TOP src libs compat freebsd_network ;
SubInclude HAIKU_TOP src libs compat freebsd_iflib ;
SubInclude HAIKU_TOP src libs compat freebsd11_wlan ;
+22
View File
@@ -0,0 +1,22 @@
SubDir HAIKU_TOP src libs compat freebsd_iflib ;
UseHeaders [ FDirName $(SUBDIR) compat ] : true ;
UseHeaders [ FDirName $(SUBDIR) .. freebsd_network compat ] : true ;
UsePrivateHeaders net ;
UsePrivateKernelHeaders ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 _XOPEN_SOURCE ALTQ ] ;
KernelStaticLibrary freebsd_iflib.a :
kthread.cpp
device_if.c
kobj.c
iflib.c
ifdi_if.c
md5c.c
mp_ring.c
nvlist.c
subr_gtaskqueue.c
strsep.c
;
@@ -0,0 +1,613 @@
/*
* This file is produced automatically.
* Do not modify anything in here by hand.
*
* Created from source file
* sys/net/ifdi_if.m
#
# Copyright (c) 2014-2018, Matthew Macy ([email protected])
# 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,
# this list of conditions and the following disclaimer.
#
# 2. Neither the name of Matthew Macy nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _ifdi_if_h_
#define _ifdi_if_h_
#ifndef __HAIKU__
extern struct kobjop_desc ifdi_knlist_add_desc;
typedef int ifdi_knlist_add_t(if_ctx_t _ctx, struct knote *_kn);
static __inline int IFDI_KNLIST_ADD(if_ctx_t _ctx, struct knote *_kn)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_knlist_add);
rc = ((ifdi_knlist_add_t *) _m)(_ctx, _kn);
return (rc);
}
extern struct kobjop_desc ifdi_knote_event_desc;
typedef int ifdi_knote_event_t(if_ctx_t _ctx, struct knote *_kn, int hint);
static __inline int IFDI_KNOTE_EVENT(if_ctx_t _ctx, struct knote *_kn, int hint)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_knote_event);
rc = ((ifdi_knote_event_t *) _m)(_ctx, _kn, hint);
return (rc);
}
#endif
extern struct kobjop_desc ifdi_object_info_get_desc;
typedef int ifdi_object_info_get_t(if_ctx_t _ctx, void *data, int size);
static __inline int IFDI_OBJECT_INFO_GET(if_ctx_t _ctx, void *data, int size)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_object_info_get);
rc = ((ifdi_object_info_get_t *) _m)(_ctx, data, size);
return (rc);
}
extern struct kobjop_desc ifdi_attach_pre_desc;
typedef int ifdi_attach_pre_t(if_ctx_t _ctx);
static __inline int IFDI_ATTACH_PRE(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_attach_pre);
rc = ((ifdi_attach_pre_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_attach_post_desc;
typedef int ifdi_attach_post_t(if_ctx_t _ctx);
static __inline int IFDI_ATTACH_POST(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_attach_post);
rc = ((ifdi_attach_post_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_reinit_pre_desc;
typedef int ifdi_reinit_pre_t(if_ctx_t _ctx);
static __inline int IFDI_REINIT_PRE(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_reinit_pre);
rc = ((ifdi_reinit_pre_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_reinit_post_desc;
typedef int ifdi_reinit_post_t(if_ctx_t _ctx);
static __inline int IFDI_REINIT_POST(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_reinit_post);
rc = ((ifdi_reinit_post_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_cloneattach_desc;
typedef int ifdi_cloneattach_t(if_ctx_t _ctx, struct if_clone *_ifc,
const char *_name, caddr_t params);
static __inline int IFDI_CLONEATTACH(if_ctx_t _ctx, struct if_clone *_ifc,
const char *_name, caddr_t params)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_cloneattach);
rc = ((ifdi_cloneattach_t *) _m)(_ctx, _ifc, _name, params);
return (rc);
}
extern struct kobjop_desc ifdi_detach_desc;
typedef int ifdi_detach_t(if_ctx_t _ctx);
static __inline int IFDI_DETACH(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_detach);
rc = ((ifdi_detach_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_suspend_desc;
typedef int ifdi_suspend_t(if_ctx_t _ctx);
static __inline int IFDI_SUSPEND(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_suspend);
rc = ((ifdi_suspend_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_shutdown_desc;
typedef int ifdi_shutdown_t(if_ctx_t _ctx);
static __inline int IFDI_SHUTDOWN(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_shutdown);
rc = ((ifdi_shutdown_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_resume_desc;
typedef int ifdi_resume_t(if_ctx_t _ctx);
static __inline int IFDI_RESUME(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_resume);
rc = ((ifdi_resume_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_tx_queues_alloc_desc;
typedef int ifdi_tx_queues_alloc_t(if_ctx_t _ctx, caddr_t *_vaddrs,
uint64_t *_paddrs, int ntxqs, int ntxqsets);
static __inline int IFDI_TX_QUEUES_ALLOC(if_ctx_t _ctx, caddr_t *_vaddrs,
uint64_t *_paddrs, int ntxqs,
int ntxqsets)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_tx_queues_alloc);
rc = ((ifdi_tx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, ntxqs, ntxqsets);
return (rc);
}
extern struct kobjop_desc ifdi_rx_queues_alloc_desc;
typedef int ifdi_rx_queues_alloc_t(if_ctx_t _ctx, caddr_t *_vaddrs,
uint64_t *_paddrs, int nrxqs, int nrxqsets);
static __inline int IFDI_RX_QUEUES_ALLOC(if_ctx_t _ctx, caddr_t *_vaddrs,
uint64_t *_paddrs, int nrxqs,
int nrxqsets)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rx_queues_alloc);
rc = ((ifdi_rx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, nrxqs, nrxqsets);
return (rc);
}
extern struct kobjop_desc ifdi_queues_free_desc;
typedef void ifdi_queues_free_t(if_ctx_t _ctx);
static __inline void IFDI_QUEUES_FREE(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_queues_free);
((ifdi_queues_free_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_rx_clset_desc;
typedef void ifdi_rx_clset_t(if_ctx_t _ctx, uint16_t _fl, uint16_t _qsetid,
caddr_t *_sdcl);
static __inline void IFDI_RX_CLSET(if_ctx_t _ctx, uint16_t _fl,
uint16_t _qsetid, caddr_t *_sdcl)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rx_clset);
((ifdi_rx_clset_t *) _m)(_ctx, _fl, _qsetid, _sdcl);
}
extern struct kobjop_desc ifdi_init_desc;
typedef void ifdi_init_t(if_ctx_t _ctx);
static __inline void IFDI_INIT(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_init);
((ifdi_init_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_stop_desc;
typedef void ifdi_stop_t(if_ctx_t _ctx);
static __inline void IFDI_STOP(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_stop);
((ifdi_stop_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_msix_intr_assign_desc;
typedef int ifdi_msix_intr_assign_t(if_ctx_t _sctx, int msix);
static __inline int IFDI_MSIX_INTR_ASSIGN(if_ctx_t _sctx, int msix)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_sctx)->ops,ifdi_msix_intr_assign);
rc = ((ifdi_msix_intr_assign_t *) _m)(_sctx, msix);
return (rc);
}
extern struct kobjop_desc ifdi_intr_enable_desc;
typedef void ifdi_intr_enable_t(if_ctx_t _ctx);
static __inline void IFDI_INTR_ENABLE(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_intr_enable);
((ifdi_intr_enable_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_intr_disable_desc;
typedef void ifdi_intr_disable_t(if_ctx_t _ctx);
static __inline void IFDI_INTR_DISABLE(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_intr_disable);
((ifdi_intr_disable_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_rx_queue_intr_enable_desc;
typedef int ifdi_rx_queue_intr_enable_t(if_ctx_t _ctx, uint16_t _qid);
static __inline int IFDI_RX_QUEUE_INTR_ENABLE(if_ctx_t _ctx, uint16_t _qid)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rx_queue_intr_enable);
rc = ((ifdi_rx_queue_intr_enable_t *) _m)(_ctx, _qid);
return (rc);
}
extern struct kobjop_desc ifdi_tx_queue_intr_enable_desc;
typedef int ifdi_tx_queue_intr_enable_t(if_ctx_t _ctx, uint16_t _qid);
static __inline int IFDI_TX_QUEUE_INTR_ENABLE(if_ctx_t _ctx, uint16_t _qid)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_tx_queue_intr_enable);
rc = ((ifdi_tx_queue_intr_enable_t *) _m)(_ctx, _qid);
return (rc);
}
extern struct kobjop_desc ifdi_link_intr_enable_desc;
typedef void ifdi_link_intr_enable_t(if_ctx_t _ctx);
static __inline void IFDI_LINK_INTR_ENABLE(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_link_intr_enable);
((ifdi_link_intr_enable_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_multi_set_desc;
typedef void ifdi_multi_set_t(if_ctx_t _ctx);
static __inline void IFDI_MULTI_SET(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_multi_set);
((ifdi_multi_set_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_mtu_set_desc;
typedef int ifdi_mtu_set_t(if_ctx_t _ctx, uint32_t _mtu);
static __inline int IFDI_MTU_SET(if_ctx_t _ctx, uint32_t _mtu)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_mtu_set);
rc = ((ifdi_mtu_set_t *) _m)(_ctx, _mtu);
return (rc);
}
extern struct kobjop_desc ifdi_mac_set_desc;
typedef int ifdi_mac_set_t(if_ctx_t _ctx, const uint8_t *_mac);
static __inline int IFDI_MAC_SET(if_ctx_t _ctx, const uint8_t *_mac)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_mac_set);
rc = ((ifdi_mac_set_t *) _m)(_ctx, _mac);
return (rc);
}
extern struct kobjop_desc ifdi_media_set_desc;
typedef void ifdi_media_set_t(if_ctx_t _ctx);
static __inline void IFDI_MEDIA_SET(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_media_set);
((ifdi_media_set_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_promisc_set_desc;
typedef int ifdi_promisc_set_t(if_ctx_t _ctx, int _flags);
static __inline int IFDI_PROMISC_SET(if_ctx_t _ctx, int _flags)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_promisc_set);
rc = ((ifdi_promisc_set_t *) _m)(_ctx, _flags);
return (rc);
}
extern struct kobjop_desc ifdi_crcstrip_set_desc;
typedef void ifdi_crcstrip_set_t(if_ctx_t _ctx, int _onoff, int _strip);
static __inline void IFDI_CRCSTRIP_SET(if_ctx_t _ctx, int _onoff, int _strip)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_crcstrip_set);
((ifdi_crcstrip_set_t *) _m)(_ctx, _onoff, _strip);
}
extern struct kobjop_desc ifdi_vflr_handle_desc;
typedef void ifdi_vflr_handle_t(if_ctx_t _ctx);
static __inline void IFDI_VFLR_HANDLE(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_vflr_handle);
((ifdi_vflr_handle_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_iov_init_desc;
typedef int ifdi_iov_init_t(if_ctx_t _ctx, uint16_t num_vfs,
const nvlist_t * params);
static __inline int IFDI_IOV_INIT(if_ctx_t _ctx, uint16_t num_vfs,
const nvlist_t * params)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_iov_init);
rc = ((ifdi_iov_init_t *) _m)(_ctx, num_vfs, params);
return (rc);
}
extern struct kobjop_desc ifdi_iov_uninit_desc;
typedef void ifdi_iov_uninit_t(if_ctx_t _ctx);
static __inline void IFDI_IOV_UNINIT(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_iov_uninit);
((ifdi_iov_uninit_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_iov_vf_add_desc;
typedef int ifdi_iov_vf_add_t(if_ctx_t _ctx, uint16_t num_vfs,
const nvlist_t * params);
static __inline int IFDI_IOV_VF_ADD(if_ctx_t _ctx, uint16_t num_vfs,
const nvlist_t * params)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_iov_vf_add);
rc = ((ifdi_iov_vf_add_t *) _m)(_ctx, num_vfs, params);
return (rc);
}
extern struct kobjop_desc ifdi_update_admin_status_desc;
typedef void ifdi_update_admin_status_t(if_ctx_t _ctx);
static __inline void IFDI_UPDATE_ADMIN_STATUS(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_update_admin_status);
((ifdi_update_admin_status_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_media_status_desc;
typedef void ifdi_media_status_t(if_ctx_t _ctx, struct ifmediareq *_ifm);
static __inline void IFDI_MEDIA_STATUS(if_ctx_t _ctx, struct ifmediareq *_ifm)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_media_status);
((ifdi_media_status_t *) _m)(_ctx, _ifm);
}
extern struct kobjop_desc ifdi_media_change_desc;
typedef int ifdi_media_change_t(if_ctx_t _ctx);
static __inline int IFDI_MEDIA_CHANGE(if_ctx_t _ctx)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_media_change);
rc = ((ifdi_media_change_t *) _m)(_ctx);
return (rc);
}
extern struct kobjop_desc ifdi_get_counter_desc;
typedef uint64_t ifdi_get_counter_t(if_ctx_t _ctx, ift_counter cnt);
static __inline uint64_t IFDI_GET_COUNTER(if_ctx_t _ctx, ift_counter cnt)
{
kobjop_t _m;
uint64_t rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_get_counter);
rc = ((ifdi_get_counter_t *) _m)(_ctx, cnt);
return (rc);
}
extern struct kobjop_desc ifdi_priv_ioctl_desc;
typedef int ifdi_priv_ioctl_t(if_ctx_t _ctx, u_long _cmd, caddr_t _data);
static __inline int IFDI_PRIV_IOCTL(if_ctx_t _ctx, u_long _cmd, caddr_t _data)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_priv_ioctl);
rc = ((ifdi_priv_ioctl_t *) _m)(_ctx, _cmd, _data);
return (rc);
}
extern struct kobjop_desc ifdi_i2c_req_desc;
typedef int ifdi_i2c_req_t(if_ctx_t _ctx, struct ifi2creq *_req);
static __inline int IFDI_I2C_REQ(if_ctx_t _ctx, struct ifi2creq *_req)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_i2c_req);
rc = ((ifdi_i2c_req_t *) _m)(_ctx, _req);
return (rc);
}
extern struct kobjop_desc ifdi_txq_setup_desc;
typedef int ifdi_txq_setup_t(if_ctx_t _ctx, uint32_t _txqid);
static __inline int IFDI_TXQ_SETUP(if_ctx_t _ctx, uint32_t _txqid)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_txq_setup);
rc = ((ifdi_txq_setup_t *) _m)(_ctx, _txqid);
return (rc);
}
extern struct kobjop_desc ifdi_rxq_setup_desc;
typedef int ifdi_rxq_setup_t(if_ctx_t _ctx, uint32_t _txqid);
static __inline int IFDI_RXQ_SETUP(if_ctx_t _ctx, uint32_t _txqid)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rxq_setup);
rc = ((ifdi_rxq_setup_t *) _m)(_ctx, _txqid);
return (rc);
}
extern struct kobjop_desc ifdi_timer_desc;
typedef void ifdi_timer_t(if_ctx_t _ctx, uint16_t _txqid);
static __inline void IFDI_TIMER(if_ctx_t _ctx, uint16_t _txqid)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_timer);
((ifdi_timer_t *) _m)(_ctx, _txqid);
}
extern struct kobjop_desc ifdi_watchdog_reset_desc;
typedef void ifdi_watchdog_reset_t(if_ctx_t _ctx);
static __inline void IFDI_WATCHDOG_RESET(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_watchdog_reset);
((ifdi_watchdog_reset_t *) _m)(_ctx);
}
extern struct kobjop_desc ifdi_watchdog_reset_queue_desc;
typedef void ifdi_watchdog_reset_queue_t(if_ctx_t _ctx, uint16_t _q);
static __inline void IFDI_WATCHDOG_RESET_QUEUE(if_ctx_t _ctx, uint16_t _q)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_watchdog_reset_queue);
((ifdi_watchdog_reset_queue_t *) _m)(_ctx, _q);
}
extern struct kobjop_desc ifdi_led_func_desc;
typedef void ifdi_led_func_t(if_ctx_t _ctx, int _onoff);
static __inline void IFDI_LED_FUNC(if_ctx_t _ctx, int _onoff)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_led_func);
((ifdi_led_func_t *) _m)(_ctx, _onoff);
}
extern struct kobjop_desc ifdi_vlan_register_desc;
typedef void ifdi_vlan_register_t(if_ctx_t _ctx, uint16_t _vtag);
static __inline void IFDI_VLAN_REGISTER(if_ctx_t _ctx, uint16_t _vtag)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_vlan_register);
((ifdi_vlan_register_t *) _m)(_ctx, _vtag);
}
extern struct kobjop_desc ifdi_vlan_unregister_desc;
typedef void ifdi_vlan_unregister_t(if_ctx_t _ctx, uint16_t _vtag);
static __inline void IFDI_VLAN_UNREGISTER(if_ctx_t _ctx, uint16_t _vtag)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_vlan_unregister);
((ifdi_vlan_unregister_t *) _m)(_ctx, _vtag);
}
extern struct kobjop_desc ifdi_sysctl_int_delay_desc;
typedef int ifdi_sysctl_int_delay_t(if_ctx_t _sctx, if_int_delay_info_t _iidi);
static __inline int IFDI_SYSCTL_INT_DELAY(if_ctx_t _sctx,
if_int_delay_info_t _iidi)
{
kobjop_t _m;
int rc;
KOBJOPLOOKUP(((kobj_t)_sctx)->ops,ifdi_sysctl_int_delay);
rc = ((ifdi_sysctl_int_delay_t *) _m)(_sctx, _iidi);
return (rc);
}
extern struct kobjop_desc ifdi_debug_desc;
typedef void ifdi_debug_t(if_ctx_t _ctx);
static __inline void IFDI_DEBUG(if_ctx_t _ctx)
{
kobjop_t _m;
KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_debug);
((ifdi_debug_t *) _m)(_ctx);
}
#endif
@@ -0,0 +1,450 @@
/*-
* Copyright (c) 2014-2017, Matthew Macy ([email protected])
* 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,
* this list of conditions and the following disclaimer.
*
* 2. Neither the name of Matthew Macy nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __IFLIB_H_
#define __IFLIB_H_
#include <sys/kobj.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/nv.h>
#include <sys/gtaskqueue.h>
struct if_clone;
/*
* The value type for indexing, limits max descriptors
* to 65535 can be conditionally redefined to uint32_t
* in the future if the need arises.
*/
typedef uint16_t qidx_t;
#define QIDX_INVALID 0xFFFF
struct iflib_ctx;
typedef struct iflib_ctx *if_ctx_t;
struct if_shared_ctx;
typedef struct if_shared_ctx *if_shared_ctx_t;
struct if_int_delay_info;
typedef struct if_int_delay_info *if_int_delay_info_t;
struct if_pseudo;
typedef struct if_pseudo *if_pseudo_t;
/*
* File organization:
* - public structures
* - iflib accessors
* - iflib utility functions
* - iflib core functions
*/
typedef struct if_rxd_frag {
uint8_t irf_flid;
qidx_t irf_idx;
uint16_t irf_len;
} *if_rxd_frag_t;
typedef struct if_rxd_info {
/* set by iflib */
uint16_t iri_qsidx; /* qset index */
uint16_t iri_vtag; /* vlan tag - if flag set */
/* XXX redundant with the new irf_len field */
uint16_t iri_len; /* packet length */
qidx_t iri_cidx; /* consumer index of cq */
struct ifnet *iri_ifp; /* some drivers >1 interface per softc */
/* updated by driver */
if_rxd_frag_t iri_frags;
uint32_t iri_flowid; /* RSS hash for packet */
uint32_t iri_csum_flags; /* m_pkthdr csum flags */
uint32_t iri_csum_data; /* m_pkthdr csum data */
uint8_t iri_flags; /* mbuf flags for packet */
uint8_t iri_nfrags; /* number of fragments in packet */
uint8_t iri_rsstype; /* RSS hash type */
uint8_t iri_pad; /* any padding in the received data */
} *if_rxd_info_t;
typedef struct if_rxd_update {
uint64_t *iru_paddrs;
caddr_t *iru_vaddrs;
qidx_t *iru_idxs;
qidx_t iru_pidx;
uint16_t iru_qsidx;
uint16_t iru_count;
uint16_t iru_buf_size;
uint8_t iru_flidx;
} *if_rxd_update_t;
#define IPI_TX_INTR 0x1 /* send an interrupt when this packet is sent */
#define IPI_TX_IPV4 0x2 /* ethertype IPv4 */
#define IPI_TX_IPV6 0x4 /* ethertype IPv6 */
typedef struct if_pkt_info {
bus_dma_segment_t *ipi_segs; /* physical addresses */
uint32_t ipi_len; /* packet length */
uint16_t ipi_qsidx; /* queue set index */
qidx_t ipi_nsegs; /* number of segments */
qidx_t ipi_ndescs; /* number of descriptors used by encap */
uint16_t ipi_flags; /* iflib per-packet flags */
qidx_t ipi_pidx; /* start pidx for encap */
qidx_t ipi_new_pidx; /* next available pidx post-encap */
/* offload handling */
uint8_t ipi_ehdrlen; /* ether header length */
uint8_t ipi_ip_hlen; /* ip header length */
uint8_t ipi_tcp_hlen; /* tcp header length */
uint8_t ipi_ipproto; /* ip protocol */
uint32_t ipi_csum_flags; /* packet checksum flags */
uint16_t ipi_tso_segsz; /* tso segment size */
uint16_t ipi_vtag; /* VLAN tag */
uint16_t ipi_etype; /* ether header type */
uint8_t ipi_tcp_hflags; /* tcp header flags */
uint8_t ipi_mflags; /* packet mbuf flags */
uint32_t ipi_tcp_seq; /* tcp seqno */
uint32_t ipi_tcp_sum; /* tcp csum */
} *if_pkt_info_t;
typedef struct if_irq {
struct resource *ii_res;
int ii_rid;
void *ii_tag;
} *if_irq_t;
struct if_int_delay_info {
if_ctx_t iidi_ctx; /* Back-pointer to the iflib ctx (softc) */
int iidi_offset; /* Register offset to read/write */
int iidi_value; /* Current value in usecs */
struct sysctl_oid *iidi_oidp;
struct sysctl_req *iidi_req;
};
typedef enum {
IFLIB_INTR_LEGACY,
IFLIB_INTR_MSI,
IFLIB_INTR_MSIX
} iflib_intr_mode_t;
/*
* This really belongs in pciio.h or some place more general
* but this is the only consumer for now.
*/
typedef struct pci_vendor_info {
uint32_t pvi_vendor_id;
uint32_t pvi_device_id;
uint32_t pvi_subvendor_id;
uint32_t pvi_subdevice_id;
uint32_t pvi_rev_id;
uint32_t pvi_class_mask;
caddr_t pvi_name;
} pci_vendor_info_t;
#define PVID(vendor, devid, name) {vendor, devid, 0, 0, 0, 0, name}
#define PVID_OEM(vendor, devid, svid, sdevid, revid, name) {vendor, devid, svid, sdevid, revid, 0, name}
#define PVID_END {0, 0, 0, 0, 0, 0, NULL}
#define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \
"U32:revision;U32:class;D:#"
#define IFLIB_PNP_INFO(b, u, t) \
MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, nitems(t) - 1)
typedef struct if_txrx {
int (*ift_txd_encap) (void *, if_pkt_info_t);
void (*ift_txd_flush) (void *, uint16_t, qidx_t pidx);
int (*ift_txd_credits_update) (void *, uint16_t qsidx, bool clear);
int (*ift_rxd_available) (void *, uint16_t qsidx, qidx_t pidx, qidx_t budget);
int (*ift_rxd_pkt_get) (void *, if_rxd_info_t ri);
void (*ift_rxd_refill) (void * , if_rxd_update_t iru);
void (*ift_rxd_flush) (void *, uint16_t qsidx, uint8_t flidx, qidx_t pidx);
int (*ift_legacy_intr) (void *);
} *if_txrx_t;
typedef struct if_softc_ctx {
int isc_vectors;
int isc_nrxqsets;
int isc_ntxqsets;
uint8_t isc_min_tx_latency; /* disable doorbell update batching */
uint8_t isc_rx_mvec_enable; /* generate mvecs on rx */
uint32_t isc_txrx_budget_bytes_max;
int isc_msix_bar; /* can be model specific - initialize in attach_pre */
int isc_tx_nsegments; /* can be model specific - initialize in attach_pre */
int isc_ntxd[8];
int isc_nrxd[8];
uint32_t isc_txqsizes[8];
uint32_t isc_rxqsizes[8];
/* is there such thing as a descriptor that is more than 248 bytes ? */
uint8_t isc_txd_size[8];
uint8_t isc_rxd_size[8];
int isc_tx_tso_segments_max;
int isc_tx_tso_size_max;
int isc_tx_tso_segsize_max;
int isc_tx_csum_flags;
int isc_capabilities;
int isc_capenable;
int isc_rss_table_size;
int isc_rss_table_mask;
int isc_nrxqsets_max;
int isc_ntxqsets_max;
uint32_t isc_tx_qdepth;
iflib_intr_mode_t isc_intr;
uint16_t isc_max_frame_size; /* set at init time by driver */
uint16_t isc_min_frame_size; /* set at init time by driver, only used if
IFLIB_NEED_ETHER_PAD is set. */
uint32_t isc_pause_frames; /* set by driver for iflib_timer to detect */
pci_vendor_info_t isc_vendor_info; /* set by iflib prior to attach_pre */
int isc_disable_msix;
if_txrx_t isc_txrx;
} *if_softc_ctx_t;
/*
* Initialization values for device
*/
struct if_shared_ctx {
unsigned isc_magic;
driver_t *isc_driver;
bus_size_t isc_q_align;
bus_size_t isc_tx_maxsize;
bus_size_t isc_tx_maxsegsize;
bus_size_t isc_tso_maxsize;
bus_size_t isc_tso_maxsegsize;
bus_size_t isc_rx_maxsize;
bus_size_t isc_rx_maxsegsize;
int isc_rx_nsegments;
int isc_admin_intrcnt; /* # of admin/link interrupts */
/* fields necessary for probe */
pci_vendor_info_t *isc_vendor_info;
char *isc_driver_version;
/* optional function to transform the read values to match the table*/
void (*isc_parse_devinfo) (uint16_t *device_id, uint16_t *subvendor_id,
uint16_t *subdevice_id, uint16_t *rev_id);
int isc_nrxd_min[8];
int isc_nrxd_default[8];
int isc_nrxd_max[8];
int isc_ntxd_min[8];
int isc_ntxd_default[8];
int isc_ntxd_max[8];
/* actively used during operation */
int isc_nfl __aligned(CACHE_LINE_SIZE);
int isc_ntxqs; /* # of tx queues per tx qset - usually 1 */
int isc_nrxqs; /* # of rx queues per rx qset - intel 1, chelsio 2, broadcom 3 */
int isc_rx_process_limit;
int isc_tx_reclaim_thresh;
int isc_flags;
const char *isc_name;
};
typedef struct iflib_dma_info {
bus_addr_t idi_paddr;
caddr_t idi_vaddr;
bus_dma_tag_t idi_tag;
bus_dmamap_t idi_map;
uint32_t idi_size;
} *iflib_dma_info_t;
#define IFLIB_MAGIC 0xCAFEF00D
typedef enum {
IFLIB_INTR_RX,
IFLIB_INTR_TX,
IFLIB_INTR_RXTX,
IFLIB_INTR_ADMIN,
IFLIB_INTR_IOV,
} iflib_intr_type_t;
#ifndef ETH_ADDR_LEN
#define ETH_ADDR_LEN 6
#endif
/*
* Interface has a separate command queue for RX
*/
#define IFLIB_HAS_RXCQ 0x01
/*
* Driver has already allocated vectors
*/
#define IFLIB_SKIP_MSIX 0x02
/*
* Interface is a virtual function
*/
#define IFLIB_IS_VF 0x04
/*
* Interface has a separate command queue for TX
*/
#define IFLIB_HAS_TXCQ 0x08
/*
* Interface does checksum in place
*/
#define IFLIB_NEED_SCRATCH 0x10
/*
* Interface doesn't expect in_pseudo for th_sum
*/
#define IFLIB_TSO_INIT_IP 0x20
/*
* Interface doesn't align IP header
*/
#define IFLIB_DO_RX_FIXUP 0x40
/*
* Driver needs csum zeroed for offloading
*/
#define IFLIB_NEED_ZERO_CSUM 0x80
/*
* Driver needs frames padded to some minimum length
*/
#define IFLIB_NEED_ETHER_PAD 0x100
/*
* Packets can be freed immediately after encap
*/
#define IFLIB_TXD_ENCAP_PIO 0x00200
/*
* Use RX completion handler
*/
#define IFLIB_RX_COMPLETION 0x00400
/*
* Skip refilling cluster free lists
*/
#define IFLIB_SKIP_CLREFILL 0x00800
/*
* Don't reset on hang
*/
#define IFLIB_NO_HANG_RESET 0x01000
/*
* Don't need/want most of the niceties of
* queue management
*/
#define IFLIB_PSEUDO 0x02000
/*
* No DMA support needed / wanted
*/
#define IFLIB_VIRTUAL 0x04000
/*
* autogenerate a MAC address
*/
#define IFLIB_GEN_MAC 0x08000
/*
* Interface needs admin task to ignore interface up/down status
*/
#define IFLIB_ADMIN_ALWAYS_RUN 0x10000
/*
* field accessors
*/
void *iflib_get_softc(if_ctx_t ctx);
device_t iflib_get_dev(if_ctx_t ctx);
if_t iflib_get_ifp(if_ctx_t ctx);
struct ifmedia *iflib_get_media(if_ctx_t ctx);
if_softc_ctx_t iflib_get_softc_ctx(if_ctx_t ctx);
if_shared_ctx_t iflib_get_sctx(if_ctx_t ctx);
void iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN]);
void iflib_request_reset(if_ctx_t ctx);
uint8_t iflib_in_detach(if_ctx_t ctx);
/*
* If the driver can plug cleanly in to newbus use these
*/
int iflib_device_probe(device_t);
int iflib_device_attach(device_t);
int iflib_device_detach(device_t);
int iflib_device_suspend(device_t);
int iflib_device_resume(device_t);
int iflib_device_shutdown(device_t);
int iflib_device_iov_init(device_t, uint16_t, const nvlist_t *);
void iflib_device_iov_uninit(device_t);
int iflib_device_iov_add_vf(device_t, uint16_t, const nvlist_t *);
/*
* If the driver can't plug cleanly in to newbus
* use these
*/
int iflib_device_register(device_t dev, void *softc, if_shared_ctx_t sctx, if_ctx_t *ctxp);
int iflib_device_deregister(if_ctx_t);
int iflib_irq_alloc(if_ctx_t, if_irq_t, int, driver_filter_t, void *filter_arg, driver_intr_t, void *arg, const char *name);
int iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid,
iflib_intr_type_t type, driver_filter_t *filter,
void *filter_arg, int qid, const char *name);
void iflib_softirq_alloc_generic(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type, void *arg, int qid, const char *name);
void iflib_irq_free(if_ctx_t ctx, if_irq_t irq);
void iflib_io_tqg_attach(struct grouptask *gt, void *uniq, int cpu, char *name);
void iflib_config_gtask_init(void *ctx, struct grouptask *gtask,
gtask_fn_t *fn, const char *name);
void iflib_config_gtask_deinit(struct grouptask *gtask);
void iflib_tx_intr_deferred(if_ctx_t ctx, int txqid);
void iflib_rx_intr_deferred(if_ctx_t ctx, int rxqid);
void iflib_admin_intr_deferred(if_ctx_t ctx);
void iflib_iov_intr_deferred(if_ctx_t ctx);
void iflib_link_state_change(if_ctx_t ctx, int linkstate, uint64_t baudrate);
int iflib_dma_alloc(if_ctx_t ctx, int size, iflib_dma_info_t dma, int mapflags);
void iflib_dma_free(iflib_dma_info_t dma);
int iflib_dma_alloc_multi(if_ctx_t ctx, int *sizes, iflib_dma_info_t *dmalist, int mapflags, int count);
void iflib_dma_free_multi(iflib_dma_info_t *dmalist, int count);
struct sx *iflib_ctx_lock_get(if_ctx_t);
struct mtx *iflib_qset_lock_get(if_ctx_t, uint16_t);
void iflib_led_create(if_ctx_t ctx);
void iflib_add_int_delay_sysctl(if_ctx_t, const char *, const char *,
if_int_delay_info_t, int, int);
/*
* Pseudo device support
*/
if_pseudo_t iflib_clone_register(if_shared_ctx_t);
void iflib_clone_deregister(if_pseudo_t);
#endif /* __IFLIB_H_ */
@@ -0,0 +1,76 @@
/*-
* Copyright (c) 2018, Matthew Macy ([email protected])
* 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,
* this list of conditions and the following disclaimer.
*
* 2. Neither the name of Matthew Macy nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __NET_IFLIB_PRIVATE_H_
#define __NET_IFLIB_PRIVATE_H_
#define IFC_LEGACY 0x001
#define IFC_QFLUSH 0x002
#define IFC_MULTISEG 0x004
#define IFC_SPARE1 0x008
#define IFC_SC_ALLOCATED 0x010
#define IFC_INIT_DONE 0x020
#define IFC_PREFETCH 0x040
#define IFC_DO_RESET 0x080
#define IFC_DO_WATCHDOG 0x100
#define IFC_CHECK_HUNG 0x200
#define IFC_PSEUDO 0x400
#define IFC_IN_DETACH 0x800
#define IFC_NETMAP_TX_IRQ 0x80000000
MALLOC_DECLARE(M_IFLIB);
#define IFLIB_MAX_TX_BYTES (2*1024*1024)
#define IFLIB_MIN_TX_BYTES (8*1024)
#define IFLIB_DEFAULT_TX_QDEPTH 2048
struct iflib_cloneattach_ctx {
struct if_clone *cc_ifc;
caddr_t cc_params;
const char *cc_name;
int cc_len;
};
extern driver_t iflib_pseudodriver;
int noop_attach(device_t dev);
int iflib_pseudo_detach(device_t dev);
int iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
struct iflib_cloneattach_ctx *clctx);
int iflib_pseudo_deregister(if_ctx_t ctx);
uint32_t iflib_get_flags(if_ctx_t ctx);
void iflib_set_detach(if_ctx_t ctx);
void iflib_stop(if_ctx_t ctx);
#endif
@@ -0,0 +1,80 @@
/*-
* Copyright (c) 2014 Chelsio Communications, Inc.
* All rights reserved.
* Written by: Navdeep Parhar <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __NET_MP_RING_H
#define __NET_MP_RING_H
#ifndef _KERNEL
#error "no user-serviceable parts inside"
#endif
#if defined(__powerpc__) || defined(__mips__) || defined(__i386__) || defined(__HAIKU__)
#define NO_64BIT_ATOMICS
#endif
struct ifmp_ring;
typedef u_int (*mp_ring_drain_t)(struct ifmp_ring *, u_int, u_int);
typedef u_int (*mp_ring_can_drain_t)(struct ifmp_ring *);
typedef void (*mp_ring_serial_t)(struct ifmp_ring *);
struct ifmp_ring {
volatile uint64_t state __aligned(CACHE_LINE_SIZE);
int size __aligned(CACHE_LINE_SIZE);
void * cookie;
struct malloc_type * mt;
mp_ring_drain_t drain;
mp_ring_can_drain_t can_drain; /* cheap, may be unreliable */
counter_u64_t enqueues;
counter_u64_t drops;
counter_u64_t starts;
counter_u64_t stalls;
counter_u64_t restarts; /* recovered after stalling */
counter_u64_t abdications;
#ifdef NO_64BIT_ATOMICS
struct mtx lock;
#endif
void * volatile items[
#if __GNUC__ < 3
0
#else
#endif
] __aligned(CACHE_LINE_SIZE);
};
int ifmp_ring_alloc(struct ifmp_ring **, int, void *, mp_ring_drain_t,
mp_ring_can_drain_t, struct malloc_type *, int);
void ifmp_ring_free(struct ifmp_ring *);
int ifmp_ring_enqueue(struct ifmp_ring *, void **, int, int, int);
void ifmp_ring_check_drainage(struct ifmp_ring *, int);
void ifmp_ring_reset_stats(struct ifmp_ring *);
int ifmp_ring_is_idle(struct ifmp_ring *);
int ifmp_ring_is_stalled(struct ifmp_ring *r);
#endif
@@ -0,0 +1,37 @@
/*
* Copyright 2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_IFLIB_SYS__TASK_H_
#define _FBSD_IFLIB_SYS__TASK_H_
/* include the real sys/_task.h */
#include_next <sys/_task.h>
#include <sys/queue.h>
typedef void gtask_fn_t(void *context);
struct gtask {
STAILQ_ENTRY(gtask) ta_link; /* (q) link for queue */
uint16_t ta_flags; /* (q) state flags */
u_short ta_priority; /* (c) Priority */
gtask_fn_t *ta_func; /* (c) task handler */
void *ta_context; /* (c) argument for handler */
};
struct grouptask {
struct gtask gt_task;
void *gt_taskqueue;
LIST_ENTRY(grouptask) gt_list;
void *gt_uniq;
#define GROUPTASK_NAMELEN 32
char gt_name[GROUPTASK_NAMELEN];
int16_t gt_irq;
int16_t gt_cpu;
};
#endif
@@ -0,0 +1,117 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2014 Jeffrey Roberson <[email protected]>
* Copyright (c) 2016 Matthew Macy <[email protected]>
* 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _SYS_GTASKQUEUE_H_
#define _SYS_GTASKQUEUE_H_
#include <sys/taskqueue.h>
#ifndef _KERNEL
#error "no user-serviceable parts inside"
#endif
struct gtaskqueue;
struct taskqgroup;
typedef void (*gtaskqueue_enqueue_fn)(void *context);
/*
* Taskqueue groups. Manages dynamic thread groups and irq binding for
* device and other tasks.
*/
void gtaskqueue_block(struct gtaskqueue *queue);
void gtaskqueue_unblock(struct gtaskqueue *queue);
int gtaskqueue_cancel(struct gtaskqueue *queue, struct gtask *gtask);
void gtaskqueue_drain(struct gtaskqueue *queue, struct gtask *task);
void gtaskqueue_drain_all(struct gtaskqueue *queue);
void grouptask_block(struct grouptask *grouptask);
void grouptask_unblock(struct grouptask *grouptask);
int grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *task);
void taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *grptask,
void *uniq, int irq, const char *name);
int taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *grptask,
void *uniq, int cpu, int irq, const char *name);
void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask);
struct taskqgroup *taskqgroup_create(const char *name);
void taskqgroup_destroy(struct taskqgroup *qgroup);
int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride);
void taskqgroup_config_gtask_init(void *ctx, struct grouptask *gtask, gtask_fn_t *fn,
const char *name);
void taskqgroup_config_gtask_deinit(struct grouptask *gtask);
#define TASK_ENQUEUED 0x1
#define TASK_SKIP_WAKEUP 0x2
#define TASK_NOENQUEUE 0x4
#define GTASK_INIT(task, flags, priority, func, context) do { \
(task)->ta_flags = flags; \
(task)->ta_priority = (priority); \
(task)->ta_func = (func); \
(task)->ta_context = (context); \
} while (0)
#define GROUPTASK_INIT(gtask, priority, func, context) \
GTASK_INIT(&(gtask)->gt_task, TASK_SKIP_WAKEUP, priority, func, context)
#define GROUPTASK_ENQUEUE(gtask) \
grouptaskqueue_enqueue((gtask)->gt_taskqueue, &(gtask)->gt_task)
#define TASKQGROUP_DECLARE(name) \
extern struct taskqgroup *qgroup_##name
#define TASKQGROUP_DEFINE(name, cnt, stride) \
\
struct taskqgroup *qgroup_##name; \
\
static void \
taskqgroup_define_##name(void *arg) \
{ \
qgroup_##name = taskqgroup_create(#name); \
} \
\
SYSINIT(taskqgroup_##name, SI_SUB_TASKQ, SI_ORDER_FIRST, \
taskqgroup_define_##name, NULL); \
\
static void \
taskqgroup_adjust_##name(void *arg) \
{ \
taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \
} \
\
SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \
taskqgroup_adjust_##name, NULL)
TASKQGROUP_DECLARE(net);
TASKQGROUP_DECLARE(softirq);
#endif /* !_SYS_GTASKQUEUE_H_ */
@@ -0,0 +1,15 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_IFLIB_SYS_LIBKERN_H_
#define _FBSD_IFLIB_SYS_LIBKERN_H_
/* include the real sys/libkern.h */
#include_next <sys/libkern.h>
char *strsep(char **, const char *delim);
#endif /* _FBSD_IFLIB_SYS_LIBKERN_H_ */
@@ -0,0 +1,59 @@
/* MD5.H - header file for MD5C.C
* $FreeBSD$
*/
/*-
SPDX-License-Identifier: RSA-MD
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef _SYS_MD5_H_
#define _SYS_MD5_H_
#define MD5_BLOCK_LENGTH 64
#define MD5_DIGEST_LENGTH 16
#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
/* MD5 context. */
typedef struct MD5Context {
u_int32_t state[4]; /* state (ABCD) */
u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
#include <sys/cdefs.h>
__BEGIN_DECLS
void MD5Init (MD5_CTX *);
void MD5Update (MD5_CTX *, const void *, unsigned int);
void MD5Final (unsigned char[__min_size(MD5_DIGEST_LENGTH)], MD5_CTX *);
#ifndef _KERNEL
char * MD5End(MD5_CTX *, char *);
char * MD5Fd(int, char *);
char * MD5FdChunk(int, char *, off_t, off_t);
char * MD5File(const char *, char *);
char * MD5FileChunk(const char *, char *, off_t, off_t);
char * MD5Data(const void *, unsigned int, char *);
#endif
__END_DECLS
#endif /* _SYS_MD5_H_ */
@@ -0,0 +1,256 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2009-2013 The FreeBSD Foundation
* Copyright (c) 2013-2015 Mariusz Zaborski <[email protected]>
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NV_H_
#define _NV_H_
#include <sys/cdefs.h>
#ifndef _KERNEL
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#endif
#ifndef _NVLIST_T_DECLARED
#define _NVLIST_T_DECLARED
struct nvlist;
typedef struct nvlist nvlist_t;
#endif
#define NV_NAME_MAX 2048
#define NV_TYPE_NONE 0
#define NV_TYPE_NULL 1
#define NV_TYPE_BOOL 2
#define NV_TYPE_NUMBER 3
#define NV_TYPE_STRING 4
#define NV_TYPE_NVLIST 5
#define NV_TYPE_DESCRIPTOR 6
#define NV_TYPE_BINARY 7
#define NV_TYPE_BOOL_ARRAY 8
#define NV_TYPE_NUMBER_ARRAY 9
#define NV_TYPE_STRING_ARRAY 10
#define NV_TYPE_NVLIST_ARRAY 11
#define NV_TYPE_DESCRIPTOR_ARRAY 12
/*
* Perform case-insensitive lookups of provided names.
*/
#define NV_FLAG_IGNORE_CASE 0x01
/*
* Names don't have to be unique.
*/
#define NV_FLAG_NO_UNIQUE 0x02
#if defined(_KERNEL) && defined(MALLOC_DECLARE)
MALLOC_DECLARE(M_NVLIST);
#endif
__BEGIN_DECLS
nvlist_t *nvlist_create(int flags);
void nvlist_destroy(nvlist_t *nvl);
int nvlist_error(const nvlist_t *nvl);
bool nvlist_empty(const nvlist_t *nvl);
int nvlist_flags(const nvlist_t *nvl);
void nvlist_set_error(nvlist_t *nvl, int error);
nvlist_t *nvlist_clone(const nvlist_t *nvl);
#ifndef _KERNEL
void nvlist_dump(const nvlist_t *nvl, int fd);
void nvlist_fdump(const nvlist_t *nvl, FILE *fp);
#endif
size_t nvlist_size(const nvlist_t *nvl);
void *nvlist_pack(const nvlist_t *nvl, size_t *sizep);
nvlist_t *nvlist_unpack(const void *buf, size_t size, int flags);
int nvlist_send(int sock, const nvlist_t *nvl);
nvlist_t *nvlist_recv(int sock, int flags);
nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl, int flags);
const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
const nvlist_t *nvlist_get_parent(const nvlist_t *nvl, void **cookiep);
const nvlist_t *nvlist_get_array_next(const nvlist_t *nvl);
bool nvlist_in_array(const nvlist_t *nvl);
const nvlist_t *nvlist_get_pararr(const nvlist_t *nvl, void **cookiep);
/*
* The nvlist_exists functions check if the given name (optionally of the given
* type) exists on nvlist.
*/
bool nvlist_exists(const nvlist_t *nvl, const char *name);
bool nvlist_exists_type(const nvlist_t *nvl, const char *name, int type);
bool nvlist_exists_null(const nvlist_t *nvl, const char *name);
bool nvlist_exists_bool(const nvlist_t *nvl, const char *name);
bool nvlist_exists_number(const nvlist_t *nvl, const char *name);
bool nvlist_exists_string(const nvlist_t *nvl, const char *name);
bool nvlist_exists_nvlist(const nvlist_t *nvl, const char *name);
bool nvlist_exists_binary(const nvlist_t *nvl, const char *name);
bool nvlist_exists_bool_array(const nvlist_t *nvl, const char *name);
bool nvlist_exists_number_array(const nvlist_t *nvl, const char *name);
bool nvlist_exists_string_array(const nvlist_t *nvl, const char *name);
bool nvlist_exists_nvlist_array(const nvlist_t *nvl, const char *name);
#ifndef _KERNEL
bool nvlist_exists_descriptor(const nvlist_t *nvl, const char *name);
bool nvlist_exists_descriptor_array(const nvlist_t *nvl, const char *name);
#endif
/*
* The nvlist_add functions add the given name/value pair.
* If a pointer is provided, nvlist_add will internally allocate memory for the
* given data (in other words it won't consume provided buffer).
*/
void nvlist_add_null(nvlist_t *nvl, const char *name);
void nvlist_add_bool(nvlist_t *nvl, const char *name, bool value);
void nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value);
void nvlist_add_string(nvlist_t *nvl, const char *name, const char *value);
void nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...) __printflike(3, 4);
#if !defined(_KERNEL) || defined(_VA_LIST_DECLARED)
void nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, va_list valueap) __printflike(3, 0);
#endif
void nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value);
void nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, size_t size);
void nvlist_add_bool_array(nvlist_t *nvl, const char *name, const bool *value, size_t nitems);
void nvlist_add_number_array(nvlist_t *nvl, const char *name, const uint64_t *value, size_t nitems);
void nvlist_add_string_array(nvlist_t *nvl, const char *name, const char * const *value, size_t nitems);
void nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, const nvlist_t * const *value, size_t nitems);
#ifndef _KERNEL
void nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value);
void nvlist_add_descriptor_array(nvlist_t *nvl, const char *name, const int *value, size_t nitems);
#endif
void nvlist_append_bool_array(nvlist_t *nvl, const char *name, const bool value);
void nvlist_append_number_array(nvlist_t *nvl, const char *name, const uint64_t value);
void nvlist_append_string_array(nvlist_t *nvl, const char *name, const char * const value);
void nvlist_append_nvlist_array(nvlist_t *nvl, const char *name, const nvlist_t * const value);
#ifndef _KERNEL
void nvlist_append_descriptor_array(nvlist_t *nvl, const char *name, int value);
#endif
/*
* The nvlist_move functions add the given name/value pair.
* The functions consumes provided buffer.
*/
void nvlist_move_string(nvlist_t *nvl, const char *name, char *value);
void nvlist_move_nvlist(nvlist_t *nvl, const char *name, nvlist_t *value);
void nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size);
void nvlist_move_bool_array(nvlist_t *nvl, const char *name, bool *value, size_t nitems);
void nvlist_move_string_array(nvlist_t *nvl, const char *name, char **value, size_t nitems);
void nvlist_move_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **value, size_t nitems);
void nvlist_move_number_array(nvlist_t *nvl, const char *name, uint64_t *value, size_t nitems);
#ifndef _KERNEL
void nvlist_move_descriptor(nvlist_t *nvl, const char *name, int value);
void nvlist_move_descriptor_array(nvlist_t *nvl, const char *name, int *value, size_t nitems);
#endif
/*
* The nvlist_get functions returns value associated with the given name.
* If it returns a pointer, the pointer represents internal buffer and should
* not be freed by the caller.
*/
bool nvlist_get_bool(const nvlist_t *nvl, const char *name);
uint64_t nvlist_get_number(const nvlist_t *nvl, const char *name);
const char *nvlist_get_string(const nvlist_t *nvl, const char *name);
const nvlist_t *nvlist_get_nvlist(const nvlist_t *nvl, const char *name);
const void *nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep);
const bool *nvlist_get_bool_array(const nvlist_t *nvl, const char *name, size_t *nitemsp);
const uint64_t *nvlist_get_number_array(const nvlist_t *nvl, const char *name, size_t *nitemsp);
const char * const *nvlist_get_string_array(const nvlist_t *nvl, const char *name, size_t *nitemsp);
const nvlist_t * const *nvlist_get_nvlist_array(const nvlist_t *nvl, const char *name, size_t *nitemsp);
#ifndef _KERNEL
int nvlist_get_descriptor(const nvlist_t *nvl, const char *name);
const int *nvlist_get_descriptor_array(const nvlist_t *nvl, const char *name, size_t *nitemsp);
#endif
/*
* The nvlist_take functions returns value associated with the given name and
* remove the given entry from the nvlist.
* The caller is responsible for freeing received data.
*/
bool nvlist_take_bool(nvlist_t *nvl, const char *name);
uint64_t nvlist_take_number(nvlist_t *nvl, const char *name);
char *nvlist_take_string(nvlist_t *nvl, const char *name);
nvlist_t *nvlist_take_nvlist(nvlist_t *nvl, const char *name);
void *nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep);
bool *nvlist_take_bool_array(nvlist_t *nvl, const char *name, size_t *nitemsp);
uint64_t *nvlist_take_number_array(nvlist_t *nvl, const char *name, size_t *nitemsp);
char **nvlist_take_string_array(nvlist_t *nvl, const char *name, size_t *nitemsp);
nvlist_t **nvlist_take_nvlist_array(nvlist_t *nvl, const char *name, size_t *nitemsp);
#ifndef _KERNEL
int nvlist_take_descriptor(nvlist_t *nvl, const char *name);
int *nvlist_take_descriptor_array(nvlist_t *nvl, const char *name, size_t *nitemsp);
#endif
/*
* The nvlist_free functions removes the given name/value pair from the nvlist
* and frees memory associated with it.
*/
void nvlist_free(nvlist_t *nvl, const char *name);
void nvlist_free_type(nvlist_t *nvl, const char *name, int type);
void nvlist_free_null(nvlist_t *nvl, const char *name);
void nvlist_free_bool(nvlist_t *nvl, const char *name);
void nvlist_free_number(nvlist_t *nvl, const char *name);
void nvlist_free_string(nvlist_t *nvl, const char *name);
void nvlist_free_nvlist(nvlist_t *nvl, const char *name);
void nvlist_free_binary(nvlist_t *nvl, const char *name);
void nvlist_free_bool_array(nvlist_t *nvl, const char *name);
void nvlist_free_number_array(nvlist_t *nvl, const char *name);
void nvlist_free_string_array(nvlist_t *nvl, const char *name);
void nvlist_free_nvlist_array(nvlist_t *nvl, const char *name);
void nvlist_free_binary_array(nvlist_t *nvl, const char *name);
#ifndef _KERNEL
void nvlist_free_descriptor(nvlist_t *nvl, const char *name);
void nvlist_free_descriptor_array(nvlist_t *nvl, const char *name);
#endif
__END_DECLS
#endif /* !_NV_H_ */
@@ -0,0 +1,23 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_IFLIB_SYS_TASKQUEUE_H_
#define _FBSD_IFLIB_SYS_TASKQUEUE_H_
/* include the real sys/taskqueue.h */
#include_next <sys/taskqueue.h>
typedef void (*taskqueue_callback_fn)(void *context);
enum taskqueue_callback_type {
TASKQUEUE_CALLBACK_TYPE_INIT,
TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
};
#define TASKQUEUE_CALLBACK_TYPE_MIN TASKQUEUE_CALLBACK_TYPE_INIT
#define TASKQUEUE_CALLBACK_TYPE_MAX TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
#define TASKQUEUE_NUM_CALLBACKS TASKQUEUE_CALLBACK_TYPE_MAX + 1
#endif /* _FBSD_IFLIB_SYS_TASKQUEUE_H_ */
+379
View File
@@ -0,0 +1,379 @@
/*
* This file is produced automatically.
* Do not modify anything in here by hand.
*
* Created from source file
* sys/net/ifdi_if.m
#
# Copyright (c) 2014-2018, Matthew Macy ([email protected])
# 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,
# this list of conditions and the following disclaimer.
#
# 2. Neither the name of Matthew Macy nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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/queue.h>
#include <sys/kernel.h>
#include <sys/kobj.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <machine/bus.h>
#include <sys/bus.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
#include <net/iflib.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <ifdi_if.h>
static void
null_void_op(if_ctx_t _ctx __unused)
{
}
#ifndef __HAIKU__
static int
null_knlist_add(if_ctx_t _ctx __unused, struct knote *_kn)
{
return (0);
}
static int
null_knote_event(if_ctx_t _ctx __unused, struct knote *_kn, int _hint)
{
return (0);
}
#endif
static void
null_timer_op(if_ctx_t _ctx __unused, uint16_t _qsidx __unused)
{
}
static int
null_int_op(if_ctx_t _ctx __unused)
{
return (0);
}
static int
null_int_int_op(if_ctx_t _ctx __unused, int arg0 __unused)
{
return (ENOTSUP);
}
static int
null_queue_intr_enable(if_ctx_t _ctx __unused, uint16_t _qid __unused)
{
return (ENOTSUP);
}
static void
null_led_func(if_ctx_t _ctx __unused, int _onoff __unused)
{
}
static void
null_vlan_register_op(if_ctx_t _ctx __unused, uint16_t vtag __unused)
{
}
static int
null_q_setup(if_ctx_t _ctx __unused, uint32_t _qid __unused)
{
return (0);
}
static int
null_i2c_req(if_ctx_t _sctx __unused, struct ifi2creq *_i2c __unused)
{
return (ENOTSUP);
}
static int
null_sysctl_int_delay(if_ctx_t _sctx __unused, if_int_delay_info_t _iidi __unused)
{
return (0);
}
static int
null_iov_init(if_ctx_t _ctx __unused, uint16_t num_vfs __unused, const nvlist_t *params __unused)
{
return (ENOTSUP);
}
static int
null_vf_add(if_ctx_t _ctx __unused, uint16_t num_vfs __unused, const nvlist_t *params __unused)
{
return (ENOTSUP);
}
static int
null_priv_ioctl(if_ctx_t _ctx __unused, u_long command, caddr_t *data __unused)
{
return (ENOTSUP);
}
static void
null_media_status(if_ctx_t ctx __unused, struct ifmediareq *ifmr)
{
ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
ifmr->ifm_active = IFM_ETHER | IFM_FDX;
}
static int
null_cloneattach(if_ctx_t ctx __unused, struct if_clone *ifc __unused,
const char *name __unused, caddr_t params __unused)
{
return (0);
}
static void
null_rx_clset(if_ctx_t _ctx __unused, uint16_t _flid __unused,
uint16_t _qid __unused, caddr_t *_sdcl __unused)
{
}
static void
null_object_info_get(if_ctx_t ctx __unused, void *data __unused, int size __unused)
{
}
static int
default_mac_set(if_ctx_t ctx, const uint8_t *mac)
{
struct ifnet *ifp = iflib_get_ifp(ctx);
struct sockaddr_dl *sdl;
if (ifp && ifp->if_addr) {
sdl = (struct sockaddr_dl *)ifp->if_addr->ifa_addr;
MPASS(sdl->sdl_type == IFT_ETHER);
memcpy(LLADDR(sdl), mac, ETHER_ADDR_LEN);
}
return (0);
}
#ifndef __HAIKU__
struct kobjop_desc ifdi_knlist_add_desc = {
0, { NULL, ID_ifdi_knlist_add, (kobjop_t)null_knlist_add }
};
struct kobjop_desc ifdi_knote_event_desc = {
0, { NULL, ID_ifdi_knote_event, (kobjop_t)null_knote_event }
};
#endif
struct kobjop_desc ifdi_object_info_get_desc = {
0, { NULL, ID_ifdi_object_info_get, (kobjop_t)null_object_info_get }
};
struct kobjop_desc ifdi_attach_pre_desc = {
0, { NULL, ID_ifdi_attach_pre, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_attach_post_desc = {
0, { NULL, ID_ifdi_attach_post, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_reinit_pre_desc = {
0, { NULL, ID_ifdi_reinit_pre, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_reinit_post_desc = {
0, { NULL, ID_ifdi_reinit_post, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_cloneattach_desc = {
0, { NULL, ID_ifdi_cloneattach, (kobjop_t)null_cloneattach }
};
struct kobjop_desc ifdi_detach_desc = {
0, { NULL, ID_ifdi_detach, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_suspend_desc = {
0, { NULL, ID_ifdi_suspend, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_shutdown_desc = {
0, { NULL, ID_ifdi_shutdown, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_resume_desc = {
0, { NULL, ID_ifdi_resume, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_tx_queues_alloc_desc = {
0, { NULL, ID_ifdi_tx_queues_alloc, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_rx_queues_alloc_desc = {
0, { NULL, ID_ifdi_rx_queues_alloc, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_queues_free_desc = {
0, { NULL, ID_ifdi_queues_free, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_rx_clset_desc = {
0, { NULL, ID_ifdi_rx_clset, (kobjop_t)null_rx_clset }
};
struct kobjop_desc ifdi_init_desc = {
0, { NULL, ID_ifdi_init, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_stop_desc = {
0, { NULL, ID_ifdi_stop, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_msix_intr_assign_desc = {
0, { NULL, ID_ifdi_msix_intr_assign, (kobjop_t)null_int_int_op }
};
struct kobjop_desc ifdi_intr_enable_desc = {
0, { NULL, ID_ifdi_intr_enable, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_intr_disable_desc = {
0, { NULL, ID_ifdi_intr_disable, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_rx_queue_intr_enable_desc = {
0, { NULL, ID_ifdi_rx_queue_intr_enable, (kobjop_t)null_queue_intr_enable }
};
struct kobjop_desc ifdi_tx_queue_intr_enable_desc = {
0, { NULL, ID_ifdi_tx_queue_intr_enable, (kobjop_t)null_queue_intr_enable }
};
struct kobjop_desc ifdi_link_intr_enable_desc = {
0, { NULL, ID_ifdi_link_intr_enable, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_multi_set_desc = {
0, { NULL, ID_ifdi_multi_set, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_mtu_set_desc = {
0, { NULL, ID_ifdi_mtu_set, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_mac_set_desc = {
0, { NULL, ID_ifdi_mac_set, (kobjop_t)default_mac_set }
};
struct kobjop_desc ifdi_media_set_desc = {
0, { NULL, ID_ifdi_media_set, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_promisc_set_desc = {
0, { NULL, ID_ifdi_promisc_set, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_crcstrip_set_desc = {
0, { NULL, ID_ifdi_crcstrip_set, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_vflr_handle_desc = {
0, { NULL, ID_ifdi_vflr_handle, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_iov_init_desc = {
0, { NULL, ID_ifdi_iov_init, (kobjop_t)null_iov_init }
};
struct kobjop_desc ifdi_iov_uninit_desc = {
0, { NULL, ID_ifdi_iov_uninit, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_iov_vf_add_desc = {
0, { NULL, ID_ifdi_iov_vf_add, (kobjop_t)null_vf_add }
};
struct kobjop_desc ifdi_update_admin_status_desc = {
0, { NULL, ID_ifdi_update_admin_status, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_media_status_desc = {
0, { NULL, ID_ifdi_media_status, (kobjop_t)null_media_status }
};
struct kobjop_desc ifdi_media_change_desc = {
0, { NULL, ID_ifdi_media_change, (kobjop_t)null_int_op }
};
struct kobjop_desc ifdi_get_counter_desc = {
0, { NULL, ID_ifdi_get_counter, (kobjop_t)kobj_error_method }
};
struct kobjop_desc ifdi_priv_ioctl_desc = {
0, { NULL, ID_ifdi_priv_ioctl, (kobjop_t)null_priv_ioctl }
};
struct kobjop_desc ifdi_i2c_req_desc = {
0, { NULL, ID_ifdi_i2c_req, (kobjop_t)null_i2c_req }
};
struct kobjop_desc ifdi_txq_setup_desc = {
0, { NULL, ID_ifdi_txq_setup, (kobjop_t)null_q_setup }
};
struct kobjop_desc ifdi_rxq_setup_desc = {
0, { NULL, ID_ifdi_rxq_setup, (kobjop_t)null_q_setup }
};
struct kobjop_desc ifdi_timer_desc = {
0, { NULL, ID_ifdi_timer, (kobjop_t)null_timer_op }
};
struct kobjop_desc ifdi_watchdog_reset_desc = {
0, { NULL, ID_ifdi_watchdog_reset, (kobjop_t)null_void_op }
};
struct kobjop_desc ifdi_watchdog_reset_queue_desc = {
0, { NULL, ID_ifdi_watchdog_reset_queue, (kobjop_t)null_timer_op }
};
struct kobjop_desc ifdi_led_func_desc = {
0, { NULL, ID_ifdi_led_func, (kobjop_t)null_led_func }
};
struct kobjop_desc ifdi_vlan_register_desc = {
0, { NULL, ID_ifdi_vlan_register, (kobjop_t)null_vlan_register_op }
};
struct kobjop_desc ifdi_vlan_unregister_desc = {
0, { NULL, ID_ifdi_vlan_unregister, (kobjop_t)null_vlan_register_op }
};
struct kobjop_desc ifdi_sysctl_int_delay_desc = {
0, { NULL, ID_ifdi_sysctl_int_delay, (kobjop_t)null_sysctl_int_delay }
};
struct kobjop_desc ifdi_debug_desc = {
0, { NULL, ID_ifdi_debug, (kobjop_t)null_void_op }
};
File diff suppressed because it is too large Load Diff
+338
View File
@@ -0,0 +1,338 @@
/*-
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*
* This code is the same as the code published by RSA Inc. It has been
* edited for clarity and style only.
*/
/*
* This file should be kept in sync with src/lib/libmd/md5c.c
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <string.h>
#endif
#include <machine/endian.h>
#include <sys/endian.h>
#include <sys/md5.h>
static void MD5Transform(u_int32_t [4], const unsigned char [64]);
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define Encode memcpy
#define Decode memcpy
#else
/*
* Encodes input (u_int32_t) into output (unsigned char). Assumes len is
* a multiple of 4.
*/
static void
Encode (unsigned char *output, u_int32_t *input, unsigned int len)
{
unsigned int i;
uint32_t ip;
for (i = 0; i < len / 4; i++) {
ip = input[i];
*output++ = ip;
*output++ = ip >> 8;
*output++ = ip >> 16;
*output++ = ip >> 24;
}
}
/*
* Decodes input (unsigned char) into output (u_int32_t). Assumes len is
* a multiple of 4.
*/
static void
Decode (u_int32_t *output, const unsigned char *input, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i += 4) {
*output++ = input[i] | (input[i+1] << 8) | (input[i+2] << 16) |
(input[i+3] << 24);
}
}
#endif
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/*
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void
MD5Init (context)
MD5_CTX *context;
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/*
* MD5 block update operation. Continues an MD5 message-digest
* operation, processing another message block, and updating the
* context.
*/
void
MD5Update (context, in, inputLen)
MD5_CTX *context;
const void *in;
unsigned int inputLen;
{
unsigned int i, index, partLen;
const unsigned char *input = in;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((u_int32_t)inputLen << 3))
< ((u_int32_t)inputLen << 3))
context->count[1]++;
context->count[1] += ((u_int32_t)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
memcpy((void *)&context->buffer[index], (const void *)input,
partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy ((void *)&context->buffer[index], (const void *)&input[i],
inputLen-i);
}
/*
* MD5 padding. Adds padding followed by original length.
*/
static void
MD5Pad (MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
}
/*
* MD5 finalization. Ends an MD5 message-digest operation, writing the
* the message digest and zeroizing the context.
*/
void
MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *context)
{
/* Do padding. */
MD5Pad (context);
/* Store state in digest */
Encode (digest, context->state, MD5_DIGEST_LENGTH);
/* Zeroize sensitive information. */
memset (context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block. */
static void
MD5Transform (state, block)
u_int32_t state[4];
const unsigned char block[64];
{
u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
memset ((void *)x, 0, sizeof (x));
}
+560
View File
@@ -0,0 +1,560 @@
/*-
* Copyright (c) 2014 Chelsio Communications, Inc.
* All rights reserved.
* Written by: Navdeep Parhar <[email protected]>
*
* 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/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/counter.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#if defined(__i386__)
#define atomic_cmpset_acq_64 atomic_cmpset_64
#define atomic_cmpset_rel_64 atomic_cmpset_64
#endif
#include <net/mp_ring.h>
union ring_state {
struct {
uint16_t pidx_head;
uint16_t pidx_tail;
uint16_t cidx;
uint16_t flags;
};
uint64_t state;
};
enum {
IDLE = 0, /* consumer ran to completion, nothing more to do. */
BUSY, /* consumer is running already, or will be shortly. */
STALLED, /* consumer stopped due to lack of resources. */
ABDICATED, /* consumer stopped even though there was work to be
done because it wants another thread to take over. */
};
static inline uint16_t
space_available(struct ifmp_ring *r, union ring_state s)
{
uint16_t x = r->size - 1;
if (s.cidx == s.pidx_head)
return (x);
else if (s.cidx > s.pidx_head)
return (s.cidx - s.pidx_head - 1);
else
return (x - s.pidx_head + s.cidx);
}
static inline uint16_t
increment_idx(struct ifmp_ring *r, uint16_t idx, uint16_t n)
{
int x = r->size - idx;
MPASS(x > 0);
return (x > n ? idx + n : n - x);
}
/* Consumer is about to update the ring's state to s */
static inline uint16_t
state_to_flags(union ring_state s, int abdicate)
{
if (s.cidx == s.pidx_tail)
return (IDLE);
else if (abdicate && s.pidx_tail != s.pidx_head)
return (ABDICATED);
return (BUSY);
}
#ifdef NO_64BIT_ATOMICS
static void
drain_ring_locked(struct ifmp_ring *r, union ring_state os, uint16_t prev, int budget)
{
union ring_state ns;
int n, pending, total;
uint16_t cidx = os.cidx;
uint16_t pidx = os.pidx_tail;
MPASS(os.flags == BUSY);
MPASS(cidx != pidx);
if (prev == IDLE)
counter_u64_add(r->starts, 1);
pending = 0;
total = 0;
while (cidx != pidx) {
/* Items from cidx to pidx are available for consumption. */
n = r->drain(r, cidx, pidx);
if (n == 0) {
os.state = ns.state = r->state;
ns.cidx = cidx;
ns.flags = STALLED;
r->state = ns.state;
if (prev != STALLED)
counter_u64_add(r->stalls, 1);
else if (total > 0) {
counter_u64_add(r->restarts, 1);
counter_u64_add(r->stalls, 1);
}
break;
}
cidx = increment_idx(r, cidx, n);
pending += n;
total += n;
/*
* We update the cidx only if we've caught up with the pidx, the
* real cidx is getting too far ahead of the one visible to
* everyone else, or we have exceeded our budget.
*/
if (cidx != pidx && pending < 64 && total < budget)
continue;
os.state = ns.state = r->state;
ns.cidx = cidx;
ns.flags = state_to_flags(ns, total >= budget);
r->state = ns.state;
if (ns.flags == ABDICATED)
counter_u64_add(r->abdications, 1);
if (ns.flags != BUSY) {
/* Wrong loop exit if we're going to stall. */
MPASS(ns.flags != STALLED);
if (prev == STALLED) {
MPASS(total > 0);
counter_u64_add(r->restarts, 1);
}
break;
}
/*
* The acquire style atomic above guarantees visibility of items
* associated with any pidx change that we notice here.
*/
pidx = ns.pidx_tail;
pending = 0;
}
}
#else
/*
* Caller passes in a state, with a guarantee that there is work to do and that
* all items up to the pidx_tail in the state are visible.
*/
static void
drain_ring_lockless(struct ifmp_ring *r, union ring_state os, uint16_t prev, int budget)
{
union ring_state ns;
int n, pending, total;
uint16_t cidx = os.cidx;
uint16_t pidx = os.pidx_tail;
MPASS(os.flags == BUSY);
MPASS(cidx != pidx);
if (prev == IDLE)
counter_u64_add(r->starts, 1);
pending = 0;
total = 0;
while (cidx != pidx) {
/* Items from cidx to pidx are available for consumption. */
n = r->drain(r, cidx, pidx);
if (n == 0) {
critical_enter();
do {
os.state = ns.state = r->state;
ns.cidx = cidx;
ns.flags = STALLED;
} while (atomic_cmpset_64(&r->state, os.state,
ns.state) == 0);
critical_exit();
if (prev != STALLED)
counter_u64_add(r->stalls, 1);
else if (total > 0) {
counter_u64_add(r->restarts, 1);
counter_u64_add(r->stalls, 1);
}
break;
}
cidx = increment_idx(r, cidx, n);
pending += n;
total += n;
/*
* We update the cidx only if we've caught up with the pidx, the
* real cidx is getting too far ahead of the one visible to
* everyone else, or we have exceeded our budget.
*/
if (cidx != pidx && pending < 64 && total < budget)
continue;
critical_enter();
do {
os.state = ns.state = r->state;
ns.cidx = cidx;
ns.flags = state_to_flags(ns, total >= budget);
} while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0);
critical_exit();
if (ns.flags == ABDICATED)
counter_u64_add(r->abdications, 1);
if (ns.flags != BUSY) {
/* Wrong loop exit if we're going to stall. */
MPASS(ns.flags != STALLED);
if (prev == STALLED) {
MPASS(total > 0);
counter_u64_add(r->restarts, 1);
}
break;
}
/*
* The acquire style atomic above guarantees visibility of items
* associated with any pidx change that we notice here.
*/
pidx = ns.pidx_tail;
pending = 0;
}
}
#endif
int
ifmp_ring_alloc(struct ifmp_ring **pr, int size, void *cookie, mp_ring_drain_t drain,
mp_ring_can_drain_t can_drain, struct malloc_type *mt, int flags)
{
struct ifmp_ring *r;
/* All idx are 16b so size can be 65536 at most */
if (pr == NULL || size < 2 || size > 65536 || drain == NULL ||
can_drain == NULL)
return (EINVAL);
*pr = NULL;
flags &= M_NOWAIT | M_WAITOK;
MPASS(flags != 0);
r = malloc(__offsetof(struct ifmp_ring, items[size]), mt, flags | M_ZERO);
if (r == NULL)
return (ENOMEM);
r->size = size;
r->cookie = cookie;
r->mt = mt;
r->drain = drain;
r->can_drain = can_drain;
r->enqueues = counter_u64_alloc(flags);
r->drops = counter_u64_alloc(flags);
r->starts = counter_u64_alloc(flags);
r->stalls = counter_u64_alloc(flags);
r->restarts = counter_u64_alloc(flags);
r->abdications = counter_u64_alloc(flags);
if (r->enqueues == NULL || r->drops == NULL || r->starts == NULL ||
r->stalls == NULL || r->restarts == NULL ||
r->abdications == NULL) {
ifmp_ring_free(r);
return (ENOMEM);
}
*pr = r;
#ifdef NO_64BIT_ATOMICS
mtx_init(&r->lock, "mp_ring lock", NULL, MTX_DEF);
#endif
return (0);
}
void
ifmp_ring_free(struct ifmp_ring *r)
{
if (r == NULL)
return;
if (r->enqueues != NULL)
counter_u64_free(r->enqueues);
if (r->drops != NULL)
counter_u64_free(r->drops);
if (r->starts != NULL)
counter_u64_free(r->starts);
if (r->stalls != NULL)
counter_u64_free(r->stalls);
if (r->restarts != NULL)
counter_u64_free(r->restarts);
if (r->abdications != NULL)
counter_u64_free(r->abdications);
free(r, r->mt);
}
/*
* Enqueue n items and maybe drain the ring for some time.
*
* Returns an errno.
*/
#ifdef NO_64BIT_ATOMICS
int
ifmp_ring_enqueue(struct ifmp_ring *r, void **items, int n, int budget, int abdicate)
{
union ring_state os, ns;
uint16_t pidx_start, pidx_stop;
int i;
MPASS(items != NULL);
MPASS(n > 0);
mtx_lock(&r->lock);
/*
* Reserve room for the new items. Our reservation, if successful, is
* from 'pidx_start' to 'pidx_stop'.
*/
os.state = r->state;
if (n >= space_available(r, os)) {
counter_u64_add(r->drops, n);
MPASS(os.flags != IDLE);
mtx_unlock(&r->lock);
if (os.flags == STALLED)
ifmp_ring_check_drainage(r, 0);
return (ENOBUFS);
}
ns.state = os.state;
ns.pidx_head = increment_idx(r, os.pidx_head, n);
r->state = ns.state;
pidx_start = os.pidx_head;
pidx_stop = ns.pidx_head;
/*
* Wait for other producers who got in ahead of us to enqueue their
* items, one producer at a time. It is our turn when the ring's
* pidx_tail reaches the beginning of our reservation (pidx_start).
*/
while (ns.pidx_tail != pidx_start) {
cpu_spinwait();
ns.state = r->state;
}
/* Now it is our turn to fill up the area we reserved earlier. */
i = pidx_start;
do {
r->items[i] = *items++;
/*HAIKU*/KASSERT((r->items[i] == NULL) || ((uintptr_t)(r->items[i]) > 1024UL), ("is %p", r->items[i]));
if (__predict_false(++i == r->size))
i = 0;
} while (i != pidx_stop);
/*
* Update the ring's pidx_tail. The release style atomic guarantees
* that the items are visible to any thread that sees the updated pidx.
*/
os.state = ns.state = r->state;
ns.pidx_tail = pidx_stop;
if (abdicate) {
if (os.flags == IDLE)
ns.flags = ABDICATED;
}
else {
ns.flags = BUSY;
}
r->state = ns.state;
counter_u64_add(r->enqueues, n);
if (!abdicate) {
/*
* Turn into a consumer if some other thread isn't active as a consumer
* already.
*/
if (os.flags != BUSY)
drain_ring_locked(r, ns, os.flags, budget);
}
mtx_unlock(&r->lock);
return (0);
}
#else
int
ifmp_ring_enqueue(struct ifmp_ring *r, void **items, int n, int budget, int abdicate)
{
union ring_state os, ns;
uint16_t pidx_start, pidx_stop;
int i;
MPASS(items != NULL);
MPASS(n > 0);
/*
* Reserve room for the new items. Our reservation, if successful, is
* from 'pidx_start' to 'pidx_stop'.
*/
for (;;) {
os.state = r->state;
if (n >= space_available(r, os)) {
counter_u64_add(r->drops, n);
MPASS(os.flags != IDLE);
if (os.flags == STALLED)
ifmp_ring_check_drainage(r, 0);
return (ENOBUFS);
}
ns.state = os.state;
ns.pidx_head = increment_idx(r, os.pidx_head, n);
critical_enter();
if (atomic_cmpset_64(&r->state, os.state, ns.state))
break;
critical_exit();
cpu_spinwait();
}
pidx_start = os.pidx_head;
pidx_stop = ns.pidx_head;
/*
* Wait for other producers who got in ahead of us to enqueue their
* items, one producer at a time. It is our turn when the ring's
* pidx_tail reaches the beginning of our reservation (pidx_start).
*/
while (ns.pidx_tail != pidx_start) {
cpu_spinwait();
ns.state = r->state;
}
/* Now it is our turn to fill up the area we reserved earlier. */
i = pidx_start;
do {
r->items[i] = *items++;
if (__predict_false(++i == r->size))
i = 0;
} while (i != pidx_stop);
/*
* Update the ring's pidx_tail. The release style atomic guarantees
* that the items are visible to any thread that sees the updated pidx.
*/
do {
os.state = ns.state = r->state;
ns.pidx_tail = pidx_stop;
if (abdicate) {
if (os.flags == IDLE)
ns.flags = ABDICATED;
}
else {
ns.flags = BUSY;
}
} while (atomic_cmpset_rel_64(&r->state, os.state, ns.state) == 0);
critical_exit();
counter_u64_add(r->enqueues, n);
if (!abdicate) {
/*
* Turn into a consumer if some other thread isn't active as a consumer
* already.
*/
if (os.flags != BUSY)
drain_ring_lockless(r, ns, os.flags, budget);
}
return (0);
}
#endif
void
ifmp_ring_check_drainage(struct ifmp_ring *r, int budget)
{
union ring_state os, ns;
os.state = r->state;
if ((os.flags != STALLED && os.flags != ABDICATED) || // Only continue in STALLED and ABDICATED
os.pidx_head != os.pidx_tail || // Require work to be available
(os.flags != ABDICATED && r->can_drain(r) == 0)) // Can either drain, or everyone left
return;
MPASS(os.cidx != os.pidx_tail); /* implied by STALLED */
ns.state = os.state;
ns.flags = BUSY;
#ifdef NO_64BIT_ATOMICS
mtx_lock(&r->lock);
if (r->state != os.state) {
mtx_unlock(&r->lock);
return;
}
r->state = ns.state;
drain_ring_locked(r, ns, os.flags, budget);
mtx_unlock(&r->lock);
#else
/*
* The acquire style atomic guarantees visibility of items associated
* with the pidx that we read here.
*/
if (!atomic_cmpset_acq_64(&r->state, os.state, ns.state))
return;
drain_ring_lockless(r, ns, os.flags, budget);
#endif
}
void
ifmp_ring_reset_stats(struct ifmp_ring *r)
{
counter_u64_zero(r->enqueues);
counter_u64_zero(r->drops);
counter_u64_zero(r->starts);
counter_u64_zero(r->stalls);
counter_u64_zero(r->restarts);
counter_u64_zero(r->abdications);
}
int
ifmp_ring_is_idle(struct ifmp_ring *r)
{
union ring_state s;
s.state = r->state;
if (s.pidx_head == s.pidx_tail && s.pidx_tail == s.cidx &&
s.flags == IDLE)
return (1);
return (0);
}
int
ifmp_ring_is_stalled(struct ifmp_ring *r)
{
union ring_state s;
s.state = r->state;
if (s.pidx_head == s.pidx_tail && s.flags == STALLED)
return (1);
return (0);
}
+166
View File
@@ -0,0 +1,166 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2013 The FreeBSD Foundation
* Copyright (c) 2013-2015 Mariusz Zaborski <[email protected]>
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NV_IMPL_H_
#define _NV_IMPL_H_
#ifndef _NVPAIR_T_DECLARED
#define _NVPAIR_T_DECLARED
struct nvpair;
typedef struct nvpair nvpair_t;
#endif
#define NV_TYPE_NVLIST_ARRAY_NEXT 254
#define NV_TYPE_NVLIST_UP 255
#define NV_TYPE_FIRST NV_TYPE_NULL
#define NV_TYPE_LAST NV_TYPE_DESCRIPTOR_ARRAY
#define NV_FLAG_BIG_ENDIAN 0x080
#define NV_FLAG_IN_ARRAY 0x100
#ifdef _KERNEL
#define nv_malloc(size) malloc((size), M_NVLIST, M_WAITOK)
#define nv_calloc(n, size) mallocarray((n), (size), M_NVLIST, \
M_WAITOK | M_ZERO)
#define nv_realloc(buf, size) realloc((buf), (size), M_NVLIST, \
M_WAITOK)
#define nv_free(buf) free((buf), M_NVLIST)
#define nv_strdup(buf) strdup((buf), M_NVLIST)
#define nv_vasprintf(ptr, ...) vasprintf(ptr, M_NVLIST, __VA_ARGS__)
#define ERRNO_SET(var) do { } while (0)
#define ERRNO_SAVE() do { do { } while(0)
#define ERRNO_RESTORE() } while (0)
#define ERRNO_OR_DEFAULT(default) (default)
#else
#define nv_malloc(size) malloc((size))
#define nv_calloc(n, size) calloc((n), (size))
#define nv_realloc(buf, size) realloc((buf), (size))
#define nv_free(buf) free((buf))
#define nv_strdup(buf) strdup((buf))
#define nv_vasprintf(ptr, ...) vasprintf(ptr, __VA_ARGS__)
#define ERRNO_SET(var) do { errno = (var); } while (0)
#define ERRNO_SAVE() do { \
int _serrno; \
\
_serrno = errno
#define ERRNO_RESTORE() errno = _serrno; \
} while (0)
#define ERRNO_OR_DEFAULT(default) (errno == 0 ? (default) : errno)
#endif
int *nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp);
size_t nvlist_ndescriptors(const nvlist_t *nvl);
void nvlist_set_flags(nvlist_t *nvl, int flags);
nvpair_t *nvlist_first_nvpair(const nvlist_t *nvl);
nvpair_t *nvlist_next_nvpair(const nvlist_t *nvl, const nvpair_t *nvp);
nvpair_t *nvlist_prev_nvpair(const nvlist_t *nvl, const nvpair_t *nvp);
void nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp);
bool nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp);
void nvlist_set_parent(nvlist_t *nvl, nvpair_t *parent);
void nvlist_set_array_next(nvlist_t *nvl, nvpair_t *ele);
const nvpair_t *nvlist_get_nvpair(const nvlist_t *nvl, const char *name);
nvpair_t *nvlist_take_nvpair(nvlist_t *nvl, const char *name);
/* Function removes the given nvpair from the nvlist. */
void nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp);
void nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp);
int nvpair_type(const nvpair_t *nvp);
const char *nvpair_name(const nvpair_t *nvp);
nvpair_t *nvpair_clone(const nvpair_t *nvp);
nvpair_t *nvpair_create_null(const char *name);
nvpair_t *nvpair_create_bool(const char *name, bool value);
nvpair_t *nvpair_create_number(const char *name, uint64_t value);
nvpair_t *nvpair_create_string(const char *name, const char *value);
nvpair_t *nvpair_create_stringf(const char *name, const char *valuefmt, ...) __printflike(2, 3);
nvpair_t *nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) __printflike(2, 0);
nvpair_t *nvpair_create_nvlist(const char *name, const nvlist_t *value);
nvpair_t *nvpair_create_descriptor(const char *name, int value);
nvpair_t *nvpair_create_binary(const char *name, const void *value, size_t size);
nvpair_t *nvpair_create_bool_array(const char *name, const bool *value, size_t nitems);
nvpair_t *nvpair_create_number_array(const char *name, const uint64_t *value, size_t nitems);
nvpair_t *nvpair_create_string_array(const char *name, const char * const *value, size_t nitems);
nvpair_t *nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value, size_t nitems);
nvpair_t *nvpair_create_descriptor_array(const char *name, const int *value, size_t nitems);
nvpair_t *nvpair_move_string(const char *name, char *value);
nvpair_t *nvpair_move_nvlist(const char *name, nvlist_t *value);
nvpair_t *nvpair_move_descriptor(const char *name, int value);
nvpair_t *nvpair_move_binary(const char *name, void *value, size_t size);
nvpair_t *nvpair_move_bool_array(const char *name, bool *value, size_t nitems);
nvpair_t *nvpair_move_nvlist_array(const char *name, nvlist_t **value, size_t nitems);
nvpair_t *nvpair_move_descriptor_array(const char *name, int *value, size_t nitems);
nvpair_t *nvpair_move_number_array(const char *name, uint64_t *value, size_t nitems);
nvpair_t *nvpair_move_string_array(const char *name, char **value, size_t nitems);
int nvpair_append_bool_array(nvpair_t *nvp, const bool value);
int nvpair_append_number_array(nvpair_t *nvp, const uint64_t value);
int nvpair_append_string_array(nvpair_t *nvp, const char *value);
int nvpair_append_nvlist_array(nvpair_t *nvp, const nvlist_t *value);
int nvpair_append_descriptor_array(nvpair_t *nvp, const int value);
bool nvpair_get_bool(const nvpair_t *nvp);
uint64_t nvpair_get_number(const nvpair_t *nvp);
const char *nvpair_get_string(const nvpair_t *nvp);
const nvlist_t *nvpair_get_nvlist(const nvpair_t *nvp);
int nvpair_get_descriptor(const nvpair_t *nvp);
const void *nvpair_get_binary(const nvpair_t *nvp, size_t *sizep);
const bool *nvpair_get_bool_array(const nvpair_t *nvp, size_t *nitemsp);
const uint64_t *nvpair_get_number_array(const nvpair_t *nvp, size_t *nitemsp);
const char * const *nvpair_get_string_array(const nvpair_t *nvp, size_t *nitemsp);
const nvlist_t * const *nvpair_get_nvlist_array(const nvpair_t *nvp, size_t *nitemsp);
const int *nvpair_get_descriptor_array(const nvpair_t *nvp, size_t *nitemsp);
void nvpair_free(nvpair_t *nvp);
#endif /* !_NV_IMPL_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,49 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2013 The FreeBSD Foundation
* Copyright (c) 2013-2015 Mariusz Zaborski <[email protected]>
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NVLIST_IMPL_H_
#define _NVLIST_IMPL_H_
#include <sys/nv.h>
#ifndef _KERNEL
#include <stdint.h>
#endif
void nvlist_report_missing(int type, const char *name);
nvpair_t *nvlist_get_nvpair_parent(const nvlist_t *nvl);
const unsigned char *nvlist_unpack_header(nvlist_t *nvl,
const unsigned char *ptr, size_t nfds, bool *isbep, size_t *leftp);
#endif /* !_NVLIST_IMPL_H_ */
+115
View File
@@ -0,0 +1,115 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009-2013 The FreeBSD Foundation
* Copyright (c) 2013-2015 Mariusz Zaborski <[email protected]>
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NVPAIR_IMPL_H_
#define _NVPAIR_IMPL_H_
#include <sys/nv.h>
#include <sys/queue.h>
#ifndef _KERNEL
#include <stdint.h>
#endif
TAILQ_HEAD(nvl_head, nvpair);
void nvpair_assert(const nvpair_t *nvp);
nvlist_t *nvpair_nvlist(const nvpair_t *nvp);
nvpair_t *nvpair_next(const nvpair_t *nvp);
nvpair_t *nvpair_prev(const nvpair_t *nvp);
void nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl);
void nvpair_remove(struct nvl_head *head, nvpair_t *nvp, const nvlist_t *nvl);
size_t nvpair_header_size(void);
size_t nvpair_size(const nvpair_t *nvp);
const unsigned char *nvpair_unpack(bool isbe, const unsigned char *ptr,
size_t *leftp, nvpair_t **nvpp);
void nvpair_free_structure(nvpair_t *nvp);
void nvpair_init_datasize(nvpair_t *nvp);
const char *nvpair_type_string(int type);
/* Pack functions. */
unsigned char *nvpair_pack_header(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_null(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_bool(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_number(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_string(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr,
int64_t *fdidxp, size_t *leftp);
unsigned char *nvpair_pack_binary(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_nvlist_up(unsigned char *ptr, size_t *leftp);
unsigned char *nvpair_pack_bool_array(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_number_array(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_string_array(const nvpair_t *nvp, unsigned char *ptr,
size_t *leftp);
unsigned char *nvpair_pack_descriptor_array(const nvpair_t *nvp,
unsigned char *ptr, int64_t *fdidxp, size_t *leftp);
unsigned char *nvpair_pack_nvlist_array_next(unsigned char *ptr, size_t *leftp);
/* Unpack data functions. */
const unsigned char *nvpair_unpack_header(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_null(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_bool(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_number(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_string(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_nvlist(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp, size_t nfds, nvlist_t **child);
const unsigned char *nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp, const int *fds, size_t nfds);
const unsigned char *nvpair_unpack_binary(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_bool_array(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_number_array(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_string_array(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp);
const unsigned char *nvpair_unpack_descriptor_array(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp, const int *fds, size_t nfds);
const unsigned char *nvpair_unpack_nvlist_array(bool isbe, nvpair_t *nvp,
const unsigned char *ptr, size_t *leftp, nvlist_t **firstel);
#endif /* !_NVPAIR_IMPL_H_ */
+71
View File
@@ -0,0 +1,71 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1990, 1993
* The Regents of the University of California. 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, 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/cdefs.h>
#include <sys/systm.h>
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
char *
strsep(char **stringp, const char *delim)
{
char *s;
const char *spanp;
int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
File diff suppressed because it is too large Load Diff