/*
 * Declarations to fit FreeBSD to RTEMS.
 *
 *******************************************************************
 *                            WARNING                              *
 * This file should *never* be included by any application program *
 *******************************************************************
 */

#ifndef _RTEMS_RTEMS_BSDNET_INTERNAL_H
#define _RTEMS_RTEMS_BSDNET_INTERNAL_H

#include <sys/_types.h>
#include <rtems.h>
#include <rtems/fs.h>
#include <rtems/score/timecounter.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef	__uintptr_t		vm_offset_t;
typedef	__intptr_t		vm_ooffset_t;
typedef	__uintptr_t		vm_pindex_t;
typedef	__uintptr_t		vm_size_t;

#define _BSD_OFF_T_	int32_t
#define _BSD_PID_T_	rtems_id
#define _BSD_VA_LIST_	char *

/* make sure we get the network versions of these */
#include <machine/types.h>
#include <machine/param.h>
#include <machine/endian.h>
#include <sys/cdefs.h>

#include <sys/time.h>
#include <sys/ioccom.h>

struct mdproc {
	int	md_flags;
	int	*md_regs;
};

/*
 * Other RTEMS/BSD glue
 */
struct socket;
extern int soconnsleep (struct socket *so);
extern void soconnwakeup (struct socket *so);
#define splnet()	0
#define splimp()	0
#define splx(_s)	do { (_s) = 0; (void) (_s); } while(0)

/* to avoid warnings */
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);

#define ovbcopy(f,t,n) bcopy(f,t,n)
#define copyout(f,t,n) (memcpy(t,f,n),0)
#define copyin(f,t,n) (memcpy(t,f,n),0)

#define random()	rtems_bsdnet_random()
#define panic	rtems_panic
#define suser(a,b)	0

#define	microtime(_tvp) _Timecounter_Microtime(_tvp)

#define hz rtems_bsdnet_ticks_per_second
#define tick rtems_bsdnet_microseconds_per_tick

#define log	rtems_bsdnet_log

/*
 * Since we can't have two sys/types.h files, we'll hack around
 * and copy the contents of the BSD sys/types.h to here....
 */

typedef	u_int64_t	u_quad_t;	/* quads */
typedef	int64_t		quad_t;
typedef	quad_t *	qaddr_t;

typedef void __sighandler_t(int);
typedef	__sighandler_t	*sig_t;	/* type of pointer to a signal function */
#define NSIG    32

#ifdef _KERNEL
typedef	int		boolean_t;
#endif

#ifndef _POSIX_SOURCE
/*
 * minor() gives a cookie instead of an index since we don't want to
 * change the meanings of bits 0-15 or waste time and space shifting
 * bits 16-31 for devices that don't use them.
 */
#define	major(x)	((int)(((u_int)(x) >> 8)&0xff))	/* major number */
#define	minor(x)	((int)((x)&0xffff00ff))		/* minor number */
#define	makedev(x,y)	((dev_t)(((x) << 8) | (y)))	/* create dev_t */
#endif

#ifndef _BYTEORDER_PROTOTYPED
#define	_BYTEORDER_PROTOTYPED
__BEGIN_DECLS
__uint32_t	 htonl(__uint32_t);
__uint16_t	 htons(__uint16_t);
__uint32_t	 ntohl(__uint32_t);
__uint16_t	 ntohs(__uint16_t);
__END_DECLS
#endif

#ifndef _BYTEORDER_FUNC_DEFINED
#define	_BYTEORDER_FUNC_DEFINED
#define	htonl(x)	__htonl(x)
#define	htons(x)	__htons(x)
#define	ntohl(x)	__ntohl(x)
#define	ntohs(x)	__ntohs(x)
#endif /* !_BYTEORDER_FUNC_DEFINED */

#define NTOHS(x) (x) = ntohs(x)
#define HTONS(x) (x) = htons(x)
#define NTOHL(x) (x) = ntohl(x)
#define HTONL(x) (x) = htonl(x)

in_addr_t	 inet_addr(const char *);

typedef quad_t          rlim_t;         /* resource limit */
typedef	u_int32_t	fixpt_t;	/* fixed point number */

/*
 * Forward structure declarations for function prototypes.  We include the
 * common structures that cross subsystem boundaries here; others are mostly
 * used in the same place that the structure is defined.
 */
struct	proc;
struct	pgrp;
struct	ucred;
struct	rusage;
struct	buf;
struct	tty;
struct	uio;
struct	rtems_bsdnet_ifconfig;

/*
 * Redo kernel memory allocation
 */
#define malloc(size,type,flags) rtems_bsdnet_malloc(size,type,flags)
#define free(ptr,type) rtems_bsdnet_free(ptr,type)
#define timeout(ftn,arg,ticks) rtems_bsdnet_timeout(ftn,arg,ticks)

