#ifndef DS8390_H
#define DS8390_H

/*
*----------------------------------------------------------------------------
*             Includes for National Semiconducter's DS8390
*----------------------------------------------------------------------------
*                   By Harry Sintonen (sintonen@iki.fi)
*           Original code by Bruce Abbott (bhabbott@inhb.co.nz)
*
*    "Some PC oriented eight (8) bit cards may require you read
*     odd-byte I/O address registers at the corresponding even-byte
*     address plus 64K.  There is sufficient I/O address space
*     provided that exceeding I/O address space should not be a problem."
*
*            (extract from Autodoc 'cardresource.doc')
*
* Even byte addresses start at $a20000, odd addresses start at $a30000.
*
* History
*
*  13-12-2000  - Separated from cnet.h.
*    5-1-2000  - Added MorphOS support.
*
*
*/

/*
*-----------------------------------------------------------------------
* The CNET CN40-BC uses a controller chip that is compatible with
* National Semiconducter's DS8390. This is the same chip that is
* used in NE1000 and NE2000 ISA bus ethernet cards.
*
*/

#include <exec/types.h>

/*
* --------------------- DS8390 registers ------------------------
*/

/* DS8390 command bits
*/
#define DSCM_STOP   0x01   /* Stop controller */
#define DSCM_START  0x02   /* Start controller */
#define DSCM_TRANS  0x04   /* Transmit packet */
#define DSCM_RREAD  0x08   /* Remote read (read from nic memory to Amiga memory) */
#define DSCM_RWRITE 0x10   /* Remote write (write from Amiga memory to nic memory) */
#define DSCM_NODMA  0x20   /* No Remote DMA present */
#define DSCM_PG0    0x00   /* Select register bank 0 */
#define DSCM_PG1    0x40   /* Select register bank 1 */
#define DSCM_PG2    0x80   /* Select register bank 2 */

/* tansmit status register values
*/
#define DSTS_PTX    0x01   /* Successful packet transmit */
#define DSTS_COLL   0x02   /* Packet transmit w/ collision */
#define DSTS_COLL16 0x04   /* Packet had >16 collisions & fail */
#define DSTS_UND    0x20   /* FIFO Underrun on transmission */

/* interrupt status register values
*/
#define DSIS_RX     0x01   /* Successful packet reception */
#define DSIS_TX     0x02   /* Successful packet transmission */
#define DSIS_RXE    0x04   /* Packet reception  w/error */
#define DSIS_TXE    0x08   /* Packet transmission  w/error */
#define DSIS_ROVRN  0x10   /* Receiver overrun in the ring */
#define DSIS_CTRS   0x20   /* Diagnostic counters need attn */
#define DSIS_RDC    0x40   /* Remote DMA Complete */
#define DSIS_RESET  0x80   /* Reset Complete */

/* interrupt mask register values
*/
#define DSIM_PRXE   0x01   /* Packet received enable */
#define DSIM_PTXE   0x02   /* Packet transmitted enable */
#define DSIM_RXEE   0x04   /* Receive error enable */
#define DSIM_TXEE   0x08   /* Transmit error enable */
#define DSIM_OVWE   0x10   /* Overwrite warning enable */
#define DSIM_CNTE   0x20   /* Counter overflow enable */
#define DSIM_RDCE   0x40   /* Remote DMA complete enable */
#define DSIM_RESET  0x80   /* Reset Complete enable */

/* Bit numbers for interrupts (same for int status and mask)
*/
#define DSIB_RX     0
#define DSIB_TX     1
#define DSIB_RXE    2
#define DSIB_TXE    3
#define DSIB_ROVRN  4
#define DSIB_CTRS   5
#define DSIB_RDC    6
#define DSIB_RESET  7

/* all ints except DMA, Reset complete
*/
#define INTMASK (0xff & ~(DSIM_RESET | DSIM_RDCE))


/* data configuration register values
*/
#define DSDC_WTS    0x01   /* Word Transfer Select */
#define DSDC_BOS    0x02   /* Byte Order Select */
#define DSDC_LAS    0x04   /* Long Address Select */
#define DSDC_BMS    0x08   /* Burst Mode Select */
#define DSDC_AR     0x10   /* Autoinitialize Remote */
#define DSDC_FT0    0x20   /* Fifo Threshold Select */
#define DSDC_FT1    0x40   /* Fifo Threshold Select */

/* receive status register values
*/
#define DSRS_RPC    0x01   /* Received Packet Complete */

/* transmit configuration register values
*/
#define DSTC_CRC    0x01   /* Inhibit CRC */
#define DSTC_LB0    0x02   /* Encoded Loopback Control */
#define DSTC_LB1    0x04   /* Encoded Loopback Control */
#define DSTC_ATD    0x08   /* Auto Transmit Disable */
#define DSTC_OFST   0x10   /* Collision Offset Enable */

