freebsd_network: Adaptations in preparation for the OpenBSD layer.
Most of these changes however add things that FreeBSD has (with a few exceptions noted in comments) which the OpenBSD shim layer merely needs to make use of. (FreeBSD used to have support for IFF_NEEDSGIANT but removed it. The support instated here is very similar to what FreeBSD used to have.)
This commit is contained in:
@@ -25,6 +25,7 @@ KernelStaticLibrary libfreebsd_network.a :
|
|||||||
fbsd_subr_bufring.c
|
fbsd_subr_bufring.c
|
||||||
fbsd_subr_sbuf.c
|
fbsd_subr_sbuf.c
|
||||||
fbsd_time.c
|
fbsd_time.c
|
||||||
|
fbsd_timingsafe.c
|
||||||
fbsd_usb_error.c
|
fbsd_usb_error.c
|
||||||
fbsd_usb_util.c
|
fbsd_usb_util.c
|
||||||
fbsd_usb_lookup.c
|
fbsd_usb_lookup.c
|
||||||
|
|||||||
@@ -297,6 +297,23 @@ rman_get_virtual(struct resource *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bus_addr_t
|
||||||
|
rman_get_start(struct resource *res)
|
||||||
|
{
|
||||||
|
return res->r_bushandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bus_size_t
|
||||||
|
rman_get_size(struct resource *res)
|
||||||
|
{
|
||||||
|
area_info info;
|
||||||
|
if (get_area_info(res->r_mapped_area, &info) != B_OK)
|
||||||
|
return 0;
|
||||||
|
return info.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Interrupt handling
|
// #pragma mark - Interrupt handling
|
||||||
|
|
||||||
|
|
||||||
@@ -329,7 +346,13 @@ intr_handler(void *data)
|
|||||||
//device_printf(intr->dev, "in soft interrupt handler.\n");
|
//device_printf(intr->dev, "in soft interrupt handler.\n");
|
||||||
|
|
||||||
atomic_or(&intr->handling, 1);
|
atomic_or(&intr->handling, 1);
|
||||||
|
if ((intr->flags & INTR_MPSAFE) == 0)
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
intr->handler(intr->arg);
|
intr->handler(intr->arg);
|
||||||
|
|
||||||
|
if ((intr->flags & INTR_MPSAFE) == 0)
|
||||||
|
mtx_unlock(&Giant);
|
||||||
atomic_and(&intr->handling, 0);
|
atomic_and(&intr->handling, 0);
|
||||||
HAIKU_REENABLE_INTERRUPTS(intr->dev);
|
HAIKU_REENABLE_INTERRUPTS(intr->dev);
|
||||||
}
|
}
|
||||||
@@ -355,8 +378,6 @@ int
|
|||||||
bus_setup_intr(device_t dev, struct resource *res, int flags,
|
bus_setup_intr(device_t dev, struct resource *res, int flags,
|
||||||
driver_filter_t* filter, driver_intr_t handler, void *arg, void **_cookie)
|
driver_filter_t* filter, driver_intr_t handler, void *arg, void **_cookie)
|
||||||
{
|
{
|
||||||
/* TODO check MPSAFE etc */
|
|
||||||
|
|
||||||
struct internal_intr *intr = (struct internal_intr *)malloc(
|
struct internal_intr *intr = (struct internal_intr *)malloc(
|
||||||
sizeof(struct internal_intr));
|
sizeof(struct internal_intr));
|
||||||
char semName[64];
|
char semName[64];
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <compat/sys/kernel.h>
|
#include <compat/sys/kernel.h>
|
||||||
|
#include <compat/sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
@@ -12,3 +13,12 @@ _get_ticks()
|
|||||||
{
|
{
|
||||||
return USEC_2_TICKS(system_time());
|
return USEC_2_TICKS(system_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
getmicrouptime(struct timeval *tvp)
|
||||||
|
{
|
||||||
|
bigtime_t usecs = system_time();
|
||||||
|
tvp->tv_sec = usecs / 1000000;
|
||||||
|
tvp->tv_usec = usecs % 1000000;
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
#define IFF_MONITOR 0x00400000 /* (n) user-requested monitor mode */
|
#define IFF_MONITOR 0x00400000 /* (n) user-requested monitor mode */
|
||||||
#define IFF_PPROMISC 0x00800000 /* (n) user-requested promisc mode */
|
#define IFF_PPROMISC 0x00800000 /* (n) user-requested promisc mode */
|
||||||
#define IFF_NOGROUP 0x01000000 /* (n) interface is not part of any groups */
|
#define IFF_NOGROUP 0x01000000 /* (n) interface is not part of any groups */
|
||||||
|
#define IFF_NEEDSGIANT 0x02000000 /* (i) hold Giant over hook calls (OpenBSD compatibility) */
|
||||||
|
|
||||||
#define LINK_STATE_UNKNOWN 0
|
#define LINK_STATE_UNKNOWN 0
|
||||||
#define LINK_STATE_DOWN 1
|
#define LINK_STATE_DOWN 1
|
||||||
|
|||||||
@@ -258,7 +258,6 @@ struct ifnet {
|
|||||||
void *if_afdata[AF_MAX];
|
void *if_afdata[AF_MAX];
|
||||||
int if_afdata_initialized;
|
int if_afdata_initialized;
|
||||||
struct mtx if_afdata_mtx;
|
struct mtx if_afdata_mtx;
|
||||||
struct task if_starttask; /* task for IFF_NEEDSGIANT */
|
|
||||||
struct task if_linktask; /* task for link change events */
|
struct task if_linktask; /* task for link change events */
|
||||||
struct mtx if_addr_mtx; /* mutex to protect address lists */
|
struct mtx if_addr_mtx; /* mutex to protect address lists */
|
||||||
|
|
||||||
@@ -752,6 +751,10 @@ int ifioctl(struct socket *, u_long, caddr_t, struct thread *);
|
|||||||
int ifpromisc(struct ifnet *, int);
|
int ifpromisc(struct ifnet *, int);
|
||||||
struct ifnet *ifunit(const char *);
|
struct ifnet *ifunit(const char *);
|
||||||
|
|
||||||
|
/* Haiku extension for OpenBSD compat */
|
||||||
|
int if_alloc_inplace(struct ifnet *ifp, u_char type);
|
||||||
|
void if_free_inplace(struct ifnet *ifp);
|
||||||
|
|
||||||
struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
|
struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
|
||||||
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
|
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
|
||||||
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
|
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
|
||||||
|
|||||||
@@ -13,12 +13,17 @@
|
|||||||
typedef void (*task_fn_t)(void *context, int pending);
|
typedef void (*task_fn_t)(void *context, int pending);
|
||||||
|
|
||||||
struct task {
|
struct task {
|
||||||
|
int ta_pending;
|
||||||
int ta_priority;
|
int ta_priority;
|
||||||
|
int ta_flags;
|
||||||
task_fn_t ta_handler;
|
task_fn_t ta_handler;
|
||||||
void *ta_argument;
|
void *ta_argument;
|
||||||
int ta_pending;
|
|
||||||
|
|
||||||
struct list_link ta_link;
|
struct list_link ta_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define TASK_NEEDSGIANT (1 << 0) /* Haiku extension, OpenBSD compatibility */
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ buf_ring_advance_sc(struct buf_ring *br)
|
|||||||
static __inline void
|
static __inline void
|
||||||
buf_ring_putback_sc(struct buf_ring *br, void *_new)
|
buf_ring_putback_sc(struct buf_ring *br, void *_new)
|
||||||
{
|
{
|
||||||
KASSERT(br->br_cons_head != br->br_prod_tail,
|
KASSERT_FREEBSD(br->br_cons_head != br->br_prod_tail,
|
||||||
("Buf-Ring has none in putback")) ;
|
("Buf-Ring has none in putback")) ;
|
||||||
br->br_ring[br->br_cons_head] = _new;
|
br->br_ring[br->br_cons_head] = _new;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,8 +207,11 @@ enum {
|
|||||||
FBSD_SWI_TASKQUEUE = 1 << 2,
|
FBSD_SWI_TASKQUEUE = 1 << 2,
|
||||||
FBSD_THREAD_TASKQUEUE = 1 << 3,
|
FBSD_THREAD_TASKQUEUE = 1 << 3,
|
||||||
FBSD_WLAN_FEATURE = 1 << 4,
|
FBSD_WLAN_FEATURE = 1 << 4,
|
||||||
|
|
||||||
FBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES
|
FBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES
|
||||||
| FBSD_THREAD_TASKQUEUE,
|
| FBSD_THREAD_TASKQUEUE,
|
||||||
|
OBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES
|
||||||
|
| FBSD_FAST_TASKQUEUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HAIKU_DRIVER_REQUIREMENTS(flags) \
|
#define HAIKU_DRIVER_REQUIREMENTS(flags) \
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ extern int random(void);
|
|||||||
u_int read_random(void *, u_int);
|
u_int read_random(void *, u_int);
|
||||||
void arc4rand(void *ptr, u_int len, int reseed);
|
void arc4rand(void *ptr, u_int len, int reseed);
|
||||||
uint32_t arc4random(void);
|
uint32_t arc4random(void);
|
||||||
|
void arc4random_buf(void *ptr, size_t len);
|
||||||
|
|
||||||
|
int timingsafe_bcmp(const void *, const void *, size_t);
|
||||||
|
|
||||||
static __inline int imax(int a, int b) { return (a > b ? a : b); }
|
static __inline int imax(int a, int b) { return (a > b ? a : b); }
|
||||||
static __inline int imin(int a, int b) { return (a < b ? a : b); }
|
static __inline int imin(int a, int b) { return (a < b ? a : b); }
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void _kernel_contigfree(void *addr, unsigned long size);
|
|||||||
#define kernel_malloc(size, base, flags) \
|
#define kernel_malloc(size, base, flags) \
|
||||||
_kernel_malloc(size, flags)
|
_kernel_malloc(size, flags)
|
||||||
|
|
||||||
#define kernel_free(ptr, base) \
|
#define kernel_free(ptr, tag) \
|
||||||
_kernel_free(ptr)
|
_kernel_free(ptr)
|
||||||
|
|
||||||
#define kernel_contigmalloc(size, type, flags, low, high, alignment, boundary) \
|
#define kernel_contigmalloc(size, type, flags, low, high, alignment, boundary) \
|
||||||
|
|||||||
@@ -212,6 +212,16 @@ m_cljset(struct mbuf *m, void *cl, int type)
|
|||||||
m->m_flags |= M_EXT;
|
m->m_flags |= M_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* These are for OpenBSD compatibility. */
|
||||||
|
#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
|
||||||
|
|
||||||
|
static __inline struct m_tag *
|
||||||
|
m_tag_find(struct mbuf *m, uint16_t type, struct m_tag *start)
|
||||||
|
{
|
||||||
|
return (SLIST_EMPTY(&m->m_pkthdr.tags) ? (struct m_tag *)NULL :
|
||||||
|
m_tag_locate(m, MTAG_ABI_COMPAT, type, start));
|
||||||
|
}
|
||||||
|
|
||||||
/* mbufq */
|
/* mbufq */
|
||||||
|
|
||||||
struct mbufq {
|
struct mbufq {
|
||||||
|
|||||||
@@ -215,6 +215,12 @@ struct pkthdr {
|
|||||||
uint8_t rsstype; /* hash type */
|
uint8_t rsstype; /* hash type */
|
||||||
uint16_t tso_segsz;
|
uint16_t tso_segsz;
|
||||||
uint16_t ether_vtag;
|
uint16_t ether_vtag;
|
||||||
|
|
||||||
|
/* Layer specific non-persistent local storage for reassembly, etc. */
|
||||||
|
union {
|
||||||
|
uintptr_t unintptr[1];
|
||||||
|
void* ptr;
|
||||||
|
} PH_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct m_tag {
|
struct m_tag {
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007, Hugo Santos. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright 1998 Massachusetts Institute of Technology
|
* Copyright 1998 Massachusetts Institute of Technology
|
||||||
*
|
*
|
||||||
@@ -61,30 +55,7 @@ bus_space_handle_t rman_get_bushandle(struct resource *);
|
|||||||
bus_space_tag_t rman_get_bustag(struct resource *);
|
bus_space_tag_t rman_get_bustag(struct resource *);
|
||||||
int rman_get_rid(struct resource *);
|
int rman_get_rid(struct resource *);
|
||||||
void* rman_get_virtual(struct resource *);
|
void* rman_get_virtual(struct resource *);
|
||||||
|
bus_addr_t rman_get_start(struct resource *);
|
||||||
|
bus_size_t rman_get_size(struct resource *);
|
||||||
|
|
||||||
|
|
||||||
static inline u_long
|
|
||||||
rman_get_start(struct resource *resourcePointer)
|
|
||||||
{
|
|
||||||
return resourcePointer->r_bushandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
rman_make_alignment_flags(uint32_t size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the hightest bit set, and add one if more than one bit
|
|
||||||
* set. We're effectively computing the ceil(log2(size)) here.
|
|
||||||
*/
|
|
||||||
for (i = 31; i > 0; i--)
|
|
||||||
if ((1 << i) & size)
|
|
||||||
break;
|
|
||||||
if (~(1 << i) & size)
|
|
||||||
i++;
|
|
||||||
|
|
||||||
return RF_ALIGNMENT_LOG2(i);
|
|
||||||
}
|
|
||||||
#endif /* _FBSD_COMPAT_SYS_RMAN_H_ */
|
#endif /* _FBSD_COMPAT_SYS_RMAN_H_ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009 Haiku Inc. All rights reserved.
|
* Copyright 2009-2022, Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _FBSD_COMPAT_SYS_SYSLOG_H_
|
#ifndef _FBSD_COMPAT_SYS_SYSLOG_H_
|
||||||
@@ -7,5 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define LOG_ERR 3 /* error conditions */
|
#define LOG_ERR 3 /* error conditions */
|
||||||
|
#define LOG_WARNING 4 /* warning conditions */
|
||||||
|
|
||||||
|
|
||||||
#endif /* _FBSD_COMPAT_SYS_SYSLOG_H_ */
|
#endif /* _FBSD_COMPAT_SYS_SYSLOG_H_ */
|
||||||
|
|||||||
@@ -41,13 +41,14 @@ int printf(const char *format, ...) __printflike(1, 2);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef INVARIANTS
|
#ifdef INVARIANTS
|
||||||
#define KASSERT(cond,msg) do { \
|
#define KASSERT_FREEBSD(cond,msg) do { \
|
||||||
if (!(cond)) \
|
if (!(cond)) \
|
||||||
panic msg; \
|
panic msg; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#define KASSERT(cond,msg) KASSERT_FREEBSD(cond,msg)
|
||||||
#else
|
#else
|
||||||
#define KASSERT(exp,msg) do { \
|
#define KASSERT_FREEBSD(exp,msg) do {} while (0)
|
||||||
} while (0)
|
#define KASSERT(cond,msg) KASSERT_FREEBSD(cond,msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DELAY(n) \
|
#define DELAY(n) \
|
||||||
|
|||||||
@@ -1,6 +1,39 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020, Haiku, Inc. All rights reserved.
|
* Copyright 2020-2022, Haiku, Inc. All rights reserved.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 1982, 1986, 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.
|
||||||
|
*
|
||||||
|
* @(#)time.h 8.5 (Berkeley) 5/4/95
|
||||||
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
#ifndef _FBSD_COMPAT_SYS_TIME_H_
|
#ifndef _FBSD_COMPAT_SYS_TIME_H_
|
||||||
#define _FBSD_COMPAT_SYS_TIME_H_
|
#define _FBSD_COMPAT_SYS_TIME_H_
|
||||||
@@ -21,7 +54,21 @@
|
|||||||
#define time_uptime USEC_2_TICKS(system_time())
|
#define time_uptime USEC_2_TICKS(system_time())
|
||||||
|
|
||||||
|
|
||||||
int ppsratecheck(struct timeval*, int*, int);
|
/* Operations on timevals. */
|
||||||
|
#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
|
||||||
|
#define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
|
||||||
|
#define timevalcmp(tvp, uvp, cmp) \
|
||||||
|
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
|
||||||
|
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
|
||||||
|
((tvp)->tv_sec cmp (uvp)->tv_sec))
|
||||||
|
|
||||||
|
|
||||||
|
void getmicrouptime(struct timeval *tvp);
|
||||||
|
|
||||||
|
int ppsratecheck(struct timeval *, int *, int);
|
||||||
|
int ratecheck(struct timeval *, const struct timeval *);
|
||||||
|
void timevaladd(struct timeval *t1, const struct timeval *t2);
|
||||||
|
void timevalsub(struct timeval *t1, const struct timeval *t2);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _FBSD_COMPAT_SYS_TIME_H_ */
|
#endif /* _FBSD_COMPAT_SYS_TIME_H_ */
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ compat_open(const char *name, uint32 flags, void **cookie)
|
|||||||
return B_BUSY;
|
return B_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
|
|
||||||
ifp->if_init(ifp->if_softc);
|
ifp->if_init(ifp->if_softc);
|
||||||
|
|
||||||
if (!HAIKU_DRIVER_REQUIRES(FBSD_WLAN_FEATURE)) {
|
if (!HAIKU_DRIVER_REQUIRES(FBSD_WLAN_FEATURE)) {
|
||||||
@@ -68,6 +70,8 @@ compat_open(const char *name, uint32 flags, void **cookie)
|
|||||||
ifp->flags &= ~DEVICE_CLOSED;
|
ifp->flags &= ~DEVICE_CLOSED;
|
||||||
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
||||||
|
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
|
|
||||||
*cookie = ifp;
|
*cookie = ifp;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -184,7 +188,11 @@ compat_write(void *cookie, off_t position, const void *buffer,
|
|||||||
memcpy(mtod(mb, void *), buffer, mb->m_len);
|
memcpy(mtod(mb, void *), buffer, mb->m_len);
|
||||||
*numBytes = length;
|
*numBytes = length;
|
||||||
|
|
||||||
return ifp->if_output(ifp, mb, NULL, NULL);
|
IFF_LOCKGIANT(ifp);
|
||||||
|
int result = ifp->if_output(ifp, mb, NULL, NULL);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,6 +200,7 @@ static status_t
|
|||||||
compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
||||||
{
|
{
|
||||||
struct ifnet *ifp = cookie;
|
struct ifnet *ifp = cookie;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
//if_printf(ifp, "compat_control(op %lu, %p, [%lu])\n", op,
|
//if_printf(ifp, "compat_control(op %lu, %p, [%lu])\n", op,
|
||||||
// arg, length);
|
// arg, length);
|
||||||
@@ -228,7 +237,11 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
|||||||
ifp->if_flags |= IFF_PROMISC;
|
ifp->if_flags |= IFF_PROMISC;
|
||||||
else
|
else
|
||||||
ifp->if_flags &= ~IFF_PROMISC;
|
ifp->if_flags &= ~IFF_PROMISC;
|
||||||
return ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
|
status = ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ETHER_GETFRAMESIZE:
|
case ETHER_GETFRAMESIZE:
|
||||||
@@ -273,10 +286,13 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
|||||||
if (user_memcpy(LLADDR(&address), arg, ETHER_ADDR_LEN) < B_OK)
|
if (user_memcpy(LLADDR(&address), arg, ETHER_ADDR_LEN) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
if (op == ETHER_ADDMULTI)
|
if (op == ETHER_ADDMULTI)
|
||||||
return if_addmulti(ifp, (struct sockaddr *)&address, NULL);
|
status = if_addmulti(ifp, (struct sockaddr *)&address, NULL);
|
||||||
|
else
|
||||||
return if_delmulti(ifp, (struct sockaddr *)&address);
|
status = if_delmulti(ifp, (struct sockaddr *)&address);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ETHER_GET_LINK_STATE:
|
case ETHER_GET_LINK_STATE:
|
||||||
@@ -289,7 +305,9 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
memset(&mediareq, 0, sizeof(mediareq));
|
memset(&mediareq, 0, sizeof(mediareq));
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq);
|
status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -313,7 +331,12 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
|
|||||||
case SIOCSIFMEDIA:
|
case SIOCSIFMEDIA:
|
||||||
case SIOCGIFMEDIA:
|
case SIOCGIFMEDIA:
|
||||||
case SIOCSIFMTU:
|
case SIOCSIFMTU:
|
||||||
return ifp->if_ioctl(ifp, op, (caddr_t)arg);
|
{
|
||||||
|
IFF_LOCKGIANT(ifp);
|
||||||
|
status = ifp->if_ioctl(ifp, op, (caddr_t)arg);
|
||||||
|
IFF_UNLOCKGIANT(ifp);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wlan_control(cookie, op, arg, length);
|
return wlan_control(cookie, op, arg, length);
|
||||||
|
|||||||
@@ -31,6 +31,46 @@
|
|||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ratecheck(): simple time-based rate-limit checking.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
|
||||||
|
{
|
||||||
|
struct timeval tv, delta;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
getmicrouptime(&tv); /* NB: 10ms precision */
|
||||||
|
delta = tv;
|
||||||
|
timevalsub(&delta, lasttime);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for 0,0 is so that the message will be seen at least once,
|
||||||
|
* even if interval is huge.
|
||||||
|
*/
|
||||||
|
if (timevalcmp(&delta, mininterval, >=) ||
|
||||||
|
(lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
|
||||||
|
*lasttime = tv;
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ppsratecheck(): packets (or events) per second limitation.
|
||||||
|
*
|
||||||
|
* Return 0 if the limit is to be enforced (e.g. the caller
|
||||||
|
* should drop a packet because of the rate limitation).
|
||||||
|
*
|
||||||
|
* maxpps of 0 always causes zero to be returned. maxpps of -1
|
||||||
|
* always causes 1 to be returned; this effectively defeats rate
|
||||||
|
* limiting.
|
||||||
|
*
|
||||||
|
* Note that we maintain the struct timeval for compatibility
|
||||||
|
* with other bsd systems. We reuse the storage and just monitor
|
||||||
|
* clock ticks for minimal overhead.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
|
ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
|
||||||
{
|
{
|
||||||
@@ -48,6 +88,45 @@ ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
|
|||||||
return (maxpps != 0);
|
return (maxpps != 0);
|
||||||
} else {
|
} else {
|
||||||
(*curpps)++; /* NB: ignore potential overflow */
|
(*curpps)++; /* NB: ignore potential overflow */
|
||||||
return (maxpps < 0 || *curpps < maxpps);
|
return (maxpps < 0 || *curpps <= maxpps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timevalfix(struct timeval *t1)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (t1->tv_usec < 0) {
|
||||||
|
t1->tv_sec--;
|
||||||
|
t1->tv_usec += 1000000;
|
||||||
|
}
|
||||||
|
if (t1->tv_usec >= 1000000) {
|
||||||
|
t1->tv_sec++;
|
||||||
|
t1->tv_usec -= 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add and subtract routines for timevals.
|
||||||
|
* N.B.: subtract routine doesn't deal with
|
||||||
|
* results which are before the beginning,
|
||||||
|
* it just gets very confused in this case.
|
||||||
|
* Caveat emptor.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
timevaladd(struct timeval *t1, const struct timeval *t2)
|
||||||
|
{
|
||||||
|
|
||||||
|
t1->tv_sec += t2->tv_sec;
|
||||||
|
t1->tv_usec += t2->tv_usec;
|
||||||
|
timevalfix(t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timevalsub(struct timeval *t1, const struct timeval *t2)
|
||||||
|
{
|
||||||
|
|
||||||
|
t1->tv_sec -= t2->tv_sec;
|
||||||
|
t1->tv_usec -= t2->tv_usec;
|
||||||
|
timevalfix(t1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/libkern.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
|
||||||
|
{
|
||||||
|
const unsigned char *p1 = b1, *p2 = b2;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (; n > 0; n--)
|
||||||
|
ret |= *p1++ ^ *p2++;
|
||||||
|
return (ret != 0);
|
||||||
|
}
|
||||||
@@ -149,21 +149,17 @@ ifindex_free_locked(u_short idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ifnet *
|
int
|
||||||
if_alloc(u_char type)
|
if_alloc_inplace(struct ifnet *ifp, u_char type)
|
||||||
{
|
{
|
||||||
char semName[64];
|
char semName[64];
|
||||||
u_short index;
|
u_short index;
|
||||||
|
|
||||||
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
|
|
||||||
if (ifp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
snprintf(semName, sizeof(semName), "%s receive", gDriverName);
|
snprintf(semName, sizeof(semName), "%s receive", gDriverName);
|
||||||
|
|
||||||
ifp->receive_sem = create_sem(0, semName);
|
ifp->receive_sem = create_sem(0, semName);
|
||||||
if (ifp->receive_sem < B_OK)
|
if (ifp->receive_sem < B_OK)
|
||||||
goto err1;
|
return ifp->receive_sem;
|
||||||
|
|
||||||
ifp->link_state_sem = -1;
|
ifp->link_state_sem = -1;
|
||||||
ifp->open_count = 0;
|
ifp->open_count = 0;
|
||||||
@@ -188,7 +184,7 @@ if_alloc(u_char type)
|
|||||||
ifnet_setbyindex(ifp->if_index, ifp);
|
ifnet_setbyindex(ifp->if_index, ifp);
|
||||||
|
|
||||||
IF_ADDR_LOCK_INIT(ifp);
|
IF_ADDR_LOCK_INIT(ifp);
|
||||||
return ifp;
|
return 0;
|
||||||
|
|
||||||
err3:
|
err3:
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -200,14 +196,28 @@ err3:
|
|||||||
err2:
|
err2:
|
||||||
delete_sem(ifp->receive_sem);
|
delete_sem(ifp->receive_sem);
|
||||||
|
|
||||||
err1:
|
return -1;
|
||||||
_kernel_free(ifp);
|
}
|
||||||
return NULL;
|
|
||||||
|
|
||||||
|
struct ifnet *
|
||||||
|
if_alloc(u_char type)
|
||||||
|
{
|
||||||
|
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
|
||||||
|
if (ifp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (if_alloc_inplace(ifp, type) != 0) {
|
||||||
|
_kernel_free(ifp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
if_free(struct ifnet *ifp)
|
if_free_inplace(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
// IEEE80211 devices won't be in this list,
|
// IEEE80211 devices won't be in this list,
|
||||||
// so don't try to remove them.
|
// so don't try to remove them.
|
||||||
@@ -227,6 +237,13 @@ if_free(struct ifnet *ifp)
|
|||||||
|
|
||||||
delete_sem(ifp->receive_sem);
|
delete_sem(ifp->receive_sem);
|
||||||
ifq_uninit(&ifp->receive_queue);
|
ifq_uninit(&ifp->receive_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
if_free(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
if_free_inplace(ifp);
|
||||||
|
|
||||||
_kernel_free(ifp);
|
_kernel_free(ifp);
|
||||||
}
|
}
|
||||||
@@ -397,10 +414,6 @@ if_detach(struct ifnet *ifp)
|
|||||||
void
|
void
|
||||||
if_start(struct ifnet *ifp)
|
if_start(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
#ifdef IFF_NEEDSGIANT
|
|
||||||
if (ifp->if_flags & IFF_NEEDSGIANT)
|
|
||||||
panic("freebsd compat.: unsupported giant requirement");
|
|
||||||
#endif
|
|
||||||
ifp->if_start(ifp);
|
ifp->if_start(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Colin Günther, coling@gmx.de. All rights reserved.
|
* Copyright 2018-2022, Haiku, Inc. All rights reserved.
|
||||||
* Copyright 2018, Haiku, Inc. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -36,3 +35,10 @@ arc4random(void)
|
|||||||
arc4rand(&ret, sizeof ret, 0);
|
arc4rand(&ret, sizeof ret, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
arc4random_buf(void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
arc4rand(ptr, len, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,7 +127,13 @@ tq_handle_thread(void *data)
|
|||||||
pending = t->ta_pending;
|
pending = t->ta_pending;
|
||||||
t->ta_pending = 0;
|
t->ta_pending = 0;
|
||||||
|
|
||||||
|
if ((t->ta_flags & TASK_NEEDSGIANT) != 0)
|
||||||
|
mtx_lock(&Giant);
|
||||||
|
|
||||||
t->ta_handler(t->ta_argument, pending);
|
t->ta_handler(t->ta_argument, pending);
|
||||||
|
|
||||||
|
if ((t->ta_flags & TASK_NEEDSGIANT) != 0)
|
||||||
|
mtx_unlock(&Giant);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -489,6 +495,7 @@ void
|
|||||||
task_init(struct task *task, int prio, task_fn_t handler, void *context)
|
task_init(struct task *task, int prio, task_fn_t handler, void *context)
|
||||||
{
|
{
|
||||||
task->ta_priority = prio;
|
task->ta_priority = prio;
|
||||||
|
task->ta_flags = 0;
|
||||||
task->ta_handler = handler;
|
task->ta_handler = handler;
|
||||||
task->ta_argument = context;
|
task->ta_argument = context;
|
||||||
task->ta_pending = 0;
|
task->ta_pending = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user