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
|
||||
|
||||
Reference in New Issue
Block a user