/* receive configuration register values
*/
#define DSRC_SEP    0x01   /* Save error packets */
#define DSRC_AR     0x02   /* Accept Runt packets */
#define DSRC_AB     0x04   /* Accept Broadcast packets */
#define DSRC_AM     0x08   /* Accept Multicast packets */
#define DSRC_PRO    0x10   /* Promiscuous physical */
#define DSRC_MON    0x20   /* Monitor mode */


/*
*-------------------------------------------------------------------------
* Packet receive header, 1 per each buffer page used in receive packet.
* The nic inserts this in front of the received packet.
*/

#ifndef  __MORPHOS__

struct prhdr
{
  UBYTE  status;     /* is this a good packet, same as ds0_rsr */
  UBYTE  nxtpg;      /* next page of packet or next packet */
  UBYTE  sz0;        /* length (lower byte) */
  UBYTE  sz1;        /* length (upper byte) */
};

#else

struct prhdr
{
  UBYTE  status;     
  UBYTE  nxtpg;      
  UBYTE  sz0;        
  UBYTE  sz1;        
} __attribute__((packed));

#endif


/*
*-------------------------------------------------------------------------
* nic has 16K of on-board RAM, from $4000 to $7fff (16 bit address)
*
* Internal DMA operations (ie. tx/rx) require the upper 8 bits of the
* address, as RAM is addressed in 256 byte pages.
*
* DMA to/from the host Amiga ("Remote DMA") requires a 16 bit word-aligned
* address
*/

#define PKTSZ   0x0600             /* space for biggest ethernet packet (6 pages) */
#define TBUF    0x4000             /* Starting location of Transmit Buffer */
#define TBUF1   (0x4000+PKTSZ)     /* Another Tx Buffer (for double-buffered tx) */
#define RBUF    (0x4000+(PKTSZ*2)) /* Starting location of Receive Ring Buffer */
#define RBUFEND 0x8000             /* Ending location of Receive Ring Buffer */

#ifndef  __MORPHOS__

struct attrmem
{
  UBYTE  am_pad0[0x4000];

  UBYTE  am_tbuf[PKTSZ];      /* Transmit Buffer */
  UBYTE  am_tbuf2[PKTSZ];     /* Another Tx Buffer (for double-buffered tx) */
  UBYTE  am_rbuf[0x3400];     /* Receive Ring Buffer */

  UBYTE  am_pad1[0x18300];

  /* even addresses 0x20300
  */

  UBYTE  nic_cr;              /* command register        (r/w) in all banks */
  UBYTE  nic_pad1;
  UBYTE  nic_pstop;           /* page stop                (w) */
  UBYTE  nic_pad3;
  UBYTE  nic_tpsr;            /* transmit page start      (w) */
  UBYTE  nic_pad5;
  UBYTE  nic_tbcr1;           /* transmit byte count      (w) */
  UBYTE  nic_pad7;
  UBYTE  nic_rsar0;           /* remote start address     (w) */
  UBYTE  nic_pad9;
  UBYTE  nic_rbcr0;           /* remote byte count        (w) */
  UBYTE  nic_pad11;
  UBYTE  nic_rcr;             /* receive configuration    (w) */
  UBYTE  nic_pad13;
  UBYTE  nic_dcr;             /* data configuration       (w) */
  UBYTE  nic_pad15;
  /* ASIC registers in the NE2000 card
  */
  UWORD  nic_data;            /*  DMA port  (r/w)  16 bit */

  UBYTE  am_pad2[0x10000-0x13];


  /* odd addresses 0x302ff
  */

  UBYTE  nic_pad0;
  UBYTE  nic_pstart;          /* page start               (w) */
  UBYTE  nic_pad2;
  UBYTE  nic_bnry;            /* boundary pointer        (r/w) */
  UBYTE  nic_pad4;
  UBYTE  nic_tbcr0;           /* transmit byte count      (w) */
  UBYTE  nic_pad6;
  UBYTE  nic_isr;             /* interrupt status        (r/w) */
  UBYTE  nic_pad8;
  UBYTE  nic_rsar1;           /* remote start address     (w) */
  UBYTE  nic_pad10;
  UBYTE  nic_rbcr1;           /* remote byte count        (w) */
  UBYTE  nic_pad12;
  UBYTE  nic_tcr;             /* transmit configuration   (w) */
  UBYTE  nic_pad14;
  UBYTE  nic_imr;             /* interrupt mask           (w) */
  UBYTE  nic_pads[15];
  /* ASIC registers in the NE2000 card
  */
  UBYTE  nic_rst;              /* card reset (r=reset, w=not) */
};

