This is the real hard stuff!

FreeBSD compatibility layer that provides a struct ifnet interface,
all #defines that are used by the driver, the mbuf functions,
mbuf queues, etc.
Also some unused things are provided by empty macros.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7399 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2004-05-03 23:31:45 +00:00
parent b567981843
commit 56676a8c4b
2 changed files with 479 additions and 0 deletions

View File

@ -0,0 +1,172 @@
/* Intel PRO/1000 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*/
#include "if_compat.h"
#include "if_em.h"
#include "device.h"
#include "debug.h"
#include "mempool.h"
spinlock mbuf_lock = 0;
struct mbuf *
m_alloc()
{
struct mbuf *m = mbuf_pool_get();
if (!m)
return m;
memset(m, 0, sizeof(m));
m->m_flags = M_PKTHDR;
return m;
}
struct mbuf *
m_gethdr(int how, int type)
{
return m_alloc();
}
void
m_clget(struct mbuf * m, int how)
{
// TRACE("m_clget\n");
m->m_ext.ext_buf = chunk_pool_get();
m->m_data = m->m_ext.ext_buf;
if (m->m_ext.ext_buf)
m->m_flags |= M_EXT;
}
void
m_adj(struct mbuf *mp, int bytes)
{
mp->m_data += bytes;
}
void
m_freem(struct mbuf *mp)
{
struct mbuf *m, *c;
// TRACE("m_freem\n");
for (m = mp; m; ) {
if (m->m_flags & M_EXT)
chunk_pool_put(m->m_ext.ext_buf);
c = m;
m = m->m_next;
mbuf_pool_put(c);
}
}
void
ether_input(struct ifnet *ifp, struct mbuf *m)
{
/*
uint8 *buf;
int len;
buf = mtod(m, uint8 *);
len = m->m_len;
TRACE("ether_input: received packet with %d bytes\n", len);
TRACE("%02x %02x %02x %02x . %02x %02x %02x %02x . %02x %02x %02x %02x \n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
buf[6], buf[7], buf[8], buf[8], buf[10], buf[11]);
m_freem(m);
return;
*/
IF_APPEND(&ifp->if_rcv, m);
release_sem_etc(ifp->if_rcv_sem, 1, B_DO_NOT_RESCHEDULE);
}
void
ether_ifattach(struct ifnet *ifp, const uint8 *etheraddr)
{
ipro1000_device *dev = ifp->if_softc->dev;
TRACE("ether_ifattach\n");
memcpy(dev->macaddr, etheraddr, 6);
ifp->if_input = ether_input;
ifp->if_rcv_sem = create_sem(0, "ifp->if_rcv_sem");
TRACE("calling if_init...\n");
ifp->if_init(ifp->if_softc);
TRACE("done calling if_init!\n");
}
void
ether_ifdetach(struct ifnet *ifp)
{
TRACE("ether_ifdetach\n");
delete_sem(ifp->if_rcv_sem);
}
struct mbuf *
if_dequeue(struct if_queue *queue)
{
cpu_status s;
struct mbuf *m;
// TRACE("IF_DEQUEUE\n");
s = disable_interrupts();
acquire_spinlock(&mbuf_lock);
m = (struct mbuf *) queue->ifq_head;
if (m) {
queue->ifq_head = m->m_nextq;
if (!queue->ifq_head)
queue->ifq_tail = 0;
m->m_nextq = 0;
}
release_spinlock(&mbuf_lock);
restore_interrupts(s);
return m;
}
void
if_prepend(struct if_queue *queue, struct mbuf *mb)
{
cpu_status s;
// TRACE("IF_PREPEND\n");
s = disable_interrupts();
acquire_spinlock(&mbuf_lock);
mb->m_nextq = (struct mbuf *) queue->ifq_head;
queue->ifq_head = mb;
if (!queue->ifq_tail)
queue->ifq_tail = mb;
release_spinlock(&mbuf_lock);
restore_interrupts(s);
}
void
if_append(struct if_queue *queue, struct mbuf *mb)
{
cpu_status s;
// TRACE("IF_APPEND\n");
s = disable_interrupts();
acquire_spinlock(&mbuf_lock);
mb->m_nextq = 0;
if (!queue->ifq_tail) {
queue->ifq_tail = mb;
queue->ifq_head = mb;
} else {
queue->ifq_tail->m_nextq = mb;
queue->ifq_tail = mb;
}
release_spinlock(&mbuf_lock);
restore_interrupts(s);
}

