/*
** $Source: dh1:network/parnet/Sana2/Spar_device.h,v $
** $State: Exp $
** $Revision: 37.1 $
** $Date: 93/08/15 16:43:51 $
** $Author: sap $
**
** SANA-II Example device driver C include file
**
** Portions (C) Copyright 1992 Commodore-Amiga, Inc.
*/

#include <exec/types.h>
#include <exec/devices.h>
#include <exec/ports.h>
#include <exec/semaphores.h>
#include <exec/memory.h>
#include <dos.h>
#include <devices/sana2.h>
#include <devices/parnet.h>

/*
** Stacksize and Priority of the Unit Process
*/
#define SPAR_STACKSIZE 4000
#define SPAR_PRI 5

/*
** Maximum Transmission Unit
*/
#define SPAR_MTU 8192+256

/* Hmm, I still need to determine the *real* PARnet bps
 */
#define SPAR_SPEED 28672

/* Use PARnet port 1024 for communications
 * WARNING: the NET:-handler uses this port also, change it to any other
 * value when you want to run both NET: and SPAR.
 */
#define SPAR_PORT 1024

/* Length of an Ethernet address. Used to calculate the offset of 
 * the packet type identifier in an Ethernet frame.
 */
#define EADDR_LEN 6

/*
 * Length of an Ethernet frame header.
 * Struct ENET_HDR {
 *       UCHAR EDestAddr[6];
 *       UCHAR ESrcAddr[6];
 *       UWORD PacketType;
 *       }
 */
#define EHDR_LEN 2*EADDR_LEN+2

/*
** Max # of Units allowed
*/
#define SD_MAXUNITS 8

/*
** Message passed to the Unit Process at
** startup time.
*/
struct StartupMessage
{
  struct Message  Msg;
  struct Unit     *Unit;
  struct Device   *Device;
};

/*
** Device Data Structure
*/
struct SPARDevice
{
    struct Library          sd_Device;
    UBYTE                   sd_Flags;
    UBYTE                   sd_Pad1;
    struct Library         *sd_SysBase;
    struct Library         *sd_DOSBase;
    ULONG                   sd_DosTag[10];
    BPTR                    sd_SegList;
    struct Unit            *sd_Units[SD_MAXUNITS];
    struct SignalSemaphore  sd_Lock;
    struct StartupMessage   sd_Startup;
};

/*
** Typedef's for the SANA-II callback functions.
*/
typedef BOOL (*SANA2_CFB)(APTR to, APTR from, LONG length);
typedef BOOL (*SANA2_CTB)(APTR to, APTR from, LONG length);

struct BufferManagement
{
   struct MinNode   bm_Node;
   SANA2_CFB        bm_CopyFromBuffer;
   SANA2_CTB        bm_CopyToBuffer;
};

struct SuperS2PTStats
{
   struct MinNode               ss_Node;
   ULONG                        ss_PType;
   struct Sana2PacketTypeStats  ss_Stats;
};

/*
** Unit Data Structure
*/
struct SPARDevUnit
{
    struct Unit              sdu_Unit;            /* Standard Unit Structure */
    UBYTE                    sdu_UnitNum;         /* Unit number */
    UBYTE                    sdu_Reserved0;       /* Padding */
    struct Device           *sdu_Device;          /* Pointer to our device node */
    UWORD                    sdu_StAddr;          /* Our PARnet hardware address */
    ULONG                    sdu_ParUnitNum;      /* PARnet driver unit number */
    BOOL                     sdu_NoMore;          /* Flag: work to do for Unit process */
    ULONG                    sdu_State;           /* Various state information */
    struct IOParReq         *sdu_ParRx;           /* PARnet IORequest for CMD_READ's */
    struct IOParReq         *sdu_ParTx;           /* PARnet IORequest for CMD_WRITE's */
    struct MsgPort          *sdu_RxPort;          /* PARnet CMD_READ IORequest reply port */
    struct MsgPort          *sdu_TxPort;          /* PARnet CMD_WRITE IORequest reply port */
    UBYTE                   *sdu_RxBuff;          /* Buffer for holding packets */
    UBYTE                   *sdu_TxBuff;          /* Temporary buffer for hold outgoing packets */
    struct Process          *sdu_Proc;            /* NB: This points to the Task, not the MsgPort */
    struct SignalSemaphore   sdu_ListLock;        /* A Semaphore for access to all of our queues. */
    struct MinList           sdu_Rx;              /* Pending CMD_READ's */
    struct MinList           sdu_RxOrph;          /* Pending CMD_READORPHAN's */
    struct MinList           sdu_Tx;              /* Pending CMD_WRITE's */
    struct MinList           sdu_Events;          /* Pending S2_ONEVENT's */
    BOOL                     sdu_TrackP;          /* Flag: a packet to track is present */
    struct MinList           sdu_Track;           /* List of packet types being tracked */
    struct MinList           sdu_BuffMgmt;        /* List of Callback routines */
    struct Sana2DeviceStats  sdu_Stats;           /* Global device statistics */
    UBYTE                    sdu_ParDevName[32];  /* Name of the PARnet driver to use */
};

/*
** State bits for sdu_State
*/

#define SPARUB_ONLINE 0
#define SPARUB_CONFIG 1
#define SPARUB_CONTROL 2
#define SPARUB_DGRAM 3
#define SPARUB_STREAM 4

#define SPARUF_ONLINE       (1<<SPARUB_ONLINE)
#define SPARUF_CONFIG       (1<<SPARUB_CONFIG)
#define SPARUF_CONTROL      (1<<SPARUB_CONTROL)
#define SPARUF_DGRAM        (1<<SPARUB_DGRAM)
#define SPARUF_STREAM       (1<<SPARUB_STREAM)

/*
** Device Name
*/

#define SPARDEVNAME "spar.device"

/*
** Compiler Magic
**
*/

/* SPARBase must be in register a6 */
#define SPARBase ((struct SPARDevice *)__builtin_getreg(14))      /* Avoid the pre-processor problem */

/* pointer to exec (initialized in DevInit(), see spar_device.asm) */
#define SysBase      (SPARBase->sd_SysBase)
#define DOSBase      (SPARBase->sd_DOSBase)

#define ASM          __asm
#define REG(x)       register __ ## x