#else

struct attrmem
{
  UBYTE  am_pad0[0x4000];

  UBYTE  am_tbuf[PKTSZ];       
  UBYTE  am_tbuf2[PKTSZ];      
  UBYTE  am_rbuf[0x3400];      

  UBYTE  am_pad1[0x18300];

  UBYTE  nic_cr;              
  UBYTE  nic_pad1;
  UBYTE  nic_pstop;           
  UBYTE  nic_pad3;
  UBYTE  nic_tpsr;            
  UBYTE  nic_pad5;
  UBYTE  nic_tbcr1;           
  UBYTE  nic_pad7;
  UBYTE  nic_rsar0;           
  UBYTE  nic_pad9;
  UBYTE  nic_rbcr0;           
  UBYTE  nic_pad11;
  UBYTE  nic_rcr;             
  UBYTE  nic_pad13;
  UBYTE  nic_dcr;             
  UBYTE  nic_pad15;
  
  UWORD __attribute__((aligned(2)))  nic_data;            

  UBYTE  am_pad2[0x10000-0x13];

  UBYTE  nic_pad0;
  UBYTE  nic_pstart;          
  UBYTE  nic_pad2;
  UBYTE  nic_bnry;            
  UBYTE  nic_pad4;
  UBYTE  nic_tbcr0;           
  UBYTE  nic_pad6;
  UBYTE  nic_isr;             
  UBYTE  nic_pad8;
  UBYTE  nic_rsar1;           
  UBYTE  nic_pad10;
  UBYTE  nic_rbcr1;           
  UBYTE  nic_pad12;
  UBYTE  nic_tcr;             
  UBYTE  nic_pad14;
  UBYTE  nic_imr;             
  UBYTE  nic_pads[15];
  
  UBYTE  nic_rst;              
} __attribute__((packed));

#endif


typedef volatile struct attrmem nic_t;


/* bank 0 registers
*/
#define nic_clda0 nic_pstop   /* current local dma addr   (r) */
#define nic_tsr   nic_tpsr    /* transmit status register (r) */
#define nic_fifo  nic_tbcr1   /* fifo contents            (r) */
#define nic_crda0 nic_rsar0   /* current remote DMA addr  (r) */
#define nic_rsr   nic_rcr     /* receive status           (r) */
#define nic_cntr1 nic_dcr     /* tally counter            (r) crc errors */

/* bank 1 and 2 registers
*/
#define nic_par1 nic_pstop    /* physical etheraddress   (r/w) */
#define nic_par3 nic_tpsr     /* physical etheraddress   (r/w) */
#define nic_par5 nic_tbcr1    /* physical etheraddress   (r/w) */
#define nic_mar0 nic_rsar0    /* multicast etheraddress  (r/w) */
#define nic_mar2 nic_rbcr0    /* multicast etheraddress  (r/w) */
#define nic_mar4 nic_rcr      /* multicast etheraddress  (r/w) */
#define nic_mar6 nic_dcr      /* multicast etheraddress  (r/w) */



/* bank 0 registers
*/
#define nic_clda1 nic_bnry    /* current local dma addr   (r) */
#define nic_ncr   nic_tbcr0   /* number of collisions     (r) */
#define nic_crda1 nic_rsar1   /* current remote DMA addr  (r) */
#define nic_cntr0 nic_tcr     /* tally counter            (r) frame align errors */
#define nic_cntr2 nic_imr     /* tally counter            (r) missed packets */

/* bank 1 and 2 registers
*/
#define nic_par0 nic_pstart   /* physical etheraddress   (r/w) */
#define nic_par2 nic_bnry     /* physical etheraddress   (r/w) */
#define nic_par4 nic_tbcr0    /* physical etheraddress   (r/w) */
#define nic_curr nic_isr      /* current page            (r/w) */
#define nic_mar1 nic_rsar1    /* multicast etheraddress  (r/w) */
#define nic_mar3 nic_rbcr1    /* multicast etheraddress  (r/w) */
#define nic_mar5 nic_tcr      /* multicast etheraddress  (r/w) */
#define nic_mar7 nic_imr      /* multicast etheraddress  (r/w) */



#define DATA_MIN_LEN  46            /* smallest amount that nic will accept */
#define DATA_MAX_LEN  1522          /* largest legal amount for Ethernet */

#define ETHER_MIN_LEN  60           /* smallest amount that nic will accept */
#define ETHER_MAX_LEN  1536         /* largest legal amount for Ethernet */

/* ethernet packet data sizes (maximum)
*/
#define ETHERPKT_SIZE  1500
#define RAWPKT_SIZE    1514


#endif /* DS8390_H */