#define	M_NOWAIT	0x0001
void *rtems_bsdnet_malloc (size_t size, int type, int flags);
void rtems_bsdnet_free (void *addr, int type);

void rtems_bsdnet_semaphore_obtain (void);
void rtems_bsdnet_semaphore_release (void);
void rtems_bsdnet_semaphore_obtain_recursive (uint32_t nest_count);
uint32_t rtems_bsdnet_semaphore_release_recursive (void);
void rtems_bsdnet_schednetisr (int n);
int rtems_bsdnet_parse_driver_name (const struct rtems_bsdnet_ifconfig *config, char **namep);

static inline unsigned long rtems_bsdnet_seconds_since_boot(void)
{
  return (unsigned long) rtems_clock_get_uptime_seconds() + 1UL;
}

unsigned long rtems_bsdnet_random (void);

rtems_id rtems_bsdnet_newproc (
  char  *name,
  int   stacksize,
  void  (*entry)(void *),
  void  *arg
);

#ifdef RTEMS_SMP
/* As rtems_bsdnet_newproc() but with ability to set CPU affinity too */
rtems_id rtems_bsdnet_newproc_affinity (
  char  *name,
  int   stacksize,
  void  (*entry)(void *),
  void  *arg,
  const cpu_set_t *set,
  const size_t setsize
);
#endif

rtems_status_code rtems_bsdnet_event_receive (
  rtems_event_set  event_in,
  rtems_option     option_set,
  rtems_interval   ticks,
  rtems_event_set *event_out
);

static inline rtems_status_code rtems_bsdnet_event_send (
  rtems_id        task_id,
  rtems_event_set event_in
)
{
  return rtems_event_system_send (task_id, event_in);
}

/*
 * Network configuration
 */
extern int rtems_bsdnet_ticks_per_second;
extern int rtems_bsdnet_microseconds_per_tick;
extern struct in_addr rtems_bsdnet_log_host_address;
extern char *rtems_bsdnet_domain_name;

/*
 * Internal IOCTL command
 */
#define SIO_RTEMS_SHOW_STATS	_IO('i', 250)

/*
 * Some extra prototypes
 */
int sethostname (const char *name, size_t namelen);
void domaininit (void *);
void ifinit (void *);
void ipintr (void);
void arpintr (void);
int socket (int, int, int);
int ioctl (int, ioctl_command_t, ...);

/*
 * Events used by networking routines.
 * Everything will break if the application
 * tries to use these events or if the `sleep'
 * events are equal to any of the NETISR * events.
 */
#define SBWAIT_EVENT   RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT
#define SOSLEEP_EVENT  RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP
#define NETISR_IP_EVENT        (1L << NETISR_IP)
#define NETISR_ARP_EVENT       (1L << NETISR_ARP)
#define NETISR_EVENTS  (NETISR_IP_EVENT|NETISR_ARP_EVENT)
#if (SBWAIT_EVENT & SOSLEEP_EVENT & NETISR_EVENTS & RTEMS_EVENT_SYSTEM_NETWORK_CLOSE)
# error "Network event conflict"
#endif

struct socket *rtems_bsdnet_fdToSocket(int fd);

void sysctl_register_all(void *);

void rtems_set_udp_buffer_sizes(u_long, u_long);

void rtems_set_tcp_buffer_sizes(u_long, u_long);

void rtems_set_sb_efficiency(u_long);

#define IFF_OACTIVE IFF_DRV_OACTIVE
#define IFF_RUNNING IFF_DRV_RUNNING

struct ifaddr;
void	ifafree(struct ifaddr *);

struct ifnet;
struct mbuf;
struct sockaddr;
struct rtentry;
int	looutput(struct ifnet *,
	   struct mbuf *, struct sockaddr *, struct rtentry *);

typedef u_long	tcp_cc;			/* connection count per rfc1644 */

#define    TCPOPT_TSTAMP_HDR		\
    (uint32_t)(((uint32_t)TCPOPT_NOP<<24)| \
               ((uint32_t)TCPOPT_NOP<<16)| \
               ((uint32_t)TCPOPT_TIMESTAMP<<8)| \
               ((uint32_t)TCPOLEN_TIMESTAMP))

#define	TCPOPT_CC		11		/* CC options: RFC-1644 */
#define TCPOPT_CCNEW		12
#define TCPOPT_CCECHO		13
#define	   TCPOLEN_CC			6
#define	   TCPOLEN_CC_APPA		(TCPOLEN_CC+2)
#define	   TCPOPT_CC_HDR(ccopt)		\
    (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)

#ifdef __cplusplus
}
#endif

#endif /* _RTEMS_RTEMS_BSDNET_INTERNAL_H */
