#ifndef CNET_H
#define CNET_H

/*
*----------------------------------------------------------------------------
*                         Includes for cnet.device
*----------------------------------------------------------------------------
*                   By Harry Sintonen (sintonen@iki.fi)
*           Original code by Bruce Abbott (bhabbott@inhb.co.nz)
*
*
* History
*
*  13-12-2000  - Rewrote in c.
*    5-1-2001  - Added MorphOS support.
*
*/

#include <exec/types.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <exec/interrupts.h>
#include <exec/semaphores.h>
#include <exec/execbase.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/ports.h>
#include <exec/errors.h>
#include <exec/resident.h>
#include <exec/initializers.h>

#include <hardware/cia.h>
#include <hardware/adkbits.h>
#include <hardware/intbits.h>
#include <hardware/custom.h>

#include <resources/card.h>
#include <devices/timer.h>
#include <utility/utility.h>
#include <dos/dos.h>
#include <intuition/intuition.h>

#include "sana2/sana2.h"
#include "sana2/sana2specialstats.h"

#include "pcmcia.h"
#include "ds8390.h"


/* size of our packet buffer
*/
#define PKTBUF_SIZE    (1536 + 16)


/* ethernet address bytesize
*/
#define ETHER_ADDR_SIZE 6


/* NSD stuff
*/
#define MY_NSDEVTYPE_SANA2         7


#ifndef  __MORPHOS__

struct my_NSDeviceQueryResult
{
  ULONG   DevQueryFormat;         /* this is type 0               */
  ULONG   SizeAvailable;          /* bytes available              */
  UWORD   DeviceType;             /* what the device does         */
  UWORD   DeviceSubType;          /* depends on the main type     */
  const UWORD *SupportedCommands; /* 0 terminated list of cmd's   */
};

/* structure of an ethernet packet - internal
*/
struct etherpacket_hdr
{
  UBYTE  dest[ETHER_ADDR_SIZE];      /* 0 destination address */
  UBYTE  src[ETHER_ADDR_SIZE];       /* 6 originator  address */
  UWORD  type;                       /* 12 packet type */
};

#else

struct my_NSDeviceQueryResult
{
  ULONG   DevQueryFormat;
  ULONG   SizeAvailable;
  UWORD   DeviceType;
  UWORD   DeviceSubType;
  const UWORD *SupportedCommands;
} __attribute__((packed));

struct etherpacket_hdr
{
  UBYTE  dest[ETHER_ADDR_SIZE];
  UBYTE  src[ETHER_ADDR_SIZE];
  UWORD __attribute__((aligned(2)))  type;
} __attribute__((packed));

#endif




/* multicastaddress range record - private
*/
struct multicastaddressrange
{
  struct MinNode mln;                /* 0 list node */
  ULONG  usecount;                   /* 8 number of times used */
  UBYTE  loweraddr[ETHER_ADDR_SIZE]; /* 12 multicast address lower bound */
  UBYTE  upperaddr[ETHER_ADDR_SIZE]; /* 18 multicast address upper bound */
};



/* buffer management node - private
*/
struct bufman
{
  struct MinNode mln;
  APTR  dmacopyfrombuf32;
  APTR  copyfrombuf;
  APTR  dmacopytobuf32;
  APTR  copytobuf;
  APTR  packetfilter;
  struct MinList rxqueue;        /* read requests */
};


/* packet statistics node - private
*/
struct packettypestats
{
  struct MinNode mln;
  LONG  packettype;
  struct Sana2PacketTypeStats stats;
};


struct initstruct
{
  const ULONG libsize;
  const void  *functable;
  const void  *datatable;
  void  (*initfunc)(void);
};


