From 56676a8c4b246dbeef4914ad4e003cf38ca57596 Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 3 May 2004 23:31:45 +0000 Subject: [PATCH] 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 --- .../drivers/network/ipro1000/if_compat.c | 172 ++++++++++ .../drivers/network/ipro1000/if_compat.h | 307 ++++++++++++++++++ 2 files changed, 479 insertions(+) create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/if_compat.c create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/if_compat.h diff --git a/src/add-ons/kernel/drivers/network/ipro1000/if_compat.c b/src/add-ons/kernel/drivers/network/ipro1000/if_compat.c new file mode 100644 index 0000000000..0d2de4b6ff --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/if_compat.c @@ -0,0 +1,172 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . 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); +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/if_compat.h b/src/add-ons/kernel/drivers/network/ipro1000/if_compat.h new file mode 100644 index 0000000000..13243ede50 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/if_compat.h @@ -0,0 +1,307 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#ifndef __IF_COMPAT_H +#define __IF_COMPAT_H + +#include + +#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