updated baxnet SANA-II driver and Gerber files
- Enforcer hit fix - replaced V2 Gerbers by V3 Gerbers
This commit is contained in:
@@ -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,16 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
|
|||||||
Changelog:
|
Changelog:
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,18 @@ TIMER/K/N,MULTICAST/S
|
|||||||
Changelog:
|
Changelog:
|
||||||
----------
|
----------
|
||||||
|
|
||||||
2.00 - parse Vampire 4 UUID for MAC auto-assignment
|
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.
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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__ */
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -85,9 +93,9 @@ const ULONG blub[6] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* enable heavy debug (D2=beginIO) */
|
/* enable heavy debug (D2=beginIO) */
|
||||||
#define D2(x)
|
//#define D2(x)
|
||||||
#define D4(x)
|
#define D4(x)
|
||||||
/* #define D2(x) D(x) */
|
#define D2(x) D(x)
|
||||||
/* #define D4(x) D(x) */
|
/* #define D4(x) D(x) */
|
||||||
|
|
||||||
|
|
||||||
@@ -102,6 +110,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 +130,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 +165,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);
|
||||||
}
|
}
|
||||||
@@ -489,7 +503,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 +511,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 +665,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 +718,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 */
|
||||||
@@ -810,6 +833,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);
|
||||||
@@ -1002,9 +1027,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.
@@ -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));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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.
@@ -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)
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -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.
@@ -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.
@@ -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;
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,8 +44,11 @@ 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)
|
||||||
@@ -97,9 +106,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 +827,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 +882,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;
|
||||||
}
|
}
|
||||||
@@ -1090,7 +1099,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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
#define _INC_VERSION_H
|
#define _INC_VERSION_H
|
||||||
|
|
||||||
#define DEVICEVERSION 2
|
#define DEVICEVERSION 2
|
||||||
#define DEVICEREVISION 4
|
#define DEVICEREVISION 7
|
||||||
#define DEVICEEXTRA
|
#define DEVICEEXTRA
|
||||||
/* #define DEVICEEXTRA Beta */
|
/* #define DEVICEEXTRA Beta */
|
||||||
#define DEVICEDATE 27.05.2019
|
#define DEVICEDATE 11.02.20
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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.
@@ -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
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
@@ -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 */
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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_ */
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
libsize equ 728
|
|
||||||
@@ -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.
@@ -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
|
|
||||||
@@ -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*/
|
|
||||||
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
enc624j6l.o
|
|
||||||
@@ -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.
@@ -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,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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user