updated ENC624j6net driver
- fixes to gcc native and cross compilation settings
- implemented hardware based multicast filtering hashes, resulting
in less unwanted traffic to our Amigas (especially Bonjour, UPNP and such)
- MULTICAST option in envarc:sana2/enc624j6net.config will now
allow all multicast traffic as opposed to the default fine grained
filtering behaviour
This commit is contained in:
@@ -44,6 +44,8 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
|
|||||||
note: this switch should not be enabled in normal cases.
|
note: this switch should not be enabled in normal cases.
|
||||||
The module features autoconfiguration that determines
|
The module features autoconfiguration that determines
|
||||||
speed and duplex automatically.
|
speed and duplex automatically.
|
||||||
|
note(2): see miitool for changing speed/duplex
|
||||||
|
settings at runtime.
|
||||||
|
|
||||||
PRIORITY - server task priority (default 1)
|
PRIORITY - server task priority (default 1)
|
||||||
|
|
||||||
@@ -51,8 +53,8 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
|
|||||||
|
|
||||||
MTU - maximum transmission unit (default 1500)
|
MTU - maximum transmission unit (default 1500)
|
||||||
|
|
||||||
MULTICAST - obsolete, kept for config file backwards compatibility with
|
MULTICAST - (V2.3+) override fine-grained automatic multicast filtering
|
||||||
old driver
|
and accept all multicast frames (default: off)
|
||||||
|
|
||||||
FLOWCONTROL - enable automatic flow control that throttles incoming
|
FLOWCONTROL - enable automatic flow control that throttles incoming
|
||||||
data when the hardware buffer gets full
|
data when the hardware buffer gets full
|
||||||
@@ -64,6 +66,8 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
|
|||||||
Changelog:
|
Changelog:
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
2.3 - implemented fine grained multicast filter hashes
|
||||||
|
|
||||||
2.2 - some more tuning to RX/TX scheduling
|
2.2 - some more tuning to RX/TX scheduling
|
||||||
- added optional debug code to lowlevel routines
|
- added optional debug code to lowlevel routines
|
||||||
- removed some obsolete bus transfers
|
- removed some obsolete bus transfers
|
||||||
@@ -110,11 +114,12 @@ Changelog:
|
|||||||
Compilation / Development Notes
|
Compilation / Development Notes
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
Either VBCC or GCC (tested with version 2.95 only) can be used. General
|
Either VBCC or GCC (tested with version 2.95 only) can be used for
|
||||||
options for compiler usage can be found in Common.mk. Also, you might want
|
cross-compiles. General options for compiler usage can be found in
|
||||||
to adapt the paths to your setup (PREFX,SYSINC). In addition to the regular
|
Common.mk. Also, you might want to adapt the paths to your setup
|
||||||
NDK, the sana2.h is expected in the devices/ subdir of the includes. sana2.h
|
(PREFX,SYSINC). In addition to the regular NDK, the sana2.h is expected
|
||||||
may be found in the AmiTCP or Roadshow SDK, respectively.
|
in the devices/ subdir of the includes. sana2.h may be found in the
|
||||||
|
AmiTCP or Roadshow SDK, respectively.
|
||||||
|
|
||||||
Call
|
Call
|
||||||
|
|
||||||
@@ -125,6 +130,15 @@ for building the device.
|
|||||||
VBCC note: When calling the GNU Make port supplied with ADE/GG natively on AmigaOS3,
|
VBCC note: When calling the GNU Make port supplied with ADE/GG natively on AmigaOS3,
|
||||||
please make sure that "vc" is within the search path of "/bin/sh".
|
please make sure that "vc" is within the search path of "/bin/sh".
|
||||||
|
|
||||||
|
Native compilation is also supported for GCC and VBCC. In addition, SAS/C
|
||||||
|
smakefiles are provided for the hardware targets.
|
||||||
|
|
||||||
|
Call
|
||||||
|
|
||||||
|
smake -f smakefile.enc
|
||||||
|
|
||||||
|
for native building with SAS/C.
|
||||||
|
|
||||||
Conceptually, the driver was meant to support multiple hardware targets. Therefore,
|
Conceptually, the driver was meant to support multiple hardware targets. Therefore,
|
||||||
it features a SANA-II frontend (device.c,deviceheader.c,deviceinit.c), a main
|
it features a SANA-II frontend (device.c,deviceheader.c,deviceinit.c), a main
|
||||||
server running in a task (server.c) and several hardware backends. A new hardware
|
server running in a task (server.c) and several hardware backends. A new hardware
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -21,19 +21,15 @@
|
|||||||
# debug = 1 will include string debugging for terminal/sushi/sashimi
|
# debug = 1 will include string debugging for terminal/sushi/sashimi
|
||||||
debug = 0
|
debug = 0
|
||||||
# compiler_vcc = 1 will trigger VBCC, else GCC
|
# compiler_vcc = 1 will trigger VBCC, else GCC
|
||||||
compiler_vcc = 1
|
compiler_vcc = 0
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# prefix for system includes (ASM)
|
# prefix for system includes (ASM)
|
||||||
# native AmigaOS compilation: set PREFX=GG: or PREFX=ADE:, depending on toolchain
|
# native AmigaOS compilation: set PREFX=GG: or PREFX=ADE:, depending on toolchain
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
#PREFX = /opt/amigaos-68k/
|
||||||
PREFX = /opt/amigaos-68k/
|
PREFX = gg:
|
||||||
#PREFX = gg:
|
|
||||||
#PREFX = c:/Users/Matze/Amiga/development/VBCC/
|
|
||||||
|
|
||||||
SYSINC = $(PREFX)os-include
|
SYSINC = $(PREFX)os-include
|
||||||
#SYSINC = $(PREFX)NDK39/Include/include_i
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@@ -130,8 +126,7 @@ endif
|
|||||||
ifeq ($(debug),1)
|
ifeq ($(debug),1)
|
||||||
CFLAGS += -DDEBUG -g
|
CFLAGS += -DDEBUG -g
|
||||||
CFLAGS2 += -DDEBUG -g
|
CFLAGS2 += -DDEBUG -g
|
||||||
LINKLIBS = -L$(PREFX)/lib -L$(PREFX)targets/m68k-amigaos/lib -ldebug
|
LINKLIBS = -L$(PREFX)/lib -ldebug
|
||||||
#LINKLIBS = -L$(PREFX)targets/m68k-amigaos/lib -ldebug
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ ASMOBJECTS = $(SUBDIR)/enc624j6l.o $(SUBDIR)/intervaltimer.o kprintf.o
|
|||||||
|
|
||||||
DEVICEID=enc624j6net.device
|
DEVICEID=enc624j6net.device
|
||||||
DEFINES = -DHW_DMA_TX # -DPROTO_V2EXPNET
|
DEFINES = -DHW_DMA_TX # -DPROTO_V2EXPNET
|
||||||
ASMDEFS = # -DPROTO_V2EXPNET
|
ASMDEFS = -DHW_DMA_TX # -DPROTO_V2EXPNET
|
||||||
CPU = 68020
|
CPU = 68020
|
||||||
|
|
||||||
DEVICEID2=enc624j6net.device_68000
|
DEVICEID2=enc624j6net.device_68000
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ _LVORawMayGetChar equ -$1fe
|
|||||||
;
|
;
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
ifd DEBUG
|
ifne DEBUG
|
||||||
|
|
||||||
XREF _KPrintF
|
; XREF _KPrintFa0a1
|
||||||
|
; XREF _KPrintF
|
||||||
|
|
||||||
WRITEDEBUG macro
|
WRITEDEBUG macro
|
||||||
movem.l d0/d1/a0/a1,-(sp)
|
movem.l d0/d1/a0/a1,-(sp)
|
||||||
@@ -51,7 +52,7 @@ WRITEDEBUG macro
|
|||||||
endif
|
endif
|
||||||
lea.l (\1),a0
|
lea.l (\1),a0
|
||||||
move.l sp,a1
|
move.l sp,a1
|
||||||
jsr _KPrintF
|
jsr _KPrintFa0a1
|
||||||
ifnb \2
|
ifnb \2
|
||||||
add.l #4,sp
|
add.l #4,sp
|
||||||
endif
|
endif
|
||||||
@@ -80,7 +81,7 @@ WRITEDEBUG macro
|
|||||||
endm
|
endm
|
||||||
else
|
else
|
||||||
WRITEDEBUG macro
|
WRITEDEBUG macro
|
||||||
nop
|
;
|
||||||
endm
|
endm
|
||||||
endc
|
endc
|
||||||
|
|
||||||
@@ -117,7 +118,7 @@ WRITEOUT macro
|
|||||||
ifd DEBUG
|
ifd DEBUG
|
||||||
move.l \1,a0
|
move.l \1,a0
|
||||||
move.l sp,a1
|
move.l sp,a1
|
||||||
jsr _KPrintF
|
jsr _KPrintFa0a1
|
||||||
endif
|
endif
|
||||||
move.l \1,d1
|
move.l \1,d1
|
||||||
move.l sp,d2
|
move.l sp,d2
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ const struct NSDeviceQueryResult NSDQueryAnswer = {
|
|||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
/* enable heavy debug (D2=beginIO) */
|
||||||
|
#define D2(x)
|
||||||
|
#define D4(x)
|
||||||
|
/* #define D2(x) D(x) */
|
||||||
|
/* #define D4(x) D(x) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -382,7 +388,8 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
|||||||
/*ioreq->ios2_Req.io_Error = S2ERR_NO_ERROR;
|
/*ioreq->ios2_Req.io_Error = S2ERR_NO_ERROR;
|
||||||
ioreq->ios2_WireError = S2WERR_GENERIC_ERROR;*/
|
ioreq->ios2_WireError = S2WERR_GENERIC_ERROR;*/
|
||||||
|
|
||||||
D(("BeginIO command %ld unit %ld\n",(LONG)ioreq->ios2_Req.io_Command,unit));
|
/* heavy debug on beginIO */
|
||||||
|
D2(("BeginIO command %ld unit %ld\n",(LONG)ioreq->ios2_Req.io_Command,unit));
|
||||||
|
|
||||||
switch( ioreq->ios2_Req.io_Command )
|
switch( ioreq->ios2_Req.io_Command )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
; ------------------------------------------------------------------------------
|
; ------------------------------------------------------------------------------
|
||||||
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
|
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
|
||||||
; | Henryk Richter <henryk.richter@gmx.net> |
|
; | Henryk Richter <henryk.richter@gmx.net> |
|
||||||
@@ -19,19 +20,25 @@
|
|||||||
; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully)
|
; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully)
|
||||||
;
|
;
|
||||||
; enable debugging code block (comment/uncomment, see below)
|
; enable debugging code block (comment/uncomment, see below)
|
||||||
DEBUG EQU 1
|
DEBUG EQU 0
|
||||||
GLOBALINT_BOARD EQU 1 ;if 1, then toggle board interrupt, else ENC624 INTIE
|
GLOBALINT_BOARD EQU 1 ;if 1, then toggle board interrupt, else ENC624 INTIE
|
||||||
|
|
||||||
incdir src:baxnet/trunk/source/
|
incdir src:baxnet/trunk/source/
|
||||||
;Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
|
;Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
|
||||||
include "enc624j6net/registers.i"
|
include "enc624j6net/registers.i"
|
||||||
include "enc624j6net/macros.i"
|
include "enc624j6net/macros.i"
|
||||||
include "debug.i"
|
|
||||||
|
|
||||||
ifnd DEBUG
|
ifnd DEBUG
|
||||||
DEBUG EQU 0
|
DEBUG EQU 0
|
||||||
endc
|
endc
|
||||||
|
|
||||||
|
ifne 1
|
||||||
|
include "debug.i"
|
||||||
|
else
|
||||||
|
WRITEDEBUG macro
|
||||||
|
nop
|
||||||
|
endm
|
||||||
|
endc
|
||||||
;
|
;
|
||||||
ADD_4RX EQU 1 ;add 4 to valid RX size (fake CRC), fixes shapeshifter RAW treatment
|
ADD_4RX EQU 1 ;add 4 to valid RX size (fake CRC), fixes shapeshifter RAW treatment
|
||||||
_OPT_LONGRESET EQU 0 ;in testing, don't enable
|
_OPT_LONGRESET EQU 0 ;in testing, don't enable
|
||||||
@@ -134,12 +141,6 @@ _LVOSignal EQU -324
|
|||||||
|
|
||||||
section code,code
|
section code,code
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; | |
|
; | |
|
||||||
; | Test/Debug code |
|
; | Test/Debug code |
|
||||||
@@ -277,7 +278,13 @@ regtests:
|
|||||||
READREG ESTAT,a0,d0
|
READREG ESTAT,a0,d0
|
||||||
READREG ECON1,a0,d1
|
READREG ECON1,a0,d1
|
||||||
READREG MACON2,a0,d2
|
READREG MACON2,a0,d2
|
||||||
READREG MABBIPG,a0,d3
|
; READREG MABBIPG,a0,d3
|
||||||
|
|
||||||
|
READREG ERXFCON,a0,d3
|
||||||
|
READREG EHT1,a0,d4
|
||||||
|
READREG EHT2,a0,d5
|
||||||
|
READREG EHT3,a0,d6
|
||||||
|
READREG EHT4,a0,d7
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
@@ -587,6 +594,7 @@ _enc624j6l_Init:
|
|||||||
WRITEREG ERXST,a0,d0 ;set RX start pointer (end will be $5fff)
|
WRITEREG ERXST,a0,d0 ;set RX start pointer (end will be $5fff)
|
||||||
WRITEREG PNextPacket,a0,d0 ;set user read pointer
|
WRITEREG PNextPacket,a0,d0 ;set user read pointer
|
||||||
|
|
||||||
|
suba.l a1,a1 ;no multicast hash table (yet)
|
||||||
bsr _enc624j6l_bc_mc_filter ;in: A0/D1, out: D0
|
bsr _enc624j6l_bc_mc_filter ;in: A0/D1, out: D0
|
||||||
|
|
||||||
move #RXSTOP_INIT&$fffe,d0
|
move #RXSTOP_INIT&$fffe,d0
|
||||||
@@ -644,6 +652,7 @@ _enc624j6l_Init:
|
|||||||
;
|
;
|
||||||
; in: A0 - board base
|
; in: A0 - board base
|
||||||
; D1 - init flags
|
; D1 - init flags
|
||||||
|
; A1 - multicast hash table (4x USHORT)
|
||||||
;out: D0 >0 = OK
|
;out: D0 >0 = OK
|
||||||
; <=0 = FAIL
|
; <=0 = FAIL
|
||||||
_enc624j6l_bc_mc_filter:
|
_enc624j6l_bc_mc_filter:
|
||||||
@@ -658,15 +667,32 @@ _enc624j6l_bc_mc_filter:
|
|||||||
move #ERXFCON_NOTMEEN|ERXFCON_MCEN|ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
move #ERXFCON_NOTMEEN|ERXFCON_MCEN|ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
||||||
bra.s .setfilter
|
bra.s .setfilter
|
||||||
.no_promisc:
|
.no_promisc:
|
||||||
moveq #PIO_INIT_MULTI_CAST,d0
|
moveq #PIO_INIT_MULTI_CAST,d0 ;all multicast ?
|
||||||
and d1,d0
|
and d1,d0
|
||||||
beq.s .no_multicast
|
beq.s .no_multicast
|
||||||
move #ERXFCON_MCEN|ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
move #ERXFCON_MCEN|ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
||||||
bra.s .setfilter
|
bra.s .setfilter
|
||||||
.no_multicast:
|
.no_multicast:
|
||||||
move #ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
move #ERXFCON_BCEN|ERXFCON_UCEN|ERXFCON_MPEN|ERXFCON_CRCEN|ERXFCON_RUNTEN,d0
|
||||||
|
|
||||||
|
; did we get a multicast hash table ?
|
||||||
|
move.l a1,d1
|
||||||
|
beq.s .nohashes
|
||||||
|
AND #$ffff-ERXFCON_MCEN,d0 ;don't accept ALL multicast
|
||||||
|
OR #ERXFCON_HTEN,d0 ;enable multicast hash table filter
|
||||||
|
|
||||||
|
move (a1),d1
|
||||||
|
WRITEREG EHT1,a0,d1
|
||||||
|
move 2(a1),d1
|
||||||
|
WRITEREG EHT2,a0,d1
|
||||||
|
move 4(a1),d1
|
||||||
|
WRITEREG EHT3,a0,d1
|
||||||
|
move 6(a1),d1
|
||||||
|
WRITEREG EHT4,a0,d1
|
||||||
|
.nohashes:
|
||||||
|
|
||||||
.setfilter:
|
.setfilter:
|
||||||
WRITEREG ERXFCON,a0,d0 ;set filter TODO: pattern matching stuff
|
WRITEREG ERXFCON,a0,d0 ;set filter
|
||||||
|
|
||||||
moveq #1,d0
|
moveq #1,d0
|
||||||
.rts:
|
.rts:
|
||||||
|
|||||||
@@ -239,8 +239,9 @@ ASM SAVEDS int enc624j6l_SetOnline( ASMR(a0) void *board ASMREG(a0) );
|
|||||||
>=0 - OK
|
>=0 - OK
|
||||||
*/
|
*/
|
||||||
ASM SAVEDS int enc624j6l_bc_mc_filter(
|
ASM SAVEDS int enc624j6l_bc_mc_filter(
|
||||||
ASMR(a0) void *board ASMREG(a0),
|
ASMR(a0) void *board ASMREG(a0),
|
||||||
ASMR(d1) unsigned long flags ASMREG(d1) );
|
ASMR(d1) unsigned long flags ASMREG(d1),
|
||||||
|
ASMR(a1) unsigned short *mc_hashes ASMREG(a1));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ extern const BYTE DeviceName[];
|
|||||||
/* use generic board fields in current unit */
|
/* use generic board fields in current unit */
|
||||||
#define duh_online du_hwl0
|
#define duh_online du_hwl0
|
||||||
#define duh_BASE du_hwp0
|
#define duh_BASE du_hwp0
|
||||||
|
#define duh_RefCount du_hwl1
|
||||||
|
|
||||||
#define HW_INTERVALDEF 100000L
|
#define HW_INTERVALDEF 100000L
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
|
|||||||
|
|
||||||
/* bring board to sane state (i.e. perform soft reset) */
|
/* bring board to sane state (i.e. perform soft reset) */
|
||||||
/* if( boardbase < (APTR)0x40000000 ) */ /* debug only */
|
/* if( boardbase < (APTR)0x40000000 ) */ /* debug only */
|
||||||
enc624j6l_CheckBoard( boardbase );
|
enc624j6l_CheckBoard( boardbase );
|
||||||
}
|
}
|
||||||
ret = i;
|
ret = i;
|
||||||
D(("%ld boards found\n",ret));
|
D(("%ld boards found\n",ret));
|
||||||
@@ -119,7 +120,33 @@ ASM SAVEDS LONG hw_Find_Boards( ASMR(a0) DEVBASEP ASMREG(a0) )
|
|||||||
ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
||||||
ASMR(d0) ULONG unit ASMREG(d0) )
|
ASMR(d0) ULONG unit ASMREG(d0) )
|
||||||
{
|
{
|
||||||
/* is there a way to lock a ZII Board ? */
|
#if 0
|
||||||
|
LONG i;
|
||||||
|
struct ConfigDev *cfg = (0);
|
||||||
|
|
||||||
|
if( unit > db->db_NBoards )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for( i=0 ; i < db->db_NBoards ; i++ )
|
||||||
|
{
|
||||||
|
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
|
||||||
|
if( !cfg )
|
||||||
|
return 0;
|
||||||
|
if( (APTR)cfg->cd_BoardAddr == db->db_Units[unit].duh_BASE )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (APTR)cfg->cd_BoardAddr != db->db_Units[unit].duh_BASE )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( db->db_Units[unit].duh_RefCount == 0 )
|
||||||
|
{
|
||||||
|
ObtainConfigBinding();
|
||||||
|
|
||||||
|
ReleaseConfigBinding();
|
||||||
|
}
|
||||||
|
db->db_Units[unit].duh_RefCount++;
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +154,20 @@ ASM SAVEDS LONG hw_AllocBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
|||||||
ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
ASM SAVEDS LONG hw_ReleaseBoard( ASMR(a0) DEVBASEP ASMREG(a0),
|
||||||
ASMR(d0) ULONG unit ASMREG(d0) )
|
ASMR(d0) ULONG unit ASMREG(d0) )
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
if( unit > db->db_NBoards )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for( i=0 ; i < db->db_NBoards ; i++ )
|
||||||
|
{
|
||||||
|
cfg = FindConfigDev( cfg, ENC_MANUFACTURER, ENC_BOARD );
|
||||||
|
if( !cfg )
|
||||||
|
return 0;
|
||||||
|
if( (APTR)cfg->cd_BoardAddr == db->db_Units[unit].duh_BASE )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,27 +468,143 @@ ASM SAVEDS LONG hw_write_phy( ASMR(a0) DEVBASEP ASMREG(
|
|||||||
return enc624j6l_WritePHY( boardbase, reg, value );
|
return enc624j6l_WritePHY( boardbase, reg, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculate CRC32 for MAC address hashing
|
||||||
|
slow but relatively short (and can be adapted to other
|
||||||
|
polynoms easily)
|
||||||
|
*/
|
||||||
|
ASM ULONG myhw_CRC32( ASMR(a0) UBYTE *buffer ASMREG(a0),
|
||||||
|
ASMR(d0) ULONG nbytes ASMREG(d0) )
|
||||||
|
{
|
||||||
|
UWORD i,j;
|
||||||
|
ULONG t,crc = 0xffffffff;
|
||||||
|
ULONG poly = 0x04c11db7;
|
||||||
|
|
||||||
|
for( j = 0 ; j < nbytes ; j++ )
|
||||||
|
{
|
||||||
|
for( i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
t = crc>>31;
|
||||||
|
crc <<= 1;
|
||||||
|
if( ( t ^ ( buffer[j] >> i ) ) & 0x01 )
|
||||||
|
crc ^= poly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
ASM ULONG CMPgeMAC( ASMR(a0) UBYTE *cur ASMREG(a0),
|
||||||
|
ASMR(a1) UBYTE *cmp ASMREG(a1) )
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
ULONG res = 1;
|
||||||
|
|
||||||
|
for( i = 0 ; i < 6 ; i++ )
|
||||||
|
{
|
||||||
|
if( cur[i] > cmp[i] )
|
||||||
|
break;
|
||||||
|
if( cur[i] < cmp[i] )
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ASM ULONG CMPleMAC( ASMR(a0) UBYTE *cur ASMREG(a0),
|
||||||
|
ASMR(a1) UBYTE *cmp ASMREG(a1) )
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
ULONG res = 1;
|
||||||
|
|
||||||
|
for( i = 0 ; i < 6 ; i++ )
|
||||||
|
{
|
||||||
|
if( cur[i] < cmp[i] )
|
||||||
|
break;
|
||||||
|
if( cur[i] > cmp[i] )
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ASM void INCMAC( ASMR(a0) UBYTE *curmc ASMREG(a0) )
|
||||||
|
{
|
||||||
|
SHORT i;
|
||||||
|
for( i=5 ; i >= 0 ; i-- )
|
||||||
|
{
|
||||||
|
curmc[i]++;
|
||||||
|
if( curmc[i] != 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: implement Multicast hashing */
|
||||||
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
|
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
|
||||||
ASMR(d0) ULONG unit ASMREG(d0),
|
ASMR(d0) ULONG unit ASMREG(d0),
|
||||||
ASMR(a1) struct List *mcastlist ASMREG(a1) )
|
ASMR(a1) struct List *mcastlist ASMREG(a1) )
|
||||||
{
|
{
|
||||||
/* TODO: implement Multicast hashing */
|
APTR boardbase = db->db_Units[unit].duh_BASE;
|
||||||
APTR boardbase = db->db_Units[unit].duh_BASE;
|
struct HWData *hwd = &db->db_hwdat;
|
||||||
ULONG flags;
|
ULONG flags;
|
||||||
|
ULONG crc,curhash;
|
||||||
|
USHORT mc_hashes[4] = {0,0,0,0}; /* EHT1, EHT2, EHT3, EHT4 */
|
||||||
|
USHORT *hash_tab;
|
||||||
|
struct MCastEntry *mc;
|
||||||
|
UBYTE *curmc;
|
||||||
|
|
||||||
flags = PIO_INIT_BROAD_CAST;
|
flags = PIO_INIT_BROAD_CAST;
|
||||||
|
|
||||||
if( db->db_Units[0].du_Flags & DUF_PROMISC )
|
if( db->db_Units[0].du_Flags & DUF_PROMISC )
|
||||||
flags |= PIO_INIT_PROMISC;
|
flags |= PIO_INIT_PROMISC;
|
||||||
|
|
||||||
/* list non-empty ? (kludge right now, can be done more fine grained) */
|
if( hwd->multicast ) /* accept ALL multicast ? (config option) */
|
||||||
if( mcastlist->lh_Head->ln_Succ )
|
|
||||||
flags |= PIO_INIT_MULTI_CAST;
|
flags |= PIO_INIT_MULTI_CAST;
|
||||||
|
|
||||||
enc624j6l_bc_mc_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
|
/* list non-empty ? */
|
||||||
|
hash_tab = NULL;
|
||||||
|
if( mcastlist->lh_Head->ln_Succ )
|
||||||
|
{
|
||||||
|
/* flags |= PIO_INIT_MULTI_CAST; */ /* see above */
|
||||||
|
hash_tab = mc_hashes;
|
||||||
|
|
||||||
|
for( mc = (struct MCastEntry *)mcastlist->lh_Head;
|
||||||
|
mc->mce_Node.mln_Succ ;
|
||||||
|
mc=(struct MCastEntry*)mc->mce_Node.mln_Succ )
|
||||||
|
{
|
||||||
|
curmc = mc->mce_start;
|
||||||
|
while( CMPleMAC( curmc, mc->mce_stop ) )
|
||||||
|
{
|
||||||
|
D(("CMPleMAC %ld %02lx%02lx%02lx%02lx%02lx%02lx - %02lx%02lx%02lx%02lx%02lx%02lx\n",\
|
||||||
|
CMPleMAC( curmc, mc->mce_stop ),\
|
||||||
|
(ULONG)curmc[0],(ULONG)curmc[1],\
|
||||||
|
(ULONG)curmc[2],(ULONG)curmc[3],\
|
||||||
|
(ULONG)curmc[4],(ULONG)curmc[5],\
|
||||||
|
(ULONG)mc->mce_stop[0],(ULONG)mc->mce_stop[1],\
|
||||||
|
(ULONG)mc->mce_stop[2],(ULONG)mc->mce_stop[3],\
|
||||||
|
(ULONG)mc->mce_stop[4],(ULONG)mc->mce_stop[5] \
|
||||||
|
));
|
||||||
|
|
||||||
|
crc = myhw_CRC32( mc->mce_start, 6 );
|
||||||
|
curhash = (crc & 0x1f800000)>>23; /* 2 bit reg, 4 bit hash pos in reg */
|
||||||
|
mc_hashes[ ((curhash >> 4)&3) ] |= 1<<(curhash&0xf);
|
||||||
|
INCMAC( curmc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D(("hw_change_multicast board %lx flags %lx hashtab %lx\n",(ULONG)boardbase,(ULONG)flags,(ULONG)hash_tab));
|
||||||
|
|
||||||
|
enc624j6l_bc_mc_filter(boardbase, flags, hash_tab );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -494,7 +651,7 @@ void myhw_ControlInterrupts( DEVBASEP )
|
|||||||
hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List;
|
hwd->hwd_Interrupt.is_Code = (void(*)())enc624j6l_IntServer_List;
|
||||||
hwd->hwd_Interrupt.is_Data = &hwd->hwd_act_boards[0];
|
hwd->hwd_Interrupt.is_Data = &hwd->hwd_act_boards[0];
|
||||||
hwd->hwd_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
|
hwd->hwd_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
|
||||||
hwd->hwd_Interrupt.is_Node.ln_Pri = 51;
|
hwd->hwd_Interrupt.is_Node.ln_Pri = 126; /* 51; */
|
||||||
hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname;
|
hwd->hwd_Interrupt.is_Node.ln_Name = (char*)intname;
|
||||||
AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
|
AddIntServer( HW_INTSOURCE, &hwd->hwd_Interrupt );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,18 @@ _LVORawIOInit equ -$1f8
|
|||||||
_LVORawMayGetChar equ -$1fe
|
_LVORawMayGetChar equ -$1fe
|
||||||
endc
|
endc
|
||||||
|
|
||||||
XDEF _KPrintF
|
; XDEF _KPrintF
|
||||||
|
XDEF _KPrintFa0a1
|
||||||
|
|
||||||
|
;_KPrintF:
|
||||||
|
rts
|
||||||
|
move.l 4(sp),a0
|
||||||
|
lea 8(sp),a1
|
||||||
|
; fall through
|
||||||
|
|
||||||
;A0 = format
|
;A0 = format
|
||||||
;A1 = arguments
|
;A1 = arguments
|
||||||
_KPrintF:
|
_KPrintFa0a1:
|
||||||
; ifd DEBUG
|
; ifd DEBUG
|
||||||
|
|
||||||
movem.l d0-d2/a0-a3/a6,-(sp)
|
movem.l d0-d2/a0-a3/a6,-(sp)
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
|
|||||||
/* this limits the number of processed read requests per run when enabled */
|
/* this limits the number of processed read requests per run when enabled */
|
||||||
#define ONE_READ_REQ 2
|
#define ONE_READ_REQ 2
|
||||||
|
|
||||||
|
/* heavy debug on read/write */
|
||||||
|
#define D2(x)
|
||||||
|
#define D4(x)
|
||||||
|
/* #define D2(x) D(x) */
|
||||||
|
/* #define D4(x) D(x) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* (avoid external link libraries) this call is not time critical */
|
/* (avoid external link libraries) this call is not time critical */
|
||||||
@@ -384,6 +390,15 @@ static LONG server_changeMulticast( DEVBASEP, ULONG unit, struct IOSana2Req *ior
|
|||||||
COPYMAC( entry->mce_start, ioreq->ios2_SrcAddr );
|
COPYMAC( entry->mce_start, ioreq->ios2_SrcAddr );
|
||||||
COPYMAC( entry->mce_stop, ioreq->ios2_SrcAddr );
|
COPYMAC( entry->mce_stop, ioreq->ios2_SrcAddr );
|
||||||
|
|
||||||
|
D(("ADD Multicast MAC %02lx%02lx%02lx%02lx%02lx%02lx - %02lx%02lx%02lx%02lx%02lx%02lx\n",\
|
||||||
|
(ULONG)entry->mce_start[0],(ULONG)entry->mce_start[1],\
|
||||||
|
(ULONG)entry->mce_start[2],(ULONG)entry->mce_start[3],\
|
||||||
|
(ULONG)entry->mce_start[4],(ULONG)entry->mce_start[5],\
|
||||||
|
(ULONG)entry->mce_stop[0],(ULONG)entry->mce_stop[1],\
|
||||||
|
(ULONG)entry->mce_stop[2],(ULONG)entry->mce_stop[3],\
|
||||||
|
(ULONG)entry->mce_stop[4],(ULONG)entry->mce_stop[5] \
|
||||||
|
));
|
||||||
|
|
||||||
ADDTAIL( &db->db_svdat.sv_mclist, entry );
|
ADDTAIL( &db->db_svdat.sv_mclist, entry );
|
||||||
|
|
||||||
apply:
|
apply:
|
||||||
@@ -715,7 +730,7 @@ static LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq )
|
|||||||
UBYTE *header_ptr;
|
UBYTE *header_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
D(("write: type %08lx, size %ld\n",ioreq->ios2_PacketType,
|
D2(("write: type %08lx, size %ld\n",ioreq->ios2_PacketType,
|
||||||
ioreq->ios2_DataLength));
|
ioreq->ios2_DataLength));
|
||||||
|
|
||||||
frame = db->db_svdat.sv_frame;
|
frame = db->db_svdat.sv_frame;
|
||||||
@@ -765,13 +780,13 @@ static LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq )
|
|||||||
if( (*dbm->dbm_CopyFromBuffer32)(copy_ptr,ioreq->ios2_Data, ioreq->ios2_DataLength) )
|
if( (*dbm->dbm_CopyFromBuffer32)(copy_ptr,ioreq->ios2_Data, ioreq->ios2_DataLength) )
|
||||||
{
|
{
|
||||||
send:
|
send:
|
||||||
D(("+hw_send\n"));
|
D2(("+hw_send\n"));
|
||||||
#ifdef HW_DMA_TX
|
#ifdef HW_DMA_TX
|
||||||
ret = hw_send_frame(db, unit, copy_ptr, framesize, header_ptr ) ? SERR_OK:SERR_ERROR;
|
ret = hw_send_frame(db, unit, copy_ptr, framesize, header_ptr ) ? SERR_OK:SERR_ERROR;
|
||||||
#else
|
#else
|
||||||
ret = hw_send_frame(db, unit, frame, framesize ) ? SERR_OK : SERR_ERROR;
|
ret = hw_send_frame(db, unit, frame, framesize ) ? SERR_OK : SERR_ERROR;
|
||||||
#endif
|
#endif
|
||||||
D(("-hw_send\n"));
|
D2(("-hw_send\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -892,14 +907,14 @@ static void server_read_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq, U
|
|||||||
{
|
{
|
||||||
frame += 14; /* skip DST,SRC,Type */
|
frame += 14; /* skip DST,SRC,Type */
|
||||||
framesize -= 18; /* also remove CRC */
|
framesize -= 18; /* also remove CRC */
|
||||||
D(("plain mode: frame flags %ld\n",bcflag));
|
D4(("plain mode: frame flags %ld\n",bcflag));
|
||||||
}
|
}
|
||||||
ioreq->ios2_Req.io_Flags &= SANA2IOF_RAW; /* ignore all other flags */
|
ioreq->ios2_Req.io_Flags &= SANA2IOF_RAW; /* ignore all other flags */
|
||||||
ioreq->ios2_Req.io_Flags |= bcflag;
|
ioreq->ios2_Req.io_Flags |= bcflag;
|
||||||
ioreq->ios2_Req.io_Error = 0;
|
ioreq->ios2_Req.io_Error = 0;
|
||||||
ioreq->ios2_WireError = 0;
|
ioreq->ios2_WireError = 0;
|
||||||
|
|
||||||
D(("ReadFrm IO %lx, DBM %lx frm %lx frmsz %ld\n",(ULONG)ioreq,(ULONG)dbm,(ULONG)frame,framesize));
|
D4(("ReadFrm IO %lx, DBM %lx frm %lx frmsz %ld\n",(ULONG)ioreq,(ULONG)dbm,(ULONG)frame,framesize));
|
||||||
|
|
||||||
if( dbm->dbm_PacketFilter ) /* Filter Packets ? */
|
if( dbm->dbm_PacketFilter ) /* Filter Packets ? */
|
||||||
{
|
{
|
||||||
@@ -918,7 +933,7 @@ static void server_read_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq, U
|
|||||||
ioreq->ios2_WireError = S2WERR_BUFF_ERROR;
|
ioreq->ios2_WireError = S2WERR_BUFF_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
D(("Copied io_Error %ld\n",(LONG)ioreq->ios2_Req.io_Error));
|
D4(("Copied io_Error %ld\n",(LONG)ioreq->ios2_Req.io_Error));
|
||||||
|
|
||||||
Remove( (struct Node*)ioreq );
|
Remove( (struct Node*)ioreq );
|
||||||
svTermIO( db, ioreq );
|
svTermIO( db, ioreq );
|
||||||
@@ -946,7 +961,7 @@ static LONG server_readqueue( DEVBASEP, ULONG unit )
|
|||||||
/* TODO: devstats */
|
/* TODO: devstats */
|
||||||
frametype = *( (USHORT*)(frame+12) );
|
frametype = *( (USHORT*)(frame+12) );
|
||||||
|
|
||||||
D(("Have Frame size %ld type %ld\n",framesize,frametype));
|
D4(("Have Frame size %ld type %ld\n",framesize,frametype));
|
||||||
|
|
||||||
ObtainSemaphore( &db->db_Units[unit].du_Sem );
|
ObtainSemaphore( &db->db_Units[unit].du_Sem );
|
||||||
|
|
||||||
@@ -964,14 +979,14 @@ orphan:
|
|||||||
ioreq = (struct IOSana2Req *)GetHead( (struct List*)&db->db_Units[unit].du_ReadOrphans );
|
ioreq = (struct IOSana2Req *)GetHead( (struct List*)&db->db_Units[unit].du_ReadOrphans );
|
||||||
if( ioreq )
|
if( ioreq )
|
||||||
{
|
{
|
||||||
D(("Orphaned Frame\n"));
|
D4(("Orphaned Frame\n"));
|
||||||
|
|
||||||
ioreq->ios2_PacketType = frametype;
|
ioreq->ios2_PacketType = frametype;
|
||||||
server_read_frame( db, unit, ioreq, frame, framesize );
|
server_read_frame( db, unit, ioreq, frame, framesize );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D(("No ioreq for orphaned frame\n"));
|
D4(("No ioreq for orphaned frame\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
goto nextframe;
|
goto nextframe;
|
||||||
@@ -1005,7 +1020,7 @@ havetype:
|
|||||||
{
|
{
|
||||||
db->db_Units[unit].du_DevStats.Overruns++;
|
db->db_Units[unit].du_DevStats.Overruns++;
|
||||||
type->srt_Sana2PacketTypeStats.PacketsDropped++;
|
type->srt_Sana2PacketTypeStats.PacketsDropped++;
|
||||||
D(("No Reader for frame\n"));
|
D4(("No Reader for frame\n"));
|
||||||
goto orphan; /* does it help if we give the frame to the orphan list? */
|
goto orphan; /* does it help if we give the frame to the orphan list? */
|
||||||
}
|
}
|
||||||
nextframe:
|
nextframe:
|
||||||
@@ -1094,9 +1109,9 @@ VOID SAVEDS ServerTask(void)
|
|||||||
}
|
}
|
||||||
if( hw_recv_pending(db,i) )
|
if( hw_recv_pending(db,i) )
|
||||||
{
|
{
|
||||||
D(("Read on unit %ld start\n",i));
|
D4(("Read on unit %ld start\n",i));
|
||||||
server_readqueue( db, i );
|
server_readqueue( db, i );
|
||||||
D(("Read on unit %ld stop\n",i));
|
D4(("Read on unit %ld stop\n",i));
|
||||||
action = 1;
|
action = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ ASMDEFS1 = -DHW_DMA_TX=1
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# debug = 1 will include string debugging for terminal/sushi/sashimi
|
# debug = 1 will include string debugging for terminal/sushi/sashimi
|
||||||
# not enabled yet in SAS/C makefile
|
# not enabled yet in SAS/C makefile
|
||||||
debug = 0
|
#debug = 0
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# prefix for system includes (ASM)
|
# prefix for system includes (ASM)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
#define _INC_VERSION_H
|
#define _INC_VERSION_H
|
||||||
|
|
||||||
#define DEVICEVERSION 2
|
#define DEVICEVERSION 2
|
||||||
#define DEVICEREVISION 2
|
#define DEVICEREVISION 3
|
||||||
#define DEVICEEXTRA
|
#define DEVICEEXTRA
|
||||||
/* #define DEVICEEXTRA Beta */
|
/* #define DEVICEEXTRA Beta */
|
||||||
#define DEVICEDATE 10.03.2019
|
#define DEVICEDATE 04.04.2019
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user