View File

@ -0,0 +1,307 @@
/* Intel PRO/1000 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*/
#ifndef __IF_COMPAT_H
#define __IF_COMPAT_H
#include <OS.h>
#define __FreeBSD_version 500001
#define IFF_BROADCAST 0x0001
#define IFF_SIMPLEX 0x0002
#define IFF_MULTICAST 0x0004
#define IFF_RUNNING 0x0008
#define IFF_OACTIVE 0x0010
#define IFF_UP 0x0020
#define IFF_PROMISC 0x0040
#define IFF_ALLMULTI 0x0080
#define IFCAP_HWCSUM 0x0001
#define IFCAP_VLAN_HWTAGGING 0x0002
#define IFCAP_VLAN_MTU 0x0004
#define IFCAP_POLLING 0x0008
#define IFCAP_TXCSUM 0x0010
#define IFCAP_RXCSUM 0x0020
#define IFM_ACTIVE 0x0001
#define IFM_FDX 0x0002
#define IFM_HDX 0x0004
#define IFM_10_T 0x0008
#define IFM_100_TX 0x0010
#define IFM_1000_T 0x0020
#define IFM_1000_TX 0x0040
#define IFM_1000_SX 0x0080
#define IFM_ETHER 0x0100
#define IFM_AUTO 0x0200
#define IFM_AVALID 0x0400
#define IFM_GMASK (IFM_FDX | IFM_HDX)
#define IFM_TYPE_MASK (IFM_ETHER)
#define IFM_SUBTYPE_MASK (IFM_AUTO | IFM_1000_SX | IFM_1000_TX | IFM_1000_T | IFM_100_TX | IFM_10_T)
#define IFM_TYPE(media) ((media) & IFM_TYPE_MASK)
#define IFM_SUBTYPE(media) ((media) & IFM_SUBTYPE_MASK)
#define CSUM_TCP 0x0001 // ifnet::if_hwassist
#define CSUM_UDP 0x0002 // ifnet::if_hwassist
#define CSUM_IP_CHECKED 0x0004
#define CSUM_IP_VALID 0x0008
#define CSUM_DATA_VALID 0x0010
#define CSUM_PSEUDO_HDR 0x0020
#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */
#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */
#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
#define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */
#define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */
#define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */
#define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */
#define ETHERMTU ETHER_MAX_LEN_JUMBO
#define IP_HEADER_SIZE 20
#define OFFSETOF_IPHDR_SUM 10
#define OFFSETOF_TCPHDR_SUM 16
#define OFFSETOF_UDPHDR_SUM 6
// vlan stuff is not supported
#define ETHERTYPE_VLAN 0x8100
#define VLAN_INPUT_TAG(a, b, c, d)
#define VLAN_TAG_VALUE(mtag) 0
#define VLAN_OUTPUT_TAG(ifp, m_head) 0
// BPF listener not supported
#define BPF_MTAP(a, b)
// sysctl stuff is not supported
#define sysctl_ctx_init(a)
#define sysctl_ctx_free(a)
#define SYSCTL_HANDLER_ARGS void
#define SYSCTL_ADD_NODE(a, b, c, d, e, f, g) \
(struct sysctl_oid *) 1
#define SYSCTL_ADD_PROC(a, b, c, d, e, f, g, h, i, j)
struct sysctl_ctx_list
{
};
struct sysctl_oid
{
};
struct adapter;
struct ifnet;
struct mbuf;
struct ifmedia
{
uint32 ifm_media;
};
struct ifmediareq
{
uint32 ifm_status;
uint32 ifm_active;
};
struct if_queue
{
volatile struct mbuf * ifq_head;
volatile struct mbuf * ifq_tail;
int ifq_maxlen; // ignored
};
typedef void (*if_start)(struct ifnet *);
typedef int (*if_ioctl)(struct ifnet *, u_long, caddr_t);
typedef void (*if_watchdog)(struct ifnet *);
typedef void (*if_init)(void *);
typedef void (*if_input)(struct ifnet *, struct mbuf *);
struct m_pkthdr
{
int len;
int csum_flags;
uint16 csum_data;
struct ifnet * rcvif; // set by receive int
};
struct m_ext
{
void *ext_buf;
};
struct mbuf
{
struct mbuf * m_next; // next buffer in chain (e.g. for jumboframes)
struct mbuf * m_nextq; // next buffer in queue
int m_len;
int m_flags;
void * m_data;
struct m_pkthdr m_pkthdr;
struct m_ext m_ext;
};
#define M_DONTWAIT 0x01
#define M_EXT 0x02
#define M_PKTHDR 0x04
#define MT_DATA 1
#define MCLBYTES 2048
struct mbuf *m_gethdr(int how, int type);
// Allocate and return a single M_PKTHDR mbuf. NULL is returned on failure.
#define MGETHDR(mb, how, type) ((mb) = m_gethdr((how), (type)))
void m_clget(struct mbuf * mb, int how);
// Fetch a single mbuf cluster and attach it to an existing mbuf. If
// successfull, configures the provided mbuf to have mbuf->m_ext.ext_buf
// pointing to the cluster, and sets the M_EXT bit in the mbuf's flags.
// The M_EXT bit is not set on failure
#define MCLGET(mb, how) m_clget((mb), (how))
struct mbuf *if_dequeue(struct if_queue *queue);
void if_prepend(struct if_queue *queue, struct mbuf *mb);
void if_append(struct if_queue *queue, struct mbuf *mb);
#define IF_DEQUEUE(queue, mb) ((mb) = if_dequeue((queue)))
#define IF_PREPEND(queue, mb) if_prepend((queue), (mb))
#define IF_APPEND(queue, mb) if_append((queue), (mb))
void m_adj(struct mbuf *mp, int bytes);
void m_freem(struct mbuf *mp);
#define mtod(m, t) ((t)((m)->m_data))
void ether_ifattach(struct ifnet *ifp, const uint8 *etheraddr);
void ether_ifdetach(struct ifnet *ifp);
#define AF_LINK 0
struct ifma_addr
{
int sa_family; // must be AF_LINK
};
struct ifmultiaddr
{
struct ifma_addr *ifma_addr;
};
struct if_data
{
int ifi_hdrlen;
};
struct ether_vlan_header
{
uint8 evl_dhost[ETHER_ADDR_LEN];
uint8 evl_shost[ETHER_ADDR_LEN];
uint16 evl_encap_proto;
uint16 evl_tag;
uint16 evl_proto;
};
struct ifnet
{
const char *if_name;
struct adapter *if_softc;
int if_unit;
int if_mtu;
volatile uint32 if_flags;
uint32 if_capabilities;
uint32 if_hwassist;
uint32 if_capenable;
uint64 if_baudrate;
int64 if_timer;
uint64 if_ibytes;
uint64 if_obytes;
uint64 if_imcasts;
uint64 if_collisions;
uint64 if_ierrors;
uint64 if_oerrors;
uint64 if_ipackets;
uint64 if_opackets;
struct if_queue if_snd; // send queue
struct if_queue if_rcv; // recveive queue
sem_id if_rcv_sem;
// struct if_multiaddrs if_multiaddrs; // multicast addr list
struct if_data if_data;
if_start if_start;
if_ioctl if_ioctl;
if_watchdog if_watchdog;
if_init if_init;
if_input if_input;
void *if_output; // unused
#define ether_output 0
};
struct arpcom
{
struct ifnet ac_if;
uint8 ac_enaddr[ETHER_ADDR_LEN];
};
#define device_get_softc(dev) \
(dev->adapter ? dev->adapter : (dev->adapter = (struct adapter *)malloc(sizeof(struct adapter), 0, 0)))
#define device_get_unit(dev) \
dev->devId
enum { // ioctl commands
SIOCSIFADDR = 0x7000,
SIOCGIFADDR,
SIOCSIFMTU,
SIOCSIFFLAGS,
SIOCADDMULTI,
SIOCDELMULTI,
SIOCSIFMEDIA,
SIOCGIFMEDIA,
SIOCSIFCAP,
};
struct ifreq // ioctl command data
{
uint32 ifr_reqcap;
int ifr_mtu;
};
// used for media properties
#define ifmedia_init(a, b, c, d)
#define ifmedia_add(a, b, c, d)
#define ifmedia_set(a, b)
#define ifmedia_ioctl(ifp, ifr, media, command) 0
// used inside multicast stuff
struct sockaddr_dl
{
u_char sdl_len;
u_char sdl_family;
u_short sdl_index;
u_char sdl_type;
u_char sdl_nlen;
u_char sdl_alen;
u_char sdl_slen;
char sdl_data[46];
};
// used inside multicast stuff
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
// called for SIOCxIFADDR (Get/Set Interface Addr)
#define ether_ioctl(ifp, command, data)
#endif // __IF_COMPAT_H