Updated LAN driver

- changed directory layout
- Multicast support (automatic RX filter adjustment)
- MC68000 target in Makefile
- clarified licensing (GPLv3)
- README files
This commit is contained in:
Henryk Richter
2018-06-14 08:20:30 +02:00
parent 95bc477444
commit b13808f240
46 changed files with 919 additions and 485 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,331 @@
/*
enc624j6l.h
author: Henryk Richter <henryk.richter@gmx.net>
purpose: header for low-level board access
to memory mapped ENC624J600 networking
device
note: all functions are relative to the base pointer,
determine IO space by a respective expansion.library
call
*/
#ifndef _INC_ENC624J6L_H
#define _INC_ENC624J6L_H
#include "compiler.h"
/*
Defines: flags copied from PlipBox
*/
/* result values */
#define PIO_OK 0
#define PIO_NOT_FOUND 1
#define PIO_TOO_LARGE 2
#define PIO_IO_ERR 3
/* init flags */
#define PIO_INIT_FULL_DUPLEX 1
#define PIO_INIT_LOOP_BACK 2
#define PIO_INIT_BROAD_CAST 4
#define PIO_INIT_FLOW_CONTROL 8
#define PIO_INIT_MULTI_CAST 16
#define PIO_INIT_PROMISC 32
/* status flags */
#define PIO_STATUS_VERSION 0
#define PIO_STATUS_LINK_UP 1
/* control ids */
#define PIO_CONTROL_FLOW 0
/*-- --*/
/*------------- <DANGER! APPLY CHANGES IN HERE ALSO TO enc624j6l.asm !!> ----------*/
/*-- --*/
/* buffers and locations */
#define PSTART_INIT 0x0BF0 /* 16 Bytes private storage for driver */
#define PSTOP_INIT 0x0BFF /* (see below for definitions) */
#define RXSTART_INIT 0x2000 /* start of RX buffer, room for 14 packets */
#define RXSTOP_INIT 0x5fff /* end of RX buffer */
#define TXSTART_INIT 0x0000 /* start of TX buffer, room for 2 packets */
#define TXSTOP_INIT 0x0BEF /* end of TX buffer (1536+1520 bytes) */
/* max frame length which the conroller will accept:
(note: maximum ethernet frame length would be 1518 w/o 802.1Q) */
#define MAX_FRAMELEN 1518
/* ------------ driver private storage ------------------------------ */
#define PNextPacket PSTART_INIT /* 2 Bytes - private "next packet" pointer for RX */
#define PNextTX PSTART_INIT+2 /* 2 Bytes - private "next packet" pointer for TX (init as 0) */
#define PSigBit PSTART_INIT+4 /* 2 Bytes interrupt bit */
#define PSigTask PSTART_INIT+6 /* 4 Bytes signaled task */
#define PLinkChange PSTART_INIT+10 /* 2 Bytes Link Change (Bit0 used right now) */
#define Punused PSTART_INIT+12 /* */
/* ------------- TX: double buffering -------------------------------- */
#define PSwapTX 0x600 /* swap between two TX buffers (one active, one activated after last TX done) */
/*-- --*/
/*------------- </DANGER! APPLY CHANGES IN HERE ALSO TO enc624j6l.asm !!> ---------*/
/*-- --*/
/*
Purpose: check whether the board is operating as needed
input: board - mmapped board base address
output: success/failure
>0 - all fine
<=0 - problem (codes undefined yet)
notes: The Olimex module on the Matze/Scrat ZII IDE LAN CP prototype
tends to boot in SPI mode instead of PSP (parallel) mode.
That case is detected by writing/reading data. If both bytes
of the words are equal to the last written byte, the board is likely
showing this issue.
Please note that this call will overwrite Board registers and
buffer memory. Call before initialization.
*/
ASM SAVEDS int enc624j6l_CheckBoard( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: obtain current MAC address
input: board - mmapped board base address
buffer - 6 bytes space to write into (network notation, big endian)
output: success/failure
>0 - all fine
<=0 - problem (codes undefined yet)
*/
ASM SAVEDS int enc624j6l_GetMAC( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) unsigned char *buffer ASMREG(a1) );
/*
Purpose: change current MAC address
input: board - mmapped board base address
buffer - 6 bytes space to read from (network notation, big endian)
output: success/failure
>0 - all fine
<=0 - problem (codes undefined yet)
*/
ASM SAVEDS int enc624j6l_SetMAC( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) unsigned char *buffer ASMREG(a1) );
/*
Purpose: delay at least the given amount of microseconds
input: delay time in microseconds
output: -
*/
ASM SAVEDS void enc28j60l_UMinDelay(
ASMR(d0) unsigned long udelay ASMREG(d0) );
/*
Purpose: initialize a board
input: board - mmapped board base address
flags - init flags (0 if in doubt)
output: success/failure
>0 - all fine
<=0 - problem (codes undefined yet)
notes:
*/
ASM SAVEDS int enc624j6l_Init( ASMR(a0) void *board ASMREG(a0),
ASMR(d1) unsigned long flags ASMREG(d1) );
/*
Purpose: stop a board
input: board - mmapped board base address
output: success/failure
>0 - all fine
<=0 - problem (codes undefined yet)
notes: Shutdown means to disconnect the PHY, put the chip
into low power mode and disable interrupts
*/
ASM SAVEDS int enc624j6l_Shutdown( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: check for pending receive frames
input: board - mmapped board base address
output: <0 - error
0 - no pending frames
>0 - number of pending frames
notes:
*/
ASM SAVEDS int enc624j6l_HaveRecv( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: copy received frame to supplied buffer
input: board - mmapped board base address
buffer - output buffer (should have >=1514 bytes)
buffersize - size of buffer
output: <0 - error
0 - nothing in receive buffer
>0 - size of received frame
notes:
*/
ASM SAVEDS int enc624j6l_RecvFrame( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) unsigned char* buffer ASMREG(a1),
ASMR(d0) short buffersize ASMREG(d0) );
/*
Purpose: send single frame out
input: board - mmapped board base address
buffer - output buffer (should have >=1514 bytes)
sendsize - size of buffer in bytes ( no CRC appended (!) )
output: <0 - error
0 - nothing in receive buffer
>0 - size of received frame
notes:
*/
ASM SAVEDS int enc624j6l_TransmitFrame( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) unsigned char* buffer ASMREG(a1),
ASMR(d0) short sendsize ASMREG(d0) );
/*
Purpose: enable RX/TX, perform autonegotiation etc.
input: board - mmapped board base address
output: <0 - error
>=0 - OK
notes: in current implementation, enc624j6l_Init() will
also attach the card to the line. So this
call is not exactly needed in the init phase.
*/
ASM SAVEDS int enc624j6l_SetOnline( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: set up RX filtering
input: board - mmapped board base address
flags - broadcast,promiscous, multicast
output: <0 - error
>=0 - OK
*/
ASM SAVEDS int enc624j6l_broadcast_multicast_filter(
ASMR(a0) void *board ASMREG(a0),
ASMR(d1) unsigned long flags ASMREG(d1) );
/*
Purpose: disable RX/TX, power down
input: board - mmapped board base address
output: <0 - error
>=0 - OK
notes:
*/
ASM SAVEDS int enc624j6l_SetOffline( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: enable HW interrupt
input: board - mmapped board base address
SigTask - task to signal upon interrupt (or NULL)
SigBit - Signal bit to send upon interrupt (or -1)
IntMask - ENC HW interrupts to enable (set 0, for now) = RX PACKET only
output: <0 - error
>=0 - OK
notes:
*/
ASM SAVEDS int enc624j6l_EnableInterrupt( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) void* SigTask ASMREG(a1),
ASMR(d0) int SigBit ASMREG(d0),
ASMR(d1) unsigned int IntMask ASMREG(d1) );
/*
Purpose: disable HW interrupt
input: board - mmapped board base address
output: <0 - error
>=0 - OK
notes:
*/
ASM SAVEDS int enc624j6l_DisableInterrupt( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: enable global HW interrupt flag on the LAN-Chip
input: board - mmapped board base address
notes:
*/
ASM SAVEDS void enc624j6l_EnableGlobalInterrupt( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: disable global HW interrupt flag on the LAN-Chip
input: board - mmapped board base address
notes:
*/
ASM SAVEDS void enc624j6l_DisableGlobalInterrupt( ASMR(a0) void *board ASMREG(a0) );
/*
Purpose: interrupt service routine ( after EnableInterrupt() )
This function will signal the task passed at EnableInterrupt time with
the given sigbit when at least one frame is pending.
input: -
output: -
*/
ASM SAVEDS void enc624j6l_IntServer_List( void );
/*
Purpose: check for link change events
input: board - mmapped board base address
output: <0 - error
0 - ok, no link change handled
>0 - ok, link change handled
notes:
*/
ASM SAVEDS int enc624j6l_CheckLinkChange( ASMR(a0) void *board ASMREG(a0) );
#endif /* _INC_ENC624J6L_H */
+450
View File
@@ -0,0 +1,450 @@
/*
hw.c
(C) 2018 Henryk Richter <henryk.richter@gmx.net>
SDNet hardware interface to device
*/
#include <exec/libraries.h>
#include <proto/exec.h>
/*#include <clib/expansion_protos.h>
#include <pragmas/expansion_pragmas.h>*/
#include <proto/expansion.h>
#include <libraries/configvars.h>
#include <hardware/intbits.h>
#include "device.h"
#include "hw.h"
#include "enc624j6l.h"
#include "registers.h"
extern const BYTE DeviceName[];
#define ENC_MANUFACTURER 2588
#define ENC_BOARD 123
/* use generic board fields in current unit */
#define duh_online du_hwl0
#define duh_BASE du_hwp0
#define HW_INTERVALDEF 100000L
/* this is a BIG TODO! Make plipbox source multi-board aware */
#define BOARD hwb->hwb_boards[0]
/* interrupt (choice here is INTB_EXTER or INTB_PORTS, depending on solder blob */
/*#define HW_INTSOURCE INTB_EXTER */ /* Int 6 */
#define HW_INTSOURCE INTB_PORTS /* Int 2 */
#define READREG(_x_,_off_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_)) )
#define WRITEREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_)) ) = (_y_);
#define SETREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_) + SET_OFFSET )) = (_y_);
#define CLRREG(_x_,_off_,_y_) *( (volatile USHORT*)( (volatile UBYTE*)(_x_) + (_off_) + CLR_OFFSET )) = (_y_);
void myhw_ControlInterrupts( DEVBASEP );
void myhw_ControlIntervalTimer( DEVBASEP );
/* these calls might not run within the context of a process and
will be called from varying tasks and without prior init:
hw_Find_Boards()
hw_AllocBoard()
hw_ReleaseBoard()
hw_GetMacAddress()
these calls are in the context of the server task:
hw_Setup() - general init (board allocated already)
hw_Shutdown() - general shutdown (board still allocated)
hw_Attach() - make hardware ready for action (online)
hw_Detach() - put hardware into sleep mode (offline)
hw_recv_sigmask() - get signals for hardware (if any)
hw_recv_pending() - check for pending receive frames
hw_recv_frame() - receive one frame
hw_send_frame() - send one frame
hw_check_link_change() - check if HW link parameters need update
and apply them (called only when no RX/TX
in progress)
hw_config_init() - set defaults for HW
hw_config_update() - update config of HW
*/
const BYTE exp_name[] = "expansion.library";
const BYTE intname[] = "enc264j6net SanaII driver";
/* return number of boards present in system */
ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
{
LONG i,ret = 0;
struct Library *ExpansionBase;
struct ConfigDev *cfg = (0);
if( (ExpansionBase = OpenLibrary( exp_name, 37 )) )
{
/* TODO: check for expansion port, i.e. distinguish V500/V600 */
/* TODO: actually verify that we have a module here */
ret = 1;
for( i=0 ; i < MAX_UNITS ; i++ )
{
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
if( !cfg )
break;
db->db_Units[i].duh_BASE = (APTR)cfg->cd_BoardAddr;
D(("Board at %lx\n",(ULONG)cfg->cd_BoardAddr ));
}
ret = i;
D(("%ld boards found\n",ret));
CloseLibrary( ExpansionBase );
}
return ret;
}
ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
/* is there a way to lock a ZII Board ? */
return 1;
}
ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
return 1;
}
/* store MAC address at "mac", 6 Bytes */
ASM SAVEDS LONG hw_GetMacAddress( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) UBYTE *mac ASMREG(a1)
)
{
APTR boardbase = db->db_Units[unit].duh_BASE;
enc624j6l_GetMAC( boardbase, mac );
return 1;
}
/* prepare all boards such that a hw_attach() will succeed */
ASM SAVEDS LONG hw_Setup( ASMR(a0) DEVBASEP ASMREG(a0) )
{
LONG ret = 0;
struct HWData *hwd = &db->db_hwdat;
InitSemaphore( &hwd->hwd_Sem );
hwd->hwd_IntSig = AllocSignal(-1);
hwd->hwd_Interrupt.is_Data = (0);
if( InitIntervalTimer( &hwd->ivtimer ) > 0 )
{
hwd->hwd_SigMask = hwd->ivtimer.IVT_SigMask | (1<<(hwd->hwd_IntSig)) ;
ret = 1;
}
return ret;
}
/* free resources, server is quitting */
ASM SAVEDS void hw_Shutdown( ASMR(a0) DEVBASEP ASMREG(a0) )
{
struct HWData *hwd = &db->db_hwdat;
LONG i;
/* safety measure */
for( i=0 ; i < db->db_NBoards ; i++ )
db->db_Units[i].duh_online = 0;
myhw_ControlInterrupts( db );
myhw_ControlIntervalTimer( db );
if( hwd->hwd_IntSig >= 0 )
FreeSignal( hwd->hwd_IntSig );
ExitIntervalTimer( &hwd->ivtimer );
}
/* bring hardware online */
ASM SAVEDS LONG hw_Attach( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0))
{
struct HWData *hwd = &db->db_hwdat;
APTR boardbase = db->db_Units[unit].duh_BASE;
LONG ret = 1;
ULONG flags;
flags = PIO_INIT_BROAD_CAST;
if( hwd->multicast )
flags |= PIO_INIT_MULTI_CAST;
if( hwd->fullduplex )
flags |= PIO_INIT_FULL_DUPLEX;
if( hwd->flowcontrol )
flags |= PIO_INIT_FLOW_CONTROL;
if( enc624j6l_Init( boardbase, flags ) <= 0 )
ret = 0; /* ERROR IN CASE OF DEVICE NOT FOUND */
else
{
enc624j6l_SetMAC( boardbase, db->db_Units[unit].du_CFGAddr );
enc624j6l_SetOnline( boardbase );
db->db_Units[unit].duh_online = 1; /* used for int server and interval timer setup */
myhw_ControlInterrupts( db ); /* start and/or stop (based on duh_online) */
myhw_ControlIntervalTimer( db ); /* start and/or stop timer (based on duh_online) */
}
return ret;
}
/* put hardware into sleep mode (offline) */
ASM SAVEDS void hw_Detach( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0))
{
APTR boardbase = db->db_Units[unit].duh_BASE;
db->db_Units[unit].duh_online = 0; /* used for int server and interval timer setup */
myhw_ControlInterrupts( db ); /* start and/or stop (based on duh_online) */
myhw_ControlIntervalTimer( db ); /* start and/or stop timer (based on duh_online) */
enc624j6l_SetOffline( boardbase );
enc624j6l_Shutdown( boardbase );
}
ASM SAVEDS void hw_ConfigInit( ASMR(a0) DEVBASEP ASMREG(a0) )
{
struct HWData *hwd = &db->db_hwdat;
hwd->timervalue = HW_INTERVALDEF;
hwd->fullduplex = 0;
hwd->flowcontrol = 0;
hwd->multicast = 0;
#if 0
USHORT i;
for( i=0 ; i < (USHORT)db->db_NBoards ; i++ )
{ /* no need, these are defaults */
db->db_Units[i].du_MTU = 1500;
db->db_Units[i].du_BitPerSec = 10000000;
}
#endif
}
ASM SAVEDS void hw_ConfigUpdate( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(a1) void*argsv ASMREG(a1))
{
struct HWConfig *args = (struct HWConfig *)argsv; /* see hwprivate.h */
struct HWData *hwd = &db->db_hwdat;
if( args->timervalue )
hwd->timervalue = *args->timervalue;
if( args->fullduplex )
hwd->fullduplex = 1;
if( args->flowcontrol )
hwd->flowcontrol = 1;
if( args->multicast )
hwd->multicast = 1;
}
ASM SAVEDS LONG hw_send_frame( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) UBYTE *frame ASMREG(a1),
ASMR(d1) ULONG framesize ASMREG(d1) )
{
enc624j6l_TransmitFrame( db->db_Units[unit].duh_BASE, frame, framesize );
return 1;
}
ASM SAVEDS LONG hw_recv_pending( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
APTR board = db->db_Units[unit].duh_BASE;
return enc624j6l_HaveRecv( board );
}
ASM SAVEDS LONG hw_recv_frame( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) UBYTE *frame ASMREG(a1))
{
LONG len;
APTR board = db->db_Units[unit].duh_BASE;
len = enc624j6l_RecvFrame( board, frame, 1522 );
return len;
}
ASM SAVEDS ULONG hw_recv_sigmask( ASMR(a0) DEVBASEP ASMREG(a0) )
{
struct HWData *hwd = &db->db_hwdat;
return hwd->hwd_SigMask;
}
/* check if HW link parameters need update -> only when board is idle otherwise (no RX/TX) */
/* re-enables hardware interrupt */
ASM SAVEDS LONG hw_check_link_change( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
APTR boardbase = db->db_Units[unit].duh_BASE;
enc624j6l_CheckLinkChange( boardbase ); /* somewhere $e90000 and beyond */
if( db->db_Units[unit].duh_online )
enc624j6l_EnableGlobalInterrupt( boardbase );
return 1; /* don't signal panic to the outside, everything is under control */
}
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(a0) ULONG unit ASMREG(d0),
ASMR(a1) struct List *mcastlist ASMREG(a1) )
{
/* TODO: implement Multicast hashing */
APTR boardbase = db->db_Units[unit].duh_BASE;
ULONG flags;
flags = PIO_INIT_BROAD_CAST;
if( db->db_Units[0].du_Flags & DUF_PROMISC )
flags |= PIO_INIT_PROMISC;
/* list non-empty ? (kludge right now, can be done more fine grained) */
if( mcastlist->lh_Head->ln_Succ )
flags |= PIO_INIT_MULTI_CAST;
enc624j6l_broadcast_multicast_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
return 1;
}
/* global for all boards (relies on hwd_online) */
void myhw_ControlInterrupts( DEVBASEP )
{
struct HWData *hwd = &db->db_hwdat;
LONG i,flag;
ObtainSemaphore( &hwd->hwd_Sem ); /* redundant here: server is a single task -> but it looks good :-) */
flag = 0;
for( i=0 ; i < db->db_NBoards ; i++ )
{
if( db->db_Units[i].duh_online )
{
hwd->hwd_act_boards[flag] = db->db_Units[i].duh_BASE;
flag++;
}
}
hwd->hwd_act_boards[flag] = (0); /* NULL-terminate */
hwd->hwd_act_boards[flag+1] = (APTR)FindTask(0); /* append task */
hwd->hwd_act_boards[flag+2] = (APTR)hwd->hwd_IntSig; /* append sigbit */
if( flag ) /* determine on/off switch */
{
/* at least 1 board is online */
if( hwd->hwd_Interrupt.is_Data )
flag = 0; /* no change */
else flag = 1; /* start timer */
}
else
{
if( hwd->hwd_Interrupt.is_Data )
flag = -1; /* stop timer */
else flag = 0; /* no change */
}
/* flag is >0 = start, <0 = stop or 0 = no change */
if( flag > 0 )
{
hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List;
hwd->hwd_Interrupt.is_Data = &hwd->hwd_act_boards[0];
hwd->hwd_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
hwd->hwd_Interrupt.is_Node.ln_Pri = 51;
hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname;
AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
}
for( i=0 ; i < db->db_NBoards ; i++ )
{
if( db->db_Units[i].duh_online )
enc624j6l_EnableInterrupt( db->db_Units[i].duh_BASE, FindTask(0), (int)hwd->hwd_IntSig, 0 );
else
enc624j6l_DisableInterrupt( db->db_Units[i].duh_BASE );
}
if( flag < 0 )
{
hwd->hwd_Interrupt.is_Data = (0);
RemIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
hwd->hwd_Interrupt.is_Code = (0);
}
ReleaseSemaphore( &hwd->hwd_Sem );
}
/* global for all boards (relies on hwd_online) */
void myhw_ControlIntervalTimer( DEVBASEP )
{
struct HWData *hwd = &db->db_hwdat;
LONG i,flag;
ObtainSemaphore( &hwd->hwd_Sem );
flag = 0;
for( i=0 ; i < db->db_NBoards ; i++ )
{
if( db->db_Units[i].duh_online )
flag = 1;
}
if( flag )
{
/* at least 1 board is online */
if( hwd->ivtimer.IVT_Runflag )
flag = 0; /* no change */
else flag = 1; /* start timer */
}
else
{
if( hwd->ivtimer.IVT_Runflag )
flag = -1; /* stop timer */
else flag = 0; /* no change */
}
if( flag > 0 )
StartIntervalTimer( &hwd->ivtimer, hwd->timervalue );
if( flag < 0 )
StopIntervalTimer( &hwd->ivtimer );
ReleaseSemaphore( &hwd->hwd_Sem );
}
@@ -0,0 +1,52 @@
/*
hwprivate.h
(C) 2018 Henryk Richter <henryk.richter@gmx.net>
private structures for hardware instance
*/
#ifndef _INC_HWPRIVATE_H
#define _INC_HWPRIVATE_H
#include "compiler.h"
/* sdnet/v2expnet specific: polling timer */
#include "intervaltimer.h"
/* this struct is available in devicebase and should carry global information */
struct HWData {
struct Interrupt hwd_Interrupt; /* keep the interrupt at top of HWData !! */
struct SignalSemaphore hwd_Sem; /* list locking (global per unit) */
APTR hwd_act_boards[MAX_UNITS+1+2]; /* poll all active boards by ptr in interrupt, NULL terminated, followed by SigTask,Sigbit */
ULONG hwd_SigMask; /* signal mask to wait for in server main instance */
struct IVT_TimerStruct ivtimer; /* Timer interval handling (via Interrupt) */
LONG TimerUsed; /* number of instances running */
LONG hwd_IntSig;
/* config options */
ULONG timervalue; /* polling interval in ms */
ULONG fullduplex; /* force full duplex */
ULONG multicast; /* multicast recv enable */
ULONG flowcontrol; /* enable RX flow control */
};
#define HW_CONFIGFILE "ENV:SANA2/enc624j6net.config"
/* appended to COMMON_TEMPLATE */
#define HW_CONFIGTEMPLATE "TIMER/K/N,FULLDUPLEX/S,MULTICAST/S,FLOWCONTROL/S"
/* referenced by server.c, hw.c */
struct HWConfig
{
struct CommonConfig common; /* import from hw.h, expected in server.c */
ULONG *timervalue;
ULONG fullduplex;
ULONG multicast;
ULONG flowcontrol;
};
#endif /* _INC_HWPRIVATE_H */
@@ -0,0 +1,341 @@
******************************************************************************
* Name: intervaltimer.s *
* Date: $Date: 2016-12-18 22:20:04 +0100 (So, 18. Dez 2016) $ *
* Authors: Henryk Richter *
******************************************************************************
;MACHINE MC68040
include exec/types.i
include lvo/exec_lib.i
include lvo/dos_lib.i
include lvo/timer_lib.i
include exec/exec.i
include dos/dos.i
include dos/dostags.i
include exec/io.i
include dos/dosextens.i
include exec/lists.i
DO_TEST EQU 0
ifne 1
include "intervaltimer.i"
else
STRUCTURE IVT_TimerStruct,0
ULONG IVT_Interval ;<1e6 in microseconds
LONG IVT_Signal ;Signal that is sent back to task from interrupt
ULONG IVT_SigMask
APTR IVT_SigTask ;Task that is signaled
APTR IVT_Port
APTR IVT_IORequest
APTR IVT_Device
STRUCT IVT_Int,IS_SIZE ;
BYTE IVT_Init ; !=0 - initialized
BYTE IVT_Runflag ; current status ( !=0 = running )
BYTE IVT_Stopflag ; stop request if != 0
BYTE IVT_Unused ;
ULONG IVT_Counter ; Counter (statistics)
LABEL IVT_Size
endc
xdef _InterruptIntervalTimer
xdef _InitIntervalTimer
xdef _ExitIntervalTimer
xdef _StartIntervalTimer
xdef _StopIntervalTimer
CALLEXEC macro
move.l 4.w,a6
jsr _LVO\1(a6)
endm
section code,text
ifne DO_TEST
TestTimer:
lea dos_name,a1 ;string base
moveq #0,d0
move.l 4.w,a6
jsr _LVOOpenLibrary(a6)
move.l d0,dosbase
beq .nodos
move.l dosbase,a6
jsr _LVOOutput(a6) ;get stdout
move.l d0,stdout
lea timerbase,a1
bsr _InitIntervalTimer
tst.l d0
bge .ok
move.l stdout,d0
move.l #failtimer,d1
move.l dosbase,16
jsr _LVOPutStr(a6)
bra .error
.ok
lea timerbase,a1
move.l #10000,d1
bsr _StartIntervalTimer
moveq #0,d3
.loop
cmp.l #10,d3
bgt.s .exitloop
move.l dosbase,A6
moveq #10,d1
jsr _LVODelay(a6)
addq.l #1,d3
lea timerbase,a1
cmp.l #100,IVT_Counter(a1)
blt.s .loop
.exitloop:
move.l #succname,d1
cmp.l #10,d3
ble.s .succ
move.l #failname,d1
.succ:
jsr _LVOVPrintf(a6)
lea timerbase,a1
bsr _StopIntervalTimer
.error
lea timerbase,a1
bsr _ExitIntervalTimer
move.l dosbase,d0
beq.s .nodos
move.l d0,a1
move.l 4.w,a6
jsr _LVOCloseLibrary(a6)
.nodos:
rts
ENDC ;DO_TEST
; A1 = IVT_TimerStruct
_InterruptIntervalTimer:
movem.l d1-a6,-(sp)
;<- basic Timer.device ops ->
move.l a1,a2
move.l IVT_Port(a2),a0
CALLEXEC GetMsg
tst.l d0
beq.s .error
move.l IVT_SigMask(a2),d0 ;move.l IVT_Signal(a2),d0
move.l IVT_SigTask(a2),a1
CALLEXEC Signal
tst.b IVT_Stopflag(a2)
bne.s .error ;not exactly an error but same consequence
move.l a2,a1
bsr _RestartIntervalTimer
;<- end basic Timer.device ops ->
;<- useful stuff ->
addq.l #1,IVT_Counter(a2)
;<- useful stuff ->
bra.s .endintroutine
.error:
clr.b IVT_Runflag(a2)
.endintroutine:
movem.l (sp)+,d1-a6
rts
_InitIntervalTimer: ;prepare timer.device for buffer swap interrupt
movem.l d1-a6,-(sp)
move.l a1,a2
move #IVT_Size-1,d0
.clr
clr.b (a1)+ ;
dbf d0,.clr
sf IVT_Init(a2)
sf IVT_Runflag(a2)
;signal to wait for from timer output if output queue full
moveq #-1,d0
CALLEXEC AllocSignal
move.l d0,IVT_Signal(a2) ; <0 ? error, valid are 0..31
blt .error ; error: have to go (shouldn't happen)
moveq #0,d1
bset d0,d1
move.l d1,IVT_SigMask(a2)
suba.l a1,a1
CALLEXEC FindTask
move.l d0,IVT_SigTask(a2)
CALLEXEC CreateMsgPort ;Create MsgPort for timing...
move.l d0,IVT_Port(a2)
beq .error ;0=error
move.l IVT_Port(a2),a0
move.l #IOTV_SIZE,d0
CALLEXEC CreateIORequest
move.l d0,IVT_IORequest(a2)
beq .error ;0=error
lea.l IVT_Int(a2),a0
lea _InterruptIntervalTimer(pc),a1
move.l a1,IS_CODE(a0)
move.l a2,IS_DATA(a0)
move.b #NT_INTERRUPT,LN_TYPE(a0)
move.b #0,LN_PRI(a0) ;-32,-16,0,16,32
move.l IVT_Port(a2),a1
;move.b #NT_MSGPORT,LN_TYPE(a1)
move.b #PA_SOFTINT,MP_FLAGS(a1)
move.l a0,MP_SIGTASK(a1) ;Softint eintragen
lea VBtimer_name,a0
moveq #UNIT_MICROHZ,d0
move.l IVT_IORequest(a2),a1
moveq #0,d1
CALLEXEC OpenDevice
tst.l d0
beq.s .ok
moveq #0,d0
bra.s .error
.ok ;OK, timer device is ready
st IVT_Init(a2)
moveq #1,d0 ;OK
.error
movem.l (sp)+,d1-a6
;ret 0 <= err, >0 = ok
rts
_ExitIntervalTimer:
;stop timer.device
movem.l d0-a6,-(sp)
move.l a1,a2
sf IVT_Init(a2)
move.l IVT_IORequest(a2),d5
beq.s .noIO
tst.b IVT_Runflag(a2)
beq.s .noAbort
st IVT_Stopflag(a2)
ifne 0
move.l d5,a1
CALLEXEC WaitIO
else
move.l d5,a1
move.l IO_DEVICE(a1),a6
jsr DEV_ABORTIO(A6) ;clear pending requests
endc
.noAbort:
move.l d5,a1
CALLEXEC CloseDevice
move.l d5,a0
CALLEXEC DeleteIORequest
clr.l IVT_IORequest(a2)
.noIO:
move.l IVT_Port(a2),d0
beq.s .noPort
move.l d0,a0
CALLEXEC DeleteMsgPort
clr.l IVT_Port(a2)
.noPort:
move.l IVT_Signal(a2),d0
not.l d0 ;if( d0 == -1 ) d0 = 0
beq.s .nosig
not.l d0 ; swap back
CALLEXEC FreeSignal
moveq #-1,d0
move.l d0,IVT_Signal(a2)
.nosig:
movem.l (sp)+,d0-a6
rts
; input:
; A1 = IVT Structure (after init)
; D1 = Number of Microseconds
_StartIntervalTimer:
movem.l d0/a1/a2/a6,-(Sp)
move.l a1,a2
move.l d1,IVT_Interval(A2)
sf IVT_Stopflag(a2)
tst.b IVT_Runflag(a2) ;running already ? -> keep it running
bne.s .notimer
move.l a2,a1
bsr _RestartIntervalTimer
.notimer
movem.l (sp)+,d0/a1/a2/a6
rts
; Non-Public
; A1 - IVT Structure
_RestartIntervalTimer:
movem.l d0/a1/a2/a6,-(sp)
move.l a1,a2
move.l IVT_IORequest(a2),d0
beq.s .notimer
move.l d0,a1
move.w #TR_ADDREQUEST,IO_COMMAND(a1)
clr.b IO_FLAGS(a1)
clr.l IOTV_TIME+EV_HI(a1)
move.l IVT_Interval(A2),IOTV_TIME+EV_LO(a1)
move.l IO_DEVICE(a1),a6
jsr DEV_BEGINIO(A6)
st IVT_Runflag(a2)
.notimer
movem.l (sp)+,d0/a1/a2/a6
rts
_StopIntervalTimer:
movem.l d0-a6,-(Sp)
move.l a1,a2
st IVT_Stopflag(a2)
tst.b IVT_Runflag(a2)
beq.s .noIO
move.l IVT_IORequest(a2),d5
beq.s .noIO
move.l d5,a1
move.l IO_DEVICE(a1),a6
jsr DEV_ABORTIO(A6) ;clear pending requests
sf IVT_Runflag(a2)
.noIO:
movem.l (sp)+,d0-a6
rts
section data,data
dosbase: dc.l 0
stdout: dc.l 0
timerbase: ds.b IVT_Size
VBtimer_name: dc.b "timer.device",0
ifne DO_TEST
dos_name: dc.b "dos.library",0
succname: dc.b "success: timer worked",10,0
failname: dc.b "failure: timer didn't work",10,0
failtimer: dc.b "timer open failure",10,0
ENDC ;DO_TEST
END
@@ -0,0 +1,57 @@
/*
******************************************************************************
* Name: intervaltimer.h *
* Date: $Date: 2016-12-18 22:20:04 +0100 (So, 18. Dez 2016) $ *
* Authors: Henryk Richter *
******************************************************************************
*/
#ifndef _INC_INTERVALTIMER_H
#define _INC_INTERVALTIMER_H
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <exec/tasks.h>
#include <exec/ports.h>
#include <devices/timer.h>
struct IVT_TimerStruct {
unsigned long IVT_Interval;
long IVT_Signal;
unsigned long IVT_SigMask;
struct Task *IVT_SigTask;
struct MsgPort *IVT_Port;
struct IORequest *IVT_IORequest;
struct Device *IVT_Device;
struct Interrupt IVT_Int;
unsigned char IVT_Init;
unsigned char IVT_Runflag;
unsigned char IVT_Stopflag;
unsigned char IVT_Unused;
unsigned long IVT_Counter;
};
#if 1
#include "compiler.h"
#else
/* self-contained in here as well */
#ifdef __SASC
#define ASM __asm
#define ASMR(x) register __ ## x
#define ASMREG(x)
#define SAVEDS __saveds
#else
#define ASM
#define ASMR(x) register
#define ASMREG(x) __asm("" #x "")
#define SAVEDS __saveds
#endif
#endif
ASM SAVEDS int InitIntervalTimer( ASMR(a1) struct IVT_TimerStruct* IntervalTimer ASMREG(a1) );
ASM SAVEDS int StartIntervalTimer( ASMR(a1) struct IVT_TimerStruct* IntervalTimer ASMREG(a1),
ASMR(d1) unsigned long Microsecs ASMREG(d1) );
ASM SAVEDS int StopIntervalTimer( ASMR(a1) struct IVT_TimerStruct* IntervalTimer ASMREG(a1) );
ASM SAVEDS int ExitIntervalTimer( ASMR(a1) struct IVT_TimerStruct* IntervalTimer ASMREG(a1) );
#endif /* _INC_INTERVALTIMER_H */
@@ -0,0 +1,27 @@
******************************************************************************
* Name: intervaltimer.i *
* Date: $Date: 2016-12-18 22:20:04 +0100 (So, 18. Dez 2016) $ *
* Authors: Henryk Richter *
******************************************************************************
ifnd _INC_INTERVALTIMER_I
_INC_INTERVALTIMER_I EQU 1
include exec/types.i
STRUCTURE IVT_TimerStruct,0
ULONG IVT_Interval ;<1e6 in microseconds
LONG IVT_Signal ;Signal that is sent back to task from interrupt
ULONG IVT_SigMask ;signal mask
APTR IVT_SigTask ;Task that is signaled
APTR IVT_Port
APTR IVT_IORequest
APTR IVT_Device
STRUCT IVT_Int,IS_SIZE ;
BYTE IVT_Init ; !=0 - initialized
BYTE IVT_Runflag ; current status ( !=0 = running )
BYTE IVT_Stopflag ; stop request if != 0
BYTE IVT_Unused ;
ULONG IVT_Counter ; Counter (statistics)
LABEL IVT_Size
endc ;_INC_TIMERTEST_I
+126
View File
@@ -0,0 +1,126 @@
; ------------------------------------------------------------------------------
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
; | Henryk Richter <henryk.richter@gmx.net> |
; ------------------------------------------------------------------------------
; macro section
;------------------ options, some depend on hardware (CPLD) configuration -------------------------
_OPT_BUFFER_SWAP EQU 0 ;perform byte swap on buffer ops (1) or assume native endian (0)
_OPT_REG_SWAP EQU 0 ;perform byte swap on register ops (1) or assume native endian (0)
_OPT_ADR_QUIRK EQU 0 ;address lines 12/13 are swapped (1) or linear addressing (0)
_OPT_FLOWCONTROL EQU 0 ;perform flow control on RX (1) or not (0)
_OPT_RECV EQU 1 ;faster recv (1) or generic (0)
_OPT_CHECKLINK_TX EQU 0 ;check for link changes in TX (1) or expect from outside (0) -> see server.c
;\1 register offset (without CLEAR offset)
;\2 address register of board I/O base
;\3 register with clear mask
ifne _OPT_REG_SWAP
CLRREG macro
rol.w #8,\3
move.w \3,\1+CLR_OFFSET(\2)
rol.w #8,\3
endm
;\1 register offset (without SET offset)
;\2 address register of board I/O base
;\3 register with set mask
SETREG macro
rol.w #8,\3
move.w \3,\1+SET_OFFSET(\2)
rol.w #8,\3
endm
;\1 register offset (e.g. ESTAT)
;\2 address register of board I/O base (e.g. a0)
;\3 destination register to be written (e.g. d0)
;
;important: when changing this, make sure the flags
;are set according to the return value
READREG macro
rol.w #8,\3
move.w \1(\2),\3
rol.w #8,\3
endm
;\1 register offset (e.g. ESTAT)
;\2 address register of board I/O base (e.g. a0)
;\3 soure register copied to HW register (e.g. d0)
WRITEREG macro
rol.w #8,\3
move.w \3,\1(\2)
rol.w #8,\3
endm
else
CLRREG macro
move.w \3,\1+CLR_OFFSET(\2)
endm
;\1 register offset (without SET offset)
;\2 address register of board I/O base
;\3 register with set mask
SETREG macro
move.w \3,\1+SET_OFFSET(\2)
endm
;\1 register offset (e.g. ESTAT)
;\2 address register of board I/O base (e.g. a0)
;\3 destination register to be written (e.g. d0)
;
;important: when changing this, make sure the flags
;are set according to the return value
READREG macro
move.w \1(\2),\3
endm
;\1 register offset (e.g. ESTAT)
;\2 address register of board I/O base (e.g. a0)
;\3 soure register copied to HW register (e.g. d0)
WRITEREG macro
move.w \3,\1(\2)
endm
endc
;read with address shuffling or direct from SRAM (affects $2000-$5000)
ifne _OPT_ADR_QUIRK
;\1 = address register
;\2 = data register, offset
;\3 = destination
READSRAM macro
eor.w #$6000,\2
move.w (\1,\2.w),\3
eor.w #$6000,\2
endm
else
READSRAM macro
move.w (\1,\2),\3
endm
endc
;read with address shuffling or direct from SRAM (affects $2000-$5000)
ifne _OPT_ADR_QUIRK
;\1 = address register
;\2 = data register, offset
;\3 = destination
READSRAM_LONG macro
eor.w #$6000,\2
move.l (\1,\2.w),\3
eor.w #$6000,\2
endm
else
READSRAM_LONG macro
move.l (\1,\2),\3
endm
endc
; wrap position index (in bytes) \1 (data register .w)
;
; if position >RXSTOP_INIT-1
; position = (position-RXSTOP_INIT+RXSTART_INIT)
; endif
WRAPINDEX macro
cmp.w #RXSTOP_INIT&$fffe,\1 ;wrap Dn if beyond buffer
ble.s .nowrap\0\@
add.w #RXSTART_INIT-RXSTOP_INIT-1,\1
.nowrap\0\@
endm
@@ -0,0 +1,606 @@
/* ------------------------------------------------------------------------------ */
/* | Lowlevel Access to memory mapped ENC624J600 in PSP mode | */
/* | Henryk Richter <henryk.richter@gmx.net> | */
/* ------------------------------------------------------------------------------ */
/* register definition section */
#ifndef _REGISTERS_H_
#define _REGISTERS_H_
/* set/clr register offsets */
#define SET_OFFSET 0x0100
#define CLR_OFFSET 0x0180
/* Register definitions */
/* SPI Bank 0 registers -------- */
#define ETXST 0x7E00
#define ETXSTL 0x7E00
#define ETXSTH 0x7E01
#define ETXLEN 0x7E02
#define ETXLENL 0x7E02
#define ETXLENH 0x7E03
#define ERXST 0x7E04
#define ERXSTL 0x7E04
#define ERXSTH 0x7E05
#define ERXTAIL 0x7E06
#define ERXTAILL 0x7E06
#define ERXTAILH 0x7E07
#define ERXHEAD 0x7E08
#define ERXHEADL 0x7E08
#define ERXHEADH 0x7E09
#define EDMAST 0x7E0A
#define EDMASTL 0x7E0A
#define EDMASTH 0x7E0B
#define EDMALEN 0x7E0C
#define EDMALENL 0x7E0C
#define EDMALENH 0x7E0D
#define EDMADST 0x7E0E
#define EDMADSTL 0x7E0E
#define EDMADSTH 0x7E0F
#define EDMACS 0x7E10
#define EDMACSL 0x7E10
#define EDMACSH 0x7E11
#define ETXSTAT 0x7E12
#define ETXSTATL 0x7E12
#define ETXSTATH 0x7E13
#define ETXWIRE 0x7E14
#define ETXWIREL 0x7E14
#define ETXWIREH 0x7E15
/* SPI all bank registers */
#define EUDAST 0x7E16
#define EUDASTL 0x7E16
#define EUDASTH 0x7E17
#define EUDAND 0x7E18
#define EUDANDL 0x7E18
#define EUDANDH 0x7E19
#define ESTAT 0x7E1A
#define ESTATL 0x7E1A
#define ESTATH 0x7E1B
#define EIR 0x7E1C
#define EIRL 0x7E1C
#define EIRH 0x7E1D
#define ECON1 0x7E1E
#define ECON1L 0x7E1E
#define ECON1H 0x7E1F
/* SPI Bank 1 registers ----- */
#define EHT1 0x7E20
#define EHT1L 0x7E20
#define EHT1H 0x7E21
#define EHT2 0x7E22
#define EHT2L 0x7E22
#define EHT2H 0x7E23
#define EHT3 0x7E24
#define EHT3L 0x7E24
#define EHT3H 0x7E25
#define EHT4 0x7E26
#define EHT4L 0x7E26
#define EHT4H 0x7E27
#define EPMM1 0x7E28
#define EPMM1L 0x7E28
#define EPMM1H 0x7E29
#define EPMM2 0x7E2A
#define EPMM2L 0x7E2A
#define EPMM2H 0x7E2B
#define EPMM3 0x7E2C
#define EPMM3L 0x7E2C
#define EPMM3H 0x7E2D
#define EPMM4 0x7E2E
#define EPMM4L 0x7E2E
#define EPMM4H 0x7E2F
#define EPMCS 0x7E30
#define EPMCSL 0x7E30
#define EPMCSH 0x7E31
#define EPMO 0x7E32
#define EPMOL 0x7E32
#define EPMOH 0x7E33
#define ERXFCON 0x7E34
#define ERXFCONL 0x7E34
#define ERXFCONH 0x7E35
/* SPI all bank registers from 0x36 to 0x3F */
/* SPI Bank 2 registers ----- */
#define MACON1 0x7E40
#define MACON1L 0x7E40
#define MACON1H 0x7E41
#define MACON2 0x7E42
#define MACON2L 0x7E42
#define MACON2H 0x7E43
#define MABBIPG 0x7E44
#define MABBIPGL 0x7E44
#define MABBIPGH 0x7E45
#define MAIPG 0x7E46
#define MAIPGL 0x7E46
#define MAIPGH 0x7E47
#define MACLCON 0x7E48
#define MACLCONL 0x7E48
#define MACLCONH 0x7E49
#define MAMXFL 0x7E4A
#define MAMXFLL 0x7E4A
#define MAMXFLH 0x7E4B
#define MICMD 0x7E52
#define MICMDL 0x7E52
#define MICMDH 0x7E53
#define MIREGADR 0x7E54
#define MIREGADRL 0x7E54
#define MIREGADRH 0x7E55
/* SPI all bank registers from 0x56 to 0x5F */
/* SPI Bank 3 registers ----- */
#define MAADR3 0x7E60
#define MAADR3L 0x7E60
#define MAADR3H 0x7E61
#define MAADR2 0x7E62
#define MAADR2L 0x7E62
#define MAADR2H 0x7E63
#define MAADR1 0x7E64
#define MAADR1L 0x7E64
#define MAADR1H 0x7E65
#define MIWR 0x7E66
#define MIWRL 0x7E66
#define MIWRH 0x7E67
#define MIRD 0x7E68
#define MIRDL 0x7E68
#define MIRDH 0x7E69
#define MISTAT 0x7E6A
#define MISTATL 0x7E6A
#define MISTATH 0x7E6B
#define EPAUS 0x7E6C
#define EPAUSL 0x7E6C
#define EPAUSH 0x7E6D
#define ECON2 0x7E6E
#define ECON2L 0x7E6E
#define ECON2H 0x7E6F
#define ERXWM 0x7E70
#define ERXWML 0x7E70
#define ERXWMH 0x7E71
#define EIE 0x7E72
#define EIEL 0x7E72
#define EIEH 0x7E73
#define EIDLED 0x7E74
#define EIDLEDL 0x7E74
#define EIDLEDH 0x7E75
/* SPI all bank registers from 0x66 to 0x6F */
/* SPI Non-banked Special Function Registers */
#define EGPDATA 0x7E80
#define EGPDATAL 0x7E80
#define ERXDATA 0x7E82
#define ERXDATAL 0x7E82
#define EUDADATA 0x7E84
#define EUDADATAL 0x7E84
#define EGPRDPT 0x7E86
#define EGPRDPTL 0x7E86
#define EGPRDPTH 0x7E87
#define EGPWRPT 0x7E88
#define EGPWRPTL 0x7E88
#define EGPWRPTH 0x7E89
#define ERXRDPT 0x7E8A
#define ERXRDPTL 0x7E8A
#define ERXRDPTH 0x7E8B
#define ERXWRPT 0x7E8C
#define ERXWRPTL 0x7E8C
#define ERXWRPTH 0x7E8D
#define EUDARDPT 0x7E8E
#define EUDARDPTL 0x7E8E
#define EUDARDPTH 0x7E8F
#define EUDAWRPT 0x7E90
#define EUDAWRPTL 0x7E90
#define EUDAWRPTH 0x7E91
/* ;;;;;;;;;;;;;;;;;;;;;;;;; */
/* ENC424J600/624J600 register bits */
/* ;;;;;;;;;;;;;;;;;;;;;;;;; */
/* ESTAT bits ---------- */
#define ESTAT_INT (1<<15)
#define ESTAT_FCIDLE (1<<14)
#define ESTAT_RXBUSY (1<<13)
#define ESTAT_CLKRDY (1<<12)
#define ESTAT_RSTDONE (1<<11)
#define ESTAT_PHYDPX (1<<10)
#define ESTAT_PHYRDY (1<<9)
#define ESTAT_PHYLNK (1<<8)
#define ESTAT_PKTCNT7 (1<<7)
#define ESTAT_PKTCNT6 (1<<6)
#define ESTAT_PKTCNT5 (1<<5)
#define ESTAT_PKTCNT4 (1<<4)
#define ESTAT_PKTCNT3 (1<<3)
#define ESTAT_PKTCNT2 (1<<2)
#define ESTAT_PKTCNT1 (1<<1)
#define ESTAT_PKTCNT0 (1)
/* EIR bits ------------ */
#define EIR_CRYPTEN (1<<15)
#define EIR_MODEXIF (1<<14)
#define EIR_HASHIF (1<<13)
#define EIR_AESIF (1<<12)
#define EIR_LINKIF (1<<11)
#define EIR_PRDYIF (1<<10)
#define EIR_r9 (1<<9)
#define EIR_r8 (1<<8)
#define EIR_r7 (1<<7)
#define EIR_PKTIF (1<<6)
#define EIR_DMAIF (1<<5)
#define EIR_r4 (1<<4)
#define EIR_TXIF (1<<3)
#define EIR_TXABTIF (1<<2)
#define EIR_RXABTIF (1<<1)
#define EIR_PCFULIF (1)
/* ECON1 bits ---------- */
#define ECON1_MODEXST (1<<15)
#define ECON1_HASHEN (1<<14)
#define ECON1_HASHOP (1<<13)
#define ECON1_HASHLST (1<<12)
#define ECON1_AESST (1<<11)
#define ECON1_AESOP1 (1<<10)
#define ECON1_AESOP0 (1<<9)
#define ECON1_PKTDEC (1<<8)
#define ECON1_FCOP1 (1<<7)
#define ECON1_FCOP0 (1<<6)
#define ECON1_DMAST (1<<5)
#define ECON1_DMACPY (1<<4)
#define ECON1_DMACSSD (1<<3)
#define ECON1_DMANOCS (1<<2)
#define ECON1_TXRTS (1<<1)
#define ECON1_RXEN (1)
/* ETXSTAT bits -------- */
#define ETXSTAT_r12 (1<<12)
#define ETXSTAT_r11 (1<<11)
#define ETXSTAT_LATECOL (1<<10)
#define ETXSTAT_MAXCOL (1<<9)
#define ETXSTAT_EXDEFER (1<<8)
#define ETXSTAT_DEFER (1<<7)
#define ETXSTAT_r6 (1<<6)
#define ETXSTAT_r5 (1<<5)
#define ETXSTAT_CRCBAD (1<<4)
#define ETXSTAT_COLCNT3 (1<<3)
#define ETXSTAT_COLCNT2 (1<<2)
#define ETXSTAT_COLCNT1 (1<<1)
#define ETXSTAT_COLCNT0 (1)
/* ERXFCON bits -------- */
#define ERXFCON_HTEN (1<<15)
#define ERXFCON_MPEN (1<<14)
#define ERXFCON_NOTPM (1<<12)
#define ERXFCON_PMEN3 (1<<11)
#define ERXFCON_PMEN2 (1<<10)
#define ERXFCON_PMEN1 (1<<9)
#define ERXFCON_PMEN0 (1<<8)
#define ERXFCON_CRCEEN (1<<7)
#define ERXFCON_CRCEN (1<<6)
#define ERXFCON_RUNTEEN (1<<5)
#define ERXFCON_RUNTEN (1<<4)
#define ERXFCON_UCEN (1<<3)
#define ERXFCON_NOTMEEN (1<<2)
#define ERXFCON_MCEN (1<<1)
#define ERXFCON_BCEN (1)
/* MACON1 bits --------- */
#define MACON1_r15 (1<<15)
#define MACON1_r14 (1<<14)
#define MACON1_r11 (1<<11)
#define MACON1_r10 (1<<10)
#define MACON1_r9 (1<<9)
#define MACON1_r8 (1<<8)
#define MACON1_LOOPBK (1<<4)
#define MACON1_r3 (1<<3)
#define MACON1_RXPAUS (1<<2)
#define MACON1_PASSALL (1<<1)
#define MACON1_r0 (1)
/* MACON2 bits --------- */
#define MACON2_DEFER (1<<14)
#define MACON2_BPEN (1<<13)
#define MACON2_NOBKOFF (1<<12)
#define MACON2_r9 (1<<9)
#define MACON2_r8 (1<<8)
#define MACON2_PADCFG2 (1<<7)
#define MACON2_PADCFG1 (1<<6)
#define MACON2_PADCFG0 (1<<5)
#define MACON2_TXCRCEN (1<<4)
#define MACON2_PHDREN (1<<3)
#define MACON2_HFRMEN (1<<2)
#define MACON2_r1 (1<<1)
#define MACON2_FULDPX (1)
/* MABBIPG bits -------- */
#define MABBIPG_BBIPG6 (1<<6)
#define MABBIPG_BBIPG5 (1<<5)
#define MABBIPG_BBIPG4 (1<<4)
#define MABBIPG_BBIPG3 (1<<3)
#define MABBIPG_BBIPG2 (1<<2)
#define MABBIPG_BBIPG1 (1<<1)
#define MABBIPG_BBIPG0 (1)
/* MAIPG bits ---------- */
#define MAIPG_r14 (1<<14)
#define MAIPG_r13 (1<<13)
#define MAIPG_r12 (1<<12)
#define MAIPG_r11 (1<<11)
#define MAIPG_r10 (1<<10)
#define MAIPG_r9 (1<<9)
#define MAIPG_r8 (1<<8)
#define MAIPG_IPG6 (1<<6)
#define MAIPG_IPG5 (1<<5)
#define MAIPG_IPG4 (1<<4)
#define MAIPG_IPG3 (1<<3)
#define MAIPG_IPG2 (1<<2)
#define MAIPG_IPG1 (1<<1)
#define MAIPG_IPG0 (1)
/* MACLCON bits -------- */
#define MACLCON_r13 (1<<13)
#define MACLCON_r12 (1<<12)
#define MACLCON_r11 (1<<11)
#define MACLCON_r10 (1<<10)
#define MACLCON_r9 (1<<9)
#define MACLCON_r8 (1<<8)
#define MACLCON_MAXRET3 (1<<3)
#define MACLCON_MAXRET2 (1<<2)
#define MACLCON_MAXRET1 (1<<1)
#define MACLCON_MAXRET0 (1)
/* MICMD bits ---------- */
#define MICMD_MIISCAN (1<<1)
#define MICMD_MIIRD (1)
/* MIREGADR bits ------- */
#define MIREGADR_r12 (1<<12)
#define MIREGADR_r11 (1<<11)
#define MIREGADR_r10 (1<<10)
#define MIREGADR_r9 (1<<9)
#define MIREGADR_r8 (1<<8)
#define MIREGADR_PHREG4 (1<<4)
#define MIREGADR_PHREG3 (1<<3)
#define MIREGADR_PHREG2 (1<<2)
#define MIREGADR_PHREG1 (1<<1)
#define MIREGADR_PHREG0 (1)
/* MISTAT bits --------- */
#define MISTAT_r3 (1<<3)
#define MISTAT_NVALID (1<<2)
#define MISTAT_SCAN (1<<1)
#define MISTAT_BUSY (1)
/* ECON2 bits ---------- */
#define ECON2_ETHEN (1<<15)
#define ECON2_STRCH (1<<14)
#define ECON2_TXMAC (1<<13)
#define ECON2_SHA1MD5 (1<<12)
#define ECON2_COCON3 (1<<11)
#define ECON2_COCON2 (1<<10)
#define ECON2_COCON1 (1<<9)
#define ECON2_COCON0 (1<<8)
#define ECON2_AUTOFC (1<<7)
#define ECON2_TXRST (1<<6)
#define ECON2_RXRST (1<<5)
#define ECON2_ETHRST (1<<4)
#define ECON2_MODLEN1 (1<<3)
#define ECON2_MODLEN0 (1<<2)
#define ECON2_AESLEN1 (1<<1)
#define ECON2_AESLEN0 (1)
/* ERXWM bits ---------- */
#define ERXWM_RXFWM7 (1<<15)
#define ERXWM_RXFWM6 (1<<14)
#define ERXWM_RXFWM5 (1<<13)
#define ERXWM_RXFWM4 (1<<12)
#define ERXWM_RXFWM3 (1<<11)
#define ERXWM_RXFWM2 (1<<10)
#define ERXWM_RXFWM1 (1<<9)
#define ERXWM_RXFWM0 (1<<8)
#define ERXWM_RXEWM7 (1<<7)
#define ERXWM_RXEWM6 (1<<6)
#define ERXWM_RXEWM5 (1<<5)
#define ERXWM_RXEWM4 (1<<4)
#define ERXWM_RXEWM3 (1<<3)
#define ERXWM_RXEWM2 (1<<2)
#define ERXWM_RXEWM1 (1<<1)
#define ERXWM_RXEWM0 (1)
/* EIE bits ------------ */
#define EIE_INTIE (1<<15)
#define EIE_MODEXIE (1<<14)
#define EIE_HASHIE (1<<13)
#define EIE_AESIE (1<<12)
#define EIE_LINKIE (1<<11)
#define EIE_PRDYIE (1<<10)
#define EIE_r9 (1<<9)
#define EIE_r8 (1<<8)
#define EIE_r7 (1<<7)
#define EIE_PKTIE (1<<6)
#define EIE_DMAIE (1<<5)
#define EIE_r4 (1<<4)
#define EIE_TXIE (1<<3)
#define EIE_TXABTIE (1<<2)
#define EIE_RXABTIE (1<<1)
#define EIE_PCFULIE (1)
/* EIDLED bits --------- */
#define EIDLED_LACFG3 (1<<15)
#define EIDLED_LACFG2 (1<<14)
#define EIDLED_LACFG1 (1<<13)
#define EIDLED_LACFG0 (1<<12)
#define EIDLED_LBCFG3 (1<<11)
#define EIDLED_LBCFG2 (1<<10)
#define EIDLED_LBCFG1 (1<<9)
#define EIDLED_LBCFG0 (1<<8)
#define EIDLED_DEVID2 (1<<7)
#define EIDLED_DEVID1 (1<<6)
#define EIDLED_DEVID0 (1<<5)
#define EIDLED_REVID4 (1<<4)
#define EIDLED_REVID3 (1<<3)
#define EIDLED_REVID2 (1<<2)
#define EIDLED_REVID1 (1<<1)
#define EIDLED_REVID0 (1)
/* PHCON1 bits --------- */
#define PHCON1_PRST (1<<15)
#define PHCON1_PLOOPBK (1<<14)
#define PHCON1_SPD100 (1<<13)
#define PHCON1_ANEN (1<<12)
#define PHCON1_PSLEEP (1<<11)
#define PHCON1_r10 (1<<10)
#define PHCON1_RENEG (1<<9)
#define PHCON1_PFULDPX (1<<8)
#define PHCON1_r7 (1<<7)
#define PHCON1_r6 (1<<6)
#define PHCON1_r5 (1<<5)
#define PHCON1_r4 (1<<4)
#define PHCON1_r3 (1<<3)
#define PHCON1_r2 (1<<2)
#define PHCON1_r1 (1<<1)
#define PHCON1_r0 (1)
/* PHSTAT1 bits -------- */
#define PHSTAT1_r15 (1<<15)
#define PHSTAT1_FULL100 (1<<14)
#define PHSTAT1_HALF100 (1<<13)
#define PHSTAT1_FULL10 (1<<12)
#define PHSTAT1_HALF10 (1<<11)
#define PHSTAT1_r10 (1<<10)
#define PHSTAT1_r9 (1<<9)
#define PHSTAT1_r8 (1<<8)
#define PHSTAT1_r7 (1<<7)
#define PHSTAT1_r6 (1<<6)
#define PHSTAT1_ANDONE (1<<5)
#define PHSTAT1_LRFAULT (1<<4)
#define PHSTAT1_ANABLE (1<<3)
#define PHSTAT1_LLSTAT (1<<2)
#define PHSTAT1_r1 (1<<1)
#define PHSTAT1_EXTREGS (1)
/* PHANA bits ---------- */
#define PHANA_ADNP (1<<15)
#define PHANA_r14 (1<<14)
#define PHANA_ADFAULT (1<<13)
#define PHANA_r12 (1<<12)
#define PHANA_ADPAUS1 (1<<11)
#define PHANA_ADPAUS0 (1<<10)
#define PHANA_r9 (1<<9)
#define PHANA_AD100FD (1<<8)
#define PHANA_AD100 (1<<7)
#define PHANA_AD10FD (1<<6)
#define PHANA_AD10 (1<<5)
#define PHANA_ADIEEE4 (1<<4)
#define PHANA_ADIEEE3 (1<<3)
#define PHANA_ADIEEE2 (1<<2)
#define PHANA_ADIEEE1 (1<<1)
#define PHANA_ADIEEE0 (1)
/* PHANLPA bits -------- */
#define PHANLPA_LPNP (1<<15)
#define PHANLPA_LPACK (1<<14)
#define PHANLPA_LPFAULT (1<<13)
#define PHANLPA_r12 (1<<12)
#define PHANLPA_LPPAUS1 (1<<11)
#define PHANLPA_LPPAUS0 (1<<10)
#define PHANLPA_LP100T4 (1<<9)
#define PHANLPA_LP100FD (1<<8)
#define PHANLPA_LP100 (1<<7)
#define PHANLPA_LP10FD (1<<6)
#define PHANLPA_LP10 (1<<5)
#define PHANLPA_LPIEEE4 (1<<4)
#define PHANLPA_LPIEEE3 (1<<3)
#define PHANLPA_LPIEEE2 (1<<2)
#define PHANLPA_LPIEEE1 (1<<1)
#define PHANLPA_LPIEEE0 (1)
/* PHANE bits ---------- */
#define PHANE_r15 (1<<15)
#define PHANE_r14 (1<<14)
#define PHANE_r13 (1<<13)
#define PHANE_r12 (1<<12)
#define PHANE_r11 (1<<11)
#define PHANE_r10 (1<<10)
#define PHANE_r9 (1<<9)
#define PHANE_r8 (1<<8)
#define PHANE_r7 (1<<7)
#define PHANE_r6 (1<<6)
#define PHANE_r5 (1<<5)
#define PHANE_PDFLT (1<<4)
#define PHANE_r3 (1<<3)
#define PHANE_r2 (1<<2)
#define PHANE_LPARCD (1<<1)
#define PHANA_LPANABL (1)
/* PHCON2 bits --------- */
#define PHCON2_r15 (1<<15)
#define PHCON2_r14 (1<<14)
#define PHCON2_EDPWRDN (1<<13)
#define PHCON2_r12 (1<<12)
#define PHCON2_EDTHRES (1<<11)
#define PHCON2_r10 (1<<10)
#define PHCON2_r9 (1<<9)
#define PHCON2_r8 (1<<8)
#define PHCON2_r7 (1<<7)
#define PHCON2_r6 (1<<6)
#define PHCON2_r5 (1<<5)
#define PHCON2_r4 (1<<4)
#define PHCON2_r3 (1<<3)
#define PHCON2_FRCLNK (1<<2)
#define PHCON2_EDSTAT (1<<1)
#define PHCON2_r0 (1)
/* PHSTAT2 bits --------- */
#define PHSTAT2_r15 (1<<15)
#define PHSTAT2_r14 (1<<14)
#define PHSTAT2_r13 (1<<13)
#define PHSTAT2_r12 (1<<12)
#define PHSTAT2_r11 (1<<11)
#define PHSTAT2_r10 (1<<10)
#define PHSTAT2_r9 (1<<9)
#define PHSTAT2_r8 (1<<8)
#define PHSTAT2_r7 (1<<7)
#define PHSTAT2_r6 (1<<6)
#define PHSTAT2_r5 (1<<5)
#define PHSTAT2_PLRITY (1<<4)
#define PHSTAT2_r3 (1<<3)
#define PHSTAT2_r2 (1<<2)
#define PHSTAT2_r1 (1<<1)
#define PHSTAT2_r0 (1)
/* PHSTAT3 bits -------- */
#define PHSTAT3_r15 (1<<15)
#define PHSTAT3_r14 (1<<14)
#define PHSTAT3_r13 (1<<13)
#define PHSTAT3_r12 (1<<12)
#define PHSTAT3_r11 (1<<11)
#define PHSTAT3_r10 (1<<10)
#define PHSTAT3_r9 (1<<9)
#define PHSTAT3_r8 (1<<8)
#define PHSTAT3_r7 (1<<7)
#define PHSTAT3_r6 (1<<6)
#define PHSTAT3_r5 (1<<5)
#define PHSTAT3_SPDDPX2 (1<<4)
#define PHSTAT3_SPDDPX1 (1<<3)
#define PHSTAT3_SPDDPX0 (1<<2)
#define PHSTAT3_r1 (1<<1)
#define PHSTAT3_r0 (1)
/* ------------------------------ internal defaults ---------------------------------- */
/* 33.333Mhz clock out frequency */
#define CLOCK_33_CLR (ECON2_COCON3|ECON2_COCON2|ECON2_COCON1) /* clr mask */
#define CLOCK_33_SET (ECON2_COCON0) /* set mask */
/* 25 MHz */
#define CLOCK_25_CLR (ECON2_COCON3|ECON2_COCON2|ECON2_COCON0) /* clr mask */
#define CLOCK_25_SET (ECON2_COCON1) /* set mask */
/* 20 MHz */
#define CLOCK_20_CLR (ECON2_COCON3|ECON2_COCON2) /* clr mask */
#define CLOCK_20_SET (ECON2_COCON1|ECON2_COCON0) /* set mask */
/* 16 MHz */
#define CLOCK_16_CLR (ECON2_COCON3|ECON2_COCON0|ECON2_COCON1) /* clr mask */
#define CLOCK_16_SET (ECON2_COCON2) /* set mask */
/* 4 MHz (after reset) */
#define CLOCK_4_CLR (ECON2_COCON2) /* clr mask */
#define CLOCK_4_SET (ECON2_COCON3|ECON2_COCON0|ECON2_COCON1) /* set mask */
#define CLOCK_DEF_CLR CLOCK_33_CLR
#define CLOCK_DEF_SET CLOCK_33_SET
#endif /* _REGISTERS_H_ */
@@ -0,0 +1,602 @@
; ------------------------------------------------------------------------------
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
; | Henryk Richter <henryk.richter@gmx.net> |
; ------------------------------------------------------------------------------
; register definition section
; set/clr register offsets
SET_OFFSET EQU $0100
CLR_OFFSET EQU $0180
; Register definitions
; SPI Bank 0 registers --------
ETXST EQU $7E00
ETXSTL EQU $7E00
ETXSTH EQU $7E01
ETXLEN EQU $7E02
ETXLENL EQU $7E02
ETXLENH EQU $7E03
ERXST EQU $7E04
ERXSTL EQU $7E04
ERXSTH EQU $7E05
ERXTAIL EQU $7E06
ERXTAILL EQU $7E06
ERXTAILH EQU $7E07
ERXHEAD EQU $7E08
ERXHEADL EQU $7E08
ERXHEADH EQU $7E09
EDMAST EQU $7E0A
EDMASTL EQU $7E0A
EDMASTH EQU $7E0B
EDMALEN EQU $7E0C
EDMALENL EQU $7E0C
EDMALENH EQU $7E0D
EDMADST EQU $7E0E
EDMADSTL EQU $7E0E
EDMADSTH EQU $7E0F
EDMACS EQU $7E10
EDMACSL EQU $7E10
EDMACSH EQU $7E11
ETXSTAT EQU $7E12
ETXSTATL EQU $7E12
ETXSTATH EQU $7E13
ETXWIRE EQU $7E14
ETXWIREL EQU $7E14
ETXWIREH EQU $7E15
; SPI all bank registers
EUDAST EQU $7E16
EUDASTL EQU $7E16
EUDASTH EQU $7E17
EUDAND EQU $7E18
EUDANDL EQU $7E18
EUDANDH EQU $7E19
ESTAT EQU $7E1A
ESTATL EQU $7E1A
ESTATH EQU $7E1B
EIR EQU $7E1C
EIRL EQU $7E1C
EIRH EQU $7E1D
ECON1 EQU $7E1E
ECON1L EQU $7E1E
ECON1H EQU $7E1F
; SPI Bank 1 registers -----
EHT1 EQU $7E20
EHT1L EQU $7E20
EHT1H EQU $7E21
EHT2 EQU $7E22
EHT2L EQU $7E22
EHT2H EQU $7E23
EHT3 EQU $7E24
EHT3L EQU $7E24
EHT3H EQU $7E25
EHT4 EQU $7E26
EHT4L EQU $7E26
EHT4H EQU $7E27
EPMM1 EQU $7E28
EPMM1L EQU $7E28
EPMM1H EQU $7E29
EPMM2 EQU $7E2A
EPMM2L EQU $7E2A
EPMM2H EQU $7E2B
EPMM3 EQU $7E2C
EPMM3L EQU $7E2C
EPMM3H EQU $7E2D
EPMM4 EQU $7E2E
EPMM4L EQU $7E2E
EPMM4H EQU $7E2F
EPMCS EQU $7E30
EPMCSL EQU $7E30
EPMCSH EQU $7E31
EPMO EQU $7E32
EPMOL EQU $7E32
EPMOH EQU $7E33
ERXFCON EQU $7E34
ERXFCONL EQU $7E34
ERXFCONH EQU $7E35
; SPI all bank registers from 0x36 to 0x3F
; SPI Bank 2 registers -----
MACON1 EQU $7E40
MACON1L EQU $7E40
MACON1H EQU $7E41
MACON2 EQU $7E42
MACON2L EQU $7E42
MACON2H EQU $7E43
MABBIPG EQU $7E44
MABBIPGL EQU $7E44
MABBIPGH EQU $7E45
MAIPG EQU $7E46
MAIPGL EQU $7E46
MAIPGH EQU $7E47
MACLCON EQU $7E48
MACLCONL EQU $7E48
MACLCONH EQU $7E49
MAMXFL EQU $7E4A
MAMXFLL EQU $7E4A
MAMXFLH EQU $7E4B
MICMD EQU $7E52
MICMDL EQU $7E52
MICMDH EQU $7E53
MIREGADR EQU $7E54
MIREGADRL EQU $7E54
MIREGADRH EQU $7E55
; SPI all bank registers from 0x56 to 0x5F
; SPI Bank 3 registers -----
MAADR3 EQU $7E60
MAADR3L EQU $7E60
MAADR3H EQU $7E61
MAADR2 EQU $7E62
MAADR2L EQU $7E62
MAADR2H EQU $7E63
MAADR1 EQU $7E64
MAADR1L EQU $7E64
MAADR1H EQU $7E65
MIWR EQU $7E66
MIWRL EQU $7E66
MIWRH EQU $7E67
MIRD EQU $7E68
MIRDL EQU $7E68
MIRDH EQU $7E69
MISTAT EQU $7E6A
MISTATL EQU $7E6A
MISTATH EQU $7E6B
EPAUS EQU $7E6C
EPAUSL EQU $7E6C
EPAUSH EQU $7E6D
ECON2 EQU $7E6E
ECON2L EQU $7E6E
ECON2H EQU $7E6F
ERXWM EQU $7E70
ERXWML EQU $7E70
ERXWMH EQU $7E71
EIE EQU $7E72
EIEL EQU $7E72
EIEH EQU $7E73
EIDLED EQU $7E74
EIDLEDL EQU $7E74
EIDLEDH EQU $7E75
; SPI all bank registers from 0x66 to 0x6F
; SPI Non-banked Special Function Registers
EGPDATA EQU $7E80
EGPDATAL EQU $7E80
ERXDATA EQU $7E82
ERXDATAL EQU $7E82
EUDADATA EQU $7E84
EUDADATAL EQU $7E84
EGPRDPT EQU $7E86
EGPRDPTL EQU $7E86
EGPRDPTH EQU $7E87
EGPWRPT EQU $7E88
EGPWRPTL EQU $7E88
EGPWRPTH EQU $7E89
ERXRDPT EQU $7E8A
ERXRDPTL EQU $7E8A
ERXRDPTH EQU $7E8B
ERXWRPT EQU $7E8C
ERXWRPTL EQU $7E8C
ERXWRPTH EQU $7E8D
EUDARDPT EQU $7E8E
EUDARDPTL EQU $7E8E
EUDARDPTH EQU $7E8F
EUDAWRPT EQU $7E90
EUDAWRPTL EQU $7E90
EUDAWRPTH EQU $7E91
;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENC424J600/624J600 register bits
;;;;;;;;;;;;;;;;;;;;;;;;;;
; ESTAT bits ----------
ESTAT_INT EQU (1<<15)
ESTAT_FCIDLE EQU (1<<14)
ESTAT_RXBUSY EQU (1<<13)
ESTAT_CLKRDY EQU (1<<12)
ESTAT_RSTDONE EQU (1<<11)
ESTAT_PHYDPX EQU (1<<10)
ESTAT_PHYRDY EQU (1<<9)
ESTAT_PHYLNK EQU (1<<8)
ESTAT_PKTCNT7 EQU (1<<7)
ESTAT_PKTCNT6 EQU (1<<6)
ESTAT_PKTCNT5 EQU (1<<5)
ESTAT_PKTCNT4 EQU (1<<4)
ESTAT_PKTCNT3 EQU (1<<3)
ESTAT_PKTCNT2 EQU (1<<2)
ESTAT_PKTCNT1 EQU (1<<1)
ESTAT_PKTCNT0 EQU (1)
; EIR bits ------------
EIR_CRYPTEN EQU (1<<15)
EIR_MODEXIF EQU (1<<14)
EIR_HASHIF EQU (1<<13)
EIR_AESIF EQU (1<<12)
EIR_LINKIF EQU (1<<11)
EIR_PRDYIF EQU (1<<10)
EIR_r9 EQU (1<<9)
EIR_r8 EQU (1<<8)
EIR_r7 EQU (1<<7)
EIR_PKTIF EQU (1<<6)
EIR_DMAIF EQU (1<<5)
EIR_r4 EQU (1<<4)
EIR_TXIF EQU (1<<3)
EIR_TXABTIF EQU (1<<2)
EIR_RXABTIF EQU (1<<1)
EIR_PCFULIF EQU (1)
; ECON1 bits ----------
ECON1_MODEXST EQU (1<<15)
ECON1_HASHEN EQU (1<<14)
ECON1_HASHOP EQU (1<<13)
ECON1_HASHLST EQU (1<<12)
ECON1_AESST EQU (1<<11)
ECON1_AESOP1 EQU (1<<10)
ECON1_AESOP0 EQU (1<<9)
ECON1_PKTDEC EQU (1<<8)
ECON1_FCOP1 EQU (1<<7)
ECON1_FCOP0 EQU (1<<6)
ECON1_DMAST EQU (1<<5)
ECON1_DMACPY EQU (1<<4)
ECON1_DMACSSD EQU (1<<3)
ECON1_DMANOCS EQU (1<<2)
ECON1_TXRTS EQU (1<<1)
ECON1_RXEN EQU (1)
; ETXSTAT bits --------
ETXSTAT_r12 EQU (1<<12)
ETXSTAT_r11 EQU (1<<11)
ETXSTAT_LATECOL EQU (1<<10)
ETXSTAT_MAXCOL EQU (1<<9)
ETXSTAT_EXDEFER EQU (1<<8)
ETXSTAT_DEFER EQU (1<<7)
ETXSTAT_r6 EQU (1<<6)
ETXSTAT_r5 EQU (1<<5)
ETXSTAT_CRCBAD EQU (1<<4)
ETXSTAT_COLCNT3 EQU (1<<3)
ETXSTAT_COLCNT2 EQU (1<<2)
ETXSTAT_COLCNT1 EQU (1<<1)
ETXSTAT_COLCNT0 EQU (1)
; ERXFCON bits --------
ERXFCON_HTEN EQU (1<<15)
ERXFCON_MPEN EQU (1<<14)
ERXFCON_NOTPM EQU (1<<12)
ERXFCON_PMEN3 EQU (1<<11)
ERXFCON_PMEN2 EQU (1<<10)
ERXFCON_PMEN1 EQU (1<<9)
ERXFCON_PMEN0 EQU (1<<8)
ERXFCON_CRCEEN EQU (1<<7)
ERXFCON_CRCEN EQU (1<<6)
ERXFCON_RUNTEEN EQU (1<<5)
ERXFCON_RUNTEN EQU (1<<4)
ERXFCON_UCEN EQU (1<<3)
ERXFCON_NOTMEEN EQU (1<<2)
ERXFCON_MCEN EQU (1<<1)
ERXFCON_BCEN EQU (1)
; MACON1 bits ---------
MACON1_r15 EQU (1<<15)
MACON1_r14 EQU (1<<14)
MACON1_r11 EQU (1<<11)
MACON1_r10 EQU (1<<10)
MACON1_r9 EQU (1<<9)
MACON1_r8 EQU (1<<8)
MACON1_LOOPBK EQU (1<<4)
MACON1_r3 EQU (1<<3)
MACON1_RXPAUS EQU (1<<2)
MACON1_PASSALL EQU (1<<1)
MACON1_r0 EQU (1)
; MACON2 bits ---------
MACON2_DEFER EQU (1<<14)
MACON2_BPEN EQU (1<<13)
MACON2_NOBKOFF EQU (1<<12)
MACON2_r9 EQU (1<<9)
MACON2_r8 EQU (1<<8)
MACON2_PADCFG2 EQU (1<<7)
MACON2_PADCFG1 EQU (1<<6)
MACON2_PADCFG0 EQU (1<<5)
MACON2_TXCRCEN EQU (1<<4)
MACON2_PHDREN EQU (1<<3)
MACON2_HFRMEN EQU (1<<2)
MACON2_r1 EQU (1<<1)
MACON2_FULDPX EQU (1)
; MABBIPG bits --------
MABBIPG_BBIPG6 EQU (1<<6)
MABBIPG_BBIPG5 EQU (1<<5)
MABBIPG_BBIPG4 EQU (1<<4)
MABBIPG_BBIPG3 EQU (1<<3)
MABBIPG_BBIPG2 EQU (1<<2)
MABBIPG_BBIPG1 EQU (1<<1)
MABBIPG_BBIPG0 EQU (1)
; MAIPG bits ----------
MAIPG_r14 EQU (1<<14)
MAIPG_r13 EQU (1<<13)
MAIPG_r12 EQU (1<<12)
MAIPG_r11 EQU (1<<11)
MAIPG_r10 EQU (1<<10)
MAIPG_r9 EQU (1<<9)
MAIPG_r8 EQU (1<<8)
MAIPG_IPG6 EQU (1<<6)
MAIPG_IPG5 EQU (1<<5)
MAIPG_IPG4 EQU (1<<4)
MAIPG_IPG3 EQU (1<<3)
MAIPG_IPG2 EQU (1<<2)
MAIPG_IPG1 EQU (1<<1)
MAIPG_IPG0 EQU (1)
; MACLCON bits --------
MACLCON_r13 EQU (1<<13)
MACLCON_r12 EQU (1<<12)
MACLCON_r11 EQU (1<<11)
MACLCON_r10 EQU (1<<10)
MACLCON_r9 EQU (1<<9)
MACLCON_r8 EQU (1<<8)
MACLCON_MAXRET3 EQU (1<<3)
MACLCON_MAXRET2 EQU (1<<2)
MACLCON_MAXRET1 EQU (1<<1)
MACLCON_MAXRET0 EQU (1)
; MICMD bits ----------
MICMD_MIISCAN EQU (1<<1)
MICMD_MIIRD EQU (1)
; MIREGADR bits -------
MIREGADR_r12 EQU (1<<12)
MIREGADR_r11 EQU (1<<11)
MIREGADR_r10 EQU (1<<10)
MIREGADR_r9 EQU (1<<9)
MIREGADR_r8 EQU (1<<8)
MIREGADR_PHREG4 EQU (1<<4)
MIREGADR_PHREG3 EQU (1<<3)
MIREGADR_PHREG2 EQU (1<<2)
MIREGADR_PHREG1 EQU (1<<1)
MIREGADR_PHREG0 EQU (1)
; MISTAT bits ---------
MISTAT_r3 EQU (1<<3)
MISTAT_NVALID EQU (1<<2)
MISTAT_SCAN EQU (1<<1)
MISTAT_BUSY EQU (1)
; ECON2 bits ----------
ECON2_ETHEN EQU (1<<15)
ECON2_STRCH EQU (1<<14)
ECON2_TXMAC EQU (1<<13)
ECON2_SHA1MD5 EQU (1<<12)
ECON2_COCON3 EQU (1<<11)
ECON2_COCON2 EQU (1<<10)
ECON2_COCON1 EQU (1<<9)
ECON2_COCON0 EQU (1<<8)
ECON2_AUTOFC EQU (1<<7)
ECON2_TXRST EQU (1<<6)
ECON2_RXRST EQU (1<<5)
ECON2_ETHRST EQU (1<<4)
ECON2_MODLEN1 EQU (1<<3)
ECON2_MODLEN0 EQU (1<<2)
ECON2_AESLEN1 EQU (1<<1)
ECON2_AESLEN0 EQU (1)
; ERXWM bits ----------
ERXWM_RXFWM7 EQU (1<<15)
ERXWM_RXFWM6 EQU (1<<14)
ERXWM_RXFWM5 EQU (1<<13)
ERXWM_RXFWM4 EQU (1<<12)
ERXWM_RXFWM3 EQU (1<<11)
ERXWM_RXFWM2 EQU (1<<10)
ERXWM_RXFWM1 EQU (1<<9)
ERXWM_RXFWM0 EQU (1<<8)
ERXWM_RXEWM7 EQU (1<<7)
ERXWM_RXEWM6 EQU (1<<6)
ERXWM_RXEWM5 EQU (1<<5)
ERXWM_RXEWM4 EQU (1<<4)
ERXWM_RXEWM3 EQU (1<<3)
ERXWM_RXEWM2 EQU (1<<2)
ERXWM_RXEWM1 EQU (1<<1)
ERXWM_RXEWM0 EQU (1)
; EIE bits ------------
EIE_INTIE EQU (1<<15)
EIE_MODEXIE EQU (1<<14)
EIE_HASHIE EQU (1<<13)
EIE_AESIE EQU (1<<12)
EIE_LINKIE EQU (1<<11)
EIE_PRDYIE EQU (1<<10)
EIE_r9 EQU (1<<9)
EIE_r8 EQU (1<<8)
EIE_r7 EQU (1<<7)
EIE_PKTIE EQU (1<<6)
EIE_DMAIE EQU (1<<5)
EIE_r4 EQU (1<<4)
EIE_TXIE EQU (1<<3)
EIE_TXABTIE EQU (1<<2)
EIE_RXABTIE EQU (1<<1)
EIE_PCFULIE EQU (1)
; EIDLED bits ---------
EIDLED_LACFG3 EQU (1<<15)
EIDLED_LACFG2 EQU (1<<14)
EIDLED_LACFG1 EQU (1<<13)
EIDLED_LACFG0 EQU (1<<12)
EIDLED_LBCFG3 EQU (1<<11)
EIDLED_LBCFG2 EQU (1<<10)
EIDLED_LBCFG1 EQU (1<<9)
EIDLED_LBCFG0 EQU (1<<8)
EIDLED_DEVID2 EQU (1<<7)
EIDLED_DEVID1 EQU (1<<6)
EIDLED_DEVID0 EQU (1<<5)
EIDLED_REVID4 EQU (1<<4)
EIDLED_REVID3 EQU (1<<3)
EIDLED_REVID2 EQU (1<<2)
EIDLED_REVID1 EQU (1<<1)
EIDLED_REVID0 EQU (1)
; PHCON1 bits ---------
PHCON1_PRST EQU (1<<15)
PHCON1_PLOOPBK EQU (1<<14)
PHCON1_SPD100 EQU (1<<13)
PHCON1_ANEN EQU (1<<12)
PHCON1_PSLEEP EQU (1<<11)
PHCON1_r10 EQU (1<<10)
PHCON1_RENEG EQU (1<<9)
PHCON1_PFULDPX EQU (1<<8)
PHCON1_r7 EQU (1<<7)
PHCON1_r6 EQU (1<<6)
PHCON1_r5 EQU (1<<5)
PHCON1_r4 EQU (1<<4)
PHCON1_r3 EQU (1<<3)
PHCON1_r2 EQU (1<<2)
PHCON1_r1 EQU (1<<1)
PHCON1_r0 EQU (1)
; PHSTAT1 bits --------
PHSTAT1_r15 EQU (1<<15)
PHSTAT1_FULL100 EQU (1<<14)
PHSTAT1_HALF100 EQU (1<<13)
PHSTAT1_FULL10 EQU (1<<12)
PHSTAT1_HALF10 EQU (1<<11)
PHSTAT1_r10 EQU (1<<10)
PHSTAT1_r9 EQU (1<<9)
PHSTAT1_r8 EQU (1<<8)
PHSTAT1_r7 EQU (1<<7)
PHSTAT1_r6 EQU (1<<6)
PHSTAT1_ANDONE EQU (1<<5)
PHSTAT1_LRFAULT EQU (1<<4)
PHSTAT1_ANABLE EQU (1<<3)
PHSTAT1_LLSTAT EQU (1<<2)
PHSTAT1_r1 EQU (1<<1)
PHSTAT1_EXTREGS EQU (1)
; PHANA bits ----------
PHANA_ADNP EQU (1<<15)
PHANA_r14 EQU (1<<14)
PHANA_ADFAULT EQU (1<<13)
PHANA_r12 EQU (1<<12)
PHANA_ADPAUS1 EQU (1<<11)
PHANA_ADPAUS0 EQU (1<<10)
PHANA_r9 EQU (1<<9)
PHANA_AD100FD EQU (1<<8)
PHANA_AD100 EQU (1<<7)
PHANA_AD10FD EQU (1<<6)
PHANA_AD10 EQU (1<<5)
PHANA_ADIEEE4 EQU (1<<4)
PHANA_ADIEEE3 EQU (1<<3)
PHANA_ADIEEE2 EQU (1<<2)
PHANA_ADIEEE1 EQU (1<<1)
PHANA_ADIEEE0 EQU (1)
; PHANLPA bits --------
PHANLPA_LPNP EQU (1<<15)
PHANLPA_LPACK EQU (1<<14)
PHANLPA_LPFAULT EQU (1<<13)
PHANLPA_r12 EQU (1<<12)
PHANLPA_LPPAUS1 EQU (1<<11)
PHANLPA_LPPAUS0 EQU (1<<10)
PHANLPA_LP100T4 EQU (1<<9)
PHANLPA_LP100FD EQU (1<<8)
PHANLPA_LP100 EQU (1<<7)
PHANLPA_LP10FD EQU (1<<6)
PHANLPA_LP10 EQU (1<<5)
PHANLPA_LPIEEE4 EQU (1<<4)
PHANLPA_LPIEEE3 EQU (1<<3)
PHANLPA_LPIEEE2 EQU (1<<2)
PHANLPA_LPIEEE1 EQU (1<<1)
PHANLPA_LPIEEE0 EQU (1)
; PHANE bits ----------
PHANE_r15 EQU (1<<15)
PHANE_r14 EQU (1<<14)
PHANE_r13 EQU (1<<13)
PHANE_r12 EQU (1<<12)
PHANE_r11 EQU (1<<11)
PHANE_r10 EQU (1<<10)
PHANE_r9 EQU (1<<9)
PHANE_r8 EQU (1<<8)
PHANE_r7 EQU (1<<7)
PHANE_r6 EQU (1<<6)
PHANE_r5 EQU (1<<5)
PHANE_PDFLT EQU (1<<4)
PHANE_r3 EQU (1<<3)
PHANE_r2 EQU (1<<2)
PHANE_LPARCD EQU (1<<1)
PHANA_LPANABL EQU (1)
; PHCON2 bits ---------
PHCON2_r15 EQU (1<<15)
PHCON2_r14 EQU (1<<14)
PHCON2_EDPWRDN EQU (1<<13)
PHCON2_r12 EQU (1<<12)
PHCON2_EDTHRES EQU (1<<11)
PHCON2_r10 EQU (1<<10)
PHCON2_r9 EQU (1<<9)
PHCON2_r8 EQU (1<<8)
PHCON2_r7 EQU (1<<7)
PHCON2_r6 EQU (1<<6)
PHCON2_r5 EQU (1<<5)
PHCON2_r4 EQU (1<<4)
PHCON2_r3 EQU (1<<3)
PHCON2_FRCLNK EQU (1<<2)
PHCON2_EDSTAT EQU (1<<1)
PHCON2_r0 EQU (1)
; PHSTAT2 bits ---------
PHSTAT2_r15 EQU (1<<15)
PHSTAT2_r14 EQU (1<<14)
PHSTAT2_r13 EQU (1<<13)
PHSTAT2_r12 EQU (1<<12)
PHSTAT2_r11 EQU (1<<11)
PHSTAT2_r10 EQU (1<<10)
PHSTAT2_r9 EQU (1<<9)
PHSTAT2_r8 EQU (1<<8)
PHSTAT2_r7 EQU (1<<7)
PHSTAT2_r6 EQU (1<<6)
PHSTAT2_r5 EQU (1<<5)
PHSTAT2_PLRITY EQU (1<<4)
PHSTAT2_r3 EQU (1<<3)
PHSTAT2_r2 EQU (1<<2)
PHSTAT2_r1 EQU (1<<1)
PHSTAT2_r0 EQU (1)
; PHSTAT3 bits --------
PHSTAT3_r15 EQU (1<<15)
PHSTAT3_r14 EQU (1<<14)
PHSTAT3_r13 EQU (1<<13)
PHSTAT3_r12 EQU (1<<12)
PHSTAT3_r11 EQU (1<<11)
PHSTAT3_r10 EQU (1<<10)
PHSTAT3_r9 EQU (1<<9)
PHSTAT3_r8 EQU (1<<8)
PHSTAT3_r7 EQU (1<<7)
PHSTAT3_r6 EQU (1<<6)
PHSTAT3_r5 EQU (1<<5)
PHSTAT3_SPDDPX2 EQU (1<<4)
PHSTAT3_SPDDPX1 EQU (1<<3)
PHSTAT3_SPDDPX0 EQU (1<<2)
PHSTAT3_r1 EQU (1<<1)
PHSTAT3_r0 EQU (1)
;------------------------------ internal defaults ----------------------------------
;33.333Mhz clock out frequency
CLOCK_33_CLR EQU (ECON2_COCON3|ECON2_COCON2|ECON2_COCON1) ;clr mask
CLOCK_33_SET EQU (ECON2_COCON0) ;set mask
;25 MHz
CLOCK_25_CLR EQU (ECON2_COCON3|ECON2_COCON2|ECON2_COCON0) ;clr mask
CLOCK_25_SET EQU (ECON2_COCON1) ;set mask
;20 MHz
CLOCK_20_CLR EQU (ECON2_COCON3|ECON2_COCON2) ;clr mask
CLOCK_20_SET EQU (ECON2_COCON1|ECON2_COCON0) ;set mask
;16 MHz
CLOCK_16_CLR EQU (ECON2_COCON3|ECON2_COCON0|ECON2_COCON1) ;clr mask
CLOCK_16_SET EQU (ECON2_COCON2) ;set mask
;4 MHz (after reset)
CLOCK_4_CLR EQU (ECON2_COCON2) ;clr mask
CLOCK_4_SET EQU (ECON2_COCON3|ECON2_COCON0|ECON2_COCON1) ;set mask
CLOCK_DEF_CLR EQU CLOCK_33_CLR
CLOCK_DEF_SET EQU CLOCK_33_SET