Merge branch 'driverupdate' into 'master'

Driverupdate

See merge request MHeinrichs/Zorro-LAN-IDE!5
This commit is contained in:
Matthias Heinrichs
2020-09-13 21:20:39 +00:00
79 changed files with 2191 additions and 11702 deletions

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+12 -1
View File
@@ -17,7 +17,8 @@ Installation of the driver is straightforward.
Just copy the enc624j6net.device to devs:networks and enable Just copy the enc624j6net.device to devs:networks and enable
the interface in your favorite TCP/IP stack as usual. There is a version the interface in your favorite TCP/IP stack as usual. There is a version
for MC68020 or later (enc624j6net.device) and another version for for MC68020 or later (enc624j6net.device) and another version for
68000 (enc624j6net.device_68000). Choose the right one. 68000 (enc624j6net.device_68000). Choose the right one. Please rename
the 68000/68010 version to enc624j6net.device before use.
So far, successful tests have been done with the free AmiTCP/IP 3.0b2, So far, successful tests have been done with the free AmiTCP/IP 3.0b2,
AmiTCP4.0-4.2, Genesis, MiamiDX and RoadShow. AmiTCP4.0-4.2, Genesis, MiamiDX and RoadShow.
@@ -66,11 +67,21 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
Changelog: Changelog:
---------- ----------
2.9 - better support for Envoy: automatically select a higher
task priority in presence of Envoy services
2.8 - some workarounds for Fusion
2.7 - fixed MuForce hit
2.4 - added second semaphore, specifically for the write list 2.4 - added second semaphore, specifically for the write list
- recompiled using GCC 2.95 for slightly smaller binary - recompiled using GCC 2.95 for slightly smaller binary
- avoid full ethernet chip reset on startup when the - avoid full ethernet chip reset on startup when the
registers seem to be in a sane state (faster init, especially registers seem to be in a sane state (faster init, especially
with DHCP) with DHCP)
- additional checks for properly built hardware:
verify data bus bits before accepting card by
a simple short mem test
2.3 - implemented fine grained multicast filter hashes 2.3 - implemented fine grained multicast filter hashes
+14 -1
View File
@@ -188,7 +188,20 @@ TIMER/K/N,MULTICAST/S
Changelog: Changelog:
---------- ----------
2.00 - parse Vampire 4 UUID for MAC auto-assignment 2.8 - some workarounds for Fusion
2.7 - fixed Enforcer hit
2.6 - more sanity checks to avoid a hanging driver in situations
where the chip communication fails (i.e. with ENC28J60
resetting itself or losing power)
2.5 - added support for larger V1200 flash type (for UUID)
- better test for Vampire V4 standalone
2.4 - version bump (aligned with other hardware targets)
2.0 - parse Vampire 4 UUID for MAC auto-assignment
- version bump - version bump
1.99 - re-enabled 32 Bit Buffer copies (unless Miami is active) 1.99 - re-enabled 32 Bit Buffer copies (unless Miami is active)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5 -5
View File
@@ -19,7 +19,7 @@
# #
############################################################################### ###############################################################################
# debug = 1 will include string debugging for terminal/sushi/sashimi # debug = 1 will include string debugging for terminal/sushi/sashimi
debug = 1 debug = 0
# compiler_vcc = 1 will trigger VBCC, else GCC # compiler_vcc = 1 will trigger VBCC, else GCC
compiler_vcc = 0 compiler_vcc = 0
@@ -27,8 +27,8 @@ compiler_vcc = 0
# prefix for system includes (ASM) # prefix for system includes (ASM)
# native AmigaOS compilation: set PREFX=GG: or PREFX=ADE:, depending on toolchain # native AmigaOS compilation: set PREFX=GG: or PREFX=ADE:, depending on toolchain
############################################################################### ###############################################################################
PREFX = /opt/amigaos-68k/ #PREFX = /opt/amigaos-68k/
#PREFX = gg: PREFX = gg:
SYSINC = $(PREFX)os-include SYSINC = $(PREFX)os-include
############################################################################### ###############################################################################
@@ -48,6 +48,7 @@ CFLAGS2 = -Os -+ -sc -c99 -cpu=$(CPU2)
VASMFORMAT = -m$(CPU) -Fhunk -nowarn=2064 -quiet -I$(SYSINC) VASMFORMAT = -m$(CPU) -Fhunk -nowarn=2064 -quiet -I$(SYSINC)
VASMFORMAT2 = -m$(CPU2) -Fhunk -nowarn=2064 -quiet -I$(SYSINC) VASMFORMAT2 = -m$(CPU2) -Fhunk -nowarn=2064 -quiet -I$(SYSINC)
else else
# GCC # GCC
@@ -59,7 +60,6 @@ CFLAGS = -Os -s -m$(CPU) -Wall -noixemul -mregparm=4 -fomit-frame-pointer -msof
CFLAGS2 = -Os -s -m$(CPU2) -Wall -noixemul -mregparm=4 -fomit-frame-pointer -msoft-float -noixemul CFLAGS2 = -Os -s -m$(CPU2) -Wall -noixemul -mregparm=4 -fomit-frame-pointer -msoft-float -noixemul
VASMFORMAT = -m$(CPU) -Faout -nowarn=2064 -quiet -I$(SYSINC) VASMFORMAT = -m$(CPU) -Faout -nowarn=2064 -quiet -I$(SYSINC)
VASMFORMAT2 = -m$(CPU2) -Faout -nowarn=2064 -quiet -I$(SYSINC) VASMFORMAT2 = -m$(CPU2) -Faout -nowarn=2064 -quiet -I$(SYSINC)
endif endif
VASM = vasmm68k_mot VASM = vasmm68k_mot
@@ -137,7 +137,7 @@ endif
ifeq ($(debug),1) ifeq ($(debug),1)
CFLAGS += -DDEBUG -g CFLAGS += -DDEBUG -g
CFLAGS2 += -DDEBUG -g CFLAGS2 += -DDEBUG -g
LINKLIBS = -L$(PREFX)/lib -ldebug #LINKLIBS = -L$(PREFX)/lib -ldebug
endif endif
############################################################################### ###############################################################################
+6 -6
View File
@@ -33,15 +33,15 @@ SUBDIR=sdnet
# two flavours of the same code base may be build with this setup # two flavours of the same code base may be build with this setup
# leave DEVICEID2 empty to disable second build # leave DEVICEID2 empty to disable second build
DEVICEID=sdnet.device DEVICEID=sdnet.device
DEFINES = # -DPROTO_V2EXPNET DEFINES = -DALLREADREQS=1 # -DPROTO_V2EXPNET
ASMDEFS = # -DPROTO_V2EXPNET ASMDEFS = -DALLREADREQS=1 # -DPROTO_V2EXPNET
CPU = 68020 CPU = 68060
TESTTOOL = sdnettest TESTTOOL = sdnettest
DEVICEID2=v2expeth.device DEVICEID2=v2expeth.device
DEFINES2 = -DPROTO_V2EXPNET DEFINES2 = -DPROTO_V2EXPNET -DALLREADREQS=1
ASMDEFS2 = -DPROTO_V2EXPNET ASMDEFS2 = -DPROTO_V2EXPNET -DALLREADREQS=1
CPU2 = 68020 CPU2 = 68060
TESTTOOL2 = v2expethtest TESTTOOL2 = v2expethtest
# additional housekeeping # additional housekeeping
+3
View File
@@ -27,6 +27,7 @@
#define SAVEDS __saveds #define SAVEDS __saveds
#define STRUCTOFFSET OFFSET /* exec/initializers.h */ #define STRUCTOFFSET OFFSET /* exec/initializers.h */
#define INLINE __inline static #define INLINE __inline static
#define STDARGS __stdargs
#else /* __SASC */ #else /* __SASC */
@@ -39,6 +40,7 @@
#define SAVEDS #define SAVEDS
#define STRUCTOFFSET OFFSET /* exec/initializers.h */ #define STRUCTOFFSET OFFSET /* exec/initializers.h */
#define INLINE static inline #define INLINE static inline
#define STDARGS __stdargs
#else /* __GNUC__ */ #else /* __GNUC__ */
@@ -52,6 +54,7 @@
#include <stddef.h> #include <stddef.h>
/* sorry, I ran into some issues inlining stuff with VBCC, disabling it */ /* sorry, I ran into some issues inlining stuff with VBCC, disabling it */
#define INLINE #define INLINE
#define STDARGS __stdargs
#else /* __VBCC__ */ #else /* __VBCC__ */
+2 -1
View File
@@ -11,7 +11,8 @@
#define _INC_DEBUG_H #define _INC_DEBUG_H
#ifdef DEBUG #ifdef DEBUG
extern void KPrintF(char *, ...), KGetChar(void); extern void STDARGS KPrintF(char *, ...);
extern void KGetChar(void);
#define D(_x_) do { KPrintF("%s:%ld:",__FILE__,__LINE__); KPrintF _x_; } while(0) #define D(_x_) do { KPrintF("%s:%ld:",__FILE__,__LINE__); KPrintF _x_; } while(0)
+6 -5
View File
@@ -18,9 +18,10 @@ _LVORawMayGetChar equ -$1fe
; ;
; ;
; ;
ifd DEBUG ifne DEBUG
XREF _KPrintF ; XREF _KPrintFa0a1
; XREF _KPrintF
WRITEDEBUG macro WRITEDEBUG macro
movem.l d0/d1/a0/a1,-(sp) movem.l d0/d1/a0/a1,-(sp)
@@ -50,7 +51,7 @@ WRITEDEBUG macro
endif endif
lea.l (\1),a0 lea.l (\1),a0
move.l sp,a1 move.l sp,a1
jsr _KPrintF jsr _KPrintFa0a1
ifnb \2 ifnb \2
add.l #4,sp add.l #4,sp
endif endif
@@ -79,7 +80,7 @@ WRITEDEBUG macro
endm endm
else else
WRITEDEBUG macro WRITEDEBUG macro
nop ;
endm endm
endc endc
@@ -116,7 +117,7 @@ WRITEOUT macro
ifd DEBUG ifd DEBUG
move.l \1,a0 move.l \1,a0
move.l sp,a1 move.l sp,a1
jsr _KPrintF jsr _KPrintFa0a1
endif endif
move.l \1,d1 move.l \1,d1
move.l sp,d2 move.l sp,d2
+74 -15
View File
@@ -32,11 +32,19 @@
#ifdef HAVE_VERSION_H #ifdef HAVE_VERSION_H
#include "version.h" #include "version.h"
#endif #endif
#ifndef NO_WR_SEM
#define WRSEM du_WrSem
#else
#define WRSEM du_Sem
#endif
/* NSD support is optional */ /* NSD support is optional */
#ifdef NEWSTYLE #ifdef NEWSTYLE
#include <devices/newstyle.h> #include <devices/newstyle.h>
#include <devices/sana2devqueryext.h> /* new extension, code can be built without this include (but also without ext query then...) */ #include <devices/sana2devqueryext.h> /* new extension, code can be built without this include (but also without ext query then...) */
const UWORD dev_supportedcmds[] = { const UWORD dev_supportedcmds[] = {
NSCMD_DEVICEQUERY, NSCMD_DEVICEQUERY,
CMD_READ, CMD_READ,
@@ -90,8 +98,7 @@ const ULONG blub[6] = {
/* #define D2(x) D(x) */ /* #define D2(x) D(x) */
/* #define D4(x) D(x) */ /* #define D4(x) D(x) */
#define HIGHPRI 11
ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0), ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0),
@@ -102,6 +109,8 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
ULONG i; ULONG i;
LONG ok; LONG ok;
D(("DevInit()\n"));
p = ((UBYTE*)db) + sizeof(struct Library); p = ((UBYTE*)db) + sizeof(struct Library);
i = sizeof(DEVBASETYPE)-sizeof(struct Library); i = sizeof(DEVBASETYPE)-sizeof(struct Library);
while( i-- ) while( i-- )
@@ -120,7 +129,9 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
dbNewList( (struct List*)&db->db_Units[i].du_WriteQueue ); dbNewList( (struct List*)&db->db_Units[i].du_WriteQueue );
dbNewList( (struct List*)&db->db_Units[i].du_EventQueue ); dbNewList( (struct List*)&db->db_Units[i].du_EventQueue );
InitSemaphore( &db->db_Units[i].du_Sem ); InitSemaphore( &db->db_Units[i].du_Sem );
#ifndef NO_WR_SEM
InitSemaphore( &db->db_Units[i].du_WrSem ); InitSemaphore( &db->db_Units[i].du_WrSem );
#endif
db->db_Units[i].du_MTU = DEF_MTU; db->db_Units[i].du_MTU = DEF_MTU;
db->db_Units[i].du_BitPerSec = DEF_BPS; db->db_Units[i].du_BitPerSec = DEF_BPS;
} }
@@ -153,6 +164,8 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
D(("No DOS\n")); D(("No DOS\n"));
} }
D(("%ld Boards found\n",ok));
/* no hardware found, reject init */ /* no hardware found, reject init */
return (ok > 0) ? (struct Device*)db : (0); return (ok > 0) ? (struct Device*)db : (0);
} }
@@ -179,7 +192,10 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
ok = 1; ok = 1;
if( (db->db_Units[unit].du_OpenCount > 0) && if( (db->db_Units[unit].du_OpenCount > 0) &&
(flags & SANA2OPF_MINE) ) (flags & SANA2OPF_MINE) )
{
ok = 0; ok = 0;
D(("DevOpen fail: OpenCount is >0 and SANA2OPF_MINE requested."));
}
#if 0 #if 0
if( (db->db_Units[unit].du_OpenCount > 0) && if( (db->db_Units[unit].du_OpenCount > 0) &&
(flags & SANA2OPF_PROM) ) (flags & SANA2OPF_PROM) )
@@ -187,7 +203,10 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
#endif #endif
if( db->db_Units[unit].du_Flags & DUF_EXCLUSIVE ) if( db->db_Units[unit].du_Flags & DUF_EXCLUSIVE )
{
ok = 0; ok = 0;
D(("DevOpen fail: device was opened already with exclusive flag set."));
}
if( ok ) if( ok )
ok = hw_AllocBoard( db, unit ); ok = hw_AllocBoard( db, unit );
@@ -489,7 +508,7 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
LONG code; LONG code;
LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq ); LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
ObtainSemaphore(&db->db_Units[unit].du_WrSem); ObtainSemaphore(&db->db_Units[unit].WRSEM);
code = write_frame( db, unit, ioreq ); code = write_frame( db, unit, ioreq );
if( code >= 0 ) if( code >= 0 )
{ {
@@ -497,12 +516,12 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
ioreq->ios2_Req.io_Error = S2ERR_NO_ERROR; ioreq->ios2_Req.io_Error = S2ERR_NO_ERROR;
ioreq->ios2_WireError = S2WERR_GENERIC_ERROR; ioreq->ios2_WireError = S2WERR_GENERIC_ERROR;
} }
ReleaseSemaphore(&db->db_Units[unit].du_WrSem); ReleaseSemaphore(&db->db_Units[unit].WRSEM);
#else #else
ioreq->ios2_Req.io_Flags &= ~SANA2IOF_QUICK; ioreq->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ObtainSemaphore(&db->db_Units[unit].du_WrSem); ObtainSemaphore(&db->db_Units[unit].WRSEM);
ADDTAIL((struct List*)&db->db_Units[unit].du_WriteQueue,(struct Node*)ioreq); ADDTAIL((struct List*)&db->db_Units[unit].du_WriteQueue,(struct Node*)ioreq);
ReleaseSemaphore(&db->db_Units[unit].du_WrSem); ReleaseSemaphore(&db->db_Units[unit].WRSEM);
Signal( (struct Task*)db->db_ServerProc, SIGBREAKF_CTRL_F ); Signal( (struct Task*)db->db_ServerProc, SIGBREAKF_CTRL_F );
ioreq = (0); ioreq = (0);
#endif #endif
@@ -651,16 +670,23 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
ioreq = (0); ioreq = (0);
break; break;
#endif #endif
case CMD_FLUSH:
/* TODO: really remove all requests */
ioreq->ios2_Req.io_Error = S2ERR_NO_ERROR;
ioreq->ios2_WireError = S2WERR_GENERIC_ERROR;
break;
case CMD_RESET: case CMD_RESET:
case CMD_UPDATE: case CMD_UPDATE:
case CMD_CLEAR: case CMD_CLEAR:
case CMD_STOP: case CMD_STOP:
case CMD_START: case CMD_START:
case CMD_FLUSH:
ioreq->ios2_Req.io_Error = IOERR_NOCMD; ioreq->ios2_Req.io_Error = IOERR_NOCMD;
/* we might not get a SANA-II request at this point, don't assume anything about struct */ /* we might not get a SANA-II request at this point, don't assume anything about struct */
/* ioreq->ios2_WireError = S2WERR_GENERIC_ERROR; */ if( ioreq->ios2_Req.io_Message.mn_Length >= sizeof( struct IOSana2Req ) )
{
ioreq->ios2_WireError = S2WERR_GENERIC_ERROR;
}
break; break;
case S2_ADDMULTICASTADDRESS: case S2_ADDMULTICASTADDRESS:
@@ -697,6 +723,8 @@ ASM SAVEDS LONG DevAbortIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
ULONG unit = (ULONG)ioreq->ios2_Req.io_Unit; ULONG unit = (ULONG)ioreq->ios2_Req.io_Unit;
D2(("DevAbortIO unit %ld\n",unit));
ObtainSemaphore(&db->db_Units[unit].du_Sem); ObtainSemaphore(&db->db_Units[unit].du_Sem);
/* start with the read list -> types -> readers -> reqlist */ /* start with the read list -> types -> readers -> reqlist */
@@ -778,31 +806,57 @@ static LONG dbIsInList( struct List *l, struct Node *entry )
return 0; return 0;
} }
/* Workaround for Envoy: assign higher priority to server task */
LONG Need_HighPri( DEVBASEP )
{
/* don't bother if we are at HIGHPRI already */
if( db->db_ServerProc )
{
if( ((struct Task*)db->db_ServerProc)->tc_Node.ln_Pri >= HIGHPRI )
return 0;
}
if( FindPort("Services Manager") )
return 1;
if( FindPort("Accounts Manager") )
return 1;
return 0;
}
/* start Server function and keep it up */ /* start Server function and keep it up */
/* note: server is global right now */ /* note: server is global right now */
static LONG dbStartServer( DEVBASEP, LONG unit ) static LONG dbStartServer( DEVBASEP, LONG unit )
{ {
struct MsgPort *port; struct MsgPort *port;
LONG ret = 0,i; LONG ret = 0,i,pri;
struct TagItem sv_tags[5]; struct TagItem sv_tags[5];
/* server running ? */ /* server running ? */
if( db->db_ServerProc ) if( db->db_ServerProc )
{
if( Need_HighPri( db ) )
SetTaskPri((struct Task*)db->db_ServerProc,HIGHPRI);
return 1; return 1;
}
if(!(port = CreateMsgPort() )) if(!(port = CreateMsgPort() ))
return 0; return 0;
pri = 0;
if( Need_HighPri( db ) )
pri = HIGHPRI;
else
if( FindPort("AMITCP") ) /* AmiTCP active ? */
pri = 6;
sv_tags[i=0].ti_Tag = NP_Entry; sv_tags[i=0].ti_Tag = NP_Entry;
sv_tags[i++].ti_Data = (ULONG)ServerTask; sv_tags[i++].ti_Data = (ULONG)ServerTask;
sv_tags[i ].ti_Tag = NP_Name; sv_tags[i ].ti_Tag = NP_Name;
sv_tags[i++].ti_Data = (ULONG)db->db_Lib.lib_Node.ln_Name; sv_tags[i++].ti_Data = (ULONG)db->db_Lib.lib_Node.ln_Name;
sv_tags[i ].ti_Tag = NP_Priority; sv_tags[i ].ti_Tag = NP_Priority;
if( FindPort("AMITCP") ) /* AmiTCP active ? */ sv_tags[i++].ti_Data = (ULONG)pri;
sv_tags[i++].ti_Data = (ULONG)6;
else
sv_tags[i++].ti_Data = (ULONG)0;
sv_tags[i ].ti_Tag = TAG_DONE; sv_tags[i ].ti_Tag = TAG_DONE;
if( (db->db_ServerProc = CreateNewProc(sv_tags))) if( (db->db_ServerProc = CreateNewProc(sv_tags)))
@@ -810,6 +864,8 @@ static LONG dbStartServer( DEVBASEP, LONG unit )
/* server is running, wait for response */ /* server is running, wait for response */
volatile struct ServerMsg msg; volatile struct ServerMsg msg;
D(("Server Started, waiting for Response\n"));
msg.sm_devbase = db; msg.sm_devbase = db;
msg.sm_result = 0; msg.sm_result = 0;
msg.sm_msg.mn_Length = sizeof(msg); msg.sm_msg.mn_Length = sizeof(msg);
@@ -928,6 +984,7 @@ havetype:
if( !(rd = dbAddReader(db,unit,frametype,type,ID ) )) if( !(rd = dbAddReader(db,unit,frametype,type,ID ) ))
return; /* bail out, no mem left */ return; /* bail out, no mem left */
havereader: havereader:
D(("dbAddReadReq type %ld to unit %ld ID %ld\n",frametype,unit,ID));
ADDTAIL( &rd->snr_Requests , (struct Node*)ioreq ); ADDTAIL( &rd->snr_Requests , (struct Node*)ioreq );
@@ -968,6 +1025,9 @@ static struct SanaReader *dbAddReader( DEVBASEP, ULONG unit, ULONG frametype, st
return (0); return (0);
rd->snr_ID = ID; rd->snr_ID = ID;
D(("dbAddReader %ld to unit %ld ID %ld\n",frametype,unit,ID));
dbNewList( &rd->snr_Requests ); dbNewList( &rd->snr_Requests );
if( (GetHead( &type->srt_Readers ) )) if( (GetHead( &type->srt_Readers ) ))
@@ -1002,9 +1062,8 @@ static void dbDeleteReader( DEVBASEP, ULONG unit, ULONG ID )
{ {
if( !(GetSucc(t2) )) if( !(GetSucc(t2) ))
t2->srt_Flags &= ~SRTF_MULTREADER; t2->srt_Flags &= ~SRTF_MULTREADER;
else t2->srt_Flags &= ~(SRTF_ONEREADER|SRTF_MULTREADER);
} }
else t2->srt_Flags &= ~(SRTF_ONEREADER|SRTF_MULTREADER);
break; break;
} }
rd = GetSucc(rd); rd = GetSucc(rd);
@@ -140,7 +140,7 @@ _LVOSignal EQU -324
;machine 68020 ;machine 68020
section code,code ;section code,code
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; | | ; | |
Binary file not shown.
+3 -2
View File
@@ -239,8 +239,9 @@ ASM SAVEDS int enc624j6l_SetOnline( ASMR(a0) void *board ASMREG(a0) );
>=0 - OK >=0 - OK
*/ */
ASM SAVEDS int enc624j6l_bc_mc_filter( ASM SAVEDS int enc624j6l_bc_mc_filter(
ASMR(a0) void *board ASMREG(a0), ASMR(a0) void *board ASMREG(a0),
ASMR(d1) unsigned long flags ASMREG(d1) ); ASMR(d1) unsigned long flags ASMREG(d1),
ASMR(a1) unsigned short *mc_hashes ASMREG(a1));
/* /*
+166 -9
View File
@@ -30,6 +30,7 @@ extern const BYTE DeviceName[];
/* use generic board fields in current unit */ /* use generic board fields in current unit */
#define duh_online du_hwl0 #define duh_online du_hwl0
#define duh_BASE du_hwp0 #define duh_BASE du_hwp0
#define duh_RefCount du_hwl1
#define HW_INTERVALDEF 100000L #define HW_INTERVALDEF 100000L
@@ -105,7 +106,7 @@ ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
/* bring board to sane state (i.e. perform soft reset) */ /* bring board to sane state (i.e. perform soft reset) */
/* if( boardbase < (APTR)0x40000000 ) */ /* debug only */ /* if( boardbase < (APTR)0x40000000 ) */ /* debug only */
enc624j6l_CheckBoard( boardbase ); enc624j6l_CheckBoard( boardbase );
} }
ret = i; ret = i;
D(("%ld boards found\n",ret)); D(("%ld boards found\n",ret));
@@ -119,7 +120,33 @@ ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0), ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) ) ASMR(d0) ULONG unit ASMREG(d0) )
{ {
/* is there a way to lock a ZII Board ? */ #if 0
LONG i;
struct ConfigDev *cfg = (0);
if( unit > db->db_NBoards )
return 0;
for( i=0 ; i < db->db_NBoards ; i++ )
{
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
if( !cfg )
return 0;
if( (APTR)cfg->cd_BoardAddr == db->db_Units[unit].duh_BASE )
break;
}
if( (APTR)cfg->cd_BoardAddr != db->db_Units[unit].duh_BASE )
return 0;
if( db->db_Units[unit].duh_RefCount == 0 )
{
ObtainConfigBinding();
ReleaseConfigBinding();
}
db->db_Units[unit].duh_RefCount++;
#endif
return 1; return 1;
} }
@@ -127,6 +154,20 @@ ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0), ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) ) ASMR(d0) ULONG unit ASMREG(d0) )
{ {
#if 0
if( unit > db->db_NBoards )
return 0;
for( i=0 ; i < db->db_NBoards ; i++ )
{
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
if( !cfg )
return 0;
if( (APTR)cfg->cd_BoardAddr == db->db_Units[unit].duh_BASE )
break;
}
#endif
return 1; return 1;
} }
@@ -427,27 +468,143 @@ ASM SAVEDS LONG hw_write_phy( ASMR(a0) DEVBASEP ASMREG(
return enc624j6l_WritePHY( boardbase, reg, value ); return enc624j6l_WritePHY( boardbase, reg, value );
} }
/*
calculate CRC32 for MAC address hashing
slow but relatively short (and can be adapted to other
polynoms easily)
*/
ASM ULONG myhw_CRC32( ASMR(a0) UBYTE *buffer ASMREG(a0),
ASMR(d0) ULONG nbytes ASMREG(d0) )
{
UWORD i,j;
ULONG t,crc = 0xffffffff;
ULONG poly = 0x04c11db7;
for( j = 0 ; j < nbytes ; j++ )
{
for( i = 0 ; i < 8 ; i++ )
{
t = crc>>31;
crc <<= 1;
if( ( t ^ ( buffer[j] >> i ) ) & 0x01 )
crc ^= poly;
}
}
return crc;
}
#if 0
ASM ULONG CMPgeMAC( ASMR(a0) UBYTE *cur ASMREG(a0),
ASMR(a1) UBYTE *cmp ASMREG(a1) )
{
USHORT i;
ULONG res = 1;
for( i = 0 ; i < 6 ; i++ )
{
if( cur[i] > cmp[i] )
break;
if( cur[i] < cmp[i] )
{
res = 0;
break;
}
}
return res;
}
#endif
ASM ULONG CMPleMAC( ASMR(a0) UBYTE *cur ASMREG(a0),
ASMR(a1) UBYTE *cmp ASMREG(a1) )
{
USHORT i;
ULONG res = 1;
for( i = 0 ; i < 6 ; i++ )
{
if( cur[i] < cmp[i] )
break;
if( cur[i] > cmp[i] )
{
res = 0;
break;
}
}
return res;
}
ASM void INCMAC( ASMR(a0) UBYTE *curmc ASMREG(a0) )
{
SHORT i;
for( i=5 ; i >= 0 ; i-- )
{
curmc[i]++;
if( curmc[i] != 0 )
{
break;
}
}
}
/* TODO: implement Multicast hashing */
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0), ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0), ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) struct List *mcastlist ASMREG(a1) ) ASMR(a1) struct List *mcastlist ASMREG(a1) )
{ {
/* TODO: implement Multicast hashing */ APTR boardbase = db->db_Units[unit].duh_BASE;
APTR boardbase = db->db_Units[unit].duh_BASE; struct HWData *hwd = &db->db_hwdat;
ULONG flags; ULONG flags;
ULONG crc,curhash;
USHORT mc_hashes[4] = {0,0,0,0}; /* EHT1, EHT2, EHT3, EHT4 */
USHORT *hash_tab;
struct MCastEntry *mc;
UBYTE *curmc;
flags = PIO_INIT_BROAD_CAST; flags = PIO_INIT_BROAD_CAST;
if( db->db_Units[0].du_Flags & DUF_PROMISC ) if( db->db_Units[0].du_Flags & DUF_PROMISC )
flags |= PIO_INIT_PROMISC; flags |= PIO_INIT_PROMISC;
/* list non-empty ? (kludge right now, can be done more fine grained) */ if( hwd->multicast ) /* accept ALL multicast ? (config option) */
if( mcastlist->lh_Head->ln_Succ )
flags |= PIO_INIT_MULTI_CAST; flags |= PIO_INIT_MULTI_CAST;
enc624j6l_bc_mc_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */ /* list non-empty ? */
hash_tab = NULL;
if( mcastlist->lh_Head->ln_Succ )
{
/* flags |= PIO_INIT_MULTI_CAST; */ /* see above */
hash_tab = mc_hashes;
for( mc = (struct MCastEntry *)mcastlist->lh_Head;
mc->mce_Node.mln_Succ ;
mc=(struct MCastEntry*)mc->mce_Node.mln_Succ )
{
curmc = mc->mce_start;
while( CMPleMAC( curmc, mc->mce_stop ) )
{
D(("CMPleMAC %ld %02lx%02lx%02lx%02lx%02lx%02lx - %02lx%02lx%02lx%02lx%02lx%02lx\n",\
CMPleMAC( curmc, mc->mce_stop ),\
(ULONG)curmc[0],(ULONG)curmc[1],\
(ULONG)curmc[2],(ULONG)curmc[3],\
(ULONG)curmc[4],(ULONG)curmc[5],\
(ULONG)mc->mce_stop[0],(ULONG)mc->mce_stop[1],\
(ULONG)mc->mce_stop[2],(ULONG)mc->mce_stop[3],\
(ULONG)mc->mce_stop[4],(ULONG)mc->mce_stop[5] \
));
crc = myhw_CRC32( mc->mce_start, 6 );
curhash = (crc & 0x1f800000)>>23; /* 2 bit reg, 4 bit hash pos in reg */
mc_hashes[ ((curhash >> 4)&3) ] |= 1<<(curhash&0xf);
INCMAC( curmc );
}
}
}
D(("hw_change_multicast board %lx flags %lx hashtab %lx\n",(ULONG)boardbase,(ULONG)flags,(ULONG)hash_tab));
enc624j6l_bc_mc_filter(boardbase, flags, hash_tab );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
return 1; return 1;
} }
@@ -494,7 +651,7 @@ void myhw_ControlInterrupts( DEVBASEP )
hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List; hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List;
hwd->hwd_Interrupt.is_Data = &hwd->hwd_act_boards[0]; 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_Type = NT_INTERRUPT;
hwd->hwd_Interrupt.is_Node.ln_Pri = 51; hwd->hwd_Interrupt.is_Node.ln_Pri = 126; /* 51; */
hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname; hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname;
AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt ); AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
} }
Binary file not shown.
+8 -1
View File
@@ -17,10 +17,17 @@ _LVORawMayGetChar equ -$1fe
endc endc
XDEF _KPrintF XDEF _KPrintF
XDEF _KPrintFa0a1
_KPrintF:
; rts
move.l 4(sp),a0
lea 8(sp),a1
; fall through
;A0 = format ;A0 = format
;A1 = arguments ;A1 = arguments
_KPrintF: _KPrintFa0a1:
; ifd DEBUG ; ifd DEBUG
movem.l d0-d2/a0-a3/a6,-(sp) movem.l d0-d2/a0-a3/a6,-(sp)
+12
View File
@@ -710,6 +710,12 @@ int main(int argc, char **argv)
} }
} }
/* out of curiosity: get MAC address */
prg->sana2devio->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
prg->sana2devio->ios2_Data = (0);
prg->sana2devio->ios2_DataLength = 0;
DoIO( (struct IORequest *)prg->sana2devio );
Printf("Device: %s\n",(ULONG)name); Printf("Device: %s\n",(ULONG)name);
/* general info */ /* general info */
if( parm_vendorname.Actual != 0 ) if( parm_vendorname.Actual != 0 )
@@ -722,6 +728,12 @@ int main(int argc, char **argv)
productname[parm_productname.Actual-1] = 0; productname[parm_productname.Actual-1] = 0;
Printf("Product: %s\n",(ULONG)productname); Printf("Product: %s\n",(ULONG)productname);
} }
/* MAC address */
{
unsigned char*p = (unsigned char*)prg->sana2devio->ios2_SrcAddr;
Printf("MAC: %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
(ULONG)p[0],(ULONG)p[1],(ULONG)p[2],(ULONG)p[3],(ULONG)p[4],(ULONG)p[5] );
}
/* after query, see what we've got */ /* after query, see what we've got */
if( res == RETURN_OK ) if( res == RETURN_OK )
+32 -5
View File
@@ -55,6 +55,11 @@
/* (note: maximum ethernet frame length would be 1518 when VLAN tagging is unused) */ /* (note: maximum ethernet frame length would be 1518 when VLAN tagging is unused) */
#define MAX_FRAMELEN 1518 #define MAX_FRAMELEN 1518
/* perform sanity checks if more this amount of "idle" calls to have_recv()
are noted (idle=nothing received)
*/
#define SANITY_CHECK_INTERVAL 32
static u16 gNextPacketPtr; static u16 gNextPacketPtr;
static u08 is_full_duplex; static u08 is_full_duplex;
static u08 rev; static u08 rev;
@@ -118,20 +123,39 @@ static void writeReg(uint8_t address, uint16_t data)
/* /*
the PHY registers require special care the PHY registers require special care
*/ */
static uint16_t readPhyByte (uint8_t address) { static uint16_t readPhyByte (uint8_t address)
{
long wtime = 0xffff;
writeRegByte(MIREGADR, address); writeRegByte(MIREGADR, address);
writeRegByte(MICMD, MICMD_MIIRD); writeRegByte(MICMD, MICMD_MIIRD);
while (readRegByte(MISTAT) & MISTAT_BUSY) while (readRegByte(MISTAT) & MISTAT_BUSY)
; {
if( (--wtime) <= 0 )
{
writeRegByte(MICMD, 0x00);
initvars.have_recv = SANITY_CHECK_INTERVAL+1;
return 0xffff;
}
}
writeRegByte(MICMD, 0x00); writeRegByte(MICMD, 0x00);
return readRegByte(MIRD+1); return readRegByte(MIRD+1);
} }
static void writePhy (uint8_t address, uint16_t data) { static void writePhy (uint8_t address, uint16_t data)
{
long wtime = 0xffff;
writeRegByte(MIREGADR, address); writeRegByte(MIREGADR, address);
writeReg(MIWR, data); writeReg(MIWR, data);
while (readRegByte(MISTAT) & MISTAT_BUSY) while (readRegByte(MISTAT) & MISTAT_BUSY)
; {
if( (--wtime) <= 0 )
{
initvars.have_recv = SANITY_CHECK_INTERVAL+1;
break;
}
}
} }
/* just a pass-through to the lowlevel routines */ /* just a pass-through to the lowlevel routines */
@@ -460,6 +484,7 @@ u08 enc28j60_send(const u08 *data, u16 size)
we would overwrite a frame still being sent out we would overwrite a frame still being sent out
-> wait first, then fill buffer -> wait first, then fill buffer
*/ */
long maxwait = 0x1ffff; /* wait patiently */
while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS) while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS)
{ {
/* errata sheet issue 12 -> TXRTS never becomes 0 */ /* errata sheet issue 12 -> TXRTS never becomes 0 */
@@ -469,6 +494,8 @@ u08 enc28j60_send(const u08 *data, u16 size)
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
} }
if( !(--maxwait) )
return PIO_OK; /* waited long enough: drop frame */
} }
/* write buffer */ /* write buffer */
@@ -591,7 +618,7 @@ u08 enc28j60_has_recv(void)
if( !ret ) if( !ret )
{ {
initvars.have_recv++; initvars.have_recv++;
if( initvars.have_recv > 10 ) if( initvars.have_recv > SANITY_CHECK_INTERVAL )
{ {
/* check for bad config vars and reset hw if that is the case */ /* check for bad config vars and reset hw if that is the case */
if( !enc28j60_check_config( &initvars ) ) if( !enc28j60_check_config( &initvars ) )
Binary file not shown.
+18
View File
@@ -428,6 +428,24 @@ ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(
} }
/* read PHY register */
ASM SAVEDS LONG hw_read_phy( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(d1) ULONG reg ASMREG(d1) )
{
return -1;
}
/* write PHY register (return -1 in case of error) */
ASM SAVEDS LONG hw_write_phy( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(d1) ULONG reg ASMREG(d1),
ASMR(d2) ULONG value ASMREG(d2) )
{
return -1;
}
/* process the list of multicast addresses for an appropriate /* process the list of multicast addresses for an appropriate
filtering list on the hardware filtering list on the hardware
Binary file not shown.
Binary file not shown.
+679
View File
@@ -0,0 +1,679 @@
/*
test program for SDNet
author: Henryk Richter <henryk.richter@gmx.net>
Runs a number of essential operations on ENC28J60
modules connected to the SD slot of Vampire V2
(500/600) cards.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <clib/macros.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "enc28j60.h"
#include "enc28j60l.h" /* import lowlevel asm functions */
/* #include "crc32.h" */
#include "vampuuid.h"
/*#define __NOLIBBASE__*/
#include <proto/vampire.h>
#include <vampire/vampire.h>
#define INVALID_SDNET_UNIT 0x33
/* delay after changing SPI speed in us */
#define SPEED_DELAY 120
struct Library *VampireBase;
/* */
/*u08 myprog = "sdnettest";*/
/* OUI = Commodore :-) */
u08 macaddr[6] = { 0x00,0x80,0x10,0x0b,0x0a,0xff };
#if 1
#define testlen 300
/* issue a DHCP request to increase the likelihood of received frames throughout the test */
u08 testframe[testlen] = {
/* Ethernet(14) */
0xff,0xff,0xff,0xff,0xff,0xff, /* broadcast */
0x00,0x80,0x10,0x0b,0x0a,0xff, /* own MAC */
0x08,0x00, /* Type IPv4 */
/* IPv4(20) */
/* IPv4 */
0x45,0x00, /* VER/IHL, DSCP */
0x01,0x1e, /* was 0d */ /* length 273 = 245+20 */
0xA0,0x0A, /* id */
0x00,0x00, /* flags, fragment offset */
0xff, /* TTL (255 for DHCP) */
0x11, /* UDP */
0x00,0x00, /* header checksum */
0,0,0,0, /* SRC IP */
255,255,255,255,/* dest IP */
/* UDP(8) */
/* UDP */
0x00,0x44, /* src port 68 */
0x00,0x43, /* dest port 67 */
0x01,0x0a, /* length including UDP header FIXME: CHANGE when payload changes */
0x00,0x00, /* checksum */
/* BOOTP(245) */
/* BOOTP/DHCP */
0x01, /* BOOT Request */
0x01, /* HW Type Ethernet */
0x06, /* HW Address length */
0x00, /* hops */
0xde,0xad,0xbe,0xef, /* transaction ID */
0x00,0x02, /* seconds elapsed */
/* mandatory bootp stuff */
0x00,0x00, /* flags */
0x00,0x00,0x00,0x00, /* client IP */
0x00,0x00,0x00,0x00, /* next server IP */
0x00,0x00,0x00,0x00, /* relay agent IP */
0x00,0x00,0x00,0x00, /* some more stuff */
0x00,0x80,0x10,0x0b,0x0a,0xff, /* own MAC */
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, /* 10 bytes padding */
/* server name (64x0) */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* boot file name (128x0) */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* DHCP magic cookie */
0x63,0x82,0x53,0x63,
/* DHCP options */
0x35,0x01,0x01, /* DHCP discover */
0x37,0x04,0x01,0x03,0x06,0x0f, /* we want mask,router,DNS,Domain Name */
0x3d,0x06, /* client identifier (3c would be vendor class) */
0,
's','d','n','e','t',
0xff, /* end */
/* padding */
/* 0x00,0x00,0x00 */
};
#else
#define testlen 98
u08 testframe[testlen] = {
0xff,0xff,0xff,0xff,0xff,0xff, /* broadcast */
0x00,0x80,0x10,0x0b,0x0a,0xff, /* own MAC */
0x08,0x00, /* Type IPv4 */
/* */
0x45,0x00, /* VER, DSCP */
0x00,0x54, /* length */
0xA0,0x0A, /* id */
0x00,0x00, /* flags, fragment offset */
0x40, /* TTL */
0x01, /* ICMP */
0x00,0x00, /* header checksum */
192,168,10,11, /* SRC IP */
192,168,10,255,/* dest IP */
/* */
0x08,0x00, /* Type, Code = ICMP Echo */
0x00,0x00, /* Checksum */
0xDE,0xAD, /* Identifier */
0x00,0x01, /* SeqNum */
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
}; /* 98 Bytes */
#endif
unsigned char recvbuf[1530];
ULONG vres = (ULONG)-1;
ULONG doquit = 0;
u16 ip_checksum( u08 *, LONG );
u16 udp_checksum( u08 *, LONG );
/* SAS/C abort override */
int CXBRK(void )
{
/* doquit = 1; */
return 0;
}
void __regargs __chkabort(void);
void __regargs __chkabort(void)
{
if( SetSignal( 0, SIGBREAKF_CTRL_C ) & SIGBREAKF_CTRL_C )
{
doquit = 1;
printf("got ctrl-c\n");
}
}
/*
global cleanup
*/
void cleanup(void)
{
if( VampireBase )
V_FreeExpansionPort( vres );
printf("cleaning up\n");
}
/*
communications test: try different clock dividers and poll revision
*/
ULONG sdnt_commtest( void )
{
ULONG ret = 0; /* def: fail */
int speed = 10; /* try different SPI clock dividers */
int wait;
u08 rev,rdy=0;
/* soft reset cpu */
enc28j60_SetSPISpeed( (ULONG)speed );
enc28j60l_UMinDelay( SPEED_DELAY ); /* wait a little, */
enc28j60l_WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
/* enc28j60l_WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
enc28j60l_WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
enc28j60l_WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);*/
enc28j60l_UMinDelay( 4000 ); /* wait 4ms */
wait = 0xfff;
while( wait-- > 0 )
{
rdy = ESTAT_CLKRDY & enc28j60l_ReadOp(ENC28J60_READ_CTRL_REG, ESTAT );
if( rdy )
wait = 0;
}
enc28j60l_UMinDelay( 20 ); /* wait a little, */
if( !rdy )
{
printf("Fail. Chip doesn`t respond ready.\n");
}
else
{
rdy = enc28j60l_ReadRegByte(EREVID);
if( rdy > 5 ) rdy++;
}
while( speed >= 0 )
{
enc28j60_SetSPISpeed( (ULONG)speed );
enc28j60l_UMinDelay( SPEED_DELAY ); /* wait a little, */
enc28j60l_ReadRegByte(EREVID);
rev = enc28j60l_ReadRegByte(EREVID);
if( rev > 5 ) rev++;
if( rdy ) /* best case: chip reported "ready" */
{
if( rev != rdy )
{
if( speed >= 2 )
printf("Fail. Different revision register reported by chip (%d vs %d at speed %d)\n",rdy,rev,speed);
else
printf("Note. Speed %d does not work properly with your card (but that was expected)\n",speed);
}
else
{
printf("Ok. Revision %d reported at speed %d\n",rev,speed);
ret |= (1<<speed);
}
}
else /* chip was not "ready" but we`re stubborn */
{
if( (rev > 0) && (rev < 0x10 ) )
{
printf("OK. got Chip rev %d at speed %d\n",rev,speed);
ret |= (1<<speed);
}
else
printf("Fail. Cannot read chip rev at speed %d\n",speed);
}
speed--;
}
if( !ret )
{
printf("Fail. No response from revision command,\n");
printf(" Check ENC28J60 power supply and cabling.\n");
}
else printf("Ok. Speed success mask %x\n",ret );
return ret;
}
/*
communications test: try different clock dividers and copy memory forth and back
input: bit mask of clock dividers to test (between 0 and 31)
*/
#define TXSTART_INIT 0x1A00 /* start of TX buffer, room for 1 packet */
#define TXSTOP_INIT 0x1FFF /* end of TX buffer */
ULONG sdnt_memtest( ULONG speeds, ULONG testsize )
{
u08 *membuf;
int i,j,res;
membuf = AllocVec( testsize*2, MEMF_ANY );
if( !membuf )
{
printf("Fail. Cannot allocate %d Bytes Memory\n",testsize*2);
return 0;
}
/*
fill buffer with something nonzero
*/
for( i=0 ; i < testsize ; i++ )
{
membuf[i] = (u08)( i ^ 0x5a );
}
/* try different speeds */
for( i=31; i >= 0 ; i-- )
{
if( speeds & (1<<i) )
{
enc28j60_SetSPISpeed( (ULONG)i );
enc28j60l_ReadRegByte(EREVID); /* safety */
enc28j60l_UMinDelay( SPEED_DELAY ); /* wait 2 ms */
enc28j60l_ReadRegByte(EREVID);
enc28j60l_WriteBuffer(membuf,(int)testsize,TXSTART_INIT);
/* enc28j60l_WriteReg( ERXRDPT, TXSTART_INIT ); */
enc28j60l_WriteReg(ERDPT, TXSTART_INIT+1 );
enc28j60l_ReadBuffer( membuf + testsize, (int)testsize );
for( j=0, res=0 ; j < (testsize-1) ; j++ )
{
/*if( membuf[j] != membuf[j+testsize] )
printf("%d vs %d\n",membuf[j], membuf[j+testsize] );*/
res |= ( membuf[j] ^ membuf[j+testsize] );
}
if( res )
{
printf("Fail. Memory transfer failure at speed %d\n",i);
speeds &= ~(1<<i);
}
else
printf("Ok. Memory transfer success at speed %d\n",i);
}
}
FreeVec( membuf );
if( !speeds )
{
printf("Fail. Memory transfer test failed. Couldn`t transfer data successfully.\n");
printf(" Check ENC28J60 power supply and cabling.\n");
}
else printf("Ok. Speed success mask %x\n",speeds );
return speeds;
}
#define TEST_MAC (1<<30)
#define TEST_LINK (1<<31)
#define TEST_TXERR (1<<29)
#define TEST_RXERR (1<<28)
#define TEST_HAVERX (1<<27)
int main( int argc, char **argv)
{
u08 res;
int runs;
int ret = 0;
#ifdef PROTO_V2EXPNET
ULONG portid = V_WIFIPORT;
#else
ULONG portid = V_SDPORT;
#endif
ULONG speeds; /* clock divider mask */
ULONG testres = 0; /* bit 31 is used for link status, bit 30 for correct MAC */
ULONG clockdiv;
printf("starting\n");
atexit( cleanup );
/*
verify vampire.resource presence
*/
if( VampireBase = OpenResource( V_VAMPIRENAME ) )
{
printf("Ok. vampire.resource present\n");
{
APTR allocator = V_AllocExpansionPort( portid, argv[0] );
if( allocator )
{
printf("Fail. Port seems to be allocated already by %s\n",allocator);
printf(" Please shut down your IP stack and try again.\n");
exit(1);
}
vres = portid;
printf("Ok. vampire.resource port %d allocated\n",vres);
}
}
else
{
printf("Fail. vampire.resource not found.\n");
printf(" Please install Vampire Gold 2.7 or later core,\n");
printf(" flash an updated ROM or\n");
printf(" loadmodule vampire.resource\n");
#ifdef PROTO_V2EXPNET
printf("Note. v2expeth.device will NOT work without the resource\n");
#else
printf("Note. sdnet.device will NOT work without the resource\n");
#endif
printf("I`ll continue the test without resource allocation...\n");
}
/*
communications test, try to read HW version
*/
speeds = sdnt_commtest();
if( !speeds )
{
printf("Exiting\n");
ret = 2;
goto end;
}
/*
transfer test from/to HW memory
*/
speeds = sdnt_memtest( speeds, 1536 );
if( !speeds )
{
ret = 3;
goto end;
}
/*
initialize Chip
*/
res = enc28j60_init( macaddr, PIO_INIT_MULTI_CAST|PIO_INIT_BROAD_CAST );
/* res = enc28j60_init( macaddr, PIO_INIT_PROMISC ); */
if( res != PIO_OK )
{
printf("init error %d\n",res);
ret = 4;
goto end;
}
{
u08 readmac[6];
int i,res;
enc28j60_getMAC( readmac );
/*readmac[5]=0;*/
for( i=0,res=0 ; i<6 ; i++ )
res |= ( readmac[i] ^ macaddr[i] );
if(res)
{
printf("Fail. Cannot read correct MAC address back: ");
printf("got %02x.%02x.%02x.%02x.%02x.%02x wanted ",
readmac[0],readmac[1],readmac[2],
readmac[3],readmac[4],readmac[5]);
printf("%02x.%02x.%02x.%02x.%02x.%02x\n",
macaddr[0],macaddr[1],macaddr[2],
macaddr[3],macaddr[4],macaddr[5]);
}
else
{
printf("OK. init success. MAC address configured.\n");
testres |= TEST_MAC;
}
}
{
unsigned char status;
/* we checked the chip rev already... */
/* enc28j60_status( PIO_STATUS_VERSION, &status ); printf("Chip Rev %d ",status); */
enc28j60_status( PIO_STATUS_LINK_UP, &status );
if( status != 1 )
printf("Fail. Link status is %d. Check your Ethernet Switch and cabling.\n",status);
else
{
printf("OK. Link status is %d\n",status);
testres |= TEST_LINK;
}
}
/* set best supported speed */
{
for( clockdiv=0 ; clockdiv < 16 ; clockdiv++ )
{
if( speeds & (1<<clockdiv) )
break;
}
printf(" Setting best speed %d (i.e. fastest working SPI clock divider)\n",clockdiv);
enc28j60_SetSPISpeed( clockdiv );
enc28j60l_UMinDelay( SPEED_DELAY ); /* wait a little, */
}
printf("..... Sending 100 frames and log broadcasts/multicasts (~10 seconds) .....\n");
printf(" (Whether something is received in the next 10 seconds depends\n");
printf(" on which and how many devices are present+active in your network)\n");
runs = 100;
ip_checksum( testframe+14, testlen-14 ); /* only the first 20 bytes are relevant */
udp_checksum( testframe+14, testlen-14 ); /* skip Ethernet header */
while( (runs--) && (!doquit) )
{
#if 1
res = enc28j60_send( testframe, testlen );
if( res != PIO_OK )
{
testres |= TEST_TXERR;
printf("send error %d\n",res);
}
#endif
if(0)
{
unsigned char status;
enc28j60_status( PIO_STATUS_LINK_UP, &status );
printf("Link status is %d\n",status);
}
res = enc28j60_has_recv();
/* printf("%d packets\n",res); */
if( res )
{
unsigned short got_size;
printf("%d packets\n",res);
testres |= TEST_HAVERX;
/* u08 enc28j60_recv(u08 *data, u16 max_size, u16 *got_size) */
res = enc28j60_recv( recvbuf,1520,&got_size);
if( res != PIO_IO_ERR )
{
/* printf("recv res %d\n",res); */
if( got_size )
{
unsigned int type = (((unsigned int)recvbuf[12])<<8) + (unsigned int)recvbuf[13];
if(1)/* if( type != 0x800 ) */
{
printf("%d bytes\n",got_size);
printf("%02x.%02x.%02x.%02x.%02x.%02x (%x)\n",
recvbuf[0],recvbuf[1],recvbuf[2],
recvbuf[3],recvbuf[4],recvbuf[5],
type );
}
}
}
}
#if 0
else
{
enc28j60_dump_regs();
}
#endif
Delay(5);
}
printf("Done. Verdict:\n");
if( testres == ( TEST_HAVERX|TEST_LINK|TEST_MAC ) )
{
#ifdef PROTO_V2EXPNET
printf(" This test determined that your expansion net is quite likely in working shape.\n");
#else
printf(" This test determined that your sdnet is quite likely in working shape.\n");
#endif
}
else
{
if( testres == ( TEST_LINK|TEST_MAC ) )
{
printf(" No reception while testing. Either you`ve got a quiet network or further testing might be needed.\n");
}
else
{
if( testres & (TEST_TXERR|TEST_RXERR) )
printf(" RX/TX problems encountered.\n");
if( !(testres & TEST_LINK) )
printf(" Link is not up\n");
if( !(testres & TEST_MAC) )
printf(" MAC address not set correctly\n");
if( testres & TEST_HAVERX )
printf(" Some problems but at least we received data\n");
}
}
if( clockdiv != 1 )
{
printf("Important: your SDNet device was not working in this test with clockdiv=1.\n");
printf(" Please call\n");
printf(" makedir ENVARC:Sana2\n");
#ifdef PROTO_V2EXPNET
printf(" echo \"SPISPEED=%d\" >ENVARC:sana2/v2expeth.config\n",clockdiv);
#else
printf(" echo \"SPISPEED=%d\" >ENVARC:sana2/sdnet.config\n",clockdiv);
#endif
}
end:
return ret;
}
/* IP header checksum
input: IP header
length (min. 20)
output: checksum (also directly in IP header)
*/
u16 ip_checksum( u08 *buffer, LONG length )
{
ULONG csum = 0;
ULONG words,i;
unsigned short *b2,*b3;
if( length < 20 )
return 0; /* no checksum */
/* IPv4 header */
b2 = (unsigned short*)buffer;
b2[5] = 0;
words = ((ULONG)(buffer[0] & 0xf))<<1; /* IHL, def: 5 (32 bit words) */
/* sum up */
for( i=0,b3=b2 ; i < words ; i++ )
{
csum += *b3++;
}
while( csum > 0xffff )
{
csum = (csum&0xffff)+(csum>>16);
}
csum = (~csum)&0xffff;
b2[5] = csum; /* store checksum */
return (u16)csum;
}
/*
calculate UDP checksum
- buffer supplied should point to IP packet, where src/dest/protocol are filled in
length is in octets, including IPv4 header and UDP header
input: IP packet including UDP header and content
output: checksum (also directly in UDP header)
*/
u16 udp_checksum( u08 *buffer, LONG length )
{
ULONG words,i;
ULONG csum = 0;
unsigned short *b2,*b3;
if( length < 28 )
return 0; /* no checksum */
/* IPv4 pseudoheader (see for UDP length below) */
csum += *((unsigned short*)(&buffer[12])); /* src IP */
csum += *((unsigned short*)(&buffer[14])); /* src IP */
csum += *((unsigned short*)(&buffer[16])); /* dest IP */
csum += *((unsigned short*)(&buffer[18])); /* dest IP */
csum += (ULONG)buffer[9]; /* protocol */
/* location of UDP header */
words = ((ULONG)(buffer[0] & 0xf))<<2; /* IHL, def: 5 (32 bit words) */
b2 = (unsigned short*)(&buffer[words]);
b2[3] = 0; /* clear checksum */
b3 = b2;
csum += b2[2]; /* UDP length */
words = (length-words)>>1; /* total length - IP header */
for( i=0 ; i<words ; i++ )
{
csum += (ULONG)*b2++;
}
if( length & 1 )
{
csum += (ULONG)*b2;
}
while( csum > 0xffff )
{
csum = (csum&0xffff)+(csum>>16);
}
csum = csum^0xffff;
b3[3] = (u16)csum; /* store checksum */
return (u16)csum;
}
+14 -4
View File
@@ -1,4 +1,3 @@
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
; | Flash ROM Read Serial Number | ; | Flash ROM Read Serial Number |
; | Copyright (c) 2016 APOLLO TEAM | ; | Copyright (c) 2016 APOLLO TEAM |
@@ -6,6 +5,7 @@
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
FLASH_ID EQU $14 ;cmd=0xAB FLASH_ID EQU $14 ;cmd=0xAB
LARGE_FLASH_ID EQU $16
FLASH_ADR_W EQU $00DFF1F8 FLASH_ADR_W EQU $00DFF1F8
FLASH_ADR_R EQU $00DFF1FA FLASH_ADR_R EQU $00DFF1FA
@@ -26,6 +26,11 @@ VAMPIDREG EQU $DFF3FC
V4_ID1 EQU $DFF3F4 V4_ID1 EQU $DFF3F4
V4_ID2 EQU $DFF3F0 V4_ID2 EQU $DFF3F0
BOARDID_V600 EQU 1
BOARDID_V500 EQU 2
BOARDID_V4SA EQU 5
BOARDID_V1200 EQU 6
xdef _vampire_UUID xdef _vampire_UUID
;-------- Get 64 Bit unique ID -------------------- ;-------- Get 64 Bit unique ID --------------------
@@ -40,8 +45,11 @@ _vampire_UUID:
move.w (a0),d0 ;ID reg empty? move.w (a0),d0 ;ID reg empty?
blt.s v2$ ;yes, try flash method blt.s v2$ ;yes, try flash method
cmp.w #$2FF,d0 ;Core type << 8 | Clock_Multiplier lsr.w #8,d0
ble.s v2$ cmp.b #BOARDID_V4SA,d0
bne.s v2$
; cmp.w #$2FF,d0 ;Core type << 8 | Clock_Multiplier
; ble.s v2$
move.l V4_ID1-VAMPIDREG(a0),d0 move.l V4_ID1-VAMPIDREG(a0),d0
move.l V4_ID2-VAMPIDREG(a0),d1 move.l V4_ID2-VAMPIDREG(a0),d1
@@ -49,8 +57,10 @@ _vampire_UUID:
v2$ v2$
bsr flashreadid bsr flashreadid
cmpi.b #FLASH_ID,d0 cmpi.b #FLASH_ID,d0
beq.s goodflash$
cmpi.b #LARGE_FLASH_ID,d0
bne.s error$ bne.s error$
goodflash$
bsr flashuniqueid bsr flashuniqueid
common$ common$
move.l d0,(a1) move.l d0,(a1)
+19 -6
View File
@@ -30,6 +30,12 @@
static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq ); static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
#endif #endif
#ifndef NO_WR_SEM
#define WRSEM du_WrSem
#else
#define WRSEM du_Sem
#endif
/* the XSurf500 network panel currently claims length 0 requests /* the XSurf500 network panel currently claims length 0 requests
if the line below is not commented out, just check pointer if the line below is not commented out, just check pointer
*/ */
@@ -38,14 +44,19 @@ static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
/* tunables: number of one-call read and write requests */ /* tunables: number of one-call read and write requests */
/* this limits the number of processed write requests per run when enabled */ /* this limits the number of processed write requests per run when enabled */
#define ONE_WRITE_REQ 1 #define ONE_WRITE_REQ 1
#ifndef ALLREADREQS
/* this limits the number of processed read requests per run when enabled */ /* this limits the number of processed read requests per run when enabled */
#define ONE_READ_REQ 2 #define ONE_READ_REQ 2
#endif /* ALLREADREQS */
/* heavy debug on read/write */ /* heavy debug on read/write */
#define D2(x) #define D2(x)
#define D4(x) #define D4(x)
#define D8(x)
/* #define D2(x) D(x) */ /* #define D2(x) D(x) */
/* #define D4(x) D(x) */ /* #define D4(x) D(x) */
/* #define D8(x) D(x) */
@@ -97,9 +108,9 @@ static void server_Offline_CancelRequests( DEVBASEP , ULONG unit )
server_AbortList( db, (struct List*)&db->db_Units[unit].du_EventQueue ); server_AbortList( db, (struct List*)&db->db_Units[unit].du_EventQueue );
server_AbortList( db, (struct List*)&db->db_Units[unit].du_ReadOrphans ); server_AbortList( db, (struct List*)&db->db_Units[unit].du_ReadOrphans );
ReleaseSemaphore( &db->db_Units[unit].du_Sem ); ReleaseSemaphore( &db->db_Units[unit].du_Sem );
ObtainSemaphore( &db->db_Units[unit].du_WrSem ); ObtainSemaphore( &db->db_Units[unit].WRSEM );
server_AbortList( db, (struct List*)&db->db_Units[unit].du_WriteQueue ); server_AbortList( db, (struct List*)&db->db_Units[unit].du_WriteQueue );
ReleaseSemaphore( &db->db_Units[unit].du_WrSem ); ReleaseSemaphore( &db->db_Units[unit].WRSEM );
/* clear Multicast list, TODO: subroutine */ /* clear Multicast list, TODO: subroutine */
{ {
@@ -818,7 +829,7 @@ static LONG server_writequeue( DEVBASEP, ULONG unit )
#endif #endif
struct IOSana2Req *ioreq,*nextio; struct IOSana2Req *ioreq,*nextio;
ObtainSemaphore( &db->db_Units[unit].du_WrSem ); ObtainSemaphore( &db->db_Units[unit].WRSEM );
#if 1 #if 1
/* whole queue per call */ /* whole queue per call */
@@ -873,7 +884,7 @@ static LONG server_writequeue( DEVBASEP, ULONG unit )
#endif #endif
} }
ReleaseSemaphore( &db->db_Units[unit].du_WrSem ); ReleaseSemaphore( &db->db_Units[unit].WRSEM );
return SERR_OK; return SERR_OK;
} }
@@ -911,14 +922,16 @@ static void server_read_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq, U
{ {
frame += 14; /* skip DST,SRC,Type */ frame += 14; /* skip DST,SRC,Type */
framesize -= 18; /* also remove CRC */ framesize -= 18; /* also remove CRC */
// framesize -= 14; /* test: KEEP CRC */
D4(("plain mode: frame flags %ld\n",bcflag)); D4(("plain mode: frame flags %ld\n",bcflag));
} }
ioreq->ios2_Req.io_Flags &= SANA2IOF_RAW; /* ignore all other flags */ ioreq->ios2_Req.io_Flags &= SANA2IOF_RAW; /* ignore all other flags */
ioreq->ios2_Req.io_Flags |= bcflag; ioreq->ios2_Req.io_Flags |= bcflag;
ioreq->ios2_Req.io_Error = 0; ioreq->ios2_Req.io_Error = 0;
ioreq->ios2_WireError = 0; ioreq->ios2_WireError = 0;
ioreq->ios2_DataLength = framesize;
D4(("ReadFrm IO %lx, DBM %lx frm %lx frmsz %ld\n",(ULONG)ioreq,(ULONG)dbm,(ULONG)frame,framesize)); D8(("ReadFrm IO %lx, DBM %lx frm %lx frmsz %ld Flags %ld\n",(ULONG)ioreq,(ULONG)dbm,(ULONG)frame,framesize,(ULONG)ioreq->ios2_Req.io_Flags));
if( dbm->dbm_PacketFilter ) /* Filter Packets ? */ if( dbm->dbm_PacketFilter ) /* Filter Packets ? */
{ {
@@ -1090,7 +1103,7 @@ VOID SAVEDS ServerTask(void)
{ {
if( !action ) /* queues quiet ? -> sleep */ if( !action ) /* queues quiet ? -> sleep */
{ {
Disable(); /* Disable(); */
i=0;BOARDLOOP( ( ; i < db->db_NBoards ; i++ ) ) i=0;BOARDLOOP( ( ; i < db->db_NBoards ; i++ ) )
{ /* housekeeping -> check for link change on idle, re-enable interrupts etc. */ { /* housekeeping -> check for link change on idle, re-enable interrupts etc. */
hw_check_link_change(db,i); hw_check_link_change(db,i);
+1
View File
@@ -87,6 +87,7 @@ IPATH =
# see all: target for defaults in $(DEFINES) # see all: target for defaults in $(DEFINES)
DEFINES = $(DEFINES1) CPU=$(CPU) DEFINES = $(DEFINES1) CPU=$(CPU)
DEFINES = $(DEFINES) DEFINE ALLREADREQS=1
#DEFINES = $(DEFINES) DEFINE DEVICEVERSION=$(DEVICEVERSION) #DEFINES = $(DEFINES) DEFINE DEVICEVERSION=$(DEVICEVERSION)
#DEFINES = $(DEFINES) DEFINE DEVICEREVISION=$(DEVICEREVISION) #DEFINES = $(DEFINES) DEFINE DEVICEREVISION=$(DEVICEREVISION)
#DEFINES = $(DEFINES) DEFINE DEVICEDATE=$(DEVICEDATE) #DEFINES = $(DEFINES) DEFINE DEVICEDATE=$(DEVICEDATE)
+1 -1
View File
@@ -46,7 +46,7 @@ ASMDEFS1 = -DHW_DMA_TX=1
############################################################################### ###############################################################################
# debug = 1 will include string debugging for terminal/sushi/sashimi # debug = 1 will include string debugging for terminal/sushi/sashimi
# not enabled yet in SAS/C makefile # not enabled yet in SAS/C makefile
debug = 0 #debug = 0
############################################################################### ###############################################################################
# prefix for system includes (ASM) # prefix for system includes (ASM)
+2 -2
View File
@@ -9,9 +9,9 @@
#define _INC_VERSION_H #define _INC_VERSION_H
#define DEVICEVERSION 2 #define DEVICEVERSION 2
#define DEVICEREVISION 4 #define DEVICEREVISION 9
#define DEVICEEXTRA #define DEVICEEXTRA
/* #define DEVICEEXTRA Beta */ /* #define DEVICEEXTRA Beta */
#define DEVICEDATE 27.05.2019 #define DEVICEDATE 23.08.20
#endif #endif
-65
View File
@@ -1,65 +0,0 @@
ENC624J6net
SANA-II Driver for Matze/Scrat ZII IDE LAN CP card
author: Henryk Richter <henryk.richter@gmx.net>
Release Notes:
--------------
- goes along with 27 December 2017 CPLD build, where interrupts are extended
- older CPLD builds will lock up Amiga at first interrupt
- provisions for swapped address lines 12/13 are in the code
- board requires Int2 to be soldered (NOT Int6)
Installation:
-------------
The driver (enc624j6net.device) needs to be copied into Devs:Networks. The configuration
depends on the TCP/IP stack of choice. Please refer to the respective documentation
how to configure a network interface.
Use the supplied GUI for stacks like Genesis or Miami and add a regular ethernet card
within those by referring to the enc624j6net.device, unit 0.
The recent RoadShow stack is commandline-based. Please add a new file in devs:NetInterfaces,
such as a copy of the PlipBox interface specification with the device entry replaced by
enc624j6net.device. The command AddNetInterface with the filename of your interface spec
as argument will then activate the driver for RoadShow.
Technical notes:
----------------
Matze's card does selective byte swapping for different areas of the chip within
the CPLD. This step enables Big Endian reads/writes to the hardware registers. Since
the SRAM would be byte-swapped as well, the latest (WIP) version of the CPLD presents
TX and RX frames in Big Endian (network order) as well. As a consequence, the
low-level part of the driver won't work out of the box with with other approaches
towards 16 Bit parallel connections of the ENC624J600 chip.
Copyrights and Acknowledgements:
--------------------------------
My deepest respects go to Christian Vogelgsang (lafalla) for his plipbox project.
His invaluable work on further cleanups and abstractions to the already well written
magPLIP made a quick swap of low-level functions quite easily possible.
The ENC624J6 source is heavily based on plipbox, which is in turn based on the magPLIP
driver found on aminet.net:
http://lallafa.de/blog/amiga-projects/plipbox/
http://aminet.net/package/comm/net/magPLIP38.1
magPLIP - SANA II compliant PLIP device driver for AmiTCP/IP, Envoy,
AS225 and other networking packages
(C) Copyright 1993-1994 Oliver Wagner, Michael Balzer
(C) Copyright 1995 Jan Kratochvil & Martin Mares
(C) Copyright 1995-1996 Marius Groeger
All Rights Reserved.
Changes have been made by Stéphane Zermatten to the driver to connect
a LinuxBox to an Amiga via a LapLing cable, based on the release 37.8.
Binary file not shown.
-33
View File
@@ -1,33 +0,0 @@
#ifndef __COMPILER_H
#define __COMPILER_H
#ifdef __SASC
/* Implementation notes:
**
** SAS/C complains if a module contains only "static" and "extern" functions
** that there would be no exported symbol. Therefore, the PUBLIC macro
** is defined empty for SAS/C but should be "extern" if possible (for
** instance with GNU CC).
*/
# define ASM __asm /* define registers for function args */
# define REG(x) register __ ## x /* specify a register in arglist */
# define INLINE __inline /* inline this function */
# define STDARGS __stdargs /* pass args to this function on stack */
# define REGARGS __regargs /* pass args to this function in regs */
# define SAVEDS __saveds /* setup data segment reg. on entry */
# define FAR __far /* reference this object in far mode */
# define MIN __builtin_min /* min{} function */
# define MAX __builtin_max /* max{} function */
# define PUTREG __builtin_putreg /* set a register to a certain value */
# define REG_D0 0 /* reg. number for PUTREG() */
# define REG_D1 1 /* reg. number for PUTREG() */
extern void PUTREG(int, long); /* prototype */
# define PUBLIC /* define a globally visible function */
# define PRIVATE static /* define a locally visible function */
# define GLOBAL extern
#else
# error Please define the above macros for your compiler
#endif
#endif
-33
View File
@@ -1,33 +0,0 @@
#ifndef __DEBUG_H
#define __DEBUG_H
#if (DEBUG != 0)
extern void KPrintF(char *, ...), KGetChar(void);
#endif
#if (DEBUG & 1)
# define d(x) do { KPrintF("%s:%s:%ld:",__FILE__,__FUNC__,__LINE__); KPrintF x; } while(0)
#else
# define d(x)
#endif
#if (DEBUG & 2)
# define d2(x) do { KPrintF("%s:%s:%ld:",__FILE__,__FUNC__,__LINE__); KPrintF x; } while(0)
#else
# define d2(x)
#endif
#if (DEBUG & 4)
# define d4(x) do { KPrintF("%s:%s:%ld:",__FILE__,__FUNC__,__LINE__); KPrintF x; } while(0)
#else
# define d4(x)
#endif
#if (DEBUG & 8)
# define d8(x) do { KPrintF("%s:%s:%ld:",__FILE__,__FUNC__,__LINE__); KPrintF x; } while(0)
#else
# define d8(x)
#endif
#endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef _DEV_INFO_H
#define _DEV_INFO_H
#define DEVICE_NAME "enc624j6net"
#define DEVICE_DATE "16.04.2018"
#define DEVICE_VER "0.2"
#define DEVICE_VERSION 0
#define DEVICE_REVISION 2
#endif
-11
View File
@@ -1,11 +0,0 @@
DEVICE_NAME MACRO
dc.b 'enc624j6net'
ENDM
DEVICE_DATE MACRO
dc.b '16.04.2018'
ENDM
DEVICE_VER MACRO
dc.b '0.2'
ENDM
DEVICE_VERSION equ 0
DEVICE_REVISION equ 2
-994
View File
@@ -1,994 +0,0 @@
#define DEBUG 0
/*F*/ /* includes */
#ifndef CLIB_ALIB_PROTOS_H
#include <clib/alib_protos.h>
#endif
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#endif
#ifndef CLIB_DOS_PROTOS_H
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#endif
#ifndef CLIB_CIA_PROTOS_H
#include <clib/cia_protos.h>
#include <pragmas/cia_pragmas.h>
#endif
#ifndef CLIB_MISC_PROTOS_H
#include <clib/misc_protos.h>
#include <pragmas/misc_pragmas.h>
#endif
#ifndef CLIB_UTILITY_PROTOS_H
#include <clib/utility_protos.h>
#include <pragmas/utility_pragmas.h>
#endif
#ifndef CLIB_TIME_PROTOS_H
#include <clib/timer_protos.h>
#include <pragmas/timer_pragmas.h>
#endif
#ifndef DEVICES_SANA2_H
#include <devices/sana2.h>
#endif
#ifndef HARDWARE_CIA_H
#include <hardware/cia.h>
#endif
#ifndef DOS_DOSTAGS_H
#include <dos/dostags.h>
#endif
#ifndef RESOURCES_MISC_H
#include <resources/misc.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif
#ifndef __GLOBAL_H
#include "global.h"
#endif
#ifndef __DEBUG_H
#include "debug.h"
#endif
#ifndef __COMPILER_H
#include "compiler.h"
#endif
#ifdef PROTO_SDNET
#include "vampuuid.h"
#define __NOLIBBASE__
#include <proto/vampire.h>
#include <vampire/vampire.h>
#endif
#ifdef PROTO_ENC624NET
#define ENC_MANUFACTURER 2588
#define ENC_BOARD 123
#include <clib/expansion_protos.h>
#include <pragmas/expansion_pragmas.h>
#include <libraries/configvars.h>
#include "enc624j6l.h" /* for MAC retrieval */
#endif
#ifdef DIRECT_WRITE
typedef enum { AW_OK, AW_BUFFER_ERROR, AW_ERROR } AW_RESULT;
PUBLIC REGARGS VOID DoEvent(BASEPTR, long event);
PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2);
#ifndef __HW_H
#include "hw.h"
#endif
#endif
#define INVALID_SDNET_UNIT 0x33 /* used by both sdnet and encnet */
/*E*/
/*F*/ /* imports */
PUBLIC VOID SAVEDS ServerTask(VOID);
PUBLIC BOOL remtracktype(BASEPTR, ULONG type);
PUBLIC BOOL addtracktype(BASEPTR, ULONG type);
PUBLIC BOOL gettrackrec(BASEPTR, ULONG type, struct Sana2PacketTypeStats *info);
PUBLIC VOID dotracktype(BASEPTR, ULONG type, ULONG ps, ULONG pr, ULONG bs, ULONG br, ULONG pd);
PUBLIC VOID freetracktypes(BASEPTR);
#define min __builtin_min
/*E*/
/*F*/ /* exports */
PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) BPTR seglist, REG(a6) struct Library *_SysBase);
PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOSana2Req *ios2, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR);
PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR);
PUBLIC ASM SAVEDS BPTR DevClose( REG(a1) struct IOSana2Req *ior, REG(a6) BASEPTR);
PUBLIC VOID DevTermIO(BASEPTR, struct IOSana2Req *ios2);
PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOSana2Req *ios2, REG(a6) BASEPTR);
PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOSana2Req *ior, REG(a6) BASEPTR);
/*E*/
/*F*/ /* private */
PRIVATE BOOL isinlist(struct Node *n, struct List *l);
PRIVATE VOID abort(BASEPTR, struct IOSana2Req *ior);
/*E*/
#ifdef PROTO_SDNET
PRIVATE void pb_FreeExpansion(BASEPTR );
PRIVATE APTR pb_AllocExpansion( ULONG portid, BASEPTR );
PRIVATE void pb_FreeExpansion(BASEPTR )
{
if( pb->pb_ExpansionPort >= 0 )
{
V_FreeExpansionPort( pb->pb_ExpansionPort );
pb->pb_ExpansionPort = -1;
}
}
PRIVATE APTR pb_AllocExpansion( ULONG portid, BASEPTR )
{
return V_AllocExpansionPort( portid, SERVERTASKNAME );
}
#endif /* PROTO_SDNET */
/*
** various support routines
*/
/*F*/ PRIVATE BOOL isinlist(struct Node *n, struct List *l)
{
struct Node *cmp;
for(cmp = l->lh_Head; cmp->ln_Succ; cmp = cmp->ln_Succ)
if (cmp == n) return TRUE;
return FALSE;
}
/*E*/
/*F*/ PRIVATE VOID abort(BASEPTR, struct IOSana2Req *ior)
{
Remove((struct Node*)ior);
ior->ios2_Req.io_Error = IOERR_ABORTED;
ior->ios2_WireError = 0;
ReplyMsg((struct Message*)ior);
}
/*E*/
/*
** initialise device
*/
/*F*/ PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) BPTR seglist, REG(a6) struct Library *_SysBase)
{
BOOL ok;
UBYTE *p;
UWORD i;
d(("entered device, initialising PLIPBase...\n"));
/* clear data base */
for(p = ((UBYTE*)pb) + sizeof(struct Library), i = sizeof(struct PLIPBase)-sizeof(struct Library); i; i--)
*p++ = 0;
SysBase = _SysBase;
pb->pb_SegList = seglist; /* store DOS segment list */
/* init some default values */
pb->pb_Flags = PLIPF_OFFLINE;
pb->pb_BPS = HW_BPS;
pb->pb_MTU = HW_ETH_MTU;
/* initialise the lists */
NewList((struct List*)&pb->pb_ReadList);
NewList((struct List*)&pb->pb_WriteList);
NewList((struct List*)&pb->pb_EventList);
NewList((struct List*)&pb->pb_ReadOrphanList);
NewList((struct List*)&pb->pb_TrackList);
NewList((struct List*)&pb->pb_BufferManagement);
/* initialise the access protection semaphores */
InitSemaphore(&pb->pb_ReadListSem);
InitSemaphore(&pb->pb_ReadOrphanListSem);
InitSemaphore(&pb->pb_EventListSem);
InitSemaphore(&pb->pb_WriteListSem);
InitSemaphore(&pb->pb_TrackListSem);
InitSemaphore(&pb->pb_Lock);
pb->pb_SpecialStats[S2SS_TXERRORS].Type = S2SS_PLIP_TXERRORS;
pb->pb_SpecialStats[S2SS_TXERRORS].Count = 0;
pb->pb_SpecialStats[S2SS_TXERRORS].String = "TX Errors";
pb->pb_SpecialStats[S2SS_COLLISIONS].Type = S2SS_PLIP_COLLISIONS;
pb->pb_SpecialStats[S2SS_COLLISIONS].Count = 0;
pb->pb_SpecialStats[S2SS_COLLISIONS].String = "Collisions";
ok = FALSE;
if (UtilityBase = OpenLibrary("utility.library", 37))
{
if (DOSBase = OpenLibrary("dos.library", 37))
{
#ifdef PROTO_ENC624NET
if( ExpansionBase = OpenLibrary("expansion.library", 37))
{
int i;
ok = TRUE;
for( i=0 ; i<(HW_MAXBOARDS+1) ; i++ )
pb->pb_HWBase.hwb_boards[i]=0; /* clear whole array */
}
else
{
d(("no expansion.library\n"));
}
#endif
#ifdef PROTO_SDNET
if( VampireBase = OpenResource( V_VAMPIRENAME ) )
{
pb->pb_ExpansionPort = -1;
ok = TRUE;
}
else
{
d(("no vampire.resource\n"));
}
#endif
}
else
{
d(("no dos\n"));
}
if (!ok) CloseLibrary(UtilityBase);
}
else
{
d(("no utility\n"));
}
d(("left %ld\n",ok));
return (struct Device *)(ok ? pb : NULL);
}
/*E*/
/*
** open device
*/
/*F*/ PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOSana2Req *ios2, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR)
{
BOOL ok = FALSE;
struct BufferManagement *bm;
LONG rv = 0; /* get rid of warning with opt build */
d(("entered for unit %ld\n",unit));
/* Make sure our open remains single-threaded. */
ObtainSemaphore(&pb->pb_Lock);
pb->pb_DevNode.lib_OpenCnt++;
#ifdef PROTO_SDNET
if( !VampireBase )
{
unit = INVALID_SDNET_UNIT; /* no vampire.resource -> illegal unit */
}
else
{
unsigned long portid = V_WIFIPORT;
if( !unit )
portid = V_SDPORT;
/* if( !pb->pb_DevNode.lib_OpenCnt ) disabled, maybe doesn't open because of other reasons */
if( pb->pb_ExpansionPort < 0 )
{
APTR allocator = pb_AllocExpansion( portid, pb );
if( allocator )
unit = INVALID_SDNET_UNIT; /* illegal unit, cannot obtain Expansion Port */
else
pb->pb_ExpansionPort = portid;
}
else
{
/* sorry, I currently don't support more than one port at a time */
if( portid != pb->pb_ExpansionPort )
unit = INVALID_SDNET_UNIT;
}
}
#endif
#ifdef PROTO_ENC624NET
if( !(pb->pb_HWBase.hwb_boards[0]) )
{
struct ConfigDev *cfg = (0);
int i;
for( i=0 ; i<HW_MAXBOARDS ; i++ )
{
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
if( !cfg )
break;
pb->pb_HWBase.hwb_boards[i] = cfg->cd_BoardAddr;
d(("board at = %ld\n",(ULONG)pb->pb_HWBase.hwb_boards[i] ));
}
pb->pb_HWBase.hwb_boards[i] = (0);
}
if( unit >= HW_MAXBOARDS )
unit = INVALID_SDNET_UNIT;
else
{
if( !pb->pb_HWBase.hwb_boards[unit] )
unit = INVALID_SDNET_UNIT;
}
#endif
/* not promiscouos mode and unit valid ? (unit0 = SD Slot, unit1 = Extension header) */
#ifdef PROTO_SDNET
if (!(flags & SANA2OPF_PROM) && (unit <= 1))
#else /* PROTO_SDNET */
if (!(flags & SANA2OPF_PROM) && (unit < HW_MAXBOARDS))
#endif
{
/* Allow access only if NOT:
**
** Anybody else has already opened it AND
** the current access is exclusive
** OR the first access was exclusive
** OR this access wants a different unit
*/
if (!((pb->pb_DevNode.lib_OpenCnt > 1) &&
((flags & SANA2OPF_MINE)
|| (pb->pb_Flags & PLIPF_EXCLUSIVE)
|| (unit != pb->pb_Unit))))
{
if (flags & SANA2OPF_MINE)
pb->pb_Flags |= PLIPF_EXCLUSIVE;
else
pb->pb_Flags &= ~PLIPF_EXCLUSIVE;
/*
** 13.05.96: Detlef Wuerkner <TetiSoft@apg.lahn.de>
** Rememer unit of 1st OpenDevice()
*/
if (pb->pb_DevNode.lib_OpenCnt == 1)
pb->pb_Unit = unit;
/* setup default mac */
{
/* */
#ifdef PROTO_ENC624NET
unsigned char addr[6] = { 0x02,0x80,0x10,0x0b,0x0a,0xff};
APTR board = pb->pb_HWBase.hwb_boards[unit];
enc624j6l_GetMAC( board, addr );
memcpy(pb->pb_CfgAddr, addr, HW_ADDRFIELDSIZE);
memcpy(pb->pb_DefAddr, addr, HW_ADDRFIELDSIZE);
#else /* PROTO_ENC624NET */
#ifdef PROTO_SDNET
/* OUI: Commodore, but "local" */
/* valid "locally administered" MAC addresses:
x2-xx-xx-xx-xx-xx
x6-xx-xx-xx-xx-xx
xA-xx-xx-xx-xx-xx
xE-xx-xx-xx-xx-xx
*/
unsigned char addr[6] = { 0x02,0x80,0x10,0x0b,0x0a,0xff};
unsigned char vsn[8];
if( vampire_UUID( vsn ) > 0 )
{
/* generate Interface ID from Vampire serial */
int i;
for(i=0 ; i<3 ; i++ )
{
addr[3+i] = vsn[i] ^ vsn[i+5];
}
}
#else /* PROTO_SDNET */
unsigned char addr[6] = { 0x1a,0x11,0xaf,0xa0,0x47,0x11 };
memcpy(pb->pb_CfgAddr, addr, HW_ADDRFIELDSIZE);
memcpy(pb->pb_DefAddr, addr, HW_ADDRFIELDSIZE);
#endif /* PROTO_SDNET */
#endif /* PROTO_ENC624NET */
}
/*
** Each opnener get's it's own BufferManagement. This is neccessary
** since we want to allow several protocol stacks to use PLIP
** simultaneously.
*/
if (bm = AllocVec(sizeof(struct BufferManagement),MEMF_CLEAR|MEMF_PUBLIC))
{
/*
** We don't care if there actually are buffer management functions,
** because there might be openers who just want some statistics
** from us.
*/
#if defined(__SASC) && (__VERSION__ == 6) && (__REVISION__ >= 56)
/* Jippieee! */
bm->bm_CopyToBuffer = (BMFunc)GetTagData(S2_CopyToBuff, NULL,
(struct TagItem *)ios2->ios2_BufferManagement);
bm->bm_CopyFromBuffer = (BMFunc)GetTagData(S2_CopyFromBuff, NULL,
(struct TagItem *)ios2->ios2_BufferManagement);
#else
/*
** The type casting below is very beautiful. This is a SAS/C bug:
** I have to cast the ULONG that I got from GetTagData() to a
** (void (*)(void)) function pointer. Now I may cast it to (BMFunc),
** which defines the __asm and register stuff.
**
** I would call this a cast with ``soft force'', as it seems that
** I slowly have to make the ULONG being used to the fact of
** becoming a pointer (``Look, old mathematical chap: didn't you
** always want to be a pointer? Did you know how less it takes, how
** mighty the dark side of the force really is?'').
*/
bm->bm_CopyToBuffer = (BMFunc)((void (*)())(GetTagData(S2_CopyToBuff, NULL,
(struct TagItem *)ios2->ios2_BufferManagement)));
bm->bm_CopyFromBuffer = (BMFunc)((void (*)())(GetTagData(S2_CopyFromBuff, NULL,
(struct TagItem *)ios2->ios2_BufferManagement)));
#endif
d(("starting servertask\n"));
if (!pb->pb_Server)
{
volatile struct ServerStartup ss;
struct MsgPort *port;
#ifdef PROTO_SDNET
/* before we can run the server, check if we can access the hardware */
#endif
if (port = CreateMsgPort())
{
d(("starting server"));
if (pb->pb_Server = CreateNewProcTags(NP_Entry, ServerTask, NP_Name,
SERVERTASKNAME, NP_Priority, 5, TAG_DONE))
{
ss.ss_Error = 1;
ss.ss_PLIPBase = pb;
ss.ss_Msg.mn_Length = sizeof(ss);
ss.ss_Msg.mn_ReplyPort = port;
d(("passing startup msg, pb is %lx\n", pb));
PutMsg(&pb->pb_Server->pr_MsgPort, (struct Message*)&ss);
WaitPort(port);
if (!ss.ss_Error)
ok = TRUE;
else
{
d(("server task failed\n"));
}
}
else
{
d(("couldn't launch server task\n"));
}
DeleteMsgPort(port);
}
else
{
d(("no temp-message port for server startup\n"));
}
}
else ok = TRUE;
if (!ok)
FreeVec(bm);
else
{
/* enqueue buffer management into list
*/
AddTail((struct List *)&pb->pb_BufferManagement,(struct Node *)bm);
pb->pb_DevNode.lib_OpenCnt++;
pb->pb_DevNode.lib_Flags &= ~LIBF_DELEXP;
ios2->ios2_BufferManagement = (VOID *)bm;
ios2->ios2_Req.io_Error = 0;
ios2->ios2_Req.io_Unit = (struct Unit *)unit;
ios2->ios2_Req.io_Device = (struct Device *)pb;
rv = 0;
}
}
}
}
/* See if something went wrong. */
if(!ok)
{
if( pb->pb_DevNode.lib_OpenCnt == 1 )
{
#ifdef PROTO_SDNET
pb_FreeExpansion(pb);
#endif
}
ios2->ios2_Req.io_Error = IOERR_OPENFAIL;
ios2->ios2_Req.io_Unit = (struct Unit *) 0;
ios2->ios2_Req.io_Device = (struct Device *) 0;
rv = IOERR_OPENFAIL;
}
ios2->ios2_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
pb->pb_DevNode.lib_OpenCnt--;
ReleaseSemaphore(&pb->pb_Lock);
return rv;
}
/*E*/
/*
** close device
*/
/*F*/ PUBLIC ASM SAVEDS BPTR DevClose(REG(a1) struct IOSana2Req *ior, REG(a6) BASEPTR)
{
BPTR seglist;
struct BufferManagement *bm;
d2(("entered\n"));
ObtainSemaphore(&pb->pb_Lock);
/* invalidate IO request block */
ior->ios2_Req.io_Device = (struct Device *)-1;
ior->ios2_Req.io_Unit = (struct Unit *)-1;
/* search and free BuffMgmt structure */
for(bm = (struct BufferManagement *)pb->pb_BufferManagement.lh_Head;
bm->bm_Node.mln_Succ; bm = (struct BufferManagement *)bm->bm_Node.mln_Succ)
if (bm == ior->ios2_BufferManagement)
{
Remove((struct Node*)bm);
FreeVec(bm);
break;
}
pb->pb_DevNode.lib_OpenCnt--;
if( !pb->pb_DevNode.lib_OpenCnt )
{
#ifdef PROTO_SDNET
pb_FreeExpansion(pb);
#endif
}
ReleaseSemaphore(&pb->pb_Lock);
if (pb->pb_DevNode.lib_Flags & LIBF_DELEXP)
seglist = DevExpunge(pb);
else
seglist = 0;
return seglist;
}
/*E*/
/*F*/ PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR)
{
BPTR seglist;
ULONG sigb;
d2(("entered\n"));
if (pb->pb_DevNode.lib_OpenCnt)
{
pb->pb_DevNode.lib_Flags |= LIBF_DELEXP;
seglist = 0;
}
else
{
/* detach device from system list */
Remove((struct Node*)pb);
/* stop the servr task */
d2(("killing server task\n"));
pb->pb_Task = FindTask(0L);
/* We must allocate a new signal, as we don't know in whose
** context we're running. If we get no signal, we poll
** for the server-exits flag.
*/
sigb = AllocSignal(-1);
pb->pb_ServerStoppedSigMask = (sigb == -1) ? 0 : (1<<sigb);
Signal((struct Task*)pb->pb_Server, SIGBREAKF_CTRL_C);
if (pb->pb_ServerStoppedSigMask)
{
Wait(pb->pb_ServerStoppedSigMask);
FreeSignal(sigb);
}
else
{
while(!(pb->pb_Flags & PLIPF_SERVERSTOPPED))
Delay(10);
}
d2(("server task has gone\n"));
/* clean up track */
freetracktypes(pb);
CloseLibrary(UtilityBase);
CloseLibrary(DOSBase);
/* save seglist for return value */
seglist = (long)pb->pb_SegList;
/* return memory
**
** NO FURTHER ACCESS TO PLIPBase ALLOWED!
*/
FreeMem( ((char *) pb) - pb->pb_DevNode.lib_NegSize,
(ULONG)(pb->pb_DevNode.lib_PosSize + pb->pb_DevNode.lib_NegSize));
}
return seglist;
}
/*E*/
/*
** initiate io command (1st level dispatcher)
*/
#if 1
/* got so tired of the SAS/C "inlining notice", made a macro instead */
#define DevForwardIO( _BP_ , _REQ_ ) \
{\
struct IOSana2Req *_rq_ = (struct IOSana2Req*)_REQ_;\
_rq_->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;\
PutMsg( (_BP_)->pb_ServerPort, (struct Message*)_rq_);\
}
#else
/*F*/ static INLINE VOID DevForwardIO(BASEPTR, struct IOSana2Req *ios2)
{
d(("forwarding request %ld\n", ios2->ios2_Req.io_Command));
/* request is no longer of type "quick i/o" */
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
PutMsg(pb->pb_ServerPort, (struct Message*)ios2);
}
/*E*/
#endif
/*F*/ PUBLIC VOID DevTermIO(BASEPTR, struct IOSana2Req *ios2)
{
d(("cmd = %ld, error = %ld, wireerror = %ld\n", ios2->ios2_Req.io_Command, ios2->ios2_Req.io_Error,ios2->ios2_WireError));
/* if this command was done asynchonously, we must
** reply the request
*/
if(!(ios2->ios2_Req.io_Flags & SANA2IOF_QUICK))
ReplyMsg((struct Message *)ios2);
else /* otherwise just mark it as done */
ios2->ios2_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
}
/*E*/
/*F*/ PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOSana2Req *ios2, REG(a6) BASEPTR)
{
ULONG mtu;
/* mark request as active */
ios2->ios2_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
ios2->ios2_Req.io_Error = S2ERR_NO_ERROR;
ios2->ios2_WireError = S2WERR_GENERIC_ERROR;
d(("cmd = %ld\n",ios2->ios2_Req.io_Command));
/*
** 1st level command dispatcher
**
** Here we decide wether we can process the request immediately avoiding
** a task switch. This is called "Quick I/O" and signalled to DoIO()
** by setting the node type of the request to NT_REPLYMSG (see TermIO()).
**
** Otherwise, we clear the SANA2IOF_QUICK flag and forward the request to
** the server. We may NEVER again access the request structure after
** the PutMsg()! The server - running at a high priority - will peempt
** us and might complety satisfy the request before we will be wakened up
** again.
** The same goes for those requests that we put into the server's queue.
*/
switch(ios2->ios2_Req.io_Command)
{
case CMD_READ:
/*
if (pb->pb_Flags & PLIPF_OFFLINE)
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
}
else
*/
if (ios2->ios2_BufferManagement == NULL)
{
ios2->ios2_Req.io_Error = S2ERR_BAD_ARGUMENT;
ios2->ios2_WireError = S2WERR_BUFF_ERROR;
}
else
{
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ObtainSemaphore(&pb->pb_ReadListSem);
AddHead((struct List*)&pb->pb_ReadList, (struct Node*)ios2);
ReleaseSemaphore(&pb->pb_ReadListSem);
ios2 = NULL;
}
break;
case S2_BROADCAST:
/* set broadcast addr: ff:ff:ff:ff:ff:ff */
memset(ios2->ios2_DstAddr, 0xff, HW_ADDRFIELDSIZE);
/* fall through */
case CMD_WRITE:
/* determine max valid size */
mtu = pb->pb_MTU;
if(ios2->ios2_Req.io_Flags & SANA2IOF_RAW) {
mtu += HW_ETH_HDR_SIZE;
}
if(ios2->ios2_DataLength > mtu)
{
ios2->ios2_Req.io_Error = S2ERR_MTU_EXCEEDED;
}
else if (ios2->ios2_BufferManagement == NULL)
{
ios2->ios2_Req.io_Error = S2ERR_BAD_ARGUMENT;
ios2->ios2_WireError = S2WERR_BUFF_ERROR;
}
else if (pb->pb_Flags & PLIPF_OFFLINE)
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
}
else
{
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ios2->ios2_Req.io_Error = 0;
ObtainSemaphore(&pb->pb_WriteListSem);
#ifdef DIRECT_WRITE
{
AW_RESULT code;
struct IOSana2Req *currentwrite = (struct IOSana2Req*)ios2;
code = write_frame(pb, ios2);
if (code == AW_BUFFER_ERROR) /* BufferManagement callback error */
{
d(("buffer error\n"));
DoEvent(pb, S2EVENT_ERROR | S2EVENT_BUFF | S2EVENT_SOFTWARE);
pb->pb_SpecialStats[S2SS_TXERRORS].Count++;
d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count));
currentwrite->ios2_Req.io_Error = S2ERR_SOFTWARE;
currentwrite->ios2_WireError = S2WERR_BUFF_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
else if (code == AW_ERROR)
{
/*
** this is a real line error, upper levels (e.g. Internet TCP) have
** to care for reliability!
*/
d(("error while transmitting packet\n"));
DoEvent(pb, S2EVENT_ERROR | S2EVENT_TX | S2EVENT_HARDWARE);
pb->pb_SpecialStats[S2SS_TXERRORS].Count++;
d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count));
currentwrite->ios2_Req.io_Error = S2ERR_TX_FAILURE;
currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
else /*if (code == AW_OK)*/ /* well done! */
{
d(("packet transmitted successfully\n"));
pb->pb_DevStats.PacketsSent++;
dotracktype(pb, (ULONG) pb->pb_Frame->hwf_Type, 1, 0, currentwrite->ios2_DataLength, 0, 0);
currentwrite->ios2_Req.io_Error = S2ERR_NO_ERROR;
currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
}
ReleaseSemaphore(&pb->pb_WriteListSem);
#else
AddTail((struct List*)&pb->pb_WriteList, (struct Node*)ios2);
ReleaseSemaphore(&pb->pb_WriteListSem);
Signal((struct Task*)pb->pb_Server, SIGBREAKF_CTRL_F);
#endif
ios2 = NULL;
}
break;
case S2_ONLINE:
case S2_OFFLINE:
case S2_CONFIGINTERFACE: /* forward request */
DevForwardIO(pb, ios2);
ios2 = NULL;
break;
case S2_GETSTATIONADDRESS:
memcpy(ios2->ios2_SrcAddr, pb->pb_CfgAddr, HW_ADDRFIELDSIZE); /* current */
memcpy(ios2->ios2_DstAddr, pb->pb_DefAddr, HW_ADDRFIELDSIZE); /* default */
break;
case S2_DEVICEQUERY:
{
struct Sana2DeviceQuery *devquery;
devquery = ios2->ios2_StatData;
devquery->DevQueryFormat = 0; /* "this is format 0" */
devquery->DeviceLevel = 0; /* "this spec defines level 0" */
if (devquery->SizeAvailable >= 18) devquery->AddrFieldSize = HW_ADDRFIELDSIZE * 8; /* Bits! */
if (devquery->SizeAvailable >= 22) devquery->MTU = pb->pb_MTU;
if (devquery->SizeAvailable >= 26) devquery->BPS = pb->pb_BPS;
if (devquery->SizeAvailable >= 30) devquery->HardwareType = S2WireType_Ethernet;
devquery->SizeSupplied = min((int)devquery->SizeAvailable, 30);
}
break;
case S2_ONEVENT:
/* Two special cases. S2EVENT_ONLINE and S2EVENT_OFFLINE are supposed to
retun immediately if we are already in the state that they are waiting
for. */
if (((ios2->ios2_WireError & S2EVENT_ONLINE) && !(pb->pb_Flags & PLIPF_OFFLINE)) ||
((ios2->ios2_WireError & S2EVENT_OFFLINE) && (pb->pb_Flags & PLIPF_OFFLINE)))
{
ios2->ios2_Req.io_Error = 0;
ios2->ios2_WireError &= (S2EVENT_ONLINE|S2EVENT_OFFLINE);
DevTermIO(pb,ios2);
ios2 = NULL;
}
else if ((ios2->ios2_WireError & (S2EVENT_ERROR|S2EVENT_TX|S2EVENT_RX|S2EVENT_ONLINE|
S2EVENT_OFFLINE|S2EVENT_BUFF|S2EVENT_HARDWARE|S2EVENT_SOFTWARE))
!= ios2->ios2_WireError)
{
/* we cannot handle such events */
ios2->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
ios2->ios2_WireError = S2WERR_BAD_EVENT;
}
else
{
/* Queue anything else */
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ObtainSemaphore(&pb->pb_EventListSem);
AddTail((struct List*)&pb->pb_EventList, (struct Node*)ios2);
ReleaseSemaphore(&pb->pb_EventListSem);
ios2 = NULL;
}
break;
/* --------------- stats support ----------------------- */
case S2_TRACKTYPE:
if (!addtracktype(pb, ios2->ios2_PacketType))
{
ios2->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
}
break;
case S2_UNTRACKTYPE:
if (!remtracktype(pb, ios2->ios2_PacketType))
{
ios2->ios2_Req.io_Error = S2ERR_BAD_STATE;
ios2->ios2_WireError = S2WERR_NOT_TRACKED;
}
break;
case S2_GETTYPESTATS:
if (!gettrackrec(pb, ios2->ios2_PacketType, (struct Sana2PacketTypeStats *)ios2->ios2_StatData))
{
ios2->ios2_Req.io_Error = S2ERR_NO_ERROR; /*S2ERR_BAD_STATE;*/
ios2->ios2_WireError = S2WERR_NOT_TRACKED;
}
break;
case S2_READORPHAN:
if (pb->pb_Flags & PLIPF_OFFLINE)
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
}
else if (ios2->ios2_BufferManagement == NULL)
{
ios2->ios2_Req.io_Error = S2ERR_BAD_ARGUMENT;
ios2->ios2_WireError = S2WERR_BUFF_ERROR;
}
else
{ /* Enqueue it to the orphan-reader-list */
ios2->ios2_Req.io_Flags &= ~SANA2IOF_QUICK;
ObtainSemaphore(&pb->pb_ReadOrphanListSem);
AddTail((struct List*)&pb->pb_ReadOrphanList, (struct Node*)ios2);
ReleaseSemaphore(&pb->pb_ReadOrphanListSem);
ios2 = NULL;
}
break;
case S2_GETGLOBALSTATS:
memcpy(ios2->ios2_StatData, &pb->pb_DevStats, sizeof(struct Sana2DeviceStats));
break;
case S2_GETSPECIALSTATS:
{
struct Sana2SpecialStatHeader *s2ssh = (struct Sana2SpecialStatHeader *)ios2->ios2_StatData;
if (pb->pb_ExtFlags & PLIPEF_NOSPECIALSTATS)
{
s2ssh->RecordCountSupplied = 0;
}
else
{
s2ssh->RecordCountSupplied = s2ssh->RecordCountMax > S2SS_COUNT ?
S2SS_COUNT : s2ssh->RecordCountMax;
CopyMem(pb->pb_SpecialStats, (void*)(s2ssh+1),
s2ssh->RecordCountSupplied*sizeof(struct Sana2SpecialStatRecord));
}
}
break;
/* --------------- unsupported requests -------------------- */
/* all standard commands we don't support */
case CMD_RESET:
case CMD_UPDATE:
case CMD_CLEAR:
case CMD_STOP:
case CMD_START:
case CMD_FLUSH:
ios2->ios2_Req.io_Error = IOERR_NOCMD;
ios2->ios2_WireError = S2WERR_GENERIC_ERROR;
break;
/* other commands (SANA-2) we don't support */
/*case S2_ADDMULTICASTADDRESS:*/
/*case S2_DELMULTICASTADDRESS:*/
/*case S2_MULTICAST:*/
default:
ios2->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
ios2->ios2_WireError = S2WERR_GENERIC_ERROR;
break;
}
if (ios2) DevTermIO(pb, ios2);
return;
}
/*E*/
/*
** stop io-command
*/
/*F*/ PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOSana2Req *ior, REG(a6) BASEPTR)
{
BOOL is;
LONG rc = 0;
d(("cmd = %ld\n",ior->ios2_Req.io_Command));
ObtainSemaphore(&pb->pb_WriteListSem);
if (is = isinlist((struct Node*)ior, (struct List*)&pb->pb_WriteList)) abort(pb,ior);
ReleaseSemaphore(&pb->pb_WriteListSem);
if (is) goto leave;
ObtainSemaphore(&pb->pb_ReadListSem);
if (is = isinlist((struct Node*)ior, (struct List*)&pb->pb_ReadList)) abort(pb,ior);
ReleaseSemaphore(&pb->pb_ReadListSem);
if (is) goto leave;
ObtainSemaphore(&pb->pb_EventListSem);
if (is = isinlist((struct Node*)ior, (struct List*)&pb->pb_EventList)) abort(pb,ior);
ReleaseSemaphore(&pb->pb_EventListSem);
if (is) goto leave;
ObtainSemaphore(&pb->pb_ReadOrphanListSem);
if (is = isinlist((struct Node*)ior, (struct List*)&pb->pb_ReadOrphanList)) abort(pb,ior);
ReleaseSemaphore(&pb->pb_ReadOrphanListSem);
if (is) goto leave;
rc = -1;
leave:
return rc;
}
/*E*/
@@ -1,46 +0,0 @@
/*
asminterface.h
Henryk Richter <henryk.richter@gmx.net>
Interface macros for ASM subroutines for GCC and SAS/C
syntax:
ASM SAVEDS int some_asm_subroutine(
ASMR(d3) unsigned int some_data ASMREG(d3),
ASMR(a0) unsigned char *some_address ASMREG(a0)
);
Reason for the double spec of An/Dn: some compilers (SAS) require the register
on the left hand side, gcc on the right hand side. I wanted to avoid a big macro
for the whole argument and moved the stuff into two macros per argument.
*/
#ifndef _INC_ASMINTERFACE_H
#define _INC_ASMINTERFACE_H
#ifdef __SASC
#define ASM __asm
#define ASMR(x) register __ ## x
#define ASMREG(x)
#define SAVEDS __saveds
#else /* __SASC */
#ifdef __GNUC__
#define ASM
#define ASMR(x) register
#define ASMREG(x) __asm("" #x "")
#define SAVEDS __saveds
#else /* __GNUC__ */
#error "Compiler not supported yet in asminterface.h"
#endif /* __GNUC__ */
#endif /* __SASC */
#endif /* _INC_ASMINTERFACE_H */
File diff suppressed because it is too large Load Diff
-318
View File
@@ -1,318 +0,0 @@
/*
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 "asminterface.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: 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( 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 */
-608
View File
@@ -1,608 +0,0 @@
/*
* hw.c - hardware dependent part of driver
*/
#define DEBUG 0
/* 15 */
/*F*/ /* includes */
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#endif
#ifndef CLIB_DOS_PROTOS_H
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#endif
#ifndef CLIB_CIA_PROTOS_H
#include <clib/cia_protos.h>
#include <pragmas/cia_pragmas.h>
#endif
#ifndef CLIB_MISC_PROTOS_H
#include <clib/misc_protos.h>
#include <pragmas/misc_pragmas.h>
#endif
#ifndef CLIB_TIME_PROTOS_H
#include <clib/timer_protos.h>
#include <pragmas/timer_pragmas.h>
#endif
#ifndef CLIB_UTILITY_PROTOS_H
#include <clib/utility_protos.h>
#include <pragmas/utility_pragmas.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef EXEC_INTERRUPTS_H
#include <exec/interrupts.h>
#endif
#ifndef EXEC_DEVICES_H
#include <exec/devices.h>
#endif
#ifndef EXEC_IO_H
#include <exec/io.h>
#endif
#ifndef DEVICES_SANA2_H
#include <devices/sana2.h>
#endif
#ifndef HARDWARE_CIA_H
#include <hardware/cia.h>
#endif
#include <hardware/intbits.h>
#ifndef RESOURCES_MISC_H
#include <resources/misc.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif
#ifndef __GLOBAL_H
#include "global.h"
#endif
#ifndef __DEBUG_H
#include "debug.h"
#endif
#ifndef __COMPILER_H
#include "compiler.h"
#endif
#ifndef __HW_H
#include "hw.h"
#endif
#include "dev_info.h"
#ifdef PROTO_SDNET
#include "enc28j60.h"
#define HW_INTERVALDEF 10000L
#endif
#ifdef PROTO_ENC624NET
#include "enc624j6l.h"
#include "registers.h"
/* 10000 without HW interrupt 100000 with HW interrupt */
#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 */
/* write_frame, see server.c, too. .oO(move this into .h) */
typedef enum { AW_OK, AW_BUFFER_ERROR, AW_ERROR } AW_RESULT;
#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_);
#endif
/* this is currently necessary on Apollo Core. We don't have an interrupt on the SD card slot */
/* used also with ENC624 (albeit with 10x longer default waiting) should we miss some interrupts */
#include "intervaltimer.h"
#define HW_INTERVAL
#define HW_INTERVALMIN 2500L
#define HW_INTERVALMAX 500000L
/* TODO: remove. I think I won't need this for the SDnet */
PRIVATE ULONG ASM SAVEDS exceptcode(REG(d0) ULONG sigmask, REG(a1) struct PLIPBase *hwb);
const char *intname = "ENC624Net_HWInterrupt";
/* just to make SAS/C happy, no other function */
int _avoid_sasc_warning_about_global_symbols( void );
int _avoid_sasc_warning_about_global_symbols( void )
{
return 0;
}
#ifdef PROTO_ENC624NET
PRIVATE void stopInt(struct PLIPBase *pb, struct HWBase *hwb, APTR board )
{
if( hwb->hwb_Interrupt.is_Data )
{
hwb->hwb_Interrupt.is_Data = (0);
enc624j6l_DisableInterrupt( board );
RemIntServer( HW_INTSOURCE, &hwb->hwb_Interrupt );
hwb->hwb_Interrupt.is_Code = (0);
}
}
PRIVATE void startInt(struct PLIPBase *pb, struct HWBase *hwb, APTR board )
{
if( hwb->hwb_Interrupt.is_Data )
stopInt( pb, hwb, board );
enc624j6l_EnableInterrupt( BOARD, FindTask(0), (int)hwb->hwb_IntSig, 0 );
hwb->hwb_Interrupt.is_Code = (void(*)())enc624j6l_IntServer;
hwb->hwb_Interrupt.is_Data = board;
hwb->hwb_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
hwb->hwb_Interrupt.is_Node.ln_Pri = 51;
hwb->hwb_Interrupt.is_Node.ln_Name = (char*)intname;
AddIntServer( HW_INTSOURCE, &hwb->hwb_Interrupt );
}
#endif
/* write_frame moved from server.c to here, because it directly interfaces with
network module in this driver, active only when ENC624_OPT is given on compiler
command line */
#ifdef ENC624_OPT
/*
** write frames direcly to HW
* CAUTION: don't mix up with hw_send_frame() / enc624j6l_TransmitFrame --
* the double buffered write location is not shared right now
*
* logic in here
* - swap buffer
* - write into buffer
* - wait for previous frame to finish (most likely there is no waiting time)
* - issue HW TX command
*
*/
/*F*/ GLOBAL REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2)
{
AW_RESULT rc;
struct HWBase *hwb = &pb->pb_HWBase;
struct BufferManagement *bm;
ULONG tl,totsize;
unsigned short *s_wrptr,*s_tmp1;
UBYTE *b_hwio_ptr = BOARD; /* somewhere $e80000 and beyond */
/* Note Link Change check moved to main loop */
d(("owrite: type %08lx, size %ld\n",ios2->ios2_PacketType,
ios2->ios2_DataLength));
hwb->hwb_txdbuf = (hwb->hwb_txdbuf & PSwapTX) ^ PSwapTX; /* swap buffers (+sanity check by "&") */
s_wrptr = (USHORT*)(b_hwio_ptr + hwb->hwb_txdbuf); /* next write location (byte->short) */
if(!(ios2->ios2_Req.io_Flags & SANA2IOF_RAW))
{ /* structured SANAII Request, not a valid Ethernet Frame (yet) */
/* Q: What about a length field and SNAP ? -> relevant here? */
/* write Ethernet header by hand: DMAC,SMAC,TYPE */
s_tmp1 = (USHORT*)ios2->ios2_DstAddr;
*s_wrptr++ = *s_tmp1++; *s_wrptr++ = *s_tmp1++; *s_wrptr++ = *s_tmp1; /* copy 6 bytes */
s_tmp1 = (USHORT*)pb->pb_CfgAddr;
*s_wrptr++ = *s_tmp1++; *s_wrptr++ = *s_tmp1++; *s_wrptr++ = *s_tmp1; /* copy 6 bytes */
*s_wrptr++ = (USHORT)ios2->ios2_PacketType; /* copy 2 bytes TYPE field */
totsize = HW_ETH_HDR_SIZE + ios2->ios2_DataLength; /* 14; */
}
else
{ /* RAW, pre-formatted Ethernet frame (sans CRC32) */
totsize = ios2->ios2_DataLength; /* */
}
/* copy frame to HW without a step in between (i.e. directly to mmapped card) */
bm = (struct BufferManagement *)ios2->ios2_BufferManagement;
if( (*bm->bm_CopyFromBuffer)(s_wrptr, ios2->ios2_Data, ios2->ios2_DataLength) )
{
/* buffer delivered to HW, now trigger actual TX */
/* waste time should the last frame still be in TX (unlikely) */
/* 100 MBit/s frame time is max. 0.12 ms (without inter-frame spacing) */
tl=0;
while( READREG(b_hwio_ptr,ECON1) & ECON1_TXRTS )
{
if( ++tl > 100000 ) /* this read cylces through ZII/ZIII and still not finished ? */
{
CLRREG( b_hwio_ptr, ECON1, ECON1_TXRTS ); /* give up, cancel last transmission */
break;
}
}
/*------ set new frame parameters ----------- */
WRITEREG( b_hwio_ptr, ETXST, hwb->hwb_txdbuf ); /* write location */
WRITEREG( b_hwio_ptr, ETXLEN,totsize ); /* frame TX length (-CRC) */
SETREG( b_hwio_ptr, ECON1, ECON1_TXRTS ); /* trigger TX */
rc = AW_OK;
}
else
{
/* meh: What's so hard about copying some bytes ? */
rc = AW_BUFFER_ERROR;
}
return rc;
}
#endif
/*
** check for link change
* - call ASM file for that task
* - the relevant flag is set by the interrupt handler and in that case,
* a number of registers is reconfigured accordingly
*
*/
/*F*/ GLOBAL REGARGS void hw_check_link_change( BASEPTR )
{
struct HWBase *hwb = &pb->pb_HWBase;
enc624j6l_CheckLinkChange(BOARD); /* somewhere $e80000 and beyond */
}
/*
magic: HW_MAGIC_OFFLINE, HW_MAGIC_ONLINE
return TRUE/FALSE
*/
GLOBAL REGARGS BOOL hw_send_magic_pkt(struct PLIPBase *pb, USHORT magic)
{
struct HWBase *hwb = &pb->pb_HWBase;
if( magic == HW_MAGIC_ONLINE )
{
#ifdef PROTO_ENC624NET
enc624j6l_SetMAC( BOARD, pb->pb_CfgAddr );
enc624j6l_SetOnline( BOARD );
startInt(pb, hwb, BOARD );
#else
enc28j60_setMAC( pb->pb_CfgAddr ); /* update MAC address (just in case) */
enc28j60_setOnline(); /* acticate RX */
#endif
#ifdef HW_INTERVAL
StartIntervalTimer( &hwb->hwb_ivtimer, hwb->hwb_timervalue ); /* 10000L */
#endif
}
if( magic == HW_MAGIC_OFFLINE )
{
#ifdef PROTO_ENC624NET
stopInt(pb, hwb, BOARD );
enc624j6l_SetOffline( BOARD );
#else
enc28j60_setOffline(); /* stop RX */
#endif
#ifdef HW_INTERVAL
StopIntervalTimer( &hwb->hwb_ivtimer );
#endif
}
return TRUE;
}
/*
setup defaults in plipbase
*/
GLOBAL REGARGS void hw_config_init(struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
hwb->hwb_timervalue = HW_INTERVALDEF;
hwb->hwb_fullduplex = 0;
#ifndef PROTO_ENC624NET
hwb->hwb_spispeed = 1; /* optimistic default */
#endif
hwb->hwb_multicast = 0;
hwb->hwb_flowcontrol= 0; /* no flow control by default */
}
GLOBAL REGARGS void hw_config_update(struct PLIPBase *pb, struct TemplateConfig *args)
{
struct HWBase *hwb = &pb->pb_HWBase;
if( args->timervalue )
{
hwb->hwb_timervalue = BOUNDS(*args->timervalue, HW_INTERVALMIN, HW_INTERVALMAX );
}
#ifndef PROTO_ENC624NET
if( args->spispeed )
{
hwb->hwb_spispeed = BOUNDS(*args->spispeed, 1, 20 );
}
#endif
if( args->fullduplex )
{
hwb->hwb_fullduplex = 1;
}
if( args->multicast )
{
hwb->hwb_multicast = 1;
}
if( args->flowcontrol )
{
hwb->hwb_flowcontrol = 1;
}
}
GLOBAL REGARGS void hw_config_dump(struct PLIPBase *pb)
{
/*
#if DEBUG & 1
struct HWBase *hwb = &pb->pb_HWBase;
#endif
d(("timeOut %ld.%ld\n", hwb->hwb_TimeOutSecs, hwb->hwb_TimeOutMicros));
d(("burstSize %ld\n", (ULONG)hwb->hwb_BurstSize));
*/
}
GLOBAL REGARGS BOOL hw_init(struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
/*ULONG tst;*/
BOOL rc = FALSE;
/* clone sys base, process */
hwb->hwb_SysBase = pb->pb_SysBase;
hwb->hwb_Server = pb->pb_Server;
hwb->hwb_MaxFrameSize = (UWORD)pb->pb_MTU + HW_ETH_HDR_SIZE;
d2(("sysbase=%08lx, server=%08lx, hwb=%08lx, maxFrameSize=%ld\n",
hwb->hwb_SysBase, hwb->hwb_Server, hwb, (ULONG)hwb->hwb_MaxFrameSize));
hwb->hwb_Interrupt.is_Data = (0); /* prepare interrupt */
hwb->hwb_Interrupt.is_Code = (0);
/*tst = AllocSignal(-1);*/
/* interesting: we get CTRL-F by default. Indidentally the same signal used for the write queue */
if ((hwb->hwb_IntSig = AllocSignal(-1)) != -1)
{
hwb->hwb_IntSigMask = 1L << hwb->hwb_IntSig;
d2(("int sigmask=%08lx\n",hwb->hwb_IntSigMask));
/*FreeSignal(tst);*/
if ((hwb->hwb_TimeoutPort = CreateMsgPort()))
{
ULONG sigmask;
struct Process *proc = pb->pb_Server;
/* save old exception setup */
hwb->hwb_OldExcept = SetExcept(0, 0xffffffff); /* turn'em off */
hwb->hwb_OldExceptCode = proc->pr_Task.tc_ExceptCode;
hwb->hwb_OldExceptData = proc->pr_Task.tc_ExceptData;
/* create new exception setup */
proc->pr_Task.tc_ExceptCode = (APTR)&exceptcode;
proc->pr_Task.tc_ExceptData = (APTR)pb;
sigmask = 1 << hwb->hwb_TimeoutPort->mp_SigBit;
SetSignal(0, sigmask);
SetExcept(sigmask, sigmask);
/* enter port address */
hwb->hwb_TimeoutReq.tr_node.io_Message.mn_ReplyPort = hwb->hwb_TimeoutPort;
if (!OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest*)&hwb->hwb_TimeoutReq, 0))
{
TimerBase = (struct Library *)hwb->hwb_TimeoutReq.tr_node.io_Device;
/* setup the timeout stuff */
hwb->hwb_TimeoutReq.tr_node.io_Flags = IOF_QUICK;
hwb->hwb_TimeoutReq.tr_node.io_Command = TR_ADDREQUEST;
hwb->hwb_TimeoutSet = 0xff;
#ifdef HW_INTERVAL
if( InitIntervalTimer( &hwb->hwb_ivtimer ) > 0 )
{
hwb->hwb_IntervalSigMask = hwb->hwb_ivtimer.IVT_Signal;
}
else
{
d(("couldn't open Interval Timer"));
}
#endif
rc = TRUE;
}
else
{
d(("couldn't open timer.device"));
}
}
else
{
d(("no port for timeout handling\n"));
}
}
else
{
d(("no interrupt signal\n",rc));
}
return rc;
}
GLOBAL REGARGS VOID hw_cleanup(struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
#ifdef HW_INTERVAL
ExitIntervalTimer( &hwb->hwb_ivtimer );
#endif
if (hwb->hwb_TimeoutPort)
{
struct Process *proc = pb->pb_Server;
/* restore old exception setup */
SetExcept(0, 0xffffffff); /* turn'em off */
proc->pr_Task.tc_ExceptCode = hwb->hwb_OldExceptCode;
proc->pr_Task.tc_ExceptData = hwb->hwb_OldExceptData;
SetExcept(hwb->hwb_OldExcept, 0xffffffff);
if (TimerBase)
{
WaitIO((struct IORequest*)&hwb->hwb_TimeoutReq);
CloseDevice((struct IORequest*)&hwb->hwb_TimeoutReq);
}
DeleteMsgPort(hwb->hwb_TimeoutPort);
}
if (hwb->hwb_IntSig != -1) {
FreeSignal(hwb->hwb_IntSig);
}
}
/*
* hwattach - setup hardware if device gets online
*/
GLOBAL REGARGS BOOL hw_attach(struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
BOOL rc = TRUE;
unsigned char flags;
flags = PIO_INIT_BROAD_CAST;
if( hwb->hwb_multicast )
flags |= PIO_INIT_MULTI_CAST;
if( hwb->hwb_fullduplex )
flags |= PIO_INIT_FULL_DUPLEX;
if( hwb->hwb_flowcontrol )
flags |= PIO_INIT_FLOW_CONTROL;
#ifdef PROTO_ENC624NET
if( enc624j6l_Init( BOARD, (unsigned long)flags ) <= 0 )
rc = FALSE; /* ERROR IN CASE OF DEVICE NOT FOUND */
#else
if( enc28j60_init( pb->pb_CfgAddr, flags ) != PIO_OK )
rc = FALSE; /* ERROR IN CASE OF DEVICE NOT FOUND */
enc28j60_SetSPISpeed( (unsigned long)hwb->hwb_spispeed );
#endif
return rc;
}
/*
* shutdown hardware if device gets offline
*/
GLOBAL REGARGS VOID hw_detach(struct PLIPBase *pb)
{
#ifdef PROTO_ENC624NET
struct HWBase *hwb = &pb->pb_HWBase;
stopInt(pb, hwb, BOARD );
enc624j6l_Shutdown( BOARD );
#else
enc28j60_exit();
#endif
}
PRIVATE ULONG ASM SAVEDS exceptcode(REG(d0) ULONG sigmask, REG(a1) struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
d8(("+ex\n"));
/*extern void KPrintF(char *,...);
KPrintF("exceptcode\n");*/
/* remove the I/O Block from the port */
WaitIO((struct IORequest*)&hwb->hwb_TimeoutReq);
/* this tells the xfer routines to cease polling */
hwb->hwb_TimeoutSet = 0xff;
d8(("-ex\n"));
return sigmask; /* re-enable the signal */
}
GLOBAL REGARGS BOOL hw_send_frame(struct PLIPBase *pb, struct HWFrame *frame)
{
BOOL rc = TRUE;
#ifdef PROTO_ENC624NET
struct HWBase *hwb = &pb->pb_HWBase;
unsigned char *frm = (unsigned char*)frame;
enc624j6l_TransmitFrame( BOARD, frm+sizeof(USHORT), frame->hwf_Size );
; frame->hwf_Size = 0;
#else
const u08 *frm = (const u08*)frame;
enc28j60_send(frm+sizeof(USHORT), frame->hwf_Size );
#endif
return rc;
}
GLOBAL REGARGS LONG hw_recv_pending(struct PLIPBase *pb)
{
#ifdef PROTO_ENC624NET
struct HWBase *hwb = &pb->pb_HWBase;
LONG num = enc624j6l_HaveRecv( BOARD );
#else
u08 num;
num = enc28j60_has_recv();
#endif
return (LONG)num;
}
GLOBAL REGARGS void hw_enable_global_int(struct PLIPBase *pb){
#ifdef PROTO_ENC624NET
struct HWBase *hwb = &pb->pb_HWBase;
enc624j6l_EnableGlobalInterrupt( BOARD );
#endif
}
GLOBAL REGARGS void hw_disable_global_int(struct PLIPBase *pb){
#ifdef PROTO_ENC624NET
struct HWBase *hwb = &pb->pb_HWBase;
enc624j6l_DisableGlobalInterrupt( BOARD );
#endif
}
/* important: don't call this without enc28j60_has_recv() > 0 check */
GLOBAL REGARGS BOOL hw_recv_frame(struct PLIPBase *pb, struct HWFrame *frame)
{
#ifdef PROTO_ENC624NET
int len;
BOOL rc = FALSE;
unsigned char *ptr = (unsigned char*)frame;
struct HWBase *hwb = &pb->pb_HWBase;
len = enc624j6l_RecvFrame( BOARD, ptr+sizeof(USHORT), 1522 );
frame->hwf_Size = len;
if( len > 0 )
rc = TRUE;
#else
BOOL rc = FALSE;
u08 *ptr = (u08*)frame;
if( PIO_OK == enc28j60_recv( ptr+sizeof(USHORT), 1518, &frame->hwf_Size ) )
rc = TRUE;
#endif
return rc;
}
GLOBAL REGARGS ULONG hw_recv_sigmask(struct PLIPBase *pb)
{
struct HWBase *hwb = &pb->pb_HWBase;
return hwb->hwb_IntSigMask | hwb->hwb_IntervalSigMask;
}
-97
View File
@@ -1,97 +0,0 @@
/* hwbase.h - hardware specific part of driver structure */
#ifndef __HWBASE_H
#define __HWBASE_H
#include "intervaltimer.h"
/* ----- base structure for hardware ----- */
/* reported BPS (bits! per second) for this device */
#define HW_BPS (10000000L) /* 10 MBit/s */
/* ENC624: MAX. Zorro Boards (untested, probably doesn't work) */
#define HW_MAXBOARDS 3
struct HWBase
{
/* used in asm module */
struct Library * hwb_SysBase;
struct Process * hwb_Server;
ULONG hwb_IntSigMask;
UWORD hwb_MaxFrameSize;
volatile UBYTE hwb_TimeoutSet;/* if != 0, a timeout occurred */
volatile UBYTE hwb_Flags;
/* NOT used in asm */
ULONG hwb_IntSig; /* sent from int to server */
ULONG hwb_IntervalSigMask;
struct MsgPort * hwb_TimeoutPort; /* for timeout handling */
struct Library * hwb_TimerBase;
struct Library * hwb_MiscBase; /* various libs & res. */
APTR hwb_OldExceptCode;
APTR hwb_OldExceptData;
ULONG hwb_OldExcept;
struct Interrupt hwb_Interrupt; /* for AddICRVector() */
struct timerequest hwb_TimeoutReq; /* for timeout handling */
ULONG hwb_AllocFlags;
APTR hwb_boards[HW_MAXBOARDS+1]; /* 0-terminated */
struct IVT_TimerStruct hwb_ivtimer; /* Timer interval handling (via Interrupt) */
#ifdef ENC624_OPT
USHORT hwb_txdbuf; /* TX double buffering location (0x0/0x600) */
USHORT hwb_unused_free_for_future;
#endif
/* config options */
ULONG hwb_timervalue; /* timer speed */
UBYTE hwb_fullduplex; /* full duplex */
UBYTE hwb_flowcontrol; /* flow control enable (1/0) */
UBYTE hwb_multicast; /* multicast enable */
UBYTE hwb_free_unused1;
#ifndef PROTO_ENC624NET
ULONG hwb_spispeed; /* SPI speed */
#endif
};
#define HWB_RECV_PENDING 0
#define HWB_COLL_TIMER_RUNNING 1
#define HWF_RECV_PENDING (1 << HWB_RECV_PENDING)
/* transparently map proto lib bases to structure */
#define MiscBase hwb->hwb_MiscBase
#define CIAABase hwb->hwb_CIAABase
#define CiaBase hwb->hwb_CIAABase
#define TimerBase hwb->hwb_TimerBase
/* ----- config ----- */
#define CONFIGFILE "ENV:SANA2/enc624j6net.config"
#ifdef PROTO_ENC624NET
#define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,MULTICAST/S,FLOWCONTROL/S"
/* structure to be filled by ReadArgs template */
struct TemplateConfig
{
struct CommonConfig common;
ULONG *timervalue;
ULONG fullduplex;
ULONG multicast;
ULONG flowcontrol;
};
#else /* PROTO_ENC624NET */
#define TEMPLATE "TIMER/K/N,FULLDUPLEX/S,SPISPEED/K/N,MULTICAST/S"
/* structure to be filled by ReadArgs template */
struct TemplateConfig
{
struct CommonConfig common;
ULONG *timervalue;
ULONG fullduplex;
ULONG *spispeed;
ULONG multicast;
ULONG flowcontrol;
};
#endif /* PROTO_ENC624NET */
#endif
@@ -1,328 +0,0 @@
******************************************************************************
* 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
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
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
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
; 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_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)
not.l d0 ; if( d0 == -1 ) d0 = 0
beq .error ; error: have to go (shouldn't happen)
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
cmp.l #-1,d0
beq .nosig
CALLEXEC FreeSignal
move.l #-1,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
dos_name: dc.b "dos.library",0
VBtimer_name: dc.b "timer.device",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
END
@@ -1,56 +0,0 @@
/*
******************************************************************************
* 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;
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 "asminterface.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 */
@@ -1,26 +0,0 @@
******************************************************************************
* 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
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
@@ -1,126 +0,0 @@
; ------------------------------------------------------------------------------
; | 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
-606
View File
@@ -1,606 +0,0 @@
/* ------------------------------------------------------------------------------ */
/* | 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_ */
-602
View File
@@ -1,602 +0,0 @@
; ------------------------------------------------------------------------------
; | 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
-188
View File
@@ -1,188 +0,0 @@
#ifndef __GLOBAL_H
#define __GLOBAL_H
/* system header files */
#ifndef DEVICES_SANA2_H
#include <devices/sana2.h>
#endif
#ifndef EXEC_SEMAPHORES_H
#include <exec/semaphores.h>
#endif
#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif
#ifndef EXEC_INTERRUPTS_H
#include <exec/interrupts.h>
#endif
#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif
#ifndef DOS_DOS_H
#include <dos/dos.h>
#endif
#ifndef __COMPILER_H
#include "compiler.h"
#endif
#ifndef __HW_H
#include "hw.h"
#endif
/****************************************************************************/
/* return val, cut to min or max if exceeding range */
#define BOUNDS(val, min, max) ((val) <= (max) ? ((val) >= (min) ? (val) :\
(min)) : (max))
/* memory economy is *everything* :-) */
#define SERVERTASKNAME pb->pb_DevNode.lib_Node.ln_Name
struct TrackRec {
struct MinNode tr_Link;
ULONG tr_PacketType;
ULONG tr_Count;
struct Sana2PacketTypeStats tr_Sana2PacketTypeStats;
};
/****************************************************************************/
typedef BOOL (* ASM BMFunc)(REG(a0) void *, REG(a1) void *, REG(d0) LONG);
struct BufferManagement
{
struct MinNode bm_Node;
BMFunc bm_CopyFromBuffer;
BMFunc bm_CopyToBuffer;
};
/****************************************************************************/
/*
** sent to the server task after being CreateNewProc()ed
*/
struct ServerStartup
{
struct Message ss_Msg;
struct PLIPBase *ss_PLIPBase;
BOOL ss_Error;
UBYTE ss_Pad[2];
};
/****************************************************************************/
enum { S2SS_TXERRORS, S2SS_COLLISIONS, S2SS_COUNT };
/*
** This count will record the number of packets that failed
** to be transmitted.
*/
#define S2SS_PLIP_TXERRORS ((((S2WireType_Ethernet) & 0xffff) << 16) | (S2SS_TXERRORS))
/*
** This count will record the number of line arbitration collisions
*/
#define S2SS_PLIP_COLLISIONS ((((S2WireType_Ethernet) & 0xffff) << 16) | (S2SS_COLLISIONS))
/****************************************************************************/
struct PLIPBase
{
struct Library pb_DevNode; /* basic device structure */
UBYTE pb_Unit; /* unit of 1st OpenDevice() */
UBYTE pb_pad1; /* make the following long alligned */
BPTR pb_SegList; /* pointer to code */
struct Library * pb_VampireBase; /* used for sdnet only */
struct Library * pb_ExpansionBase;
struct Library * pb_UtilityBase;
struct Library * pb_DOSBase;
struct Library * pb_SysBase;
struct ServerStartup * pb_Startup; /* main server proces */
struct Process * pb_Server; /* main server proces */
struct Task * pb_Task; /* used for server shutdown */
ULONG pb_ServerStoppedSigMask; /* for shutdown */
struct MsgPort * pb_ServerPort; /* for IOReq forwarding */
struct Sana2DeviceStats pb_DevStats; /* SANA-2 wants this */
struct Sana2SpecialStatRecord
pb_SpecialStats[S2SS_COUNT];
volatile struct List pb_ReadList, /* the readers */
pb_WriteList, /* the writers */
pb_EventList, /* event tracking */
pb_ReadOrphanList, /* for spurious packets */
pb_TrackList, /* track type */
pb_BufferManagement; /* Copy-In/Out */
struct SignalSemaphore pb_EventListSem, /* protection for lists */
pb_ReadListSem,
pb_WriteListSem,
pb_TrackListSem,
pb_ReadOrphanListSem,
pb_Lock;
LONG pb_ExpansionPort; /* allocated expansion port */
volatile UBYTE pb_Flags; /* see below */
UBYTE pb_pad2;
volatile UWORD pb_ExtFlags; /* see below */
UBYTE pb_CfgAddr[HW_ADDRFIELDSIZE];
UBYTE pb_DefAddr[HW_ADDRFIELDSIZE];
struct HWBase pb_HWBase;
struct HWFrame * pb_Frame;
ULONG pb_BPS;
ULONG pb_MTU;
};
#ifdef __SASC
/*
** redirect all shared library bases to our device base.
*/
# define SysBase pb->pb_SysBase
# define DOSBase pb->pb_DOSBase
# define UtilityBase pb->pb_UtilityBase
# define VampireBase pb->pb_VampireBase
# define ExpansionBase pb->pb_ExpansionBase
/*
** This macro declares a local variable which temporary gets
** SysBase directly from AbsExecBase.
*/
# define LOCALSYSBASE struct { void *pb_SysBase; } *pb = (void*)0x4
/*
** Use this macro as argument for all functions which need to
** have access to your data base.
*/
# define BASEPTR struct PLIPBase *pb
#else
# error Please define library bases for your compiler
#endif
/*
** Values for PLIPBase->pb_Flags
** Note that the Flags field is intentionally only 8 bits wide so that
** the ASM parts may use the bit functions.
*/
#define PLIPB_REPLYSS 0 /* server-startup must be replied */
#define PLIPB_EXCLUSIVE 1 /* current opener is exclusive */
#define PLIPB_OFFLINE 2 /* currently not online (sic!) */
#define PLIPB_SERVERSTOPPED 3 /* set by server while passing away */
#define PLIPF_REPLYSS (1<<PLIPB_REPLYSS)
#define PLIPF_EXCLUSIVE (1<<PLIPB_EXCLUSIVE)
#define PLIPF_OFFLINE (1<<PLIPB_OFFLINE)
#define PLIPF_SERVERSTOPPED (1<<PLIPB_SERVERSTOPPED)
/*
** Values for PLIPBase->pb_ExtFlags
*/
#define PLIPEB_NOSPECIALSTATS 0 /* don't report special stats */
#define PLIPEF_NOSPECIALSTATS (1<<PLIPEB_NOSPECIALSTATS)
#endif
-64
View File
@@ -1,64 +0,0 @@
/* hw.h - hardware module of plihwbox.device */
#ifndef __HW_H
#define __HW_H
/* ----- hardware frame structure ----- */
/* magic packet types */
#define HW_MAGIC_ONLINE 0xffff
#define HW_MAGIC_OFFLINE 0xfffe
#define HW_MAGIC_LOOPBACK 0xfffd
/* transport ethernet addresses */
#define HW_ADDRFIELDSIZE 6
#define HW_ETH_HDR_SIZE 14 /* ethernet header: dst, src, type */
#define HW_ETH_MTU 1500
struct HWFrame {
USHORT hwf_Size;
/* use layout of ethernet header here */
UBYTE hwf_DstAddr[HW_ADDRFIELDSIZE];
UBYTE hwf_SrcAddr[HW_ADDRFIELDSIZE];
USHORT hwf_Type;
/*UBYTE hwf_Data[MTU];*/
};
/* ----- config stuff ----- */
#define COMMON_TEMPLATE "NOSPECIALSTATS/S,PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,"
struct CommonConfig {
ULONG nospecialstats;
LONG *priority;
ULONG *bps;
ULONG *mtu;
};
/* fetch device specific device base */
#include "hwbase.h"
struct PLIPBase;
/* hw API */
GLOBAL REGARGS BOOL hw_init(struct PLIPBase *pb);
GLOBAL REGARGS VOID hw_cleanup(struct PLIPBase *pb);
GLOBAL REGARGS BOOL hw_attach(struct PLIPBase *pb);
GLOBAL REGARGS VOID hw_detach(struct PLIPBase *pb);
GLOBAL REGARGS BOOL hw_send_frame(struct PLIPBase *pb, struct HWFrame *frame);
GLOBAL REGARGS BOOL hw_send_magic_pkt(struct PLIPBase *pb, USHORT magic);
GLOBAL REGARGS ULONG hw_recv_sigmask(struct PLIPBase *pb);
GLOBAL REGARGS LONG hw_recv_pending(struct PLIPBase *pb);
GLOBAL REGARGS BOOL hw_recv_frame(struct PLIPBase *pb, struct HWFrame *frame);
GLOBAL REGARGS void hw_config_init(struct PLIPBase *pb);
GLOBAL REGARGS void hw_config_update(struct PLIPBase *pb, struct TemplateConfig *cfg);
GLOBAL REGARGS void hw_config_dump(struct PLIPBase *pb);
GLOBAL REGARGS void hw_enable_global_int(struct PLIPBase *pb);
GLOBAL REGARGS void hw_disable_global_int(struct PLIPBase *pb);
GLOBAL REGARGS void hw_check_link_change(struct PLIPBase *pb);
#endif
-1
View File
@@ -1 +0,0 @@
libsize equ 728
-8
View File
@@ -1,8 +0,0 @@
#include <stdio.h>
#include "global.h"
int main(int argc, char **argv)
{
printf("libsize equ %d\n", sizeof(struct PLIPBase));
return 0;
}
Binary file not shown.
-88
View File
@@ -1,88 +0,0 @@
IFND EXEC_NODES_I
INCLUDE "exec/nodes.i"
ENDC
IFND EXEC_RESIDENT_I
INCLUDE "exec/resident.i"
ENDC
IFND EXEC_INITIALIZERS_I
INCLUDE "exec/initializers.i"
ENDC
IFND EXEC_LIBRARIES_I
INCLUDE "exec/libraries.i"
ENDC
IFND DOS_DOS_I
INCLUDE "dos/dos.i"
ENDC
include "libsize.auto.i"
include "dev_info.i"
xref _DevInit
xref _DevOpen
xref _DevClose
xref _DevExpunge
xref _DevExtFunc
xref _DevBeginIO
xref _DevAbortIO
section "text",code
moveq #RETURN_FAIL,d0
rts
romtag:
dc.w RTC_MATCHWORD
dc.l romtag
dc.l endskip
dc.b RTF_AUTOINIT
dc.b DEVICE_VERSION
dc.b NT_DEVICE
dc.b 0 ; priority
dc.l devname
dc.l devid
dc.l inittable
devname:
DEVICE_NAME
dc.b ".device",0
dc.b 0,'$VER: '
devid:
DEVICE_NAME
dc.b " "
DEVICE_VER
dc.b " ("
DEVICE_DATE
dc.b ")",13,10,0
cnop 0,2
inittable:
dc.l libsize
dc.l functable,datatable,_DevInit
functable:
dc.l _DevOpen
dc.l _DevClose
dc.l _DevExpunge
dc.l stub
dc.l _DevBeginIO
dc.l _DevAbortIO
dc.l -1
datatable:
INITBYTE LN_TYPE,NT_DEVICE
INITLONG LN_NAME,devname
INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
INITWORD LIB_VERSION,DEVICE_VERSION
INITWORD LIB_REVISION,DEVICE_REVISION
INITLONG LIB_IDSTRING,devid
dc.w 0
stub:
moveq #0,d0
rts
endskip:
END
-780
View File
@@ -1,780 +0,0 @@
#define DEBUG 0
/*F*/ /* includes */
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#endif
#ifndef CLIB_DOS_PROTOS_H
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef DEVICES_SANA2_H
#include <devices/sana2.h>
#endif
#ifndef CLIB_TIME_PROTOS_H
#include <clib/timer_protos.h>
#include <pragmas/timer_pragmas.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif
#ifndef __GLOBAL_H
#include "global.h"
#endif
#ifndef __DEBUG_H
#include "debug.h"
#endif
#ifndef __COMPILER_H
#include "compiler.h"
#endif
#ifndef __HW_H
#include "hw.h"
#endif
/*E*/
/*F*/ /* defines, types and enums */
/*
** return codes for write_frame()
*/
typedef enum { AW_OK, AW_BUFFER_ERROR, AW_ERROR } AW_RESULT;
/*
** definitions
*/
#define SINGLE_RW 1
#define MAX_READ_PACKAGE 128
/*E*/
/*F*/ /* imports */
/* external functions */
GLOBAL VOID dotracktype(BASEPTR, ULONG type, ULONG ps, ULONG pr, ULONG bs, ULONG br, ULONG pd);
GLOBAL VOID DevTermIO(BASEPTR, struct IOSana2Req *ios2);
/*E*/
/*F*/ /* exports */
PUBLIC VOID SAVEDS ServerTask(void);
/*E*/
/*F*/ /* private */
PRIVATE struct PLIPBase *startup(void);
PUBLIC REGARGS VOID DoEvent(BASEPTR, long event);
PRIVATE VOID readargs(BASEPTR);
PRIVATE BOOL init(BASEPTR);
PRIVATE REGARGS BOOL goonline(BASEPTR);
PRIVATE REGARGS VOID gooffline(BASEPTR);
PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2);
PRIVATE REGARGS VOID dowritereqs(BASEPTR);
PRIVATE REGARGS VOID doreadreqs(BASEPTR);
PRIVATE REGARGS VOID dos2reqs(BASEPTR);
/*E*/
/*
** functions to go online/offline
*/
/*F*/ PRIVATE REGARGS VOID rejectpackets(BASEPTR)
{
struct IOSana2Req *ios2;
ObtainSemaphore(&pb->pb_WriteListSem);
while(ios2 = (struct IOSana2Req *)RemHead((struct List*)&pb->pb_WriteList))
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
DevTermIO(pb,ios2);
}
ReleaseSemaphore(&pb->pb_WriteListSem);
ObtainSemaphore(&pb->pb_ReadListSem);
while(ios2 = (struct IOSana2Req *)RemHead((struct List*)&pb->pb_ReadList))
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
DevTermIO(pb,ios2);
}
ReleaseSemaphore(&pb->pb_ReadListSem);
ObtainSemaphore(&pb->pb_ReadOrphanListSem);
while(ios2 = (struct IOSana2Req *)RemHead((struct List*)&pb->pb_ReadOrphanList))
{
ios2->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
ios2->ios2_WireError = S2WERR_UNIT_OFFLINE;
DevTermIO(pb,ios2);
}
ReleaseSemaphore(&pb->pb_ReadOrphanListSem);
}
/*E*/
/*F*/ PRIVATE REGARGS BOOL goonline(BASEPTR)
{
BOOL rc = TRUE;
d(("trying to go online\n"));
if (pb->pb_Flags & PLIPF_OFFLINE)
{
if (!hw_attach(pb))
{
d(("error going online\n"));
rc = FALSE;
}
else
{
struct HWBase *hwb = &pb->pb_HWBase;
/* send magic */
hw_send_magic_pkt(pb, HW_MAGIC_ONLINE);
GetSysTime(&pb->pb_DevStats.LastStart);
pb->pb_Flags &= ~PLIPF_OFFLINE;
DoEvent(pb, S2EVENT_ONLINE);
d(("i'm now online!\n"));
}
}
return rc;
}
/*E*/
/*F*/ PRIVATE REGARGS VOID gooffline(BASEPTR)
{
if (!(pb->pb_Flags & PLIPF_OFFLINE))
{
hw_send_magic_pkt(pb, HW_MAGIC_OFFLINE);
hw_detach(pb);
pb->pb_Flags |= PLIPF_OFFLINE;
DoEvent(pb, S2EVENT_OFFLINE);
}
d(("ok!\n"));
}
/*E*/
/*
** SANA-2 Event management
*/
/*F*/ PUBLIC REGARGS VOID DoEvent(BASEPTR, long event)
{
struct IOSana2Req *ior, *ior2;
d(("event is %lx\n",event));
ObtainSemaphore(&pb->pb_EventListSem );
for(ior = (struct IOSana2Req *) pb->pb_EventList.lh_Head;
ior2 = (struct IOSana2Req *) ior->ios2_Req.io_Message.mn_Node.ln_Succ;
ior = ior2 )
{
if (ior->ios2_WireError & event)
{
Remove((struct Node*)ior);
DevTermIO(pb, ior);
}
}
ReleaseSemaphore(&pb->pb_EventListSem );
}
/*E*/
/* moved this function out to hw.c for the ENC624 variant */
#ifndef ENC624_OPT
/*
** writing packets
*/
/*F*/ PUBLIC REGARGS AW_RESULT write_frame(BASEPTR, struct IOSana2Req *ios2)
{
AW_RESULT rc;
struct HWFrame *frame = pb->pb_Frame;
struct BufferManagement *bm;
UBYTE *frame_ptr;
d(("write: type %08lx, size %ld\n",ios2->ios2_PacketType,
ios2->ios2_DataLength));
/* copy raw frame: simply overwrite ethernet frame part of plip packet */
if(ios2->ios2_Req.io_Flags & SANA2IOF_RAW) {
frame->hwf_Size = ios2->ios2_DataLength;
frame_ptr = &frame->hwf_DstAddr[0];
} else {
frame->hwf_Size = ios2->ios2_DataLength + HW_ETH_HDR_SIZE;
frame->hwf_Type = (USHORT)ios2->ios2_PacketType;
memcpy(frame->hwf_SrcAddr, pb->pb_CfgAddr, HW_ADDRFIELDSIZE);
memcpy(frame->hwf_DstAddr, ios2->ios2_DstAddr, HW_ADDRFIELDSIZE);
frame_ptr = (UBYTE *)(frame + 1);
}
bm = (struct BufferManagement *)ios2->ios2_BufferManagement;
if (!(*bm->bm_CopyFromBuffer)(frame_ptr,
ios2->ios2_Data, ios2->ios2_DataLength))
{
rc = AW_BUFFER_ERROR;
}
else
{
d8(("+hw_send\n"));
rc = hw_send_frame(pb, frame) ? AW_OK : AW_ERROR;
d8(("-hw_send\n"));
#if DEBUG&8
if(rc==AW_ERROR) d8(("Error sending packet (size=%ld)\n", (LONG)pb->pb_Frame->hwf_Size));
#endif
}
return rc;
}
/*E*/
#endif /* ENC624_OPT */
/*F*/ PRIVATE REGARGS VOID dowritereqs(BASEPTR)
{
struct IOSana2Req *currentwrite, *nextwrite;
AW_RESULT code;
ObtainSemaphore(&pb->pb_WriteListSem);
#if 0
/* test only */
currentwrite = (struct IOSana2Req *)pb->pb_WriteList.lh_Head;
if( currentwrite->ios2_Req.io_Message.mn_Node.ln_Succ )
#else
for(currentwrite = (struct IOSana2Req *)pb->pb_WriteList.lh_Head;
nextwrite = (struct IOSana2Req *) currentwrite->ios2_Req.io_Message.mn_Node.ln_Succ;
currentwrite = nextwrite )
#endif
{
code = write_frame(pb, currentwrite);
if (code == AW_BUFFER_ERROR) /* BufferManagement callback error */
{
d(("buffer error\n"));
DoEvent(pb, S2EVENT_ERROR | S2EVENT_BUFF | S2EVENT_SOFTWARE);
pb->pb_SpecialStats[S2SS_TXERRORS].Count++;
d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count));
currentwrite->ios2_Req.io_Error = S2ERR_SOFTWARE;
currentwrite->ios2_WireError = S2WERR_BUFF_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
else if (code == AW_ERROR)
{
/*
** this is a real line error, upper levels (e.g. Internet TCP) have
** to care for reliability!
*/
d(("error while transmitting packet\n"));
DoEvent(pb, S2EVENT_ERROR | S2EVENT_TX | S2EVENT_HARDWARE);
pb->pb_SpecialStats[S2SS_TXERRORS].Count++;
d(("pb->pb_SpecialStats[S2SS_TXERRORS].Count = %ld\n",pb->pb_SpecialStats[S2SS_TXERRORS].Count));
currentwrite->ios2_Req.io_Error = S2ERR_TX_FAILURE;
currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
else /*if (code == AW_OK)*/ /* well done! */
{
d(("packet transmitted successfully\n"));
pb->pb_DevStats.PacketsSent++;
dotracktype(pb, (ULONG) pb->pb_Frame->hwf_Type, 1, 0, currentwrite->ios2_DataLength, 0, 0);
currentwrite->ios2_Req.io_Error = S2ERR_NO_ERROR;
currentwrite->ios2_WireError = S2WERR_GENERIC_ERROR;
Remove((struct Node*)currentwrite);
DevTermIO(pb, currentwrite);
}
}
ReleaseSemaphore(&pb->pb_WriteListSem);
}
/*E*/
PRIVATE REGARGS BOOL read_frame(struct IOSana2Req *req, struct HWFrame *frame)
{
int i;
BOOL broadcast;
LONG datasize;
BYTE *frame_ptr;
struct BufferManagement *bm;
BOOL ok;
/* deliver a raw frame: copy data right into ethernet header */
if(req->ios2_Req.io_Flags & SANA2IOF_RAW) {
frame_ptr = &frame->hwf_DstAddr[0];
datasize = frame->hwf_Size;
req->ios2_Req.io_Flags = SANA2IOF_RAW;
}
else {
frame_ptr = (UBYTE *)(frame + 1);
datasize = frame->hwf_Size - HW_ETH_HDR_SIZE;
req->ios2_Req.io_Flags = 0;
}
req->ios2_DataLength = datasize;
/* copy packet buffer */
bm = (struct BufferManagement *)req->ios2_BufferManagement;
if (!(*bm->bm_CopyToBuffer)(req->ios2_Data, frame_ptr, datasize))
{
d(("CopyToBuffer: error\n"));
req->ios2_Req.io_Error = S2ERR_SOFTWARE;
req->ios2_WireError = S2WERR_BUFF_ERROR;
ok = FALSE;
}
else
{
req->ios2_Req.io_Error = req->ios2_WireError = 0;
ok = TRUE;
}
/* now extract addresses from ethernet header */
memcpy(req->ios2_SrcAddr, frame->hwf_SrcAddr, HW_ADDRFIELDSIZE);
memcpy(req->ios2_DstAddr, frame->hwf_DstAddr, HW_ADDRFIELDSIZE);
/* need to set broadcast flag? */
broadcast = TRUE;
for(i=0;i<HW_ADDRFIELDSIZE;i++) {
if(frame->hwf_DstAddr[i] != 0xff) {
broadcast = FALSE;
break;
}
}
if(broadcast) {
req->ios2_Req.io_Flags |= SANA2IOF_BCAST;
}
/* store packet type */
req->ios2_PacketType = (USHORT)frame->hwf_Type;
return ok;
}
/*
** reading packets
*/
/*F*/ PRIVATE REGARGS VOID doreadreqs(BASEPTR)
{
LONG datasize;
struct IOSana2Req *got;
ULONG pkttyp;
BOOL rv,ok;
struct HWFrame *frame = pb->pb_Frame;
/* while(hw_recv_pending(pb)){ */
while(1){
/* if(1){ */
d8(("+hw_recv\n"));
rv = hw_recv_frame(pb, frame);
d8(("-hw_recv\n"));
if (rv)
{
pb->pb_DevStats.PacketsReceived++;
pkttyp = frame->hwf_Type;
#if 0
/* perform internal loop back of magic packets of type 0xfffd */
if(pkttyp == HW_MAGIC_LOOPBACK) {
d(("loop back packet (size %ld)\n",frame->hwf_Size));
hw_send_frame(pb, frame);
return;
}
/* plipbox requests online magic (again) */
if(pkttyp == HW_MAGIC_ONLINE) {
d(("request online magic"));
hw_send_magic_pkt(pb, HW_MAGIC_ONLINE);
return;
}
#endif
datasize = frame->hwf_Size - HW_ETH_HDR_SIZE;
dotracktype(pb, pkttyp, 0, 1, 0, datasize, 0);
d(("packet %08lx, size %ld received\n",pkttyp,datasize));
ok = FALSE;
ObtainSemaphore(&pb->pb_ReadListSem);
/* traverse the list of read-requests */
for(got = (struct IOSana2Req *)pb->pb_ReadList.lh_Head;
got->ios2_Req.io_Message.mn_Node.ln_Succ;
got = (struct IOSana2Req *)got->ios2_Req.io_Message.mn_Node.ln_Succ )
{
/* check if this one requests for the new packet we got */
if (got->ios2_PacketType == pkttyp )
{
Remove((struct Node*)got);
ok =TRUE;
break;
}
}
ReleaseSemaphore(&pb->pb_ReadListSem);
if(!ok){
/* If no one wanted this packet explicitely, there is one chance
** left: somebody waiting for orphaned packets. If this fails, too,
** we will drop it.
*/
d(("unknown packet\n"));
pb->pb_DevStats.UnknownTypesReceived++;
ObtainSemaphore(&pb->pb_ReadOrphanListSem);
got = (struct IOSana2Req *)RemHead((struct List*)&pb->pb_ReadOrphanList);
ReleaseSemaphore(&pb->pb_ReadOrphanListSem);
if (got)
{
d(("orphan read\n"));
ok=TRUE;
}
}
if(ok){
/* deliver packet */
ok = read_frame(got, frame);
if(!ok) {
DoEvent(pb, S2EVENT_ERROR | S2EVENT_BUFF | S2EVENT_SOFTWARE);
}
d(("packet received, satisfying S2Request\n"));
DevTermIO(pb, got);
}
else{
/* throw it away*/
dotracktype(pb, pkttyp, 0, 0, 0, 0, 1);
d(("packet thrown away...\n"));
}
/* got = NULL; */
}
else
{
#if 1
break;
#else
d(("Error receiving (%ld. len=%ld)\n", rv, frame->hwf_Size));
/* something went wrong during receipt */
DoEvent(pb, S2EVENT_HARDWARE | S2EVENT_ERROR | S2EVENT_RX);
got = NULL;
pb->pb_DevStats.BadData++;
#endif
}
}
}
/*E*/
/*
** 2nd level device command dispatcher (~SANA2IOF_QUICK)
*/
/*F*/ PRIVATE REGARGS VOID dos2reqs(BASEPTR)
{
struct IOSana2Req *ios2;
/*
** Every pending IO message will be GetMsg()'ed and processed. At the
** end of the loop it will be DevTermIO()'ed back to the sender,
** _but_only_if_ it is non-NULL. In such cases the message has been
** put in a separate queue to be DevTermIO()'ed later (i.e. CMD_WRITEs
** and similar stuff).
** You find the same mimique in the 1st level dispatcher (device.c)
*/
while(ios2 = (struct IOSana2Req *)GetMsg(pb->pb_ServerPort))
{
d(("sana2req %ld from serverport\n", ios2->ios2_Req.io_Command));
switch (ios2->ios2_Req.io_Command)
{
case S2_ONLINE:
if (!goonline(pb))
{
ios2->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
ios2->ios2_WireError = S2WERR_GENERIC_ERROR;
}
break;
case S2_OFFLINE:
gooffline(pb);
rejectpackets(pb); /* reject all pending requests */
break;
case S2_CONFIGINTERFACE:
/* copy address from src addr */
memcpy(pb->pb_CfgAddr, ios2->ios2_SrcAddr, HW_ADDRFIELDSIZE);
/* if already online then first go offline */
if(!(pb->pb_Flags & PLIPF_OFFLINE)) {
gooffline(pb);
}
/* now go online */
if (!goonline(pb))
{
ios2->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
ios2->ios2_WireError = S2WERR_GENERIC_ERROR;
}
break;
}
if (ios2) DevTermIO(pb,ios2);
}
}
/*E*/
/*
** startup,initialisation and termination functions
*/
/*F*/ PRIVATE struct PLIPBase *startup(void)
{
struct ServerStartup *ss;
struct Process *we;
struct PLIPBase *base;
LOCALSYSBASE;
we = (struct Process*)FindTask(NULL);
d(("waiting for startup msg...\n"));
WaitPort(&we->pr_MsgPort);
ss = (struct ServerStartup *)GetMsg(&we->pr_MsgPort);
base = ss->ss_PLIPBase;
base->pb_Startup = ss;
d(("go startup msg at %lx, PLIPBase is %lx\n", ss, ss->ss_PLIPBase));
/* we will keep the startup message, to inform mother if we
** really could come up or if we failed to obtain some
** resource.
*/
return base;
}
/*E*/
#define PLIP_MINPRIORITY -128
#define PLIP_MAXPRIORITY 127
/*F*/ PRIVATE VOID readargs(BASEPTR)
{
struct RDArgs *rda;
struct TemplateConfig args = { 0 };
BPTR cfginput, oldinput;
d(("entered\n"));
hw_config_init(pb);
if (cfginput = Open(CONFIGFILE, MODE_OLDFILE))
{
d(("opened cfg\n"));
oldinput = SelectInput(cfginput);
rda = ReadArgs(COMMON_TEMPLATE TEMPLATE, (LONG *)&args, NULL);
if(rda)
{
d(("got args\n"));
/* common options */
if (args.common.priority)
SetTaskPri((struct Task*)pb->pb_Server,
BOUNDS(*args.common.priority, PLIP_MINPRIORITY, PLIP_MAXPRIORITY));
if (args.common.nospecialstats)
pb->pb_ExtFlags |= PLIPEF_NOSPECIALSTATS;
if(args.common.mtu)
pb->pb_MTU = *args.common.mtu;
if(args.common.bps)
pb->pb_BPS = *args.common.bps;
/* special config */
hw_config_update(pb, &args);
FreeArgs(rda);
}
Close(SelectInput(oldinput));
}
/* dump default config options */
d(("pri %ld, flags %08lx\n", (LONG)pb->pb_Server->pr_Task.tc_Node.ln_Pri, pb->pb_Flags));
hw_config_dump(pb);
d(("left\n"));
}
/*E*/
/*F*/ PRIVATE BOOL init(BASEPTR)
{
BOOL rc = FALSE;
readargs(pb);
if ((pb->pb_ServerPort = CreateMsgPort()))
{
/* init hardware */
if(hw_init(pb)) {
ULONG size = (ULONG)sizeof(struct HWFrame);
if( pb->pb_MTU > 1518 )
size += pb->pb_MTU + 16;
else size += 1518 + 4;
d(("allocating 0x%lx/%ld bytes frame buffer\n",size,size));
if ((pb->pb_Frame = AllocVec(size, MEMF_CLEAR|MEMF_ANY)))
{
rc = TRUE;
}
else
{
d(("couldn't allocate frame buffer\n"));
}
}
else
{
d(("hw init failed\n"));
}
}
else
{
d(("no server port\n"));
}
d(("left %ld\n",rc));
return rc;
}
/*E*/
/*F*/ PRIVATE VOID cleanup(BASEPTR)
{
struct BufferManagement *bm;
gooffline(pb);
while(bm = (struct BufferManagement *)RemHead((struct List *)&pb->pb_BufferManagement))
FreeVec(bm);
if (pb->pb_Frame) FreeVec(pb->pb_Frame);
hw_cleanup(pb);
if (pb->pb_ServerPort) DeleteMsgPort(pb->pb_ServerPort);
if (pb->pb_Flags & PLIPF_REPLYSS)
{
Forbid();
ReplyMsg((struct Message*)pb->pb_Startup);
}
}
/*E*/
/*
** entry point, mainloop
*/
/*F*/ PUBLIC VOID SAVEDS ServerTask(void)
{
BASEPTR;
d(("server running\n"));
if (pb = startup())
{
/* if we fail to allocate all resources, this flag reminds cleanup()
** to ReplyMsg() the startup message
*/
pb->pb_Flags |= PLIPF_REPLYSS;
if (init(pb))
{
ULONG recv, portsigmask, recvsigmask, wmask,specialmask;
LONG haverec;
BOOL running;
struct IOSana2Req *wr;
/* Ok, we are fine and will tell this mother personally :-) */
pb->pb_Startup->ss_Error = 0;
/* don't forget this, or we will have to keep a warm place */
/* in our coffin for the system */
pb->pb_Flags &= ~PLIPF_REPLYSS;
ReplyMsg((struct Message*)pb->pb_Startup);
portsigmask = 1 << pb->pb_ServerPort->mp_SigBit;
recvsigmask = hw_recv_sigmask(pb);
specialmask = portsigmask | SIGBREAKF_CTRL_C;
wmask = SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_C | portsigmask | recvsigmask;
/* main loop of server task */
d(("--- server main loop: %08lx ---\n", wmask));
for(running=TRUE;running;)
{
d4(("** wmask is 0x%08lx\n", wmask));
/* send packets if any */
d2(("*+ do_write\n"));
wr = (struct IOSana2Req *)pb->pb_WriteList.lh_Head;
if( wr->ios2_Req.io_Message.mn_Node.ln_Succ )
{
dowritereqs(pb);
}
d2(("*- do_write\n"));
/* if no recv is pending then wait for incoming signals */
haverec = hw_recv_pending(pb);
recv = 0;
if( !haverec ) /* if( (!haverec) && (!wr->ios2_Req.io_Message.mn_Node.ln_Succ) ) */
{
d2(("**> wait\n"));
hw_enable_global_int(pb);
/* we've got some spare time here: check for link change condition */
hw_check_link_change(pb);
recv = Wait(wmask);
d2(("**> wait: got 0x%08lx\n", recv));
/*haverec = hw_recv_pending(pb);*/
}
/* accept pending receive and start reading */
d2(("*+ do_read\n"));
doreadreqs(pb);
d2(("*- do_read\n"));
if( recv & specialmask )
{
/* handle SANA-II send requests */
if (recv & portsigmask)
{
d(("SANA-II request(s)\n"));
dos2reqs(pb);
recv &= ~portsigmask;
}
/* stop server task */
if (recv & SIGBREAKF_CTRL_C)
{
d(("received break signal\n"));
running = FALSE;
}
}
} /*main loop of server task*/
}
else
d(("init() failed\n"));
d(("--- server exit main loop ---\n"));
cleanup(pb);
/* Exec will enable it's scheduler after we're dead. */
Forbid();
/* signal mother we're done */
if (pb->pb_ServerStoppedSigMask)
Signal(pb->pb_Task, pb->pb_ServerStoppedSigMask);
pb->pb_Flags |= PLIPF_SERVERSTOPPED;
}
else
d(("no startup packet\n"));
}
/*E*/
-256
View File
@@ -1,256 +0,0 @@
#sc:c/smake
#
#####################################################################
#
# $VER: smakefile 0.8 (09-Jan-2017)
# Henryk Richter
#
# based on Magplip build file
#####################################################################
#
DEVICE_DATE = 16.04.2018
DEVICE_VERSION = 0
DEVICE_REVISION = 3
# see below for EXTRAOBJ, disable for plipbox, enable for sdnet/enc624j6net
HWSRCDIR = enc624j6net
DEVICE_NAME = enc624j6net
DEFS = DEFINE PROTO_ENC624NET=1
# direct SANA-II to HW Write without intermediate buffer
# don`t enable on current (Feb2018) CPLD, byte swap issue
# JIC after 25-Apr-2018 will fix the byte swap on byte write
#DEFINE ENC624_OPT=1
# quick hack/test to write directly - didn't work out well for me
#DEFINE DIRECT_WRITE=1
#####################################################################
#
# I keep various include trees, so for this project I directly reference
# the SAS/C installation for include paths
# The ASM stuff assumes the library offsets in "lvo/*", change if
# desired
#
LIBS = LIB sc:LIB/amiga.lib LIB sc:lib/sc.lib LIB sc:lib/debug.lib
CINCLUDES = INCDIR="sc:include" INCDIR="sc:netinclude" INCDIR="$(HWSRCDIR)"
#ASMINCLUDES = INCDIR="INCLUDE:" $(CINCLUDES)
ASMINCLUDES = -Isc:include -I$(HWSRCDIR)
CPUSUFFIX = 020 # 020 030 040 060 (note: asm sources use 020+ code in some places)
CPUCCOPT = CPU=68$(CPUSUFFIX)
CP = C:Copy
MV = C:Rename
RM = C:Delete >NIL:
LD = sc:c/slink
CC = sc:c/sc
AS = vasmm68k_mot
MAKE = sc:c/smake
ECHO = Echo
SUFFIX = $(PRSUFFIX)$(CPUSUFFIX)
#
#####################################################################
#####################################################################
#
# naming
#
DEVICE_DIR = build
BASENAME = $(DEVICE_NAME)
NAME = $(DEVICE_NAME).device
TESTNAME = enc624j6test
#
#####################################################################
#####################################################################
#
# assembler/compiler flags
#
# this applies to normal and optimized compilation:
#
STDFLAGS = $(CINCLUDES) NOMULTIPLEINCLUDES ERRREXX COMMENTNEST NOSTKCHK NOCHKABORT\
SMALLCODE SMALLDATA VERBOSE NOICONS STRICT ANSI $(DEFS)
#
# this applies only to normal compilation:
#
NORMCFLAGS = $(STDFLAGS)
#
# this applies only to optimized compilation:
#
OPTCFLAGS = $(STDFLAGS) $(CPUCCOPT) PARAMETERS=REGISTERS OPT OPTTIME OPTINLINE\
OPTSCHEDULE STRINGMERGE STRUCTUREEQUIVALENCE
#
# this applies to assembler compilation
#
#AFLAGS = CPU=68020 VERBOSE DEFINE $(PROTOCOL)PLIP=1
AFLAGS = -Fhunk -devpac -m68020 -quiet
#
#####################################################################
#####################################################################
#
# linkage flags
#
#LDFLAGS = NOICONS SC MAP bla.map $(LIBS) TO
LDFLAGS = NOICONS SC $(LIBS) TO
OPTLDFLAGS = NOICONS SC SD ND $(LIBS) TO
#
#####################################################################
#####################################################################
#
# the object files
#
# these are extra files for ENC624J6Net, disable for plipbox build
EXTRAOBJ=$(HWSRCDIR)/enc624j6l.o $(HWSRCDIR)/intervaltimer.o
EXTRAOBJOPT=$(HWSRCDIR)/enc624j6l.o $(HWSRCDIR)/intervaltimer.o
# these are for Plipbox build
#EXTRAOBJ=$(HWSRCDIR)/hwpar.o
#EXTRAOBJOPT=$(HWSRCDIR)/hwpar.o
#
# device support files
NORMOBJ=rt.o device.no server.no track.no $(HWSRCDIR)/hw.no $(EXTRAOBJ)
OPTOBJ=rt.o device.opt$(CPUSUFFIX) server.opt$(CPUSUFFIX) track.opt$(CPUSUFFIX) \
$(HWSRCDIR)/hw.opt$(CPUSUFFIX) $(EXTRAOBJOPT)
#
# Auto-generated includes
DEVINFO_INC=dev_info.i
DEVINFO_HINC=dev_info.h
BUILDDEPS=libsize.auto.i $(DEVINFO_INC) $(DEVINFO_HINC)
#
#
#####################################################################
#####################################################################
#
# rules
#
# compile a file normally
#
.c.no: $(BUILDDEPS)
$(CC) $(NORMCFLAGS) OBJECTNAME $@ $*.c
#
# compile a file optimizing
#
.c.opt$(SUFFIX): $(BUILDDEPS)
$(CC) $(OPTCFLAGS) OBJECTNAME $@ $*.c
# DISASM $@.disas.s
#
# assemble a file
#
#.asm.o: $(BUILDDEPS)
# $(AS) $(AFLAGS) OBJECTNAME $@ $*.asm
.asm.o: $(BUILDDEPS)
$(AS) $(AFLAGS) $(ASMINCLUDES) -o $@ $*.asm
.s.o: $(BUILDDEPS)
$(AS) $(AFLAGS) $(ASMINCLUDES) -o $@ $*.asm
#
#####################################################################
#####################################################################
#
# targets
#
help:
-@Echo "Usage:"
-@Echo "To make an unoptimized version"
-@Echo " $(MAKE) all"
-@Echo "To make an optimized version"
-@Echo " $(MAKE) all_opt"
-@Echo "To %remove all intermediate files"
-@Echo " %$(MAKE) clean"
all: $(DEVICE_DIR)/$(NAME)
# $(TESTNAME)
all_opt: $(DEVICE_DIR)/$(NAME).$(CPUSUFFIX)
clean_norm:
-@$(RM) *.o
-@$(RM) *.no
-@$(RM) $(DEVICE_DIR)/$(NAME)
-@$(RM) $(HWSRCDIR)/*.no
-@$(RM) $(HWSRCDIR)/*.o
clean_opt:
-@$(RM) *.o
-@$(RM) *.opt* $(HWSRCDIR)/*.opt*
-@$(RM) $(HWSRCDIR)/*.o $(EXTRAOBJOPT)
-@$(RM) $(DEVICE_DIR)/$(NAME).$(CPUSUFFIX)
clean: clean_norm clean_opt
-@$(RM) $(DEVINFO_HINC) $(DEVINFO_INC) $(EXTRAOBJ) libsize.auto.i libsize.exe
$(DEVICE_DIR)/$(NAME).$(CPUSUFFIX): $(OPTOBJ) $(BUILDDEPS)
$(LD) $(OPTOBJ) $(OPTLDFLAGS) $@
$(DEVICE_DIR)/$(NAME): $(NORMOBJ)
$(LD) $(NORMOBJ) $(LDFLAGS) $@
$(TESTNAME) : $(NORMOBJ) sdnettest.no
$(LD) sc:lib/c.o sdnettest.no $(NORMOBJ) LIB sc:lib/scnb.lib $(LDFLAGS) $@
#
# libsize.auto.i is used in rt.asm, this is an extra step (needing an AmigaOS
# environment) but ensures that the hwbase and plipbase sizes are "current"
#
libsize.auto.i : libsize.exe
-@libsize.exe >$@
libsize.exe : libsize.c global.h $(HWSRCDIR)/hwbase.h
-@$(CC) $(NORMCFLAGS) OBJECTNAME t:libsize.o libsize.c
-@$(LD) sc:lib/c.o t:libsize.o LIB sc:lib/scnb.lib $(LDFLAGS) $@
-@$(RM) t:libsize.o
# --- dev_info.i ---
$(DEVINFO_INC): smakefile
@Echo "DEVICE_NAME MACRO" > $(DEVINFO_INC)
@Echo " dc.b '$(DEVICE_NAME)'" >> $(DEVINFO_INC)
@Echo " ENDM" >> $(DEVINFO_INC)
@Echo "DEVICE_DATE MACRO" >> $(DEVINFO_INC)
@Echo " dc.b '$(DEVICE_DATE)'" >> $(DEVINFO_INC)
@Echo " ENDM" >> $(DEVINFO_INC)
@Echo "DEVICE_VER MACRO" >> $(DEVINFO_INC)
@Echo " dc.b '$(DEVICE_VERSION).$(DEVICE_REVISION)'" >> $(DEVINFO_INC)
@Echo " ENDM" >> $(DEVINFO_INC)
@Echo "DEVICE_VERSION equ $(DEVICE_VERSION)" >> $(DEVINFO_INC)
@Echo "DEVICE_REVISION equ $(DEVICE_REVISION)" >> $(DEVINFO_INC)
# --- dev_info.h ---
$(DEVINFO_HINC): smakefile
-@Echo "\#ifndef _DEV_INFO_H" > $(DEVINFO_HINC)
-@Echo "\#define _DEV_INFO_H" >> $(DEVINFO_HINC)
-@Echo "\#define DEVICE_NAME " NOLINE >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" NOLINE FIRST=2
-@Echo NOLINE "$(DEVICE_NAME)" >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" FIRST=2
-@Echo "\#define DEVICE_DATE " NOLINE >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" NOLINE FIRST=2
-@Echo NOLINE "$(DEVICE_DATE)" >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" FIRST=2
-@Echo "\#define DEVICE_VER " NOLINE >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" NOLINE FIRST=2
-@Echo NOLINE "$(DEVICE_VERSION).$(DEVICE_REVISION)" >> $(DEVINFO_HINC)
-@Echo >> $(DEVINFO_HINC) !" FIRST=2
-@Echo "\#define DEVICE_VERSION $(DEVICE_VERSION)" >> $(DEVINFO_HINC)
-@Echo "\#define DEVICE_REVISION $(DEVICE_REVISION)" >> $(DEVINFO_HINC)
-@Echo "\#endif" >> $(DEVINFO_HINC)
#
#####################################################################
#####################################################################
#
# various dependencies (most from Magplip, unmodified so far)
#
rt.o: rt.asm $(DEVINFO_HINC) $(DEVINFO_INC) libsize.auto.i
$(PROTOCOL)device.opt$(SUFFIX) device.no: device.c global.h
$(PROTOCOL)server.opt$(SUFFIX) server.no: server.c global.h
$(PROTOCOL)track.opt$(SUFFIX) track.no: track.c global.h
#
#####################################################################
Binary file not shown.
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
enc624j6l.o
-6
View File
@@ -1,6 +0,0 @@
@set ASM_INCLUDE="C:\Users\Matze\Amiga\SoftwareHacks\NDK_3.1\INCLUDES_LIBS\INCLUDE_I"
del *.o
del TestENC
vasm -quiet -align -Fhunk -I.. -I%ASM_INCLUDE% -ldots -nosym -opt-speed -o enc624j6l.o enc624j6l.asm
vlink -Bstatic -bamigahunk -L"C:\Users\Matze\Amiga\SoftwareHacks\NDK_3.1\INCLUDES_LIBS\LINKER_LIBS" -l"AMIGA" -l"DEBUG" -o"TestENC" -s -F files.txt
Binary file not shown.
Binary file not shown.
-153
View File
@@ -1,153 +0,0 @@
/*F*/ /* includes */
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif
#ifndef EXEC_NODES_H
#include <exec/nodes.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif
#ifndef __GLOBAL_H
#include "global.h"
#endif
#ifndef __DEBUG_H
#include "debug.h"
#endif
/*E*/
/*F*/ /* exports */
PUBLIC BOOL addtracktype(BASEPTR, ULONG type);
PUBLIC BOOL remtracktype(BASEPTR, ULONG type);
PUBLIC VOID dotracktype(BASEPTR, ULONG type, ULONG ps, ULONG pr, ULONG bs, ULONG br, ULONG pd);
PUBLIC BOOL gettrackrec(BASEPTR, ULONG type, APTR info);
PUBLIC VOID freetracktypes(BASEPTR);
/*E*/
/*F*/ /* private */
PRIVATE struct TrackRec *findtracktype(BASEPTR, ULONG type);
/*E*/
/*F*/ PRIVATE INLINE struct TrackRec *findtracktype(BASEPTR, ULONG type)
{
struct TrackRec * tr;
for (tr = (struct TrackRec *) pb->pb_TrackList.lh_Head; tr->tr_Link.mln_Succ;
tr = (struct TrackRec *) tr->tr_Link.mln_Succ)
{
if( tr->tr_PacketType == type )
{
#if 0
/* simple MTF for PacketType search */
if( (struct Node*)tr != pb->pb_TrackList.lh_Head )
{
Remove( (struct Node*)tr );
AddHead( (struct List*)&pb->pb_TrackList, (struct Node*)tr );
}
#endif
return( tr );
}
}
return( NULL );
}
/*E*/
/*F*/ PUBLIC BOOL addtracktype(BASEPTR, ULONG type)
{
struct TrackRec *tr;
BOOL rv = FALSE;
ObtainSemaphore(&pb->pb_TrackListSem);
if (!(tr = findtracktype(pb, type)))
{
if (tr = AllocVec(sizeof(*tr), MEMF_CLEAR))
{
tr->tr_Count = 1;
tr->tr_PacketType = type;
AddTail((struct List*)&pb->pb_TrackList, (struct Node *)tr);
rv = TRUE;
}
}
else
{
++tr->tr_Count;
rv = TRUE;
}
ReleaseSemaphore(&pb->pb_TrackListSem);
return rv;
}
/*E*/
/*F*/ PUBLIC BOOL remtracktype(BASEPTR, ULONG type)
{
struct TrackRec *tr;
BOOL rv = FALSE;
ObtainSemaphore( &pb->pb_TrackListSem );
if (tr = findtracktype(pb, type))
{
if (!(--tr->tr_Count))
{
Remove((struct Node *)tr);
FreeVec(tr);
}
rv = TRUE;
}
ReleaseSemaphore( &pb->pb_TrackListSem );
return rv;
}
/*E*/
/*F*/ PUBLIC VOID dotracktype(BASEPTR, ULONG type, ULONG ps, ULONG pr, ULONG bs, ULONG br, ULONG pd)
{
struct TrackRec * tr;
ObtainSemaphore(&pb->pb_TrackListSem);
if (tr = findtracktype(pb, type))
{
tr->tr_Sana2PacketTypeStats.PacketsSent += ps;
tr->tr_Sana2PacketTypeStats.PacketsReceived += pr;
tr->tr_Sana2PacketTypeStats.BytesSent += bs;
tr->tr_Sana2PacketTypeStats.BytesReceived += br;
tr->tr_Sana2PacketTypeStats.PacketsDropped += pd;
}
ReleaseSemaphore(&pb->pb_TrackListSem);
}
/*E*/
/*F*/ PUBLIC BOOL gettrackrec(BASEPTR, ULONG type, struct Sana2PacketTypeStats *info)
{
struct TrackRec * tr;
BOOL rv = FALSE;
ObtainSemaphoreShared( &pb->pb_TrackListSem );
if (tr = findtracktype(pb, type))
{
*info = tr->tr_Sana2PacketTypeStats;
rv = TRUE;
}
ReleaseSemaphore( &pb->pb_TrackListSem );
return rv;
}
/*E*/
/*F*/ PUBLIC VOID freetracktypes(BASEPTR)
{
struct Node *tr;
ObtainSemaphore(&pb->pb_TrackListSem);
while(tr = RemHead((struct List*)&pb->pb_TrackList))
FreeVec(tr);
ReleaseSemaphore(&pb->pb_TrackListSem);
}
/*E*/
Binary file not shown.
+1 -7
View File
@@ -1,12 +1,6 @@
These are the AmigaOS drivers for the subsystems of the board. These are the AmigaOS drivers for the subsystems of the board.
Please note that two Network drivers are present. The files in "enc624j6net"
are for the initial/legacy SANA-II driver, derived from the PlipBox code base.
The recommended SANA-II driver for the Ethernet port is located in "baxnet". The recommended SANA-II driver for the Ethernet port is located in "baxnet".
The "baxnet" based driver supports additional SANA-II features, is faster and
at supports more than one card at the same time.
Please use enc624j6net.device from baxnet/bin on MC68020 or faster CPUs. A cut-down version for 68000 and 68010 is provided as well. Please rename enc624j6net.device_68000 to enc624j6net.device before copying it to DEVS:Networks.
+10 -9
View File
@@ -1,10 +1,10 @@
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
-- Company: -- Company: a1k.org
-- Engineer: -- Engineer: M. Heinrichs, H. Richter
-- --
-- Create Date: 22:08:29 12/13/2016 -- Create Date: 14:45:29 07/15/2020
-- Design Name: -- Design Name:
-- Module Name: LAN_IDE_CP - Behavioral -- Module Name: LAN_IDE_CP-Z2v2 - Behavioral
-- Project Name: -- Project Name:
-- Target Devices: -- Target Devices:
-- Tool versions: -- Tool versions:
@@ -69,7 +69,6 @@ entity LAN_IDE_CP is
IDE_R : out STD_LOGIC; IDE_R : out STD_LOGIC;
IDE_A : out STD_LOGIC_VECTOR (2 downto 0); IDE_A : out STD_LOGIC_VECTOR (2 downto 0);
IDE_CS : out STD_LOGIC_VECTOR (1 downto 0); IDE_CS : out STD_LOGIC_VECTOR (1 downto 0);
-- LAN_CFG : out STD_LOGIC_VECTOR (4 downto 1);
LAN_RD : out STD_LOGIC; LAN_RD : out STD_LOGIC;
LAN_CS : out STD_LOGIC; LAN_CS : out STD_LOGIC;
LAN_WRH : out STD_LOGIC; LAN_WRH : out STD_LOGIC;
@@ -402,7 +401,7 @@ begin
elsif(AUTO_CONFIG_DONE = 1)then elsif(AUTO_CONFIG_DONE = 1)then
CP_BASEADR(7 downto 0) <= D(15 downto 8); --Base adress CP_BASEADR(7 downto 0) <= D(15 downto 8); --Base adress
SHUT_UP(1) <= '0'; --enable board SHUT_UP(1) <= '0'; --enable board
AUTO_CONFIG_DONE_CYCLE <= '1' & AUTOBOOT_OFF; --done here, if Autoboot = 1 skip ide part! AUTO_CONFIG_DONE_CYCLE <= '1' & not AUTOBOOT_OFF; --done here, if Autoboot = 1 skip ide part!
elsif(AUTO_CONFIG_DONE = 2)then elsif(AUTO_CONFIG_DONE = 2)then
IDE_BASEADR(7 downto 0) <= D(15 downto 8); --Base adress IDE_BASEADR(7 downto 0) <= D(15 downto 8); --Base adress
SHUT_UP(2) <= '0'; --enable board SHUT_UP(2) <= '0'; --enable board
@@ -424,7 +423,6 @@ begin
LAN_WRL <= LAN_WRL_S when AS='0' and reset = '1' else LAN_WR_RST; LAN_WRL <= LAN_WRL_S when AS='0' and reset = '1' else LAN_WR_RST;
LAN_WRH <= LAN_WRH_S when AS='0' and reset = '1' else LAN_WR_RST; LAN_WRH <= LAN_WRH_S when AS='0' and reset = '1' else LAN_WR_RST;
LAN_RD <= LAN_RD_S when AS='0' and reset = '1' else '0'; LAN_RD <= LAN_RD_S when AS='0' and reset = '1' else '0';
-- LAN_CFG <= "0010"; -- "ZZZZ";
CP_WE <= CP_WE_S when AS='0' and CP_WE_QUIRK ='1' else '1'; CP_WE <= CP_WE_S when AS='0' and CP_WE_QUIRK ='1' else '1';
CP_RD <= CP_RD_S when AS='0' else '1'; CP_RD <= CP_RD_S when AS='0' else '1';
@@ -437,7 +435,9 @@ begin
A(14 downto 7); A(14 downto 7);
A_LAN(5 downto 2) <= LAN_A_CLRREG(5 downto 2) when (LAN_RST_SM = wait0 or LAN_RST_SM = clr or LAN_RST_SM = clr_commit) else A_LAN(5 downto 2) <= LAN_A_CLRREG(5 downto 2) when (LAN_RST_SM = wait0 or LAN_RST_SM = clr or LAN_RST_SM = clr_commit) else
LAN_A_SETREG(5 downto 2) when (LAN_RST_SM = wait1 or LAN_RST_SM = set or LAN_RST_SM = set_commit) else LAN_A_SETREG(5 downto 2) when (LAN_RST_SM = wait1 or LAN_RST_SM = set or LAN_RST_SM = set_commit) else
A(5 downto 2) when cp='1' else A(6 downto 3); --mux the clock-port adresses! -- A(5 downto 2) when cp='1' else A(6 downto 3); --mux the clock-port adresses!
A(4 downto 1) when cp='1' else A(6 downto 3); --mux the clock-port adresses! (shifted 1 down due to V2 bug)
A_LAN(1 downto 0)<= LAN_A_CLRREG(1 downto 0) when (LAN_RST_SM = wait0 or LAN_RST_SM = clr or LAN_RST_SM = clr_commit) else A_LAN(1 downto 0)<= LAN_A_CLRREG(1 downto 0) when (LAN_RST_SM = wait0 or LAN_RST_SM = clr or LAN_RST_SM = clr_commit) else
LAN_A_SETREG(1 downto 0) when (LAN_RST_SM = wait1 or LAN_RST_SM = set or LAN_RST_SM = set_commit) else LAN_A_SETREG(1 downto 0) when (LAN_RST_SM = wait1 or LAN_RST_SM = set or LAN_RST_SM = set_commit) else
A(2 downto 1); A(2 downto 1);
@@ -468,7 +468,8 @@ begin
IDE_CS(1)<= not(A(13)); IDE_CS(1)<= not(A(13));
IDE_A(2 downto 0) <= A(11 downto 9); IDE_A(2 downto 0) <= A(11 downto 9);
ROM_B <= "00"; ROM_B <= "00";
ROM_OE <= ROM_OE_S when AS='0' and AUTOBOOT_OFF = '0' else '1'; -- ROM_OE <= ROM_OE_S when AS='0' and AUTOBOOT_OFF = '0' else '1';
ROM_OE <= ROM_OE_S when AS='0' else '1';
-- INT_OUT <= 'Z'; -- INT_OUT <= 'Z';
INT2_OUT <= '0' when INT2_OUT <= '0' when
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
Important: The Zorro-II firmware dated 15-Jul-2020 and later
changes the handling of the "IDE_OFF" jumper compared to earlier
firmwares. Now IDE_OFF now behaves as stated on the silkscreen
and will disable the IDE controller if the jumper is set.
This changed behaviour is consistent with the Zorro-III firmware
now.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -6
View File
@@ -1,13 +1,17 @@
# Zorro-LAN-IDE # Zorro-LAN-IDE
This is an Zorro-expansion card for the big Amigas (A2000/300/4000 or A500 with Zorro-interface). It has a SANAII-compatible Ethernet driver, an AT-BUS compatible IDE controller and a clockport for variuous expansions like a RapidRoard from Individual Computers. This is a Zorro-expansion card for the big Amigas (A2000/300/4000 or A500 with Zorro-interface). It has a SANAII-compatible Ethernet driver, an AT-BUS compatible IDE controller and a clockport for variuous expansions like a RapidRoard from Individual Computers.
Here is a pic of the first revision: Here is a pic of the first revision:
![Zorro-Card with LAN-Module](https://gitlab.com/MHeinrichs/Zorro-LAN-IDE/raw/master/Bilder/Aufgebaut.jpg) ![Zorro-Card with LAN-Module](https://gitlab.com/MHeinrichs/Zorro-LAN-IDE/raw/master/Bilder/Aufgebaut.jpg)
All components are Autoconfig. The FastEthernet is based on a ENC624J600 lan chip. The clockport is compatible to A600/A1200 ones but residies at a different address. The IDE works from Kickstart 1.3 to 3.1.4 ! All components are Autoconfig. The FastEthernet is based on a ENC624J600 lan chip. The clockport is compatible to A600/A1200 ones but resides at a different address. The IDE works from Kickstart 1.3 to 3.1.4 !
At present there are two firmwares: One for Zorro2, which runs in every Amiga with Zorro-Sots and one for A3000/4000, which puts the LAN-Chip into a Zorro3 environment. The while the Zorro2 variant can transfer 3.5mb/s at most the Zorro3-variant has a significantly faster LAN<->Amiga interface of 6-7mb/sec. Please note that these RAW data transfer numbers are not the only factor in LAN performance on Amiga and that the actual observed speeds with TCP transfers are in the range of 1-2 MB/s (depending on IP stack and CPU).
Here is a pic of the current board revision:
![Zorro-Card with onboard LAN chip](https://gitlab.com/MHeinrichs/Zorro-LAN-IDE/raw/master/Bilder/LANIDEv03.JPG)
At present there are two firmwares: One for Zorro2, which runs in every Amiga with Zorro-Sots and one for A3000/4000, which puts the LAN-Chip into a Zorro3 environment. The while the Zorro2 variant can transfer 3.5mb/s at most the Zorro3-variant has a signifficantly faster LAN<->Amiga interface of 6-7mb/sec. However, the SANAII-IP Stack is not very efficient and eats much of the performance, thus 1-2MB/sec are the maximum observed right now.
## Things to improve ## Things to improve
@@ -32,9 +36,9 @@ All sources published under GNU GENERAL PUBLIC LICENSE V2.0
## How to make the clockport work with a RapidRoad? ## How to make the clockport work with a RapidRoad?
Make sure you connected the cable the right way! There is no "standarized way". So the easiest thing is to find out on the RapidRoad side on which row of the clockport the two outer pins are ground. These Pins mus run to the row of the Zorro-LAN-IDE-CP-card where the squared solder-hole is located. *Please tripple check the cable with a multimeter! Wrong polarity of the cable can caus damage to your hardware!* Make sure you connected the cable the right way! There is no "standarized way". So the easiest thing is to find out on the RapidRoad side on which row of the clockport the two outer pins are ground. These Pins mus run to the row of the Zorro-LAN-IDE-CP-card where the squared solder-hole is located. *Please triple check the cable with a multimeter! Wrong polarity of the cable can cause damage to your hardware!*
Now you have to set up the driver to look for a clockport at the address of the expansion board. The address can be figured out by the system tool "ShowConfig" (Manufactor id: 2588 Product: 124). Now you have to set up the driver to look for a clockport at the address of the expansion board. The address can be figured out by the system tool "ShowConfig" (Manufactor id: 2588 Product: 124).
However, there is work on a software sollution, that the RapidRoad finds itself automatically! However, there is work on a software solution, that the RapidRoad finds itself automatically!
## What is in this repository? ## What is in this repository?
This repository consists of several directories: This repository consists of several directories:
@@ -53,7 +57,7 @@ You find the eagle board and schematic files (brd/sch) for the pcb. The software
You can generate Gerber-files from the brd files according to the specs of your PCB-manufactor. Some specs: min trace width: 0.15mm/6mil, min trace dist: 0.15mm/6mil, min drill: 0.3mm You can generate Gerber-files from the brd files according to the specs of your PCB-manufactor. Some specs: min trace width: 0.15mm/6mil, min trace dist: 0.15mm/6mil, min drill: 0.3mm
**ATTENTION: THE PCB has 4 layers!** **ATTENTION: THE PCB has 4 layers!**
**ATTENTION: Revision 2E has not been build yet!**
## How to get the parts? ## How to get the parts?
Most parts can be found on digikey or mouser or a parts supplier of your choice. Most parts can be found on digikey or mouser or a parts supplier of your choice.