updated LAN driver
This commit is contained in:
@@ -64,6 +64,18 @@ PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,FULLDUPLEX/S,FLOWCONTROL/S,TIMER/K/N,MULTICAST/
|
||||
Changelog:
|
||||
----------
|
||||
|
||||
2.2 - some more tuning to RX/TX scheduling
|
||||
- added optional debug code to lowlevel routines
|
||||
- removed some obsolete bus transfers
|
||||
- uses DMACopyFromBuffer for IP-stacks supporting
|
||||
this capability
|
||||
- explicit 32 bit alignment for RX/TX to speed up
|
||||
ZIII transfers
|
||||
- added experimental support for MII interface to
|
||||
poll and modify speed and duplex settings on the
|
||||
fly
|
||||
- miitool added (see README.miitool)
|
||||
|
||||
2.00 - improved RX speed for buffer wraparound cases
|
||||
- some more safety checks for boards with unresponsive
|
||||
ENC chips (explicit card bus clear before verification of
|
||||
|
||||
@@ -18,7 +18,11 @@ combination. Please note that fixed parameters must be set at both
|
||||
ends of the link. Otherwise the link will work slowly or not at all.
|
||||
|
||||
None of the settings this tool applies is permanent. Changed parameters
|
||||
are only valid until a reboot of the NIC.
|
||||
are only valid until the next reset of the NIC.
|
||||
|
||||
This utility is able to detect an active Ethernet interface in case that
|
||||
the RoadShow TCP/IP stack is active. Otherwise, the device needs to be
|
||||
passed as commandline option explicitly.
|
||||
|
||||
Examples for usage are given at the end of this text.
|
||||
|
||||
@@ -80,6 +84,9 @@ Valid Speed/Duplex combinations (not case sensitive):
|
||||
|
||||
Examples:
|
||||
|
||||
current status (detailed, autodetect)
|
||||
miitool v
|
||||
|
||||
current status (detailed):
|
||||
miitool DEV=enc624j6net.device v
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
VWiznet - A SANA-II driver for W5500 10/100 ethernet modules
|
||||
|
||||
Copyright (C) 2018-2019 Henryk Richter <henryk.richter@gmx.net>
|
||||
|
||||
This driver is supposed to support W5500 modules hooked up to the expansion
|
||||
port of Vampire 500V2+ cards.
|
||||
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
Installation of the driver is straightforward.
|
||||
Just copy vwiznet500ex.device from the bin subdirectory to devs:networks
|
||||
and enable the interface in your favorite TCP/IP stack as usual. So far,
|
||||
successful tests have been done with the free AmiTCP/IP 3.0b2, AmiTCP4.0-4.2,
|
||||
Genesis, MiamiDX and RoadShow.
|
||||
|
||||
The minimum system requirement is the Gold 2.10 release of Apollo Core
|
||||
for Vampire 500V2+.
|
||||
|
||||
|
||||
|
||||
Vampire500 Expansion port Hardware
|
||||
-----------------------------------
|
||||
|
||||
Please see http://wiki.apollo-accelerators.com/doku.php/expansionport for
|
||||
guidance on pinout of the expansion port.
|
||||
|
||||
The W5500 can be clocked way higher than the ENC28J60 that was used for
|
||||
SDNet. As a consequence of clocks beyond 25 MHz, signal integrity is of
|
||||
some concern. Therefore it is suggested to connect the module is as close
|
||||
as possible to the expansion port and use an Ethernet expansion cable
|
||||
in order to reach the edge of the computer case.
|
||||
|
||||
An adapter PCB is in the making. That PCB plugs directly into the Vampire
|
||||
expansion port, connects readily available W5500 modules on the other
|
||||
side and contains some components to keep signal integrity in a good shape.
|
||||
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
Below you find the options accepted by the driver. Please note that no special
|
||||
configuration is necessary for normal operation. What you find documented below
|
||||
is available for tuning purposes.
|
||||
|
||||
The options template for the config files
|
||||
ENVARC:SANA2/vwiznet500ex.config
|
||||
|
||||
is as follows:
|
||||
|
||||
PRIORITY=PRI/K/N,BPS/K/N,MTU/K/N,SPISPEED/K/N,TIMER/K/N,NOINTERRUPT/S
|
||||
|
||||
SPISPEED - SPI clock divider (1-10, default 1), controls maximum
|
||||
clock of SPI bus. Actual I/O clock is Core_Clock/(3+SPISPEED).
|
||||
|
||||
PRIORITY - server task priority (default 1)
|
||||
|
||||
BPS - bit per seconds for statistics purposes
|
||||
|
||||
MTU - maximum transmission unit (default 1500)
|
||||
|
||||
NOINTERRUPT - disable hardware interrupt and use polling instead
|
||||
(default: interrupt enabled)
|
||||
|
||||
TIMER - when disabling interrupt you also need to specify
|
||||
a timer interval in microseconds
|
||||
(default: 0, i.e. no timer)
|
||||
|
||||
|
||||
example1 (useful for DSL via PPPoE,
|
||||
higher priority for server task = more speed with AmiTCP
|
||||
at the expense of multitasking friendliness):
|
||||
echo "MTU=1492 SPISPEED=1 PRIORITY=6" >ENVARC:sana2/vwiznet500ex.config
|
||||
|
||||
|
||||
|
||||
Changelog:
|
||||
----------
|
||||
|
||||
1.99 - re-enabled 32 Bit Buffer copies (unless Miami is active)
|
||||
- default server task priority for AmiTCP=6 (otherwise 0)
|
||||
- tuned RX/TX balancing to make RoadShow happy
|
||||
- added Packet Filter hook processing (needs testing)
|
||||
|
||||
1.98 - preparations for V2 of the adapter PCB: hardware based reset
|
||||
|
||||
1.97 - added New style device commands
|
||||
- implemented SANA-II Device Query Extension
|
||||
|
||||
1.96 - tuned defaults
|
||||
|
||||
1.95 - initial build, aligned with sdnet/v2expeth version
|
||||
|
||||
|
||||
|
||||
Copyrights / License:
|
||||
---------------------
|
||||
|
||||
Copyright (C) 2018-2019 Henryk Richter <henryk.richter@gmx.net>, all rights reserved.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,11 +25,15 @@ compiler_vcc = 1
|
||||
|
||||
###############################################################################
|
||||
# prefix for system includes (ASM)
|
||||
#
|
||||
# native AmigaOS compilation: set PREFX=GG: or PREFX=ADE:, depending on toolchain
|
||||
###############################################################################
|
||||
PREFX = c:/Users/Matze/Amiga/development/VBCC/
|
||||
|
||||
PREFX = /opt/amigaos-68k/
|
||||
#PREFX = gg:
|
||||
SYSINC = $(PREFX)NDK39/Include/include_i
|
||||
#PREFX = c:/Users/Matze/Amiga/development/VBCC/
|
||||
|
||||
SYSINC = $(PREFX)os-include
|
||||
#SYSINC = $(PREFX)NDK39/Include/include_i
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@@ -41,6 +45,7 @@ ifeq ($(compiler_vcc),1)
|
||||
# VBCC (use explicit vlink line for LINK= if complaints about R_PC happen)
|
||||
CCX = vc
|
||||
LINK = vlink -bamigahunk -x -s -mrel -Cvbcc -Bstatic -nostdlib #-Rshort
|
||||
LINKEXE = vlink -bamigahunk -x -s -mrel -Cvbcc -Bstatic
|
||||
#LINK = $(CCX) -nostdlib
|
||||
CFLAGS = -Os -+ -sc -c99 -cpu=$(CPU)
|
||||
CFLAGS2 = -Os -+ -sc -c99 -cpu=$(CPU2)
|
||||
@@ -50,6 +55,7 @@ else
|
||||
# GCC
|
||||
CCX = m68k-amigaos-gcc
|
||||
LINK = $(CCX) -nostartfiles -s
|
||||
LINKEXE = $(CCX) -s -noixemul
|
||||
CFLAGS = -O3 -s -m$(CPU) -Wall -noixemul -mregparm=4 -fomit-frame-pointer -msoft-float -noixemul
|
||||
CFLAGS2 = -O3 -s -m$(CPU2) -Wall -noixemul -mregparm=4 -fomit-frame-pointer -msoft-float -noixemul
|
||||
|
||||
@@ -77,29 +83,41 @@ IPATH =
|
||||
###############################################################################
|
||||
ifeq ($(compiler_vcc),1)
|
||||
# skip quotes with VCC, the AmigaOS native version doesn't like them
|
||||
DEFINES += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
DEFINES += -DDEVICEDATE=$(DEVICEDATE) -DDEVICENAME="$(DEVICEID)"
|
||||
DEFINES += -DDEVICEEXTRA=$(DEVICEEXTRA)
|
||||
ASMDEFS += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES += -DDEVICEDATE=$(DEVICEDATE)
|
||||
#DEFINES += -DDEVICEEXTRA=$(DEVICEEXTRA)
|
||||
DEFINES += -DDEVICENAME="$(DEVICEID)"
|
||||
DEFINES += -DHAVE_VERSION_H=1
|
||||
DEFINES += -DNEWSTYLE
|
||||
#ASMDEFS += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#ASMDEFS += -DDEVICEDATE=$(DEVICEDATE) -DDEVICENAME=$(DEVICEID)
|
||||
|
||||
DEFINES2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
DEFINES2 += -DDEVICEDATE=$(DEVICEDATE) -DDEVICENAME="$(DEVICEID2)"
|
||||
DEFINES2 += -DDEVICEEXTRA=$(DEVICEEXTRA)
|
||||
ASMDEFS2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES2 += -DDEVICEDATE=$(DEVICEDATE)
|
||||
#DEFINES2 += -DDEVICEEXTRA=$(DEVICEEXTRA)
|
||||
DEFINES2 += -DDEVICENAME="$(DEVICEID2)"
|
||||
DEFINES2 += -DHAVE_VERSION_H=1
|
||||
DEFINES2 += -DNEWSTYLE
|
||||
#ASMDEFS2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
|
||||
else
|
||||
|
||||
DEFINES += -D"DEVICEVERSION=$(DEVICEVERSION)" -D"DEVICEREVISION=$(DEVICEREVISION)"
|
||||
DEFINES += -D"DEVICEDATE=$(DEVICEDATE)" -D"DEVICENAME="$(DEVICEID)""
|
||||
DEFINES += -D"DEVICEEXTRA=$(DEVICEEXTRA)"
|
||||
ASMDEFS += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES += -D"DEVICEVERSION=$(DEVICEVERSION)" -D"DEVICEREVISION=$(DEVICEREVISION)"
|
||||
#DEFINES += -D"DEVICEDATE=$(DEVICEDATE)"
|
||||
#DEFINES += -D"DEVICEEXTRA=$(DEVICEEXTRA)"
|
||||
DEFINES += -D"DEVICENAME="$(DEVICEID)""
|
||||
DEFINES += -DHAVE_VERSION_H=1
|
||||
DEFINES += -DNEWSTYLE
|
||||
#ASMDEFS += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#ASMDEFS += -DDEVICEDATE=$(DEVICEDATE) -DDEVICENAME=$(DEVICEID)
|
||||
|
||||
DEFINES2 += -D"DEVICEVERSION=$(DEVICEVERSION)" -D"DEVICEREVISION=$(DEVICEREVISION)"
|
||||
DEFINES2 += -D"DEVICEDATE=$(DEVICEDATE)" -D"DEVICENAME="$(DEVICEID2)""
|
||||
DEFINES2 += -D"DEVICEEXTRA=$(DEVICEEXTRA)"
|
||||
ASMDEFS2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
#DEFINES2 += -D"DEVICEVERSION=$(DEVICEVERSION)" -D"DEVICEREVISION=$(DEVICEREVISION)"
|
||||
#DEFINES2 += -D"DEVICEDATE=$(DEVICEDATE)" -D"DEVICENAME="$(DEVICEID2)""
|
||||
#DEFINES2 += -D"DEVICEEXTRA=$(DEVICEEXTRA)"
|
||||
DEFINES2 += -D"DEVICENAME="$(DEVICEID2)""
|
||||
DEFINES2 += -DHAVE_VERSION_H=1
|
||||
DEFINES2 += -DNEWSTYLE
|
||||
#ASMDEFS2 += -DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
|
||||
|
||||
endif
|
||||
|
||||
@@ -112,7 +130,8 @@ endif
|
||||
ifeq ($(debug),1)
|
||||
CFLAGS += -DDEBUG -g
|
||||
CFLAGS2 += -DDEBUG -g
|
||||
LINKLIBS = -L$(PREFX)targets/m68k-amigaos/lib -ldebug
|
||||
LINKLIBS = -L$(PREFX)/lib -L$(PREFX)targets/m68k-amigaos/lib -ldebug
|
||||
#LINKLIBS = -L$(PREFX)targets/m68k-amigaos/lib -ldebug
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
@@ -144,11 +163,11 @@ OBJECTS2 = $(patsubst %.o,%.2o,$(OBJECTS))
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
all: $(DEVICEID) $(DEVICEID2)
|
||||
all: $(DEVICEID) $(DEVICEID2) $(TESTTOOL) $(TESTTOOL2)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(OBJECTS2)
|
||||
rm -f $(DEVICEID) $(DEVICEID2)
|
||||
rm -f $(DEVICEID) $(DEVICEID2) $(EXTRACLEAN)
|
||||
|
||||
# not for cross compile :-)
|
||||
install: $(DEVICEID) $(DEVICEID2)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,3 @@
|
||||
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
; ------------------------------------------------------------------------------
|
||||
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
|
||||
; | Henryk Richter <henryk.richter@gmx.net> |
|
||||
@@ -20,14 +19,14 @@
|
||||
; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully)
|
||||
;
|
||||
; enable debugging code block (comment/uncomment, see below)
|
||||
;DEBUG EQU 1
|
||||
DEBUG EQU 1
|
||||
GLOBALINT_BOARD EQU 1 ;if 1, then toggle board interrupt, else ENC624 INTIE
|
||||
|
||||
incdir src:baxnet/trunk/source/
|
||||
;Temp:Amiga/src/Zorro-LAN-IDE.git/Driver/enc624j6net/
|
||||
include "enc624j6net/registers.i"
|
||||
include "enc624j6net/macros.i"
|
||||
include "debug.i"
|
||||
include "hw.i"
|
||||
|
||||
ifnd DEBUG
|
||||
DEBUG EQU 0
|
||||
@@ -41,7 +40,7 @@ _OPT_LONGRESET EQU 0 ;in testing, don't enable
|
||||
;
|
||||
; options for buffer memory configuration, please reserve some space for private variables
|
||||
;
|
||||
PSTART_INIT EQU $0BF0 ; 16 Bytes private storage for driver
|
||||
PSTART_INIT EQU $0BF8 ; 8 Bytes private storage for driver
|
||||
PSTOP_INIT EQU $0BFF ; (see below for definitions)
|
||||
|
||||
RXSTART_INIT EQU $0C00 ; start of RX buffer, room for 14 packets
|
||||
@@ -57,10 +56,8 @@ MAX_FRAMELEN EQU 1518
|
||||
;------------ driver private storage ------------------------------
|
||||
PNextPacket EQU PSTART_INIT ;2 Bytes - private "next packet" pointer for RX
|
||||
PNextTX EQU PSTART_INIT+2 ;2 Bytes - private "next packet" pointer for TX (init as 0)
|
||||
PSigBit EQU PSTART_INIT+4 ;2 Bytes interrupt bit
|
||||
PSigTask EQU PSTART_INIT+6 ;4 Bytes signaled task
|
||||
PLinkChange EQU PSTART_INIT+10 ;2 Bytes Link Change (copy of PHYDPX,PHYLNK bits)
|
||||
Punused EQU PSTART_INIT+12 ;
|
||||
PLinkChange EQU PSTART_INIT+4 ;2 Bytes Link Change (copy of PHYDPX,PHYLNK bits)
|
||||
Punused EQU PSTART_INIT+6 ;
|
||||
|
||||
;------------- TX: double buffering --------------------------------
|
||||
PSwapTX EQU $600 ;swap between two TX buffers (one active, one activated after last TX done)
|
||||
@@ -560,6 +557,8 @@ _enc624j6l_Init:
|
||||
move.l a0,d0
|
||||
beq .err
|
||||
|
||||
WRITEDEBUG Init_MSG,a0
|
||||
|
||||
READREG ESTAT,a0,d0
|
||||
and #(ESTAT_CLKRDY|ESTAT_PHYRDY),d0
|
||||
cmp #(ESTAT_CLKRDY|ESTAT_PHYRDY),d0
|
||||
@@ -787,20 +786,13 @@ _enc624j6l_EnableInterrupt:
|
||||
move.l a0,d1
|
||||
beq.s .err
|
||||
|
||||
WRITEREG PSigBit,a0,d0 ;save signal bit
|
||||
|
||||
move.l a1,d0
|
||||
WRITEREG PSigTask+2,a0,d0 ;lower two bytes
|
||||
swap d0 ;
|
||||
WRITEREG PSigTask,a0,d0 ;upper two bytes
|
||||
|
||||
; enable interrupt for incoming packet
|
||||
moveq #-1,d0 ;magic trick: the board enables Interrupts
|
||||
lea $4000(a0),a0
|
||||
move.w d0,($4000,a0)
|
||||
lea -$4000(a0),a0
|
||||
|
||||
move #EIE_PKTIE|EIE_PCFULIE|EIE_INTIE,d0
|
||||
move #EIE_PKTIE|EIE_INTIE|EIE_PCFULIE,d0
|
||||
SETREG EIE,a0,d0
|
||||
|
||||
moveq #1,d0
|
||||
@@ -823,8 +815,20 @@ _enc624j6l_EnableInterrupt:
|
||||
; Notes: assumes that init() was called before
|
||||
;
|
||||
_enc624j6l_EnableGlobalInterrupt:
|
||||
move #EIE_PKTIE|EIE_PCFULIE|EIE_INTIE,d0 ; move #EIE_INTIE,d0
|
||||
ifne GLOBALINT_BOARD
|
||||
|
||||
moveq #-1,d0 ;magic trick: the board enables Interrupts
|
||||
lea $4000(a0),a0
|
||||
move.w d0,($4000,a0)
|
||||
lea -$4000(a0),a0
|
||||
|
||||
else ;GLOBALINT_BOARD
|
||||
|
||||
move #EIE_PKTIE|EIE_INTIE|EIE_PCFULIE,d0
|
||||
SETREG EIE,a0,d0
|
||||
|
||||
endc ;GLOBALINT_BOARD
|
||||
|
||||
moveq #1,d0
|
||||
.rts
|
||||
rts
|
||||
@@ -842,8 +846,21 @@ _enc624j6l_EnableGlobalInterrupt:
|
||||
; Notes: assumes that init() was called before
|
||||
;
|
||||
_enc624j6l_DisableGlobalInterrupt:
|
||||
|
||||
ifne GLOBALINT_BOARD
|
||||
|
||||
moveq #0,d0 ;magic trick: the board enables Interrupts
|
||||
lea $4000(a0),a0
|
||||
move.w d0,($4000,a0)
|
||||
lea -$4000(a0),a0
|
||||
|
||||
else ;GLOBALINT_BOARD
|
||||
|
||||
move #EIE_INTIE,d0
|
||||
CLRREG EIE,a0,d0
|
||||
|
||||
endc ;GLOBALINT_BOARD
|
||||
|
||||
moveq #1,d0
|
||||
.rts
|
||||
rts
|
||||
@@ -878,10 +895,6 @@ _enc624j6l_DisableInterrupt:
|
||||
move #EIE_INTIE|EIE_PKTIE|EIE_LINKIE|EIE_AESIE|EIE_MODEXIE|EIE_HASHIE|EIE_PRDYIE|EIE_DMAIE|EIE_TXIE|EIE_TXABTIE|EIE_RXABTIE|EIE_PCFULIE,d0
|
||||
CLRREG EIE,a0,d0
|
||||
|
||||
moveq #0,d0
|
||||
WRITEREG PSigTask+2,a0,d0 ;lower two bytes
|
||||
WRITEREG PSigTask,a0,d0 ;upper two bytes
|
||||
|
||||
moveq #1,d0
|
||||
.err:
|
||||
rts
|
||||
@@ -905,35 +918,50 @@ _enc624j6l_DisableInterrupt:
|
||||
; ULONG sigbit
|
||||
;
|
||||
_enc624j6l_IntServer_List:
|
||||
move.l a6,-(sp)
|
||||
|
||||
move.l a1,d0 ;no pointer supplied ? -> return
|
||||
beq.s .end
|
||||
movem.l d1/A1/a6,-(sp)
|
||||
|
||||
beq.s .rts
|
||||
move.l a1,a6
|
||||
|
||||
moveq #0,d1
|
||||
move.l (A6)+,d0 ;read magic word
|
||||
cmp.l #HW_MAGIC_WORD,D0 ; are we in the right structure?
|
||||
bne.s .done
|
||||
|
||||
.boardloop:
|
||||
move.l (A6)+,d0 ;next entry from list
|
||||
move.l (a1)+,d0 ;next entry from list
|
||||
beq.s .done ;
|
||||
move.l d0,a1 ;current board
|
||||
move.l d0,a0 ;current board
|
||||
|
||||
READREG EIR,A1,d0 ;get interrupt status reg
|
||||
and #EIR_PKTIF|EIR_PCFULIF,D0
|
||||
beq.s .boardloop ;no interrupt here
|
||||
or.l d0,D1 ; save if at least one one board has interrupted
|
||||
move #EIE_INTIE,D0 ;disable board interrupt until someone enables it again
|
||||
CLRREG EIE,A1,d0
|
||||
BRA.s .boardloop
|
||||
READREG EIR,a0,d0 ;get interrupt status reg
|
||||
and #EIR_PKTIF|EIR_PCFULIF|EIR_RXABTIF|EIR_PKTIF|EIR_TXABTIF,d0
|
||||
|
||||
or.l d0,d1
|
||||
bra.s .boardloop
|
||||
.done:
|
||||
tst.w d1
|
||||
beq.s .rts
|
||||
|
||||
; clear EIE_INTIE in all active boards directly from here
|
||||
.intdis_loop:
|
||||
move.l (a6)+,d0
|
||||
beq.s .boardsdone
|
||||
move.l d0,a1
|
||||
|
||||
ifne GLOBALINT_BOARD
|
||||
|
||||
moveq #0,d0 ;magic trick: the board enables Interrupts
|
||||
lea $4000(a1),a1
|
||||
move.w d0,($4000,a1)
|
||||
|
||||
else ;GLOBALINT_BOARD
|
||||
|
||||
move #EIE_INTIE,D0 ;disable board interrupt until someone enables it again
|
||||
CLRREG EIE,A1,d0
|
||||
|
||||
endc ;GLOBALINT_BOARD
|
||||
|
||||
bra.s .intdis_loop
|
||||
.boardsdone:
|
||||
|
||||
;faster: get from extended Driver board list instead from ZII/ZIII card
|
||||
ifne 1
|
||||
|
||||
move.l (a6)+,d0 ;SigTask
|
||||
beq.s .rts
|
||||
@@ -941,33 +969,16 @@ _enc624j6l_IntServer_List:
|
||||
move.l (a6)+,d1 ;SigBit
|
||||
move.l d0,a1 ;SigTask
|
||||
|
||||
move.l (a6)+,a6 ;ExecBase
|
||||
move.l (a6)+,a6 ;ExecBase (from FastRAM)
|
||||
;move.l 4.w,a6
|
||||
moveq #0,d0
|
||||
|
||||
bset d1,d0
|
||||
|
||||
else
|
||||
|
||||
READREG PSigTask,a0,d0 ;upper two bytes
|
||||
swap d0 ;
|
||||
READREG PSigTask+2,a0,d0 ;lower two bytes
|
||||
tst.l d0 ; no task ?
|
||||
beq.s .rts
|
||||
move.l d0,a1 ; signaled task
|
||||
|
||||
moveq #0,d0
|
||||
READREG PSigBit,a0,d1 ;get signal bit
|
||||
bset d1,d0 ;signal mask
|
||||
|
||||
move.l 4.w,a6
|
||||
|
||||
endc
|
||||
|
||||
jsr _LVOSignal(a6)
|
||||
|
||||
.rts
|
||||
movem.l (sp)+,D1/A1/A6
|
||||
.end
|
||||
move.l (sp)+,a6
|
||||
moveq #0,d0 ;set Z flag
|
||||
rts
|
||||
|
||||
@@ -1071,7 +1082,11 @@ _enc624j6l_CheckLinkChange:
|
||||
;
|
||||
|
||||
ifne DEBUG
|
||||
RXReset_MSG: dc.b "RXReset Head %04lx Tail %04lx NextPacket %04lx ReadPTR %04lx Bytes %04lx",10,0
|
||||
RXReset_MSG: dc.b "RXReset Head %04lx Tail %04lx NextPacket %04lx NextReadPTR %04lx Bytes(maybe) %04lx ESTAT %04lx",13,10,0
|
||||
Init_MSG: dc.b "ENC624j6net init (debug build) board address %lx",13,10,0
|
||||
TXWait_MSG: dc.b "TransmitFrame: waiting",13,10,0
|
||||
TXAbort_MSG: dc.b "TransmitFrame: abort",13,10,0
|
||||
cnop 0,4
|
||||
endc
|
||||
|
||||
_enc624j6l_RXReset:
|
||||
@@ -1084,6 +1099,8 @@ _enc624j6l_RXReset:
|
||||
moveq #0,d1
|
||||
moveq #0,d2
|
||||
moveq #0,d3
|
||||
moveq #0,d7
|
||||
READREG ESTAT,a0,d7
|
||||
READREG ERXHEAD,A0,d0
|
||||
READREG ERXTAIL,A0,d1
|
||||
READREG PNextPacket,a0,d2
|
||||
@@ -1100,10 +1117,7 @@ _enc624j6l_RXReset:
|
||||
rol.w #8,d4 ;swap pointer to Big Endian
|
||||
endc
|
||||
|
||||
|
||||
|
||||
|
||||
WRITEDEBUG RXReset_MSG,d0,d1,d2,d3,d4
|
||||
WRITEDEBUG RXReset_MSG,d0,d1,d2,d3,d4,d7
|
||||
|
||||
movem.l (sp)+,d2-d7
|
||||
endc
|
||||
@@ -1202,8 +1216,10 @@ _enc624j6l_RecvFrame: ;
|
||||
beq .rts ;nothing in buffer, return sheer emptiness
|
||||
;at least one frame in buffer
|
||||
|
||||
ifne DEBUG
|
||||
READREG ERXHEAD,A0,d4
|
||||
READREG ERXTAIL,A0,d5
|
||||
endc
|
||||
|
||||
;----------- check next packet pointer and verify expected state -----------
|
||||
READREG PNextPacket,a0,d7 ;get user read pointer from private space
|
||||
@@ -1215,15 +1231,6 @@ _enc624j6l_RecvFrame: ;
|
||||
rol.w #8,d0 ;swap pointer to Big Endian
|
||||
endc
|
||||
|
||||
; btst #0,d0
|
||||
; beq.s .nozerobit
|
||||
; nop
|
||||
;.nozerobit
|
||||
; btst #0,d7
|
||||
; beq.s .nozerobit2
|
||||
; nop
|
||||
;.nozerobit2
|
||||
|
||||
;verify next packet pointer, re-initialize recv if this is invalid
|
||||
cmp #RXSTOP_INIT,d0 ;bad pointer (<0 or >end of memory)
|
||||
bhi.w .recv_err
|
||||
@@ -1238,55 +1245,40 @@ _enc624j6l_RecvFrame: ;
|
||||
add.w d0,d1 ;next pkt + unwrap distance
|
||||
.ptrcheck:
|
||||
sub.w d7,d1 ;length of pkt
|
||||
cmp #MAX_FRAMELEN+2+6,d1 ;must be smaller than max framelen + ptr + status vector
|
||||
cmp #MAX_FRAMELEN+2+6+2,d1 ;must be smaller than max framelen + ptr + status vector + alignment
|
||||
bhi .recv_err ;-> reinit recv (am I paranoid ? -> try ENC28J60, then you know why...)
|
||||
|
||||
;debug: collect packet positions
|
||||
;move.l recvptr,a2
|
||||
;move d0,(a2)+
|
||||
;move.l a2,recvptr
|
||||
;addq.l #1,recvcount
|
||||
;cmp.l #65536,recvcount
|
||||
;bgt .recv_err
|
||||
|
||||
WRITEREG PNextPacket,a0,d0 ;write pointer for next packet
|
||||
|
||||
;------------------ check receive status vector -----------------------------
|
||||
addq.w #2,d7 ;increment pointer
|
||||
WRAPINDEX d7 ;wrap D7 if beyond buffer
|
||||
;lea (a0,d7.w),a2 ;read ptr for first control word
|
||||
;READREG 0,a2,d0 ;last control word = length (byte count)
|
||||
READSRAM a0,d7,d0 ;move (a0,d7.w),d0
|
||||
ifeq _OPT_BUFFER_SWAP
|
||||
rol.w #8,d0 ;swap pointer to Big Endian
|
||||
endc
|
||||
|
||||
and.w #$f800,d0 ;verify (should be all zeros in upper 9 bits)
|
||||
ifne 0
|
||||
READSRAM a0,d7,d2 ;move (a0,d7.w),d0
|
||||
ifeq _OPT_BUFFER_SWAP
|
||||
rol.w #8,d2 ;swap pointer to Big Endian
|
||||
endc
|
||||
and.w #$f800,d2 ;verify (should be all zeros in upper 9 bits)
|
||||
bne .recv_err ;receive buffer is wrong -> re-initialize
|
||||
endc
|
||||
|
||||
addq.w #4,d7 ;increment pointer
|
||||
WRAPINDEX d7 ;wrap D7 if beyond buffer
|
||||
|
||||
WRITEREG PNextPacket,a0,d0 ;write pointer for next packet
|
||||
|
||||
ifne 0
|
||||
;lea (a0,d7.w),a2 ;new read pointer for length
|
||||
;READREG 0,a2,d0 ;last control word = length (byte count)
|
||||
READSRAM a0,d7,d0 ;move (a0,d7.w),d0
|
||||
READSRAM a0,d7,d2 ;move (a0,d7.w),d0
|
||||
ifeq _OPT_BUFFER_SWAP
|
||||
rol.w #8,d0 ;swap pointer to Big Endian
|
||||
endc
|
||||
rol.w #8,d2 ;swap pointer to Big Endian
|
||||
endc ;_OPT_BUFFER_SWAP
|
||||
endc ;0
|
||||
|
||||
ifne 1
|
||||
;D1 is the distance to the next frame = stored length + recv vevtor
|
||||
sub #6+2,d1 ;STATUS VECTOR, Pointer
|
||||
subq #6+2,d1 ;STATUS VECTOR, Pointer
|
||||
move d1,d0 ;
|
||||
|
||||
else
|
||||
|
||||
cmp #2,d0
|
||||
blt .recv_err ;can't be: SRC MAC 6 DST MAC 6 LEN/TYPE 2 CRC 4 (discounting variable data)
|
||||
cmp #MAX_FRAMELEN,d0
|
||||
bgt .recv_err
|
||||
|
||||
endc
|
||||
|
||||
subq #4,d0 ;subtract CRC length
|
||||
|
||||
addq.w #2,d7 ;increment pointer (skip status vector length field)
|
||||
@@ -1365,6 +1357,10 @@ _enc624j6l_RecvFrame: ;
|
||||
bra.s .end_read
|
||||
|
||||
.nooptrecv:
|
||||
;DEBUG ONLY
|
||||
;bra.s .emergency_slow
|
||||
;DEBUG ONLY
|
||||
|
||||
ifeq _OPT_BUFFER_SWAP ;1
|
||||
;
|
||||
;wraparound aware loop for big endian buffer
|
||||
@@ -1462,7 +1458,13 @@ _enc624j6l_RecvFrame: ;
|
||||
rts
|
||||
.err: moveq #-1,d0 ;receive error
|
||||
bra.s .rts
|
||||
|
||||
.recv_err:
|
||||
moveq #0,d0
|
||||
READREG ESTAT,a0,d2 ;number of pending frames
|
||||
move.b d2,d0 ;clear out count (ESTAT_PKTCNT7...ESTAT_PKTCNT0)
|
||||
beq.s .rts ;nothing in buffer, return sheer emptiness
|
||||
|
||||
;serious problem: we need to re-initialize the recv buffer here
|
||||
bsr _enc624j6l_RXReset
|
||||
|
||||
@@ -1613,18 +1615,22 @@ _enc624j6l_TransmitFrame:
|
||||
.copydone
|
||||
|
||||
;---------------- wait on last frame ----------------------------------
|
||||
move #200,d3
|
||||
move #600,d3 ;
|
||||
.txwait:
|
||||
READREG ECON1,a0,d1
|
||||
and.w #ECON1_TXRTS,d1
|
||||
beq.s .txrdy
|
||||
;100 MBit/s frame time is max. 0.12 ms (without inter-frame spacing)
|
||||
|
||||
;wait 20 us via CIA
|
||||
moveq #20,d0
|
||||
;WRITEDEBUG TXWait_MSG
|
||||
|
||||
;wait 5 us via CIA
|
||||
moveq #5,d0
|
||||
bsr _enc624j6l_UMinDelay
|
||||
dbf d3,.txwait ;approx. 4ms max. wait
|
||||
|
||||
WRITEDEBUG TXAbort_MSG
|
||||
|
||||
;hmpf. abort last transmission
|
||||
move #ECON1_TXRTS,d1 ;
|
||||
CLRREG ECON1,a0,d1 ;
|
||||
|
||||
@@ -460,9 +460,7 @@ void myhw_ControlInterrupts( DEVBASEP )
|
||||
|
||||
ObtainSemaphore( &hwd->hwd_Sem ); /* redundant here: server is a single task -> but it looks good :-) */
|
||||
|
||||
hwd->hwd_act_boards[0] = HW_MAGIC_WORD;
|
||||
|
||||
flag = 1;
|
||||
flag = 0;
|
||||
for( i=0 ; i < db->db_NBoards ; i++ )
|
||||
{
|
||||
if( db->db_Units[i].duh_online )
|
||||
@@ -476,7 +474,7 @@ void myhw_ControlInterrupts( DEVBASEP )
|
||||
hwd->hwd_act_boards[flag+2] = (APTR)hwd->hwd_IntSig; /* append sigbit */
|
||||
hwd->hwd_act_boards[flag+3] = (APTR)db->db_SysBase; /* append ExecBase *((APTR*)0x4); */
|
||||
|
||||
if( flag>1 ) /* determine on/off switch */
|
||||
if( flag ) /* determine on/off switch */
|
||||
{
|
||||
/* at least 1 board is online */
|
||||
if( hwd->hwd_Interrupt.is_Data )
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
incdir include:
|
||||
ifnd _LVOSupervisor
|
||||
include exec/exec_lib.i
|
||||
include lvo/exec_lib.i
|
||||
;include exec/exec_lib.i
|
||||
endc
|
||||
include exec/execbase.i
|
||||
|
||||
@@ -18,7 +19,7 @@ _LVORawMayGetChar equ -$1fe
|
||||
;A0 = format
|
||||
;A1 = arguments
|
||||
_KPrintF:
|
||||
ifd DEBUG
|
||||
; ifd DEBUG
|
||||
|
||||
movem.l d0-d2/a0-a3/a6,-(sp)
|
||||
|
||||
@@ -37,7 +38,7 @@ _KPrintF:
|
||||
jsr _LVORawPutChar(a6) ; move.b d0,(a3)+
|
||||
movem.l (sp)+,d0/d1/a0/a1/a6
|
||||
|
||||
endc ;DEBUG
|
||||
; endc ;DEBUG
|
||||
|
||||
rts
|
||||
|
||||
|
||||
+201
-69
@@ -4,7 +4,6 @@
|
||||
/** SANA-II extension for access to Ethernet PHY registers over MII interface **/
|
||||
/** **/
|
||||
/** Copyright (c) 2019, Henryk Richter, Timm S. Müller **/
|
||||
/** All rights reserved. **/
|
||||
/** **/
|
||||
/** Redistribution and use in source and binary forms, with or without **/
|
||||
/** modification, are permitted provided that the following conditions are met: **/
|
||||
@@ -16,9 +15,6 @@
|
||||
/** 3. All advertising materials mentioning features or use of this software **/
|
||||
/** must display the following acknowledgement: **/
|
||||
/** This product includes software developed by Henryk Richter. **/
|
||||
/** 4. Neither the name of the Henryk Richter nor the **/
|
||||
/** names of its contributors may be used to endorse or promote products **/
|
||||
/** derived from this software without specific prior written permission. **/
|
||||
/** **/
|
||||
/** THIS SOFTWARE IS PROVIDED BY Henryk Richter ''AS IS'' AND ANY **/
|
||||
/** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED **/
|
||||
@@ -32,15 +28,22 @@
|
||||
/** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
/** Acknowledgements: **/
|
||||
/** text and definitions in "media" table and "miitool.h" file originate from mii-tool.c **/
|
||||
/** written/copyright 1997-2000 by Donald Becker **/
|
||||
/*******************************************************************************************/
|
||||
/*
|
||||
Notes:
|
||||
- make sure you have an up-to-date devices/sana2devqueryext.h
|
||||
- make sure you have devices/newstyle.h
|
||||
- compilation
|
||||
sc miitool.c link
|
||||
|
||||
sc miitool.c link INCLUDEDIR=sc:netinclude
|
||||
gcc miitool.c -Igg:netinclude -o miitool
|
||||
- if you don`t have the Roadshow SDK installed, just comment "RSHOW" out to build
|
||||
without auto-detection code
|
||||
*/
|
||||
|
||||
#define RSHOW
|
||||
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
@@ -49,8 +52,17 @@
|
||||
#include <devices/sana2.h>
|
||||
#include <devices/sana2devqueryext.h>
|
||||
#include "miitool.h"
|
||||
#ifdef RSHOW
|
||||
#include <libraries/bsdsocket.h>
|
||||
#include <proto/bsdsocket.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
struct UtilityBase *UtilityBase;
|
||||
static USHORT Utility_MY = 0;
|
||||
#endif
|
||||
|
||||
#define OPT_TEMPLATE "DEVICE=DEV/K,UNIT/K/N,VERBOSE=V/S,FORCEMEDIA/K,ADVERTISE/K,RENEG=RESTART/S,RESET/S,VERYVERBOSE=VV/S"
|
||||
const char opt_template[] = OPT_TEMPLATE;
|
||||
struct progopts {
|
||||
@@ -70,12 +82,17 @@ struct prgdata {
|
||||
struct Device *sana2dev;
|
||||
UBYTE devvalid;
|
||||
struct progopts opts;
|
||||
BYTE *auto_devname; /* device name, if auto-detected */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void end_prog( struct prgdata *prg )
|
||||
{
|
||||
if( prg->auto_devname )
|
||||
FreeVec( prg->auto_devname );
|
||||
|
||||
if( prg->sana2devio )
|
||||
{
|
||||
if( prg->devvalid )
|
||||
@@ -84,6 +101,16 @@ void end_prog( struct prgdata *prg )
|
||||
}
|
||||
if( prg->sana2devport )
|
||||
DeleteMsgPort( prg->sana2devport );
|
||||
|
||||
#ifdef __GNUC__
|
||||
if( (UtilityBase) && (Utility_MY) )
|
||||
{
|
||||
CloseLibrary( (struct Library*)UtilityBase );
|
||||
Utility_MY = 0;
|
||||
UtilityBase = NULL;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -105,6 +132,13 @@ LONG start_prog( struct prgdata *prg )
|
||||
if( !prg->sana2devio )
|
||||
goto err;
|
||||
|
||||
#ifdef __GNUC__
|
||||
if( !UtilityBase )
|
||||
{
|
||||
UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library",37);
|
||||
Utility_MY = 1;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
return 1;
|
||||
err:
|
||||
end_prog( prg );
|
||||
@@ -189,36 +223,37 @@ const struct {
|
||||
BYTE *name;
|
||||
UWORD namelen;
|
||||
UWORD value;
|
||||
} media[] = {
|
||||
/* The order through 100baseT4 matches bits in the BMSR */
|
||||
} mediatypes[] = {
|
||||
/* these are kept in this order for the dump loop decision about best mode */
|
||||
{ "10baseT-HD", 10,MII_AN_10BASET_HD },
|
||||
{ "10baseT-FD", 10,MII_AN_10BASET_FD },
|
||||
{ "100baseTx-HD", 12,MII_AN_100BASETX_HD },
|
||||
{ "100baseTx-FD", 12,MII_AN_100BASETX_FD },
|
||||
{ "100baseT4", 9,MII_AN_100BASET4 },
|
||||
/* generic mode names where only the speed matters */
|
||||
{ "100baseTx", 9,MII_AN_100BASETX_FD | MII_AN_100BASETX_HD },
|
||||
{ "10baseT", 7,MII_AN_10BASET_FD | MII_AN_10BASET_HD },
|
||||
{ "100bTx", 6,MII_AN_100BASETX_FD | MII_AN_100BASETX_HD },
|
||||
{ "10bT", 4,MII_AN_10BASET_FD | MII_AN_10BASET_HD },
|
||||
};
|
||||
#define NMEDIA (sizeof(media)/sizeof(media[0]))
|
||||
#define NMEDIA (sizeof(mediatypes)/sizeof(mediatypes[0]))
|
||||
|
||||
void dump_mii_media( USHORT par, BOOL bestonly )
|
||||
|
||||
void dump_mii_media( USHORT parms, BOOL bestonly )
|
||||
{
|
||||
LONG i;
|
||||
|
||||
par >>= 5; /* get upper bits */
|
||||
for( i=4 ; i >= 0 ; i-- )
|
||||
for( i=9 ; i >= 5 ; i-- )
|
||||
{
|
||||
if( par & (1<<i) )
|
||||
if( parms & (1<<i) )
|
||||
{
|
||||
Printf(" ");
|
||||
Printf("%s",(ULONG)media[i].name);
|
||||
Printf(" %s",(ULONG)mediatypes[i-5].name);
|
||||
if( bestonly )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( par & (1<<5) )
|
||||
|
||||
if( parms & (1<<10) )
|
||||
Printf(" flow-control");
|
||||
}
|
||||
|
||||
@@ -234,13 +269,13 @@ LONG parse_speedduplex( BYTE *parameters )
|
||||
while( *s != 0 )
|
||||
{
|
||||
for( i=0 ; i < NMEDIA ; i++ )
|
||||
if( Strnicmp( media[i].name, s, media[i].namelen ) == 0 )
|
||||
if( Strnicmp( mediatypes[i].name, s, mediatypes[i].namelen ) == 0 )
|
||||
break;
|
||||
if( i==NMEDIA )
|
||||
goto err;
|
||||
|
||||
s += media[i].namelen;
|
||||
res |= media[i].value;
|
||||
s += mediatypes[i].namelen;
|
||||
res |= mediatypes[i].value;
|
||||
|
||||
/* skip " " and/or "," */
|
||||
while( *s != 0 )
|
||||
@@ -254,26 +289,26 @@ LONG parse_speedduplex( BYTE *parameters )
|
||||
|
||||
return res;
|
||||
err:
|
||||
Printf("Invalid media specification %s\n",parameters);
|
||||
Printf("Invalid media specification %s\n",(ULONG)parameters);
|
||||
Printf("Valid Arguments:\n");
|
||||
for( i=0 ; i < NMEDIA ; i++ )
|
||||
Printf("%s\n",media[i].name);
|
||||
Printf("%s\n",(ULONG)mediatypes[i].name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
note: this code assumes that "mii" has the register contents in natural
|
||||
note: this code assumes that "mii" has the register contents in network
|
||||
byte ordering. Also, the registers themselves shall be consecutive
|
||||
in memory.
|
||||
*/
|
||||
int dump_mii( struct S2DevQueryMIIParam *mii, LONG length, LONG verbose )
|
||||
{
|
||||
USHORT bmcr,bmsr,advert,curlink;
|
||||
USHORT bmcr,bmsr,selfad,curlink;
|
||||
LONG i;
|
||||
|
||||
bmcr = mii[MII_BMCR].Content;
|
||||
bmsr = mii[MII_BMSR].Content;
|
||||
advert = mii[MII_ANAR].Content;
|
||||
selfad = mii[MII_ANAR].Content;
|
||||
curlink = mii[MII_ANLPAR].Content;
|
||||
|
||||
if( bmcr == 0xffff )
|
||||
@@ -286,12 +321,12 @@ int dump_mii( struct S2DevQueryMIIParam *mii, LONG length, LONG verbose )
|
||||
{
|
||||
if( bmsr & MII_BMSR_AN_COMPLETE)
|
||||
{
|
||||
if( advert & curlink )
|
||||
if( selfad & curlink )
|
||||
{
|
||||
if( curlink & MII_AN_ACK )
|
||||
/* if( curlink & MII_AN_ACK ) */
|
||||
Printf("negotiated ");
|
||||
else Printf("no autonegotiation,");
|
||||
dump_mii_media( advert & curlink, 1 );
|
||||
/* else Printf("no autonegotiation,"); */
|
||||
dump_mii_media( selfad & curlink, 1 );
|
||||
Printf(", ");
|
||||
}
|
||||
else
|
||||
@@ -308,8 +343,8 @@ int dump_mii( struct S2DevQueryMIIParam *mii, LONG length, LONG verbose )
|
||||
else
|
||||
{
|
||||
Printf("%s Mbit, %s duplex, ",
|
||||
(bmcr & MII_BMCR_100MBIT) ? "100" : "10",
|
||||
(bmcr & MII_BMCR_DUPLEX) ? "full" : "half" );
|
||||
(bmcr & MII_BMCR_100MBIT) ? (ULONG)"100" : (ULONG)"10",
|
||||
(bmcr & MII_BMCR_DUPLEX) ? (ULONG)"full" : (ULONG)"half" );
|
||||
}
|
||||
if( bmsr & MII_BMSR_LINK_VALID )
|
||||
Printf("link ok");
|
||||
@@ -353,8 +388,8 @@ int dump_mii( struct S2DevQueryMIIParam *mii, LONG length, LONG verbose )
|
||||
Printf("autonegotiation enabled\n");
|
||||
else
|
||||
Printf("%s Mbit, %s duplex\n",
|
||||
(bmcr & MII_BMCR_100MBIT) ? "100" : "10",
|
||||
(bmcr & MII_BMCR_DUPLEX) ? "full" : "half");
|
||||
(bmcr & MII_BMCR_100MBIT) ? (ULONG)"100" : (ULONG)"10",
|
||||
(bmcr & MII_BMCR_DUPLEX) ? (ULONG)"full" : (ULONG)"half");
|
||||
Printf(" basic status: ");
|
||||
if( bmsr & MII_BMSR_AN_COMPLETE )
|
||||
Printf("autonegotiation complete, ");
|
||||
@@ -366,7 +401,7 @@ int dump_mii( struct S2DevQueryMIIParam *mii, LONG length, LONG verbose )
|
||||
Printf("\n capabilities:");
|
||||
dump_mii_media( bmsr >> 6, 0 );
|
||||
Printf("\n advertising: ");
|
||||
dump_mii_media( advert, 0 );
|
||||
dump_mii_media( selfad, 0 );
|
||||
if( curlink & MII_AN_ABILITY_MASK )
|
||||
{
|
||||
Printf("\n link partner:");
|
||||
@@ -438,6 +473,111 @@ LONG write_mii( struct prgdata *prg, struct S2DevQueryMIIParam *mii, LONG num )
|
||||
return parm_mii.Actual;
|
||||
}
|
||||
|
||||
#ifdef RSHOW
|
||||
/* return string length without closing 0 */
|
||||
LONG myStrLen( BYTE *str )
|
||||
{
|
||||
LONG ret = 0;
|
||||
|
||||
if( str )
|
||||
{
|
||||
while( *str++ )
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* copy string, append 0 */
|
||||
void myStrNCpy( BYTE *dst, BYTE*src, LONG bytes )
|
||||
{
|
||||
if( !dst )
|
||||
return;
|
||||
|
||||
if( src )
|
||||
{
|
||||
while( (bytes--) && (*src != 0) )
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* find active interface and its device in RoadShow (optional) */
|
||||
/* "which" index of Ethernet adapter 0,1,2,... */
|
||||
/* "unit" is the output unit */
|
||||
BYTE *find_active_interface(LONG which, LONG *unit )
|
||||
{
|
||||
struct Library *SocketBase;
|
||||
BYTE *ret = NULL;
|
||||
struct List * interface_list = NULL;
|
||||
struct Node *n;
|
||||
BYTE *dev = NULL;
|
||||
LONG hw = -1;
|
||||
|
||||
SocketBase = OpenLibrary("bsdsocket.library",4);
|
||||
if( !SocketBase )
|
||||
{
|
||||
Printf("Cannot open bsdsocket.library version 4 for device auto-detection\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
LONG have_iface = 0;
|
||||
|
||||
if( !(SocketBaseTags(SBTM_GETREF(SBTC_HAVE_INTERFACE_API), &have_iface, TAG_DONE) == 0)
|
||||
||(!have_iface) )
|
||||
{
|
||||
Printf("RoadShow-style interface API not available in IP stack\n");
|
||||
break;
|
||||
}
|
||||
|
||||
interface_list = ObtainInterfaceList();
|
||||
if( !interface_list )
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
for( n=interface_list->lh_Head ; n->ln_Succ != NULL ; n=n->ln_Succ )
|
||||
{
|
||||
/* Printf("Interface %s\n",n->ln_Name); */
|
||||
/* find Ethernet interface */
|
||||
if(!QueryInterfaceTags( n->ln_Name, IFQ_HardwareType, &hw,
|
||||
IFQ_DeviceName, &dev,
|
||||
IFQ_DeviceUnit, unit ) )
|
||||
continue;
|
||||
|
||||
/* Printf("device %s hwtype %ld\n",dev,hw); */
|
||||
|
||||
if( hw == S2WireType_Ethernet )
|
||||
break;
|
||||
}
|
||||
|
||||
if( hw == S2WireType_Ethernet )
|
||||
{
|
||||
if( dev )
|
||||
{
|
||||
ret = AllocVec( myStrLen( dev ), 0 );
|
||||
if( ret )
|
||||
myStrNCpy( ret, dev, myStrLen(dev) );
|
||||
}
|
||||
}
|
||||
}
|
||||
while(0);
|
||||
|
||||
if( interface_list )
|
||||
ReleaseInterfaceList(interface_list);
|
||||
|
||||
CloseLibrary(SocketBase);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* 8 basic registers, we poll 16 out of curiosity */
|
||||
#define MII_REGNUM 16
|
||||
/* two spare registers for write mode */
|
||||
@@ -468,17 +608,34 @@ int main(int argc, char **argv)
|
||||
return res;
|
||||
}
|
||||
|
||||
unit = (prg->opts.unit) ? *prg->opts.unit : 0;
|
||||
|
||||
if( !prg->opts.devname )
|
||||
{
|
||||
#ifdef RSHOW
|
||||
LONG _unit;
|
||||
prg->auto_devname = find_active_interface( 0, &_unit );
|
||||
if( prg->auto_devname )
|
||||
{
|
||||
unit = _unit;
|
||||
name = prg->auto_devname;
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("cannot auto-determine device, please use DEVICE=... as argument\n");
|
||||
end_prog(prg);
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
name = "enc624j6net.device";
|
||||
Printf("TODO: auto-detect, now trying default %s\n",name);
|
||||
Printf("device auto-detect not compiled in, now trying default %s\n",name);
|
||||
#endif
|
||||
/* end_prog(prg);
|
||||
return res; */
|
||||
}
|
||||
else
|
||||
name = prg->opts.devname;
|
||||
|
||||
unit = (prg->opts.unit) ? *prg->opts.unit : 0;
|
||||
if( prg->opts.vverbose )
|
||||
prg->opts.verbose = 2;
|
||||
else
|
||||
@@ -524,7 +681,7 @@ int main(int argc, char **argv)
|
||||
parm_productname.Data = productname;
|
||||
parm_productname.Length = sizeof(productname);
|
||||
parm_productname.Actual = 0;
|
||||
#if 1
|
||||
|
||||
tags[i=0].ti_Tag = S2_DevQueryExtVendorName;
|
||||
tags[i++].ti_Data = (ULONG) &parm_vendorname;
|
||||
tags[i ].ti_Tag = S2_DevQueryExtProductName;
|
||||
@@ -542,55 +699,28 @@ int main(int argc, char **argv)
|
||||
parm_mii.Actual = query_mii( prg, mii, 0, 15 );
|
||||
if( parm_mii.Actual )
|
||||
{
|
||||
/* read BMSR twice */
|
||||
/* read BMSR a second time */
|
||||
query_mii( prg, mii+MII_BMSR, MII_BMSR, MII_BMSR );
|
||||
res = RETURN_OK;
|
||||
}
|
||||
else
|
||||
res = RETURN_WARN;
|
||||
#else
|
||||
/* MII specific */
|
||||
parm_mii.Data = (APTR)mii;
|
||||
parm_mii.Length = sizeof(mii);
|
||||
parm_mii.Actual = 0;
|
||||
|
||||
for( i=0 ; i < 16 ; i++ ) /* MII standard register set: 8 */
|
||||
{
|
||||
mii[i].ID = i; /* mii[i].Content = 0; */
|
||||
}
|
||||
mii[16].ID = MII_BMSR; /* read BMSR twice */
|
||||
|
||||
tags[i=0].ti_Tag = S2_DevQueryExtVendorName;
|
||||
tags[i++].ti_Data = (ULONG) &parm_vendorname;
|
||||
tags[i ].ti_Tag = S2_DevQueryExtProductName;
|
||||
tags[i++].ti_Data = (ULONG) &parm_productname;
|
||||
tags[i ].ti_Tag = S2_DevQueryExtGetMII;
|
||||
tags[i++].ti_Data = (ULONG) &parm_mii;
|
||||
tags[i ].ti_Tag = TAG_DONE;
|
||||
|
||||
prg->sana2devio->ios2_Req.io_Command = S2_DEVICEQUERYEXT;
|
||||
prg->sana2devio->ios2_Data = tags;
|
||||
prg->sana2devio->ios2_DataLength = sizeof tags;
|
||||
|
||||
if( DoIO((struct IORequest *) prg->sana2devio ) != 0 )
|
||||
Printf("Sana2DeviceQueryExtension for MII access not present\n");
|
||||
res = RETURN_WARN;
|
||||
else res = RETURN_OK;
|
||||
|
||||
mii[MII_BMSR].Content = mii[16].Content; /* read BMSR twice */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Printf("Device: %s\n",name);
|
||||
Printf("Device: %s\n",(ULONG)name);
|
||||
/* general info */
|
||||
if( parm_vendorname.Actual != 0 )
|
||||
{
|
||||
vendorname[parm_vendorname.Actual-1] = 0;
|
||||
Printf("Vendor: %s\n",vendorname);
|
||||
Printf("Vendor: %s\n",(ULONG)vendorname);
|
||||
}
|
||||
if( parm_productname.Actual != 0 )
|
||||
{
|
||||
productname[parm_productname.Actual-1] = 0;
|
||||
Printf("Product: %s\n",productname);
|
||||
Printf("Product: %s\n",(ULONG)productname);
|
||||
}
|
||||
|
||||
/* after query, see what we've got */
|
||||
@@ -603,6 +733,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* command or query ? */
|
||||
if( !(prg->opts.renegotiate) && !(prg->opts.reset)
|
||||
&& !(prg->opts.advertise) && !(prg->opts.force)
|
||||
)
|
||||
@@ -659,3 +790,4 @@ int main(int argc, char **argv)
|
||||
end_prog(prg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,51 @@ struct S2DevQueryExtParam
|
||||
/* Current physical link speed, see definitions below: */
|
||||
#define S2_DevQueryExtLinkSpeed (S2_DevQueryExtTagBase + 4)
|
||||
|
||||
/* proposal added by Henryk Richter: access to MII */
|
||||
/* MII is the standardized ethernet interface to the
|
||||
PHY registers. It allows to read and modify autonegotiation
|
||||
settings and status, as well as manual reconfiguration of
|
||||
link parameters. In order to ease the burden on the
|
||||
SANA-II driver, this interface is transparent in the sense
|
||||
that no processing of MII registers is necessary.
|
||||
|
||||
Please note that MII read/write is slow. Use with discretion.
|
||||
|
||||
The format of the Data APTR is per entry as follows:
|
||||
UWORD ID
|
||||
UWORD Content
|
||||
|
||||
S2_DevQueryExtGetMII
|
||||
Please pass a writable Data array of Length=2*NumIDs to the call and
|
||||
initialize the IDs you are interested in. The driver will initialize
|
||||
the Content of the IDs it knows about. Should a requested ID be
|
||||
unsupported by the driver or underlying chipset, the driver will
|
||||
overwrite the respective IDs with S2_DEVQUERYEXT_MII_INVALID and
|
||||
clear the associated Content field.
|
||||
In case of fatal error, the "Actual" field of S2DevQueryExtParam
|
||||
will be 0. Otherwise, the last successfully updated location + 2
|
||||
will be returned.
|
||||
|
||||
S2_DevQueryExtSetMII
|
||||
Please pass a Data array of Length=2*NumIDs to the call and initialize
|
||||
the IDs to write along with their content. The driver will write the
|
||||
MII registers corresponding with the IDs in the given order.
|
||||
In case of fatal error, the "Actual" field of S2DevQueryExtParam
|
||||
will be 0. Otherwise, the last successfully updated location + 2
|
||||
will be returned.
|
||||
|
||||
*/
|
||||
#define S2_DevQueryExtGetMII (S2_DevQueryExtTagBase + 0x20)
|
||||
#define S2_DevQueryExtSetMII (S2_DevQueryExtTagBase + 0x21)
|
||||
|
||||
struct S2DevQueryMIIParam
|
||||
{
|
||||
UWORD ID;
|
||||
UWORD Content;
|
||||
};
|
||||
#define S2_DEVQUERYEXT_MII_INVALID 0xfe
|
||||
|
||||
|
||||
#define S2_DEVQUERYEXT_LINK_UNDEFINED 0xffffffff
|
||||
#define S2_DEVQUERYEXT_LINK_DOWN 0
|
||||
#define S2_DEVQUERYEXT_LINK_UP 1
|
||||
|
||||
@@ -37,7 +37,7 @@ 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 2
|
||||
#define ONE_WRITE_REQ 1
|
||||
/* this limits the number of processed read requests per run when enabled */
|
||||
#define ONE_READ_REQ 2
|
||||
|
||||
@@ -1071,6 +1071,7 @@ VOID SAVEDS ServerTask(void)
|
||||
{
|
||||
if( !action ) /* queues quiet ? -> sleep */
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -127,7 +127,7 @@ CFLAGS = $(CFLAGS) INCLUDEDIR="" INCLUDEDIR=$(SUBDIR) $(DEFINES)
|
||||
# ASM based alternative to deviceheader.o would be romtag.o
|
||||
|
||||
OBJECTS = deviceheader.o$(TYPE) deviceinit.o$(TYPE) device.o$(TYPE) \
|
||||
server.o$(TYPE) $(SUBDIR)/hw.o$(TYPE)
|
||||
server.o$(TYPE) $(SUBDIR)/hw.o$(TYPE) kprintf.o$(TYPE)
|
||||
|
||||
OBJECTS = $(OBJECTS) $(ASMOBJECTS)
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#define _INC_VERSION_H
|
||||
|
||||
#define DEVICEVERSION 2
|
||||
#define DEVICEREVISION 1
|
||||
#define DEVICEREVISION 2
|
||||
#define DEVICEEXTRA
|
||||
/* #define DEVICEEXTRA Beta */
|
||||
#define DEVICEDATE 21.02.2019
|
||||
#define DEVICEDATE 10.03.2019
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user