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
|
||||
the interface in your favorite TCP/IP stack as usual. There is a version
|
||||
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,
|
||||
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:
|
||||
----------
|
||||
|
||||
2.7 - fixed MuForce hit
|
||||
|
||||
2.4 - added second semaphore, specifically for the write list
|
||||
- recompiled using GCC 2.95 for slightly smaller binary
|
||||
- avoid full ethernet chip reset on startup when the
|
||||
registers seem to be in a sane state (faster init, especially
|
||||
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
|
||||
|
||||
|
||||
@@ -188,7 +188,18 @@ TIMER/K/N,MULTICAST/S
|
||||
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
|
||||
|
||||
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
|
||||
debug = 0
|
||||
# compiler_vcc = 1 will trigger VBCC, else GCC
|
||||
compiler_vcc = 0
|
||||
|
||||
@@ -48,6 +48,7 @@ CFLAGS2 = -Os -+ -sc -c99 -cpu=$(CPU2)
|
||||
VASMFORMAT = -m$(CPU) -Fhunk -nowarn=2064 -quiet -I$(SYSINC)
|
||||
VASMFORMAT2 = -m$(CPU2) -Fhunk -nowarn=2064 -quiet -I$(SYSINC)
|
||||
|
||||
|
||||
else
|
||||
|
||||
# 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
|
||||
VASMFORMAT = -m$(CPU) -Faout -nowarn=2064 -quiet -I$(SYSINC)
|
||||
VASMFORMAT2 = -m$(CPU2) -Faout -nowarn=2064 -quiet -I$(SYSINC)
|
||||
|
||||
endif
|
||||
|
||||
VASM = vasmm68k_mot
|
||||
@@ -137,7 +137,7 @@ endif
|
||||
ifeq ($(debug),1)
|
||||
CFLAGS += -DDEBUG -g
|
||||
CFLAGS2 += -DDEBUG -g
|
||||
LINKLIBS = -L$(PREFX)/lib -ldebug
|
||||
#LINKLIBS = -L$(PREFX)/lib -ldebug
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -33,15 +33,15 @@ SUBDIR=sdnet
|
||||
# two flavours of the same code base may be build with this setup
|
||||
# leave DEVICEID2 empty to disable second build
|
||||
DEVICEID=sdnet.device
|
||||
DEFINES = # -DPROTO_V2EXPNET
|
||||
ASMDEFS = # -DPROTO_V2EXPNET
|
||||
CPU = 68020
|
||||
DEFINES = -DALLREADREQS=1 # -DPROTO_V2EXPNET
|
||||
ASMDEFS = -DALLREADREQS=1 # -DPROTO_V2EXPNET
|
||||
CPU = 68060
|
||||
TESTTOOL = sdnettest
|
||||
|
||||
DEVICEID2=v2expeth.device
|
||||
DEFINES2 = -DPROTO_V2EXPNET
|
||||
ASMDEFS2 = -DPROTO_V2EXPNET
|
||||
CPU2 = 68020
|
||||
DEFINES2 = -DPROTO_V2EXPNET -DALLREADREQS=1
|
||||
ASMDEFS2 = -DPROTO_V2EXPNET -DALLREADREQS=1
|
||||
CPU2 = 68060
|
||||
TESTTOOL2 = v2expethtest
|
||||
|
||||
# additional housekeeping
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define SAVEDS __saveds
|
||||
#define STRUCTOFFSET OFFSET /* exec/initializers.h */
|
||||
#define INLINE __inline static
|
||||
#define STDARGS __stdargs
|
||||
|
||||
#else /* __SASC */
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
#define SAVEDS
|
||||
#define STRUCTOFFSET OFFSET /* exec/initializers.h */
|
||||
#define INLINE static inline
|
||||
#define STDARGS __stdargs
|
||||
|
||||
#else /* __GNUC__ */
|
||||
|
||||
@@ -52,6 +54,7 @@
|
||||
#include <stddef.h>
|
||||
/* sorry, I ran into some issues inlining stuff with VBCC, disabling it */
|
||||
#define INLINE
|
||||
#define STDARGS __stdargs
|
||||
|
||||
#else /* __VBCC__ */
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
#define _INC_DEBUG_H
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
@@ -18,9 +18,10 @@ _LVORawMayGetChar equ -$1fe
|
||||
;
|
||||
;
|
||||
;
|
||||
ifd DEBUG
|
||||
ifne DEBUG
|
||||
|
||||
XREF _KPrintF
|
||||
; XREF _KPrintFa0a1
|
||||
; XREF _KPrintF
|
||||
|
||||
WRITEDEBUG macro
|
||||
movem.l d0/d1/a0/a1,-(sp)
|
||||
@@ -50,7 +51,7 @@ WRITEDEBUG macro
|
||||
endif
|
||||
lea.l (\1),a0
|
||||
move.l sp,a1
|
||||
jsr _KPrintF
|
||||
jsr _KPrintFa0a1
|
||||
ifnb \2
|
||||
add.l #4,sp
|
||||
endif
|
||||
@@ -79,7 +80,7 @@ WRITEDEBUG macro
|
||||
endm
|
||||
else
|
||||
WRITEDEBUG macro
|
||||
nop
|
||||
;
|
||||
endm
|
||||
endc
|
||||
|
||||
@@ -116,7 +117,7 @@ WRITEOUT macro
|
||||
ifd DEBUG
|
||||
move.l \1,a0
|
||||
move.l sp,a1
|
||||
jsr _KPrintF
|
||||
jsr _KPrintFa0a1
|
||||
endif
|
||||
move.l \1,d1
|
||||
move.l sp,d2
|
||||
|
||||
@@ -32,11 +32,19 @@
|
||||
#ifdef HAVE_VERSION_H
|
||||
#include "version.h"
|
||||
#endif
|
||||
|
||||
#ifndef NO_WR_SEM
|
||||
#define WRSEM du_WrSem
|
||||
#else
|
||||
#define WRSEM du_Sem
|
||||
#endif
|
||||
|
||||
/* NSD support is optional */
|
||||
#ifdef NEWSTYLE
|
||||
#include <devices/newstyle.h>
|
||||
#include <devices/sana2devqueryext.h> /* new extension, code can be built without this include (but also without ext query then...) */
|
||||
|
||||
|
||||
const UWORD dev_supportedcmds[] = {
|
||||
NSCMD_DEVICEQUERY,
|
||||
CMD_READ,
|
||||
@@ -85,9 +93,9 @@ const ULONG blub[6] = {
|
||||
};
|
||||
|
||||
/* enable heavy debug (D2=beginIO) */
|
||||
#define D2(x)
|
||||
//#define D2(x)
|
||||
#define D4(x)
|
||||
/* #define D2(x) D(x) */
|
||||
#define D2(x) D(x)
|
||||
/* #define D4(x) D(x) */
|
||||
|
||||
|
||||
@@ -102,6 +110,8 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
|
||||
ULONG i;
|
||||
LONG ok;
|
||||
|
||||
D(("DevInit()\n"));
|
||||
|
||||
p = ((UBYTE*)db) + sizeof(struct Library);
|
||||
i = sizeof(DEVBASETYPE)-sizeof(struct Library);
|
||||
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_EventQueue );
|
||||
InitSemaphore( &db->db_Units[i].du_Sem );
|
||||
#ifndef NO_WR_SEM
|
||||
InitSemaphore( &db->db_Units[i].du_WrSem );
|
||||
#endif
|
||||
db->db_Units[i].du_MTU = DEF_MTU;
|
||||
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(("%ld Boards found\n",ok));
|
||||
|
||||
/* no hardware found, reject init */
|
||||
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 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 );
|
||||
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_WireError = S2WERR_GENERIC_ERROR;
|
||||
}
|
||||
ReleaseSemaphore(&db->db_Units[unit].du_WrSem);
|
||||
ReleaseSemaphore(&db->db_Units[unit].WRSEM);
|
||||
#else
|
||||
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);
|
||||
ReleaseSemaphore(&db->db_Units[unit].du_WrSem);
|
||||
ReleaseSemaphore(&db->db_Units[unit].WRSEM);
|
||||
Signal( (struct Task*)db->db_ServerProc, SIGBREAKF_CTRL_F );
|
||||
ioreq = (0);
|
||||
#endif
|
||||
@@ -651,16 +665,23 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
ioreq = (0);
|
||||
break;
|
||||
#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_UPDATE:
|
||||
case CMD_CLEAR:
|
||||
case CMD_STOP:
|
||||
case CMD_START:
|
||||
case CMD_FLUSH:
|
||||
ioreq->ios2_Req.io_Error = IOERR_NOCMD;
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
|
||||
D2(("DevAbortIO unit %ld\n",unit));
|
||||
|
||||
ObtainSemaphore(&db->db_Units[unit].du_Sem);
|
||||
|
||||
/* start with the read list -> types -> readers -> reqlist */
|
||||
@@ -810,6 +833,8 @@ static LONG dbStartServer( DEVBASEP, LONG unit )
|
||||
/* server is running, wait for response */
|
||||
volatile struct ServerMsg msg;
|
||||
|
||||
D(("Server Started, waiting for Response\n"));
|
||||
|
||||
msg.sm_devbase = db;
|
||||
msg.sm_result = 0;
|
||||
msg.sm_msg.mn_Length = sizeof(msg);
|
||||
@@ -1002,9 +1027,8 @@ static void dbDeleteReader( DEVBASEP, ULONG unit, ULONG ID )
|
||||
{
|
||||
if( !(GetSucc(t2) ))
|
||||
t2->srt_Flags &= ~SRTF_MULTREADER;
|
||||
else t2->srt_Flags &= ~(SRTF_ONEREADER|SRTF_MULTREADER);
|
||||
}
|
||||
else t2->srt_Flags &= ~(SRTF_ONEREADER|SRTF_MULTREADER);
|
||||
|
||||
break;
|
||||
}
|
||||
rd = GetSucc(rd);
|
||||
|
||||
@@ -140,7 +140,7 @@ _LVOSignal EQU -324
|
||||
|
||||
;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
|
||||
*/
|
||||
ASM SAVEDS int enc624j6l_bc_mc_filter(
|
||||
ASMR(a0) void *board ASMREG(a0),
|
||||
ASMR(d1) unsigned long flags ASMREG(d1) );
|
||||
ASMR(a0) void *board ASMREG(a0),
|
||||
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 */
|
||||
#define duh_online du_hwl0
|
||||
#define duh_BASE du_hwp0
|
||||
#define duh_RefCount du_hwl1
|
||||
|
||||
#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) */
|
||||
/* if( boardbase < (APTR)0x40000000 ) */ /* debug only */
|
||||
enc624j6l_CheckBoard( boardbase );
|
||||
enc624j6l_CheckBoard( boardbase );
|
||||
}
|
||||
ret = i;
|
||||
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),
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -127,6 +154,20 @@ ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
||||
ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -427,27 +468,143 @@ ASM SAVEDS LONG hw_write_phy( ASMR(a0) DEVBASEP ASMREG(
|
||||
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),
|
||||
ASMR(d0) ULONG unit ASMREG(d0),
|
||||
ASMR(a1) struct List *mcastlist ASMREG(a1) )
|
||||
{
|
||||
/* TODO: implement Multicast hashing */
|
||||
APTR boardbase = db->db_Units[unit].duh_BASE;
|
||||
ULONG flags;
|
||||
APTR boardbase = db->db_Units[unit].duh_BASE;
|
||||
struct HWData *hwd = &db->db_hwdat;
|
||||
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;
|
||||
|
||||
if( db->db_Units[0].du_Flags & DUF_PROMISC )
|
||||
flags |= PIO_INIT_PROMISC;
|
||||
|
||||
/* list non-empty ? (kludge right now, can be done more fine grained) */
|
||||
if( mcastlist->lh_Head->ln_Succ )
|
||||
if( hwd->multicast ) /* accept ALL multicast ? (config option) */
|
||||
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;
|
||||
}
|
||||
@@ -494,7 +651,7 @@ void myhw_ControlInterrupts( DEVBASEP )
|
||||
hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List;
|
||||
hwd->hwd_Interrupt.is_Data = &hwd->hwd_act_boards[0];
|
||||
hwd->hwd_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
|
||||
hwd->hwd_Interrupt.is_Node.ln_Pri = 51;
|
||||
hwd->hwd_Interrupt.is_Node.ln_Pri = 126; /* 51; */
|
||||
hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname;
|
||||
AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -17,10 +17,17 @@ _LVORawMayGetChar equ -$1fe
|
||||
endc
|
||||
|
||||
XDEF _KPrintF
|
||||
XDEF _KPrintFa0a1
|
||||
|
||||
_KPrintF:
|
||||
; rts
|
||||
move.l 4(sp),a0
|
||||
lea 8(sp),a1
|
||||
; fall through
|
||||
|
||||
;A0 = format
|
||||
;A1 = arguments
|
||||
_KPrintF:
|
||||
_KPrintFa0a1:
|
||||
; ifd DEBUG
|
||||
|
||||
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);
|
||||
/* general info */
|
||||
if( parm_vendorname.Actual != 0 )
|
||||
@@ -722,6 +728,12 @@ int main(int argc, char **argv)
|
||||
productname[parm_productname.Actual-1] = 0;
|
||||
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 */
|
||||
if( res == RETURN_OK )
|
||||
|
||||
@@ -55,6 +55,11 @@
|
||||
/* (note: maximum ethernet frame length would be 1518 when VLAN tagging is unused) */
|
||||
#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 u08 is_full_duplex;
|
||||
static u08 rev;
|
||||
@@ -118,20 +123,39 @@ static void writeReg(uint8_t address, uint16_t data)
|
||||
/*
|
||||
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(MICMD, MICMD_MIIRD);
|
||||
while (readRegByte(MISTAT) & MISTAT_BUSY)
|
||||
;
|
||||
{
|
||||
if( (--wtime) <= 0 )
|
||||
{
|
||||
writeRegByte(MICMD, 0x00);
|
||||
initvars.have_recv = SANITY_CHECK_INTERVAL+1;
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
writeRegByte(MICMD, 0x00);
|
||||
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);
|
||||
writeReg(MIWR, data);
|
||||
while (readRegByte(MISTAT) & MISTAT_BUSY)
|
||||
;
|
||||
{
|
||||
if( (--wtime) <= 0 )
|
||||
{
|
||||
initvars.have_recv = SANITY_CHECK_INTERVAL+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
-> wait first, then fill buffer
|
||||
*/
|
||||
long maxwait = 0x1ffff; /* wait patiently */
|
||||
while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_TXRTS)
|
||||
{
|
||||
/* 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_CLR, ECON1, ECON1_TXRST);
|
||||
}
|
||||
if( !(--maxwait) )
|
||||
return PIO_OK; /* waited long enough: drop frame */
|
||||
}
|
||||
|
||||
/* write buffer */
|
||||
@@ -591,7 +618,7 @@ u08 enc28j60_has_recv(void)
|
||||
if( !ret )
|
||||
{
|
||||
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 */
|
||||
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
|
||||
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 |
|
||||
; | Copyright (c) 2016 APOLLO TEAM |
|
||||
@@ -6,6 +5,7 @@
|
||||
; ------------------------------------------------------------------------------
|
||||
|
||||
FLASH_ID EQU $14 ;cmd=0xAB
|
||||
LARGE_FLASH_ID EQU $16
|
||||
|
||||
FLASH_ADR_W EQU $00DFF1F8
|
||||
FLASH_ADR_R EQU $00DFF1FA
|
||||
@@ -26,6 +26,11 @@ VAMPIDREG EQU $DFF3FC
|
||||
V4_ID1 EQU $DFF3F4
|
||||
V4_ID2 EQU $DFF3F0
|
||||
|
||||
BOARDID_V600 EQU 1
|
||||
BOARDID_V500 EQU 2
|
||||
BOARDID_V4SA EQU 5
|
||||
BOARDID_V1200 EQU 6
|
||||
|
||||
xdef _vampire_UUID
|
||||
|
||||
;-------- Get 64 Bit unique ID --------------------
|
||||
@@ -40,8 +45,11 @@ _vampire_UUID:
|
||||
|
||||
move.w (a0),d0 ;ID reg empty?
|
||||
blt.s v2$ ;yes, try flash method
|
||||
cmp.w #$2FF,d0 ;Core type << 8 | Clock_Multiplier
|
||||
ble.s v2$
|
||||
lsr.w #8,d0
|
||||
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_ID2-VAMPIDREG(a0),d1
|
||||
@@ -49,8 +57,10 @@ _vampire_UUID:
|
||||
v2$
|
||||
bsr flashreadid
|
||||
cmpi.b #FLASH_ID,d0
|
||||
beq.s goodflash$
|
||||
cmpi.b #LARGE_FLASH_ID,d0
|
||||
bne.s error$
|
||||
|
||||
goodflash$
|
||||
bsr flashuniqueid
|
||||
common$
|
||||
move.l d0,(a1)
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
|
||||
#endif
|
||||
|
||||
#ifndef NO_WR_SEM
|
||||
#define WRSEM du_WrSem
|
||||
#else
|
||||
#define WRSEM du_Sem
|
||||
#endif
|
||||
|
||||
/* the XSurf500 network panel currently claims length 0 requests
|
||||
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 */
|
||||
/* this limits the number of processed write requests per run when enabled */
|
||||
#define ONE_WRITE_REQ 1
|
||||
|
||||
#ifndef ALLREADREQS
|
||||
/* this limits the number of processed read requests per run when enabled */
|
||||
#define ONE_READ_REQ 2
|
||||
#endif /* ALLREADREQS */
|
||||
|
||||
/* heavy debug on read/write */
|
||||
#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_ReadOrphans );
|
||||
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 );
|
||||
ReleaseSemaphore( &db->db_Units[unit].du_WrSem );
|
||||
ReleaseSemaphore( &db->db_Units[unit].WRSEM );
|
||||
|
||||
/* clear Multicast list, TODO: subroutine */
|
||||
{
|
||||
@@ -818,7 +827,7 @@ static LONG server_writequeue( DEVBASEP, ULONG unit )
|
||||
#endif
|
||||
struct IOSana2Req *ioreq,*nextio;
|
||||
|
||||
ObtainSemaphore( &db->db_Units[unit].du_WrSem );
|
||||
ObtainSemaphore( &db->db_Units[unit].WRSEM );
|
||||
|
||||
#if 1
|
||||
/* whole queue per call */
|
||||
@@ -873,7 +882,7 @@ static LONG server_writequeue( DEVBASEP, ULONG unit )
|
||||
#endif
|
||||
}
|
||||
|
||||
ReleaseSemaphore( &db->db_Units[unit].du_WrSem );
|
||||
ReleaseSemaphore( &db->db_Units[unit].WRSEM );
|
||||
|
||||
return SERR_OK;
|
||||
}
|
||||
@@ -1090,7 +1099,7 @@ VOID SAVEDS ServerTask(void)
|
||||
{
|
||||
if( !action ) /* queues quiet ? -> sleep */
|
||||
{
|
||||
Disable();
|
||||
/* Disable(); */
|
||||
i=0;BOARDLOOP( ( ; i < db->db_NBoards ; i++ ) )
|
||||
{ /* housekeeping -> check for link change on idle, re-enable interrupts etc. */
|
||||
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
|
||||
# not enabled yet in SAS/C makefile
|
||||
debug = 0
|
||||
#debug = 0
|
||||
|
||||
###############################################################################
|
||||
# prefix for system includes (ASM)
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#define _INC_VERSION_H
|
||||
|
||||
#define DEVICEVERSION 2
|
||||
#define DEVICEREVISION 4
|
||||
#define DEVICEREVISION 7
|
||||
#define DEVICEEXTRA
|
||||
/* #define DEVICEEXTRA Beta */
|
||||
#define DEVICEDATE 27.05.2019
|
||||
#define DEVICEDATE 11.02.20
|
||||
|
||||
#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.
|
||||
|
||||
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 "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