/* The device node - private
*/
struct MyDevice
{
  struct Library      dd_library;       /* standard */
  UWORD               dd_flags;         /* various flags */
  UBYTE               dd_dcr;           /* copy of nic data config reg */
  UBYTE               dd_rcr;           /* copy of nic rx config reg */
  UBYTE               dd_imr;           /* copy of nic intmask register */
  UBYTE               dd_align00;       /* aligment */
  ULONG               dd_retries;       /* tx collision count */
  ULONG               dd_badmulticasts; /* bad multicast count */
  ULONG               dd_overflows;     /* nic rx buffer overflow count */

  struct ExecBase    *dd_SysBase;       /* cached execbase */
  struct UtilityBase *dd_utilitybase;   /* for tags etc */
  APTR                dd_mempool;       /* memory pool for allocations */

  BPTR                dd_seglist;       /* device seglist */
  APTR                dd_cardres;       /* card.resource base */

  struct Device      *dd_timerbase;     /* timer device base */

  struct Sana2PacketTypeStats *dd_typestats2048; /* IP protocol stats ptr, or NULL */
  struct Sana2PacketTypeStats *dd_typestats2054; /* ARP protocol stats ptr, or NULL */

  struct CardMemoryMap *dd_cmm;         /* pointer to card.resource memory map */
  nic_t                *dd_attrmem;     /* pointer to card.resource attribute memory */

  struct MinList      dd_orphanlist;    /* orphan requests */
  struct MinList      dd_writelist;     /* write requests */
  struct MinList      dd_eventlist;     /* events */
  struct MinList      dd_bufmanlist;    /* buffer management vectors */
  struct MinList      dd_tracklist;     /* tracking nodes */
  struct MinList      dd_multicasts;    /* multicast filters */
#ifdef __MORPHOS__
  struct PPCCardHandle dd_cardhandle;   /* credit card handle */
#else
  struct CardHandle   dd_cardhandle;    /* credit card handle */
#endif /* __MORPHOS__ */

  /* hardware address from ROM */
  UBYTE               dd_romstationaddress[ETHER_ADDR_SIZE];
  /* hardware station addr used */
  UBYTE               dd_stationaddress[ETHER_ADDR_SIZE];

  struct Sana2DeviceStats dd_devicestats;

  struct Interrupt    dd_cardremoved;   /* card removed interrupt */
  struct Interrupt    dd_cardinserted;  /* card inserted interrupt */
  struct Interrupt    dd_cardstatus;    /* card status interrupt */

#ifdef __MORPHOS__
  struct Interrupt    dd_ppccardremoved; /* ppc card removed interrupt */
  struct Interrupt    dd_ppccardinserted;/* ppc card inserted interrupt */
  struct Interrupt    dd_ppccardstatus;  /* ppc card status interrupt */
#endif /* __MORPHOS__ */

  struct Interrupt    dd_rxint;         /* receive software interrupt */
  struct Interrupt    dd_txint;         /* transmit software interrupt */

  struct SignalSemaphore dd_mempoolsema;    /* dd_mempool arbitration */
  struct SignalSemaphore dd_multicastssema; /* multicast list arbitration */

  struct timerequest  dd_timereq;       /* Timer I/O Request */

  UBYTE               dd_tuplebuf[48];  /* buffer for init_card CopyTuple() */
  UBYTE               dd_mcastaddr[8];  /* multicast address filter bitfield */
  UBYTE               dd_rxbuffer[PKTBUF_SIZE]; /* received packet buffer */
  UBYTE               dd_txbuffer[PKTBUF_SIZE]; /* transmit packet buffer */
};


/* bit definitions for dd_flags
*/

#define DDF_CARDHANDLE (1<<0)  /* got cardhandle */
#define DDF_NICUP      (1<<1)  /* controller hardware is initialised */
#define DDF_CONFIGURED (1<<2)  /* station address is configured */
#define DDF_ONLINE     (1<<3)  /* device is online */
#define DDF_OFFLINE    (1<<4)  /* device was put offline */
#define DDF_TX         (1<<5)  /* transmit buffer is full */
#define DDF_MINE       (1<<6)  /* exclusive mode */
#define DDF_PROM       (1<<7)  /* promiscuous mode */

#endif /* CNET_H */
