CP and LAN working! Clockport needed to be stopped if FCS='1'

This commit is contained in:
MHeinrichs
2019-03-07 23:53:52 +01:00
parent 943507175a
commit 7936ad431b
161 changed files with 45433 additions and 43327 deletions
+94
View File
@@ -0,0 +1,94 @@
MIITool
-------
This utility allows to observe and change the physical parameters
of Ethernet NICs on AmigaOS. The parameters include autonegotiation
settings and forced speed/duplex combinations. While it is expected
that autonegotiation "just works" with modern equipment, there still
are people with some interest in retro-computing who might or might
not experience link-related problems or are just curious about some
inner workings of everyday hardware.
A modern switch ("link partner") should advertise it`s capabilities
properly such that the Ethernet hardware can select the optimal mode
out of the supported set. If that is not the case, you can narrow down
the list of advertised modes such that the link partners come to a
working agreement. The last resort is to set a fixed speed/duplex
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.
Examples for usage are given at the end of this text.
Prerequisites:
- AmigaOS 2.04 on 68k
- active Ethernet SANA-II driver, i.e. after starting the IP-Stack
Invocation:
- MIITool is supposed to be run from CLI/Shell.
Arguments template:
DEVICE/K,UNIT/K/N,V/S,FORCEMEDIA/K,ADVERTISE/K,RENEG/S,RESET/S,VV/S
Detailed description of arguments:
keyword - description
------------------------
DEVICE/K - device name corresponding to active ethernet interface
DEV/K example: DEVICE=enc624j6net.device
UNIT/K/N - unit number of device to be opened (default: 0)
example: UNIT=0
FORCEMEDIA - speed/duplex combination to set unconditionally,
see below for a list of valid speed or duplex modes
ADVERTISE - speed/duplex combinations to announce by autonegotiation,
implicitly restart autonegotiation,
see below for a list of valid speed or duplex modes
RENEG - restart autonegotiation, please allow a couple of seconds
RESTART until the negotiation is finished
RESET - reset PHY to power-on state
VERBOSE - more detailed outputs
V
VERYVERBOSE- even more detailed outputs
VV
Valid Speed/Duplex combinations (not case sensitive):
10baseT-HD - 10 Mbit/s half duplex
10baseT-FD - 10 Mbit/s full duplex
100baseTx-HD - 100 Mbit/s half duplex over two wire pairs
100baseTx-FD - 100 Mbit/s full duplex over two wire pairs (common)
100baseT4 - 100 Mbit/s full duplex over 4 wire pairs (rare)
10baseT - 10 Mbit/s half or full duplex
10bT - 10 Mbit/s half or full duplex
100baseTx - 100 Mbit/s half or full duplex
100bTx - 100 Mbit/s half or full duplex
Examples:
current status (detailed):
miitool DEV=enc624j6net.device v
negotiate 10 Mbit/s only
miitool DEV=enc624j6net.device ADVERTISE=10bT
negotiate 100baseTx and 10baseT half duplex only:
miitool DEV=enc624j6net.device ADVERTISE=100bTx,10baseT-HD
force 100 Mbit/s full duplex
miitool DEV=enc624j6net.device FORCEMEDIA=100baseTx-FD
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -23,7 +23,7 @@
#DEVICEREVISION=95
#DEVICEDATE=08.09.2018
SUBDIR=enc624j6net
ASMOBJECTS = $(SUBDIR)/enc624j6l.o $(SUBDIR)/intervaltimer.o
ASMOBJECTS = $(SUBDIR)/enc624j6l.o $(SUBDIR)/intervaltimer.o kprintf.o
###############################################################################
# Devices to build (1 or 2, keep DEVICEID2 empty if only one build is desired)
@@ -31,7 +31,7 @@ ASMOBJECTS = $(SUBDIR)/enc624j6l.o $(SUBDIR)/intervaltimer.o
###############################################################################
DEVICEID=enc624j6net.device
DEFINES = # -DPROTO_V2EXPNET
DEFINES = -DHW_DMA_TX # -DPROTO_V2EXPNET
ASMDEFS = # -DPROTO_V2EXPNET
CPU = 68020
+188
View File
@@ -0,0 +1,188 @@
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
; ifd DEBUG
; XDEF _AbsExecBase
; XDEF _LVORawDoFmt
; XDEF _LVORawPutChar
; XDEF _LVORawMayGetChar
; XDEF _AbsExecBase
; endif
ifnd _LVORawDoFmt
_LVORawDoFmt equ -$20a
endc
ifnd _LVORawPutChar
_LVORawPutChar equ -$204
_LVORawIOInit equ -$1f8
_LVORawMayGetChar equ -$1fe
endc
;
;
;
ifd DEBUG
XREF _KPrintF
WRITEDEBUG macro
movem.l d0/d1/a0/a1,-(sp)
ifnb \9
move.l \9,-(sp)
endif
ifnb \8
move.l \8,-(sp)
endif
ifnb \7
move.l \7,-(sp)
endif
ifnb \6
move.l \6,-(sp)
endif
ifnb \5
move.l \5,-(sp)
endif
ifnb \4
move.l \4,-(sp)
endif
ifnb \3
move.l \3,-(sp)
endif
ifnb \2
move.l \2,-(sp)
endif
lea.l (\1),a0
move.l sp,a1
jsr _KPrintF
ifnb \2
add.l #4,sp
endif
ifnb \3
add.l #4,sp
endif
ifnb \4
add.l #4,sp
endif
ifnb \5
add.l #4,sp
endif
ifnb \6
add.l #4,sp
endif
ifnb \7
add.l #4,sp
endif
ifnb \8
add.l #4,sp
endif
ifnb \9
add.l #4,sp
endif
movem.l (sp)+,d0/d1/a0/a1
endm
else
WRITEDEBUG macro
nop
endm
endc
;
;
;
WRITEOUT macro
movem.l d0/d1/d2/a0/a1/a6,-(sp)
ifnb \9
move.l \9,-(sp)
endif
ifnb \8
move.l \8,-(sp)
endif
ifnb \7
move.l \7,-(sp)
endif
ifnb \6
move.l \6,-(sp)
endif
ifnb \5
move.l \5,-(sp)
endif
ifnb \4
move.l \4,-(sp)
endif
ifnb \3
move.l \3,-(sp)
endif
ifnb \2
move.l \2,-(sp)
endif
ifd DEBUG
move.l \1,a0
move.l sp,a1
jsr _KPrintF
endif
move.l \1,d1
move.l sp,d2
movea.l DOSBase,a6
jsr _LVOVPrintf(a6)
ifnb \2
add.l #4,sp
endif
ifnb \3
add.l #4,sp
endif
ifnb \4
add.l #4,sp
endif
ifnb \5
add.l #4,sp
endif
ifnb \6
add.l #4,sp
endif
ifnb \7
add.l #4,sp
endif
ifnb \8
add.l #4,sp
endif
ifnb \9
add.l #4,sp
endif
movem.l (sp)+,d0/d1/d2/a0/a1/a6
endm
;COUNTERS only when DEBUG is on
ifd DEBUG
ifne DEBUG
DEBUG_COUNTERS EQU 1
endc
endc
ifd DEBUG_COUNTERS
COUNTER_INC macro
addq.l #1,\1
endm
else
COUNTER_INC macro
nop
endm
endc
; write usage of all emulated instructions if DEBUG is 1 to RAWIO (sushi/sashimi/serial)
ifd DEBUG
ifne DEBUG
HAVE_DEBUGINSTR EQU 1
DEBUGINSTR macro
ifnb \3
WRITEDEBUG \1,\2,\3
else
WRITEDEBUG \1,\2
endc
endm
endc
endc
ifnd HAVE_DEBUGINSTR
DEBUGINSTR macro
endm
endc
+14 -1
View File
@@ -18,6 +18,8 @@
in server.c as a separate process. Interrupts are forwarded
as signals to server.c as well (depending on target hardware).
S2_CONFIGINTERFACE worked more than once, it *must* only work once.
*/
#define DEVICE_MAIN
@@ -200,6 +202,12 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
dbm->dbm_PacketFilter = (APTR)( GetTagData(S2_PacketFilter,0,
(struct TagItem *)ioreq->ios2_BufferManagement));
dbm->dbm_CopyFromBufferDMA = (BMCALL)((void (*)())(GetTagData(S2_DMACopyFromBuff32, 0,
(struct TagItem *)ioreq->ios2_BufferManagement)));
dbm->dbm_CopyToBufferDMA = (BMCALL)((void (*)())(GetTagData(S2_DMACopyToBuff32, 0,
(struct TagItem *)ioreq->ios2_BufferManagement)));
/* v1.95: disabled CopyToBuffer32 due to problems with MiamiDX */
/* v1.99: try identifying Miami */
/* MiamiDX requires byte count to be a multiple of 4 */
@@ -215,7 +223,7 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
dbm->dbm_CopyFromBuffer32 = (BMCALL)((void (*)())(GetTagData(S2_CopyFromBuff32, 0,
(struct TagItem *)ioreq->ios2_BufferManagement)));
}
D(("BufferMgmt CBuf32 %lx PF %lx CBuf %lx\n",(ULONG)dbm->dbm_CopyFromBuffer32,(ULONG)dbm->dbm_PacketFilter,(ULONG)dbm->dbm_CopyFromBuffer));
if( !dbm->dbm_CopyToBuffer32 )
@@ -265,6 +273,8 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
}
ioreq->ios2_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
D(("DevOpen return code %ld\n",ret));
return ret;
}
@@ -588,6 +598,8 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
{
struct IOStdReq *stdrq = (struct IOStdReq *)ioreq;
D(("NSCMD_DEVICEQUERY size %ld\n",(ULONG)stdrq->io_Length));
if( (!stdrq->io_Data) || (stdrq->io_Length < sizeof( NSDQueryAnswer ) ) )
{
ioreq->ios2_Req.io_Error = IOERR_BADLENGTH;
@@ -598,6 +610,7 @@ ASM SAVEDS VOID DevBeginIO( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
stdrq->io_Actual = sizeof( NSDQueryAnswer );
ioreq->ios2_Req.io_Error = 0;
}
D(("NSCMD_DEVICEQUERY return %ld\n",(ULONG)ioreq->ios2_Req.io_Error));
}
break;
/* query contents may ask for live data: handle in server.c */
+3 -1
View File
@@ -123,7 +123,7 @@ struct devbase {
};
typedef BOOL (* ASM BMCALL)( ASMR(a0) void * ASMREG(a0), ASMR(a1) void * ASMREG(a1), ASMR(d0) LONG ASMREG(d0) );
typedef LONG (* ASM BMCALL)( ASMR(a0) void * ASMREG(a0), ASMR(a1) void * ASMREG(a1), ASMR(d0) LONG ASMREG(d0) );
struct db_BufferManagement {
struct MinNode dbm_n;
@@ -131,6 +131,8 @@ struct db_BufferManagement {
BMCALL dbm_CopyToBuffer32;
BMCALL dbm_CopyFromBuffer;
BMCALL dbm_CopyToBuffer;
BMCALL dbm_CopyFromBufferDMA; /* this buffering method requires additional support from lowlevel HW implementation */
BMCALL dbm_CopyToBufferDMA; /* usage of this pointer requires additional checks */
APTR dbm_PacketFilter; /* this is actually a Hook */
ULONG dbm_ID;
};
Binary file not shown.
Binary file not shown.
+188 -40
View File
@@ -1,3 +1,4 @@
;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
; ------------------------------------------------------------------------------
; | Lowlevel Access to memory mapped ENC624J600 in PSP mode |
; | Henryk Richter <henryk.richter@gmx.net> |
@@ -15,18 +16,23 @@
;
;
;TODO:
; - Pattern Matching, MC/MC filtering: Multicast,Broadcast,Unicast(self),MagicPacket,correct CRC,"not me" Unicast
; - Pattern Matching, MC filtering: Multicast,Broadcast,Unicast(self),MagicPacket,correct CRC,"not me" Unicast
; - _enc624j6l_RXReset -> won't recover from totally unresponsive chip (but exits gracefully)
; - RXSTART_INIT = $0c00 -> currently $2000 due to previous location bug
;
; enable debugging code block (comment/uncomment, see below)
;DEBUG EQU 1
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"
; enable debugging code block
ifnd DEBUG
DEBUG EQU 0
endc
;
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
@@ -116,6 +122,9 @@ ENC_BOARDID EQU 123 ;ZII-IDE-LAN-CP
XDEF _enc624j6l_bc_mc_filter
XDEF _enc624j6l_ReadPHY
XDEF _enc624j6l_WritePHY
;
; System includes
;
@@ -250,9 +259,9 @@ opendos:
beq .noframe ;nothing received
;debug: disable recv
move.l _boardbase(pc),a0
moveq #ECON1_RXEN,d0
CLRREG ECON1,a0,d0
;move.l _boardbase(pc),a0
;moveq #ECON1_RXEN,d0
;CLRREG ECON1,a0,d0
move.l _boardbase(pc),a0
lea readframe,a1
@@ -791,7 +800,7 @@ _enc624j6l_EnableInterrupt:
move.w d0,($4000,a0)
lea -$4000(a0),a0
move #EIE_PKTIE|EIE_INTIE,d0
move #EIE_PKTIE|EIE_PCFULIE|EIE_INTIE,d0
SETREG EIE,a0,d0
moveq #1,d0
@@ -814,7 +823,7 @@ _enc624j6l_EnableInterrupt:
; Notes: assumes that init() was called before
;
_enc624j6l_EnableGlobalInterrupt:
move #EIE_INTIE,d0
move #EIE_PKTIE|EIE_PCFULIE|EIE_INTIE,d0 ; move #EIE_INTIE,d0
SETREG EIE,a0,d0
moveq #1,d0
.rts
@@ -896,35 +905,32 @@ _enc624j6l_DisableInterrupt:
; ULONG sigbit
;
_enc624j6l_IntServer_List:
move.l a6,-(sp)
move.l a1,d0 ;no pointer supplied ? -> return
beq.s .rts
beq.s .end
movem.l d1/A1/a6,-(sp)
move.l a1,a6
moveq #0,d1
.boardloop:
move.l (a1)+,d0 ;next entry from list
beq.s .done ;
move.l d0,a0 ;current board
move.l (A6)+,d0 ;read magic word
cmp.l #HW_MAGIC_WORD,D0 ; are we in the right structure?
bne.s .done
READREG EIR,a0,d0 ;get interrupt status reg
and #EIR_PKTIF,d0
or.l d0,d1
bra.s .boardloop
.boardloop:
move.l (A6)+,d0 ;next entry from list
beq.s .done ;
move.l d0,a1 ;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
.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
move #EIE_INTIE,D0 ;disable board interrupt until someone enables it again
CLRREG EIE,A1,d0
bra.s .intdis_loop
.boardsdone:
;faster: get from extended Driver board list instead from ZII/ZIII card
ifne 1
@@ -960,7 +966,8 @@ _enc624j6l_IntServer_List:
jsr _LVOSignal(a6)
.rts
move.l (sp)+,a6
movem.l (sp)+,D1/A1/A6
.end
moveq #0,d0 ;set Z flag
rts
@@ -1062,8 +1069,45 @@ _enc624j6l_CheckLinkChange:
; Notes: - Doesn't check for Board Pointer (!)
; - doesn't re-enable RX (!)
;
ifne DEBUG
RXReset_MSG: dc.b "RXReset Head %04lx Tail %04lx NextPacket %04lx ReadPTR %04lx Bytes %04lx",10,0
endc
_enc624j6l_RXReset:
ifne DEBUG
;print current HW registers to serial
movem.l d2-d7,-(sp)
moveq #0,d0
moveq #0,d1
moveq #0,d2
moveq #0,d3
READREG ERXHEAD,A0,d0
READREG ERXTAIL,A0,d1
READREG PNextPacket,a0,d2
READSRAM a0,d2,d3 ;move (a0,d7.w),d0
ifeq _OPT_BUFFER_SWAP
rol.w #8,d3 ;swap pointer to Big Endian
endc ;d3=next Packet (from receive status vector)
moveq #2,d5
add d2,d5 ;increment pointer by one word
WRAPINDEX d5 ;wrap D4 if beyond buffer
READSRAM a0,d5,d4 ;receive byte count
ifeq _OPT_BUFFER_SWAP
rol.w #8,d4 ;swap pointer to Big Endian
endc
WRITEDEBUG RXReset_MSG,d0,d1,d2,d3,d4
movem.l (sp)+,d2-d7
endc
moveq #ECON2_RXRST,d0 ;RX Reset, clears RXEN
SETREG ECON2,a0,d0 ;
;moveq #ECON1_RXEN,d0 ;done by RX reset
@@ -1171,6 +1215,15 @@ _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
@@ -1259,10 +1312,23 @@ _enc624j6l_RecvFrame: ;
lea (a0,d7.w),a2 ;read pointer
ifeq _OPT_BUFFER_SWAP
btst #1,d7 ;do we have a read address that`s not long aligned?
beq.s .no_impair
move.w (a2)+,(a1)+ ;long-align address
subq #2,d0
ble.w .end_read ;should not happen (>14 per valid frame)
moveq #15,d1 ;
move.l d0,d2 ;total bytes
and.l d0,d1 ;remainder: max 15 bytes
lsr.w #4,d2 ;total/16
addq #2,d0
bra.s .impair
.no_impair:
move.l d0,d2 ;total bytes
moveq #15,d1 ;
lsr.w #4,d2 ;total/16
and.l d0,d1 ;remainder: max 15 bytes
.impair:
addq #3,d1 ;remainder, rounded up to +3 bytes
subq #1,d2 ;dbf
blt.s .nopt16_read ;less than 16 bytes -> bail out
@@ -1424,7 +1490,7 @@ _enc624j6l_RecvFrame: ;
; notes:
;
_enc624j6l_TransmitFrame:
movem.l d2-d5/a2,-(sp)
movem.l d2-d5/a3,-(sp)
;---------------- parameter check -------------------------------------
@@ -1455,33 +1521,60 @@ _enc624j6l_TransmitFrame:
eor.w #PSwapTX,d2 ;swap buffer
WRITEREG PNextTX,a0,d2 ;remember pointer (d2 also for ETXST later)
lea (a0,d2.w),a2 ;write pointer for frame
lea (a0,d2.w),a3 ;write pointer for frame
ifeq _OPT_BUFFER_SWAP
ifd HW_DMA_TX
move.l a2,d3
beq.s .no_separate_header
ifne 1
move.l -2(a2),(a3)+ ;garbage (2), DstMAC,SrcMAC,Type/Len = 16 Bytes
move.l 2(a2),(a3)+
move.l 6(a2),(a3)+
move.l 10(a2),(a3)+
moveq #14,d3
addq #2,d2 ;start pointer behind garbage (2)
else
move.l (a2),(a3)+ ;copy DstMAC,SrcMAC,Type/Len = 14 Bytes
move.l 4(a2),(a3)+
move.l 8(a2),(a3)+
move.w 12(a2),(a3)+
moveq #14,d3
endc
.no_separate_header
endc
;faster TX when buffer swapping is not necessary
move.l d0,d4 ;remember length
moveq #63,d5 ;
and.l d5,d0 ;remainder of 64 byte copy loop
move.l d4,d5 ;length in bytes
ifd HW_DMA_TX
add.l d3,d4 ;length+header (either 0 or 14)
endc
asr.w #6,d5 ;64 byte blocks
subq.w #1,d5 ;dbf
blt.s .smallcopy
bra.s .largecopy_start
.largecopy:
move.l d1,(a2)+
move.l d1,(a3)+
.largecopy_start:
rept 15
move.l (a1)+,(a2)+ ;save to SRAM
move.l (a1)+,(a3)+ ;save to SRAM
endr
move.l (a1)+,d1
dbf d5,.largecopy
move.l d1,(a2)+
move.l d1,(a3)+
else ;_OPT_BUFFER_SWAP
ifd HW_DMA_TX
error "HW_DMA_TX not supported for _OPT_BUFFER_SWAP configuration, disable!"
endc
move.w d0,d4 ;still need length later
endc ;_OPT_BUFFER_SWAP
@@ -1507,11 +1600,11 @@ _enc624j6l_TransmitFrame:
rol.w d4,d3
swap d1
swap d3
move.l d1,(a2)+ ;save to SRAM
move.l d3,(a2)+ ;save to SRAM
move.l d1,(a3)+ ;save to SRAM
move.l d3,(a3)+ ;save to SRAM
else ;_OPT_BUFFER_SWAP
move.l (a1)+,(a2)+ ;save to SRAM
move.l (a1)+,(a2)+ ;save to SRAM
move.l (a1)+,(a3)+ ;save to SRAM
move.l (a1)+,(a3)+ ;save to SRAM
endc ;_OPT_BUFFER_SWAP
dbf d0,.txcopy
@@ -1546,7 +1639,7 @@ _enc624j6l_TransmitFrame:
SETREG ECON1,a0,d1 ;
.err:
movem.l (sp)+,d2-d5/a2
movem.l (sp)+,d2-d5/a3
rts
ifne _OPT_CHECKLINK_TX
@@ -1559,6 +1652,7 @@ _enc624j6l_TransmitFrame:
endc
;---------------------------------------------------------------------------------------
;
; read PHY register (16 Bit)
@@ -1613,6 +1707,60 @@ _enc624j6l_ReadPHY:
.err:
moveq #-1,d0
rts
;---------------------------------------------------------------------------------------
;
; write PHY register (16 Bit)
;
; input: A0 - APTR mmapped board base address
; D0 - LONG Phy register (5 valid bits)
; D1 - SHORT value written into PHY reg
;
; output: LONG D0 <0 - error (bad register index)
; - 16 Bit PHY reg contents
;
; trash: -
;
; notes:
;
;
_enc624j6l_WritePHY:
cmp.w #31,d0
bhi.w .err
bset #8,d0 ;$100 + PHY_REG
WRITEREG MIREGADR,a0,d0 ;set PHY register address
WRITEREG MIWR,a0,d1 ;set desired content
moveq #25,d0 ;25 us delay (at least)
bsr _enc624j6l_UMinDelay ;
moveq #100,d1
.waitloop:
READREG MISTAT,a0,d0
btst #0,d0
beq.s .notbusy
tst.b $BFE301 ;1 CIA access = 1.4 us
subq.w #1,d1 ;>165 us exceeded ? -> something is wrong, SPEC says 25.6 us
blt.s .notbusy ;error
bra.s .waitloop
.notbusy
; moveq #0,d0
; WRITEREG MICMD,a0,d0 ;cancel write command
moveq #0,d0
.ret:
rts
.err:
moveq #-1,d0
bra.s .ret
;------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------
;
+24 -3
View File
@@ -196,17 +196,23 @@ ASM SAVEDS int enc624j6l_RecvFrame( ASMR(a0) void *board ASMREG(a0),
input: board - mmapped board base address
buffer - output buffer (should have >=1514 bytes)
sendsize - size of buffer in bytes ( no CRC appended (!) )
header - 14 Bytes Ethernet header
(total frame transmit size = sendsize+14)
output: <0 - error
0 - nothing in receive buffer
>0 - size of received frame
notes:
"header" argument valid only when "HW_DMA_TX" is defined (Makefile)
*/
ASM SAVEDS int enc624j6l_TransmitFrame( ASMR(a0) void *board ASMREG(a0),
ASMR(a1) unsigned char* buffer ASMREG(a1),
ASMR(d0) short sendsize ASMREG(d0) );
ASMR(d0) short sendsize ASMREG(d0)
#ifdef HW_DMA_TX
,ASMR(a2) unsigned char* header ASMREG(a2)
#endif
);
/*
@@ -330,7 +336,7 @@ ASM SAVEDS int enc624j6l_CheckLinkChange( ASMR(a0) void *board ASMREG(a0) );
Purpose: read PHY register
input: board - mmapped board base address
flags - broadcast,promiscous, multicast
phyreg - PHY register to read
output: <0 - error
>=0 - OK
@@ -340,5 +346,20 @@ ASM SAVEDS int enc624j6l_ReadPHY(
ASMR(d0) unsigned long phyreg ASMREG(d0) );
/*
Purpose: write PHY register
input: board - mmapped board base address
phyreg - PHY register to read
value - value written into PHY reg
output: <0 - error
>=0 - OK
*/
ASM SAVEDS int enc624j6l_WritePHY(
ASMR(a0) void *board ASMREG(a0),
ASMR(d0) unsigned long phyreg ASMREG(d0),
ASMR(d1) unsigned short data ASMREG(d1) );
#endif /* _INC_ENC624J6L_H */
+68 -23
View File
@@ -51,18 +51,18 @@ void myhw_ControlIntervalTimer( DEVBASEP );
/* these calls might not run within the context of a process and
will be called from varying tasks and without prior init:
hw_Find_Boards()
hw_Find_Boards() - this one just identifies available HW and returns #boards
hw_AllocBoard()
hw_ReleaseBoard()
hw_GetMacAddress()
hw_GetMacAddress() - get default MAC address from board
these calls are in the context of the server task:
hw_Setup() - general init (board allocated already)
hw_Shutdown() - general shutdown (board still allocated)
hw_Attach() - make hardware ready for action (online)
hw_Detach() - put hardware into sleep mode (offline)
hw_Setup() - general init (board allocated already)
hw_Shutdown() - general shutdown (board still allocated)
hw_Attach() - make hardware ready for action (online)
hw_Detach() - put hardware into sleep mode (offline)
hw_recv_sigmask() - get signals for hardware (if any)
hw_recv_sigmask() - get signals for hardware (if any, i.e. signal on interrupt)
hw_recv_pending() - check for pending receive frames
hw_recv_frame() - receive one frame
@@ -71,10 +71,11 @@ void myhw_ControlIntervalTimer( DEVBASEP );
and apply them (called only when no RX/TX
in progress)
hw_config_init() - set defaults for HW
hw_config_update() - update config of HW
hw_ConfigInit() - set defaults for HW
hw_ConfigUpdate() - update config of HW
hw_get_mac_status() - running parameters
hw_change_multicast - re-initialize multicast filter for new address list
hw_get_mac_status() - running parameters (optional), S2_DEVICEQUERYEXT
*/
const BYTE exp_name[] = "expansion.library";
@@ -274,13 +275,31 @@ ASM SAVEDS void hw_ConfigUpdate( ASMR(a0) DEVBASEP ASMREG(a0),
hwd->multicast = 1;
}
/*
send a single frame to the hardware:
- either fully assembled frame (14 bytes DMAC,SMAC,TYPE followed by payload
- or payload in "frame" and 14 byte header in "header"
- provide Makefile-level definition of HW_DMA_TX in the latter case
- note: if you pass "header==NULL" with active HW_DMA_TX definition,
the hw_send_frame assumes the header to be present (SANA-II RAW frames) and
is handling "frame" as fully assembled frame
*/
ASM SAVEDS LONG hw_send_frame( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) UBYTE *frame ASMREG(a1),
ASMR(d1) ULONG framesize ASMREG(d1) )
ASMR(d1) ULONG framesize ASMREG(d1)
#ifdef HW_DMA_TX
,ASMR(a2) UBYTE *header ASMREG(a2)
#endif
)
{
enc624j6l_TransmitFrame( db->db_Units[unit].duh_BASE, frame, framesize );
/* TX with separate header support ? (optional) */
enc624j6l_TransmitFrame( db->db_Units[unit].duh_BASE, frame, framesize
#ifdef HW_DMA_TX
,header
#endif
);
return 1;
}
@@ -329,14 +348,16 @@ ASM SAVEDS LONG hw_check_link_change( ASMR(a0) DEVBASEP ASMREG(
return 1; /* don't signal panic to the outside, everything is under control */
}
/* obtain running parameters of Ethernet MAC: link up/down, Speed, Duplex */
/* obtain running parameters of Ethernet MAC: link up/down, Speed, Duplex for
SANA-II DeviceQueryExtension (general parameters)
*/
ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) )
{
struct HWData *hwd = &db->db_hwdat;
APTR boardbase = db->db_Units[unit].duh_BASE;
struct HWData *hwd = &db->db_hwdat;
APTR boardbase = db->db_Units[unit].duh_BASE;
LONG ret;
LONG ret;
LONG phstat3;
LONG phstat1;
LONG phcon1;
@@ -345,8 +366,8 @@ ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(
phstat3 = enc624j6l_ReadPHY( boardbase, PHSTAT3 );
phcon1 = enc624j6l_ReadPHY( boardbase, PHCON1 );
phstat1 = enc624j6l_ReadPHY( boardbase, PHSTAT1 ); /* read again to see whether link is established */
if( ( phstat1 < 0 ) || ( phstat3 < 0 ) )
return HW_MAC_INVALID; /* no valid data found */
if( ( phstat1 < 0 ) || ( phstat3 < 0 ) )
return HW_MAC_INVALID; /* no valid data found */
/* a) check Link */
ret = 0;
@@ -358,7 +379,7 @@ ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(
if( phcon1 & PHCON1_ANEN ) /* autonegotiation enabled */
ret |= HW_MAC_AUTONEGOTIATION;
phstat3 = (phstat3>>2)&7; /* get active Speed/Duplex */
phstat3 = (phstat3>>2)&7; /* get active Speed/Duplex */
switch( phstat3 )
{
case 6:
@@ -385,6 +406,30 @@ 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) )
{
APTR boardbase = db->db_Units[unit].duh_BASE;
return enc624j6l_ReadPHY( boardbase, reg );
}
/* 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) )
{
APTR boardbase = db->db_Units[unit].duh_BASE;
return enc624j6l_WritePHY( boardbase, reg, value );
}
ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) struct List *mcastlist ASMREG(a1) )
@@ -404,8 +449,6 @@ ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(
enc624j6l_bc_mc_filter(boardbase, flags );/* flags & (PIO_INIT_BROAD_CAST|PIO_INIT_MULTI_CAST) ); */
return 1;
}
@@ -417,7 +460,9 @@ void myhw_ControlInterrupts( DEVBASEP )
ObtainSemaphore( &hwd->hwd_Sem ); /* redundant here: server is a single task -> but it looks good :-) */
flag = 0;
hwd->hwd_act_boards[0] = HW_MAGIC_WORD;
flag = 1;
for( i=0 ; i < db->db_NBoards ; i++ )
{
if( db->db_Units[i].duh_online )
@@ -431,7 +476,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 ) /* determine on/off switch */
if( flag>1 ) /* determine on/off switch */
{
/* at least 1 board is online */
if( hwd->hwd_Interrupt.is_Data )
+1 -1
View File
@@ -22,7 +22,7 @@
struct HWData {
struct Interrupt hwd_Interrupt; /* keep the interrupt at top of HWData !! */
struct SignalSemaphore hwd_Sem; /* list locking (global per unit) */
APTR hwd_act_boards[MAX_UNITS+1+3]; /* poll all active boards by ptr in interrupt, NULL terminated, followed by SigTask,Sigbit,ExecBase */
APTR hwd_act_boards[MAX_UNITS+1+3+1]; /* poll all active boards by ptr in interrupt, MAGIC_WORD INIT, NULL terminated, followed by SigTask,Sigbit,ExecBase */
ULONG hwd_SigMask; /* signal mask to wait for in server main instance */
+28 -2
View File
@@ -51,7 +51,7 @@ struct devbase;
#define HW_MACB_SPEEDS_END 18 /* this is the next free bit */
#define HW_MAC_SPEEDSMASK ((1<<HW_MACB_SPEEDS_END)-4)
#define HW_MAC_NEXTSPEED(_a_) ( (_a_)+2 )
#define HW_MAGIC_WORD 0xB00BDEED
@@ -94,10 +94,24 @@ ASM SAVEDS void hw_ConfigInit( ASMR(a0) DEVBASEP ASMREG(a0) )
ASM SAVEDS void hw_ConfigUpdate( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(a1) void * ASMREG(a1) );
/*
send a single frame to the hardware:
- either fully assembled frame (14 bytes DMAC,SMAC,TYPE followed by payload
- or payload in "frame" and 14 byte header in "header"
- provide Makefile-level definition of HW_DMA_TX in the latter case
- note: if you pass "header==NULL" with active HW_DMA_TX definition,
the hw_send_frame assumes the header to be present (SANA-II RAW frames) and
is handling "frame" as fully assembled frame
*/
ASM SAVEDS LONG hw_send_frame( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(a1) UBYTE *frame ASMREG(a1),
ASMR(d1) ULONG framesize ASMREG(d1) );
ASMR(d1) ULONG framesize ASMREG(d1)
#ifdef HW_DMA_TX
,ASMR(a2) UBYTE *header ASMREG(a2)
#endif
);
ASM SAVEDS LONG hw_recv_frame( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
@@ -116,6 +130,18 @@ ASM SAVEDS LONG hw_change_multicast( ASMR(a0) DEVBASEP ASMREG(
ASM SAVEDS LONG hw_get_mac_status( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0) );
/* read PHY register (return -1 in case of error) */
ASM SAVEDS LONG hw_read_phy( ASMR(a0) DEVBASEP ASMREG(a0),
ASMR(d0) ULONG unit ASMREG(d0),
ASMR(d1) ULONG reg ASMREG(d1) );
/* 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) );
/* kept this global for now: Z-II/Z-III boards share the same interrupt */
ASM SAVEDS ULONG hw_recv_sigmask( ASMR(a0) DEVBASEP ASMREG(a0) );
+1 -1
View File
@@ -39,5 +39,5 @@ HW_MACB_SPEED5000 EQU 10
HW_MACB_SPEED10000 EQU 12 ; Am I optimistic ?
HW_MACB_SPEEDS_END EQU 14 ; this is the next free bit
HW_MAC_SPEEDSMASK EQU ((1<<HW_MACB_SPEEDS_END)-4)
HW_MAGIC_WORD EQU $B00BDEED
endc ;_INC_HW_I
+44
View File
@@ -0,0 +1,44 @@
incdir include:
ifnd _LVOSupervisor
include exec/exec_lib.i
endc
include exec/execbase.i
ifnd _LVORawDoFmt
_LVORawDoFmt equ -$20a
endc
ifnd _LVORawPutChar
_LVORawPutChar equ -$204
_LVORawIOInit equ -$1f8
_LVORawMayGetChar equ -$1fe
endc
XDEF _KPrintF
;A0 = format
;A1 = arguments
_KPrintF:
ifd DEBUG
movem.l d0-d2/a0-a3/a6,-(sp)
move.l 4.w,a6
jsr _LVORawIOInit(a6) ;better safe than sorry
lea .kprintfproc(pc),a2
suba.l a3,a3 ;data pointer (0 here)
jsr _LVORawDoFmt(a6)
movem.l (sp)+,d0-d2/a0-a3/a6
rts
.kprintfproc:
movem.l d0/d1/a0/a1/a6,-(sp)
move.l 4.w,a6
jsr _LVORawPutChar(a6) ; move.b d0,(a3)+
movem.l (sp)+,d0/d1/a0/a1/a6
endc ;DEBUG
rts
+661
View File
@@ -0,0 +1,661 @@
/*******************************************************************************************/
/** **/
/** miitool.c **/
/** 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: **/
/** 1. Redistributions of source code must retain the above copyright **/
/** notice, this list of conditions and the following disclaimer. **/
/** 2. Redistributions in binary form must reproduce the above copyright **/
/** notice, this list of conditions and the following disclaimer in the **/
/** documentation and/or other materials provided with the distribution. **/
/** 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 **/
/** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE **/
/** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY **/
/** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES **/
/** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; **/
/** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND **/
/** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **/
/** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **/
/** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **/
/** **/
/*******************************************************************************************/
/*
Notes:
- make sure you have an up-to-date devices/sana2devqueryext.h
- make sure you have devices/newstyle.h
- compilation
sc miitool.c link
*/
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <devices/newstyle.h>
#include <devices/sana2.h>
#include <devices/sana2devqueryext.h>
#include "miitool.h"
#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 {
BYTE *devname;
LONG *unit; /* unit to open */
ULONG verbose; /* verbose mode enabled */
BYTE *force; /* force media type */
BYTE *advertise; /* advertise specific types */
ULONG renegotiate; /* restart autonegotiation */
ULONG reset; /* reset MII */
ULONG vverbose; /* higher verbosity level */
};
struct prgdata {
struct MsgPort *sana2devport;
struct IOSana2Req *sana2devio;
struct Device *sana2dev;
UBYTE devvalid;
struct progopts opts;
};
void end_prog( struct prgdata *prg )
{
if( prg->sana2devio )
{
if( prg->devvalid )
CloseDevice( (struct IORequest *)prg->sana2devio );
DeleteIORequest( (struct IORequest *)prg->sana2devio );
}
if( prg->sana2devport )
DeleteMsgPort( prg->sana2devport );
}
/*
note: call this only once at program startup
*/
LONG start_prog( struct prgdata *prg )
{
SHORT i;
UBYTE *t = (UBYTE*)prg;
for( i=0 ; i < sizeof( struct prgdata ) ; i++ )
*t++ = 0;
prg->sana2devport = CreateMsgPort();
if( !prg->sana2devport )
goto err;
prg->sana2devio = (struct IOSana2Req *) CreateIORequest(
prg->sana2devport, sizeof(struct IOSana2Req));
if( !prg->sana2devio )
goto err;
return 1;
err:
end_prog( prg );
return 0;
}
void clr_device( struct prgdata *prg )
{
if( !prg->devvalid )
return;
prg->devvalid = 0;
CloseDevice( (struct IORequest *)prg->sana2devio );
}
LONG get_device(struct prgdata *prg, BYTE *name, LONG unit )
{
if( !name )
return 0;
if( prg->devvalid ) /* close previously opened device */
clr_device( prg );
prg->devvalid = OpenDevice(name,unit,(struct IORequest *)prg->sana2devio,0) == 0;
if( !prg->devvalid )
{
Printf( "Cannot open %s unit %ld\n",(ULONG)name,unit );
return 0;
}
return 1;
}
static BOOL findcmd(struct NSDeviceQueryResult *nsdqr, UWORD cmd)
{
UWORD *p;
for (p = nsdqr->SupportedCommands; (*p); ++p)
if (*p == cmd)
return TRUE;
return FALSE;
}
/*
verify NSD support, SANA-II type, Device Query extension on previously opened device
*/
LONG probe_device( struct prgdata *prg )
{
struct IOStdReq *stdreq;
struct NSDeviceQueryResult nsdqr;
if( !prg )
return 0;
if( !prg->devvalid )
return 0;
stdreq = (struct IOStdReq *)prg->sana2devio;
stdreq->io_Command = NSCMD_DEVICEQUERY;
stdreq->io_Flags = 0;
stdreq->io_Data = &nsdqr;
stdreq->io_Length = sizeof nsdqr;
if (DoIO((struct IORequest *) stdreq) != 0)
{
Printf("I/O error: no NewStyleDevice.\n");
return 0;
}
if (nsdqr.DeviceType != NSDEVTYPE_SANA2)
{
Printf("Device is not a SANA-II device (type %ld, needed %ld\n).", (LONG)nsdqr.DeviceType, (LONG) NSDEVTYPE_SANA2);
return 0;
}
if (!findcmd(&nsdqr, S2_DEVICEQUERYEXT))
{
Printf("Device does not support S2_DEVICEQUERYEXT.\n");
return 0;
}
return 1;
}
const struct {
BYTE *name;
UWORD namelen;
UWORD value;
} media[] = {
/* The order through 100baseT4 matches bits in the BMSR */
{ "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 },
{ "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]))
void dump_mii_media( USHORT par, BOOL bestonly )
{
LONG i;
par >>= 5; /* get upper bits */
for( i=4 ; i >= 0 ; i-- )
{
if( par & (1<<i) )
{
Printf(" ");
Printf("%s",(ULONG)media[i].name);
if( bestonly )
break;
}
}
if( par & (1<<5) )
Printf(" flow-control");
}
LONG parse_speedduplex( BYTE *parameters )
{
LONG i,res = 0;
BYTE *s;
if( !parameters )
return 0;
s = parameters;
while( *s != 0 )
{
for( i=0 ; i < NMEDIA ; i++ )
if( Strnicmp( media[i].name, s, media[i].namelen ) == 0 )
break;
if( i==NMEDIA )
goto err;
s += media[i].namelen;
res |= media[i].value;
/* skip " " and/or "," */
while( *s != 0 )
{
if( (*s==' ') || (*s==',') )
s++;
else
break;
}
}
return res;
err:
Printf("Invalid media specification %s\n",parameters);
Printf("Valid Arguments:\n");
for( i=0 ; i < NMEDIA ; i++ )
Printf("%s\n",media[i].name);
return -1;
}
/*
note: this code assumes that "mii" has the register contents in natural
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;
LONG i;
bmcr = mii[MII_BMCR].Content;
bmsr = mii[MII_BMSR].Content;
advert = mii[MII_ANAR].Content;
curlink = mii[MII_ANLPAR].Content;
if( bmcr == 0xffff )
{
Printf("No MII transceiver found\n");
return 0;
}
if( bmcr & MII_BMCR_AN_ENA)
{
if( bmsr & MII_BMSR_AN_COMPLETE)
{
if( advert & curlink )
{
if( curlink & MII_AN_ACK )
Printf("negotiated ");
else Printf("no autonegotiation,");
dump_mii_media( advert & curlink, 1 );
Printf(", ");
}
else
{
Printf("autonegotiation failed, ");
}
}
else
if (bmcr & MII_BMCR_RESTART)
{
Printf("autonegotiation restarted, ");
}
}
else
{
Printf("%s Mbit, %s duplex, ",
(bmcr & MII_BMCR_100MBIT) ? "100" : "10",
(bmcr & MII_BMCR_DUPLEX) ? "full" : "half" );
}
if( bmsr & MII_BMSR_LINK_VALID )
Printf("link ok");
else Printf("no link");
Printf("\n");
if( verbose > 1 )
{
Printf("PHY Registers:");
for( i=0 ; i < length/sizeof( struct S2DevQueryMIIParam ) ; i++ )
{
if(!(i%8))
Printf("\n");
if( mii[i].ID == S2_DEVQUERYEXT_MII_INVALID )
Printf("N/A ");
else
Printf("%04lx ",(LONG)(mii[i].Content));
}
Printf("\n");
}
if( verbose )
{
Printf(" vendor %02lx:%02lx:%02lx, model %ld rev %ld\n",
(LONG)mii[2].Content>>10,
(LONG)(mii[2].Content>>2)&0xff,
(LONG)((mii[2].Content<<6)|(mii[3].Content>>10))&0xff,
(LONG)(mii[3].Content>>4)&0x3f,
(LONG)(mii[3].Content&0x0f)
);
Printf(" basic mode: ");
if( bmcr & MII_BMCR_RESET )
Printf("software reset, ");
if( bmcr & MII_BMCR_LOOPBACK )
Printf("loopback, ");
if( bmcr & MII_BMCR_ISOLATE )
Printf("isolate, ");
if( bmcr & MII_BMCR_COLTEST )
Printf("collision test, ");
if( bmcr & MII_BMCR_AN_ENA )
Printf("autonegotiation enabled\n");
else
Printf("%s Mbit, %s duplex\n",
(bmcr & MII_BMCR_100MBIT) ? "100" : "10",
(bmcr & MII_BMCR_DUPLEX) ? "full" : "half");
Printf(" basic status: ");
if( bmsr & MII_BMSR_AN_COMPLETE )
Printf("autonegotiation complete, ");
else if( bmcr & MII_BMCR_RESTART )
Printf("autonegotiation restarted, ");
if( bmsr & MII_BMSR_REMOTE_FAULT )
Printf(" remote fault, ");
Printf( (bmsr & MII_BMSR_LINK_VALID) ? "link ok" : "no link");
Printf("\n capabilities:");
dump_mii_media( bmsr >> 6, 0 );
Printf("\n advertising: ");
dump_mii_media( advert, 0 );
if( curlink & MII_AN_ABILITY_MASK )
{
Printf("\n link partner:");
dump_mii_media( curlink, 0 );
}
Printf("\n");
}
return 1;
}
/*
Query consecutive set of MII registers from start to end (inclusive)
*/
LONG query_mii( struct prgdata *prg, struct S2DevQueryMIIParam *mii, LONG start, LONG end )
{
struct S2DevQueryMIIParam *miitmp;
struct S2DevQueryExtParam parm_mii;
struct TagItem tags[2];
LONG i;
/* MII specific */
parm_mii.Data = (APTR)mii;
parm_mii.Length = (end-start+1)*sizeof(struct S2DevQueryMIIParam);
parm_mii.Actual = 0;
for( i=start,miitmp=mii ; i <= end ; i++,miitmp++ ) /* MII standard register set: 8 */
{
miitmp->ID = i;
}
tags[i=0].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 )
return 0;
else
return parm_mii.Actual;
}
LONG write_mii( struct prgdata *prg, struct S2DevQueryMIIParam *mii, LONG num )
{
struct S2DevQueryExtParam parm_mii;
struct TagItem tags[2];
LONG i;
/* MII specific */
parm_mii.Data = (APTR)mii;
parm_mii.Length = (num)*sizeof(struct S2DevQueryMIIParam);
parm_mii.Actual = 0;
tags[i=0].ti_Tag = S2_DevQueryExtSetMII;
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 )
return 0;
else
return parm_mii.Actual;
}
/* 8 basic registers, we poll 16 out of curiosity */
#define MII_REGNUM 16
/* two spare registers for write mode */
#define MII_SPARE 2
int main(int argc, char **argv)
{
struct prgdata _prg,*prg=&_prg;
int res = RETURN_FAIL;
char vendorname[128], productname[128];
struct S2DevQueryExtParam parm_productname;
struct S2DevQueryExtParam parm_vendorname;
struct S2DevQueryExtParam parm_mii;
struct S2DevQueryMIIParam mii[MII_REGNUM+MII_SPARE];
struct TagItem tags[3];
int i;
struct RDArgs *rdargs;
BYTE *name;
LONG unit,autoneg,force;
if( !start_prog(prg) )
return res;
if( !(rdargs = ReadArgs( (char*)opt_template,(LONG*)&prg->opts,NULL) ) )
{
Printf("Argument error\n");
end_prog(prg);
return res;
}
if( !prg->opts.devname )
{
name = "enc624j6net.device";
Printf("TODO: auto-detect, now trying default %s\n",name);
/* 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
if( prg->opts.verbose )
prg->opts.verbose = 1;
/* parameter check */
if( ( (prg->opts.force) && (prg->opts.renegotiate) ) ||
( (prg->opts.force) && (prg->opts.advertise) )
)
{
Printf("Error: Forced and Autonegotiation parameter mismatch\n");
end_prog(prg);
return RETURN_FAIL;
}
/* convert text to binary mask */
autoneg = parse_speedduplex( prg->opts.advertise );
force = parse_speedduplex( prg->opts.force );
if( (autoneg|force) < 0 )
{
end_prog(prg);
return RETURN_FAIL;
}
if( get_device( prg, name , unit ) )
{
if( probe_device( prg ) )
res = RETURN_OK;
}
if( res != RETURN_OK )
{
end_prog(prg);
return res;
}
/* device open, query extension present, now query it */
{
/* general information */
parm_vendorname.Data = vendorname;
parm_vendorname.Length = sizeof(vendorname);
parm_vendorname.Actual = 0;
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;
tags[i++].ti_Data = (ULONG) &parm_productname;
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);
DoIO( (struct IORequest *)prg->sana2devio );
/* separate query subroutine in here for MII, though not
absolutely necessary (MII is queried more than once) */
parm_mii.Actual = query_mii( prg, mii, 0, 15 );
if( parm_mii.Actual )
{
/* read BMSR twice */
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 )
res = RETURN_WARN;
else res = RETURN_OK;
mii[MII_BMSR].Content = mii[16].Content; /* read BMSR twice */
#endif
}
Printf("Device: %s\n",name);
/* general info */
if( parm_vendorname.Actual != 0 )
{
vendorname[parm_vendorname.Actual-1] = 0;
Printf("Vendor: %s\n",vendorname);
}
if( parm_productname.Actual != 0 )
{
productname[parm_productname.Actual-1] = 0;
Printf("Product: %s\n",productname);
}
/* after query, see what we've got */
if( res == RETURN_OK )
{
/* MII data */
if( parm_mii.Actual == 0 )
{
Printf("Unable to query MII data.\n");
}
else
{
if( !(prg->opts.renegotiate) && !(prg->opts.reset)
&& !(prg->opts.advertise) && !(prg->opts.force)
)
{
Printf("Active Parameters:\n");
dump_mii( mii, parm_mii.Actual, prg->opts.verbose );
}
}
if( prg->opts.reset )
{
Printf("resetting the transceiver...\n");
mii[MII_REGNUM].ID = MII_BMCR;
mii[MII_REGNUM].Content = MII_BMCR_RESET;
write_mii( prg, &mii[MII_REGNUM], 1 );
}
if( prg->opts.advertise )
{
mii[MII_REGNUM].ID = MII_ANAR;
mii[MII_REGNUM].Content = autoneg|1;
write_mii( prg, &mii[MII_REGNUM], 1 );
prg->opts.renegotiate = 1;
}
if( prg->opts.renegotiate )
{
Printf("restarting autonegotiation...\n");
mii[MII_REGNUM].ID = MII_BMCR;
mii[MII_REGNUM].Content = 0x0000;
write_mii( prg, &mii[MII_REGNUM], 1 );
mii[MII_REGNUM].ID = MII_BMCR;
mii[MII_REGNUM].Content = MII_BMCR_AN_ENA|MII_BMCR_RESTART;
write_mii( prg, &mii[MII_REGNUM], 1 );
}
if( prg->opts.force )
{
UWORD bmcr = 0;
if( force & (MII_AN_100BASETX_FD|MII_AN_100BASETX_HD))
bmcr |= MII_BMCR_100MBIT;
if( force & (MII_AN_100BASETX_FD|MII_AN_10BASET_FD))
bmcr |= MII_BMCR_DUPLEX;
mii[MII_REGNUM].ID = MII_BMCR;
mii[MII_REGNUM].Content = bmcr;
write_mii( prg, &mii[MII_REGNUM], 1 );
}
}
end_prog(prg);
return res;
}
+70
View File
@@ -0,0 +1,70 @@
/*******************************************************************************************/
/** **/
/** miitool.h **/
/** definitions for PHY registers **/
/** **/
/** Copyright (C) 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org **/
/** **/
/** origin: mii.h in net-tools-1.60 **/
/** **/
/*******************************************************************************************/
#ifndef _INC_MIITOOL_H
#define _INC_MIITOOL_H
/* Basic Mode Control Register */
#define MII_BMCR 0x00
#define MII_BMCR_RESET 0x8000
#define MII_BMCR_LOOPBACK 0x4000
#define MII_BMCR_100MBIT 0x2000
#define MII_BMCR_AN_ENA 0x1000
#define MII_BMCR_ISOLATE 0x0400
#define MII_BMCR_RESTART 0x0200
#define MII_BMCR_DUPLEX 0x0100
#define MII_BMCR_COLTEST 0x0080
/* Basic Mode Status Register */
#define MII_BMSR 0x01
#define MII_BMSR_CAP_MASK 0xf800
#define MII_BMSR_100BASET4 0x8000
#define MII_BMSR_100BASETX_FD 0x4000
#define MII_BMSR_100BASETX_HD 0x2000
#define MII_BMSR_10BASET_FD 0x1000
#define MII_BMSR_10BASET_HD 0x0800
#define MII_BMSR_NO_PREAMBLE 0x0040
#define MII_BMSR_AN_COMPLETE 0x0020
#define MII_BMSR_REMOTE_FAULT 0x0010
#define MII_BMSR_AN_ABLE 0x0008
#define MII_BMSR_LINK_VALID 0x0004
#define MII_BMSR_JABBER 0x0002
#define MII_BMSR_EXT_CAP 0x0001
#define MII_PHY_ID1 0x02
#define MII_PHY_ID2 0x03
/* Auto-Negotiation Advertisement Register */
#define MII_ANAR 0x04
/* Auto-Negotiation Link Partner Ability Register */
#define MII_ANLPAR 0x05
#define MII_AN_NEXT_PAGE 0x8000
#define MII_AN_ACK 0x4000
#define MII_AN_REMOTE_FAULT 0x2000
#define MII_AN_ABILITY_MASK 0x07e0
#define MII_AN_FLOW_CONTROL 0x0400
#define MII_AN_100BASET4 0x0200
#define MII_AN_100BASETX_FD 0x0100
#define MII_AN_100BASETX_HD 0x0080
#define MII_AN_10BASET_FD 0x0040
#define MII_AN_10BASET_HD 0x0020
#define MII_AN_PROT_MASK 0x001f
#define MII_AN_PROT_802_3 0x0001
/* Auto-Negotiation Expansion Register */
#define MII_ANER 0x06
#define MII_ANER_MULT_FAULT 0x0010
#define MII_ANER_LP_NP_ABLE 0x0008
#define MII_ANER_NP_ABLE 0x0004
#define MII_ANER_PAGE_RX 0x0002
#define MII_ANER_LP_AN_ABLE 0x0001
#endif /* _INC_MIITOOL_H */
+13 -10
View File
@@ -36,21 +36,20 @@ extern const BYTE DeviceName[];
#define HW_INTERVALDEF 10000
#define HW_DEFSPI 2
/* these calls might not run within the context of a process and
will be called from varying tasks and without prior init:
hw_Find_Boards()
hw_Find_Boards() - this one just identifies available HW and returns #boards
hw_AllocBoard()
hw_ReleaseBoard()
hw_GetMacAddress()
hw_GetMacAddress() - get default MAC address from board
these calls are in the context of the server task:
hw_Setup() - general init (board allocated already)
hw_Shutdown() - general shutdown (board still allocated)
hw_Attach() - make hardware ready for action (online)
hw_Detach() - put hardware into sleep mode (offline)
hw_Setup() - general init (board allocated already)
hw_Shutdown() - general shutdown (board still allocated)
hw_Attach() - make hardware ready for action (online)
hw_Detach() - put hardware into sleep mode (offline)
hw_recv_sigmask() - get signals for hardware (if any)
hw_recv_sigmask() - get signals for hardware (if any, i.e. signal on interrupt)
hw_recv_pending() - check for pending receive frames
hw_recv_frame() - receive one frame
@@ -59,10 +58,14 @@ extern const BYTE DeviceName[];
and apply them (called only when no RX/TX
in progress)
hw_config_init() - set defaults for HW
hw_config_update() - update config of HW
hw_ConfigInit() - set defaults for HW
hw_ConfigUpdate() - update config of HW
hw_change_multicast - re-initialize multicast filter for new address list
hw_get_mac_status() - running parameters (optional), S2_DEVICEQUERYEXT
*/
#ifdef PROTO_V2EXPNET
#define USE_INTERRUPT
+143 -12
View File
@@ -35,9 +35,12 @@ static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq );
*/
#define S2QUERYEXT_NOLENGTHCHECK
/* this limits the number of write requests per run, also improves
Roadshow performance when active */
#define ONE_WRITE_REQ
/* 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
/* this limits the number of processed read requests per run when enabled */
#define ONE_READ_REQ 2
/* (avoid external link libraries) this call is not time critical */
@@ -570,6 +573,67 @@ static LONG server_queryext( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq )
}
}
#ifdef S2_DevQueryExtGetMII
tval = GetTagData( S2_DevQueryExtGetMII, 0, tlist );
if( tval )
{
struct S2DevQueryMIIParam *miip;
LONG res;
LONG curidx=0,lastidx = 0;
D(("MII Register Query"));
s2qep = (struct S2DevQueryExtParam *)tval;
len = s2qep->Length; /* in Bytes */
miip = (struct S2DevQueryMIIParam *)s2qep->Data;
while( curidx <= len-sizeof( struct S2DevQueryMIIParam ) )
{
if( (res = hw_read_phy( db, unit, miip->ID )) >= 0 )
{
miip->Content = res;
lastidx = curidx;
}
else
{ /* can't read register ID, invalidate */
miip->ID = S2_DEVQUERYEXT_MII_INVALID;
miip->Content = 0;
}
miip++;
curidx += sizeof( struct S2DevQueryMIIParam );
}
s2qep->Actual = lastidx;
}
#endif
#ifdef S2_DevQueryExtSetMII
tval = GetTagData( S2_DevQueryExtSetMII, 0, tlist );
if( tval )
{
struct S2DevQueryMIIParam *miip;
LONG res;
LONG curidx=0,lastidx = 0;
D(("MII Register Write"));
s2qep = (struct S2DevQueryExtParam *)tval;
len = s2qep->Length; /* in Bytes */
miip = (struct S2DevQueryMIIParam *)s2qep->Data;
while( curidx <= len-sizeof( struct S2DevQueryMIIParam ) )
{
if( miip->ID != S2_DEVQUERYEXT_MII_INVALID )
{
if( (res = hw_write_phy( db, unit, miip->ID, miip->Content )) >= 0 )
lastidx = curidx;
miip++;
curidx += sizeof( struct S2DevQueryMIIParam );
}
}
s2qep->Actual = lastidx;
}
#endif
return 1;
}
@@ -632,20 +696,34 @@ LONG server_writeerror( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq, LONG cod
#ifndef EXTERNAL_WRITE_FRAME
/* note: entering here with locked semaphore */
/*
note: entering here with locked semaphore
note(2): HW_DMA_TX is maybe a little misleading in it's actual use here.
This implementation will use that SANA-II capability in the following
way: Obtain a pointer to either the whole frame (RAW) or the Payload
and send either a complete frame or two chunks down to the hardware.
HW_DMA_TX is defined by the Makefile. One of the chunks
is the constant-size header (14 Bytes) and the other is the payload.
*/
static LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq )
{
LONG ret;/* = SERR_OK;*/
UBYTE *copy_ptr,*frame;
ULONG framesize;
struct db_BufferManagement *dbm;
#ifdef HW_DMA_TX
UBYTE *header_ptr;
#endif
D(("write: type %08lx, size %ld\n",ioreq->ios2_PacketType,
ioreq->ios2_DataLength));
frame = db->db_svdat.sv_frame;
framesize = ioreq->ios2_DataLength;
copy_ptr = frame;
copy_ptr = frame;
#ifdef HW_DMA_TX
header_ptr= NULL;
#endif
/* copy raw frame: simply overwrite ethernet frame part of plip packet */
if( !(ioreq->ios2_Req.io_Flags & SANA2IOF_RAW) )
@@ -653,18 +731,46 @@ static LONG write_frame( DEVBASEP, ULONG unit, struct IOSana2Req *ioreq )
COPYMAC( frame, ioreq->ios2_DstAddr ); /* macro in server.h */
COPYMAC( frame+6, db->db_Units[unit].du_CFGAddr );
*( (USHORT*)(frame+12)) = ioreq->ios2_PacketType;
copy_ptr += 14;
#ifdef HW_DMA_TX
header_ptr = frame;
copy_ptr += 16; /* aligned behind header with a gap of 2 */
#else
copy_ptr += 14;
framesize += 14;
#endif
}
dbm = (struct db_BufferManagement *)ioreq->ios2_BufferManagement;
/* copy32 is valid ptr, even if the stack offers only regular CopyFromBuffer */
/* #if 0 */
#ifdef HW_DMA_TX
/* hw implementation supports it, now check if we can use DMA copy buffer */
if( dbm->dbm_CopyFromBufferDMA )
{
UBYTE *dma_ptr;
dma_ptr = (UBYTE*)(*dbm->dbm_CopyFromBufferDMA)( ioreq->ios2_Data, NULL, 0 );
if( dma_ptr )
{
/* pass extra header if not raw */
hw_send_frame(db, unit, dma_ptr,framesize, header_ptr );
ret = SERR_OK; /* FIXME: error code */
goto dmasend_done;
}
}
#endif
/* copy32 is a valid ptr, even if the stack offers only regular CopyFromBuffer */
if( (*dbm->dbm_CopyFromBuffer32)(copy_ptr,ioreq->ios2_Data, ioreq->ios2_DataLength) )
{
send:
D(("+hw_send\n"));
ret = hw_send_frame(db, unit, frame, framesize) ? SERR_OK : SERR_ERROR;
#ifdef HW_DMA_TX
ret = hw_send_frame(db, unit, copy_ptr, framesize, header_ptr ) ? SERR_OK:SERR_ERROR;
#else
ret = hw_send_frame(db, unit, frame, framesize ) ? SERR_OK : SERR_ERROR;
#endif
D(("-hw_send\n"));
}
else
@@ -676,6 +782,10 @@ send:
ret = SERR_BUFFER_ERROR;
}
#ifdef HW_DMA_TX
dmasend_done:
#endif
return ret;
}
#endif
@@ -684,17 +794,20 @@ send:
static LONG server_writequeue( DEVBASEP, ULONG unit )
{
LONG code;
#ifdef ONE_WRITE_REQ
LONG t = 0;
#endif
struct IOSana2Req *ioreq,*nextio;
ObtainSemaphore( &db->db_Units[unit].du_Sem );
#if 1 /* #ifdef ONE_WRITE_REQ */
#if 1
/* whole queue per call */
for( ioreq = (struct IOSana2Req *)db->db_Units[unit].du_WriteQueue.lh_Head;
(nextio= (struct IOSana2Req *)ioreq->ios2_Req.io_Message.mn_Node.ln_Succ);
ioreq = nextio )
#else
/* single write per call */
/* single write per call (deprecated in favor of ONE_WRITE_REQ) */
ioreq = (struct IOSana2Req *)db->db_Units[unit].du_WriteQueue.lh_Head;
if( ioreq->ios2_Req.io_Message.mn_Node.ln_Succ )
#endif
@@ -731,8 +844,13 @@ static LONG server_writequeue( DEVBASEP, ULONG unit )
server_writeerror( db, unit, ioreq, code );
}
#ifdef ONE_WRITE_REQ
if( hw_recv_pending(db,unit) )
t++;
if( t >= ONE_WRITE_REQ ) /* this somewhat balances hardware polling overhead vs. IP-stack timing */
{
t = 0;
if( hw_recv_pending(db,unit) )
break;
}
#endif
}
@@ -817,6 +935,9 @@ static LONG server_readqueue( DEVBASEP, ULONG unit )
LONG framesize;
LONG frametype;
LONG dropflag;
#ifdef ONE_READ_REQ
LONG t=0;
#endif
while(1)
{
@@ -895,7 +1016,17 @@ nextframe:
/* TODO: check for error, send S2EVENT_HARDWARE|S2EVENT_ERROR|S2EVENT_RX along with stats db_DevStats.BadData */
goto end;
}
}
#ifdef ONE_READ_REQ
t++;
if( t>= ONE_READ_REQ )
{
struct IOSana2Req *wr = (struct IOSana2Req *)db->db_Units[unit].du_WriteQueue.lh_Head;
/* t=0; */
if( wr->ios2_Req.io_Message.mn_Node.ln_Succ )
goto end; /* pending writes ? -> leave after ONE_READ_REQ requests */
}
#endif
} /* while(1) */
end:
return SERR_OK;
}
+4 -2
View File
@@ -30,8 +30,8 @@ ASMOBJECTS = $(SUBDIR)/enc624j6l.o$(TYPE) $(SUBDIR)/intervaltimer.o$(TYPE)
# more than one flavour of the same code base may be build with this setup
# arguments passed down recursively (example):
#DEVICEID=v2expeth.device
#DEFINES1 = -DPROTO_V2EXPNET
#ASMDEFS = -DPROTO_V2EXPNET
DEFINES1 = DEFINE HW_DMA_TX=1
ASMDEFS1 = -DHW_DMA_TX=1
#CPU = 68020
@@ -98,6 +98,8 @@ DEFINES = $(DEFINES) DEFINE DEVICENAME=$(DEVICEID)
ASMDEFS = $(ASMDEFS1)
#-DDEVICEVERSION=$(DEVICEVERSION) -DDEVICEREVISION=$(DEVICEREVISION)
###############################################################################
#
# debug
+2 -2
View File
@@ -9,9 +9,9 @@
#define _INC_VERSION_H
#define DEVICEVERSION 2
#define DEVICEREVISION 0
#define DEVICEREVISION 1
#define DEVICEEXTRA
/* #define DEVICEEXTRA Beta */
#define DEVICEDATE 13.01.2019
#define DEVICEDATE 21.02.2019
